mirror of
https://github.com/tstack/lnav
synced 2024-11-03 23:15:38 +00:00
[loader] make sure values defined in formats have a corresponding capture in at least one pattern
This commit is contained in:
parent
072fad4173
commit
001f26d066
2
NEWS
2
NEWS
@ -82,6 +82,8 @@ lnav v0.11.0:
|
||||
scrolling in a view.
|
||||
|
||||
Breaking Changes:
|
||||
* Formats definitions are now checked to ensure that values have a
|
||||
corresponding capture in at least one pattern.
|
||||
* Added a 'language' column to the lnav_view_filters table that
|
||||
specifies the language of the 'pattern' column, either 'regex'
|
||||
or 'sql'.
|
||||
|
@ -19,7 +19,7 @@
|
||||
"kind": "string",
|
||||
"identifier": true
|
||||
},
|
||||
"alb": {
|
||||
"elb": {
|
||||
"kind": "string",
|
||||
"identifier": true
|
||||
},
|
||||
|
@ -17,10 +17,6 @@
|
||||
"logger": {
|
||||
"kind": "string",
|
||||
"identifier": true
|
||||
},
|
||||
"thread": {
|
||||
"kind": "string",
|
||||
"identifier": true
|
||||
}
|
||||
},
|
||||
"level-field": "level",
|
||||
|
@ -20,9 +20,6 @@
|
||||
"identifier": true,
|
||||
"rewriter": ":pipe-line-to explain-syscall.sh ${syscall}"
|
||||
},
|
||||
"args": {
|
||||
"kind": "string"
|
||||
},
|
||||
"rc": {
|
||||
"kind": "integer",
|
||||
"foreign-key": true
|
||||
|
@ -1769,7 +1769,7 @@ external_log_format::build(std::vector<lnav::console::user_message>& errors)
|
||||
this->elf_has_module_format = true;
|
||||
}
|
||||
|
||||
for (pcre_named_capture::iterator name_iter = pat.p_pcre->named_begin();
|
||||
for (auto name_iter = pat.p_pcre->named_begin();
|
||||
name_iter != pat.p_pcre->named_end();
|
||||
++name_iter)
|
||||
{
|
||||
@ -1903,6 +1903,31 @@ external_log_format::build(std::vector<lnav::console::user_message>& errors)
|
||||
vd->vd_meta.lvm_kind = value_kind_t::VALUE_TEXT;
|
||||
}
|
||||
|
||||
if (this->elf_type == elf_type_t::ELF_TYPE_TEXT) {
|
||||
bool found_in_pattern = false;
|
||||
for (const auto& pat : this->elf_patterns) {
|
||||
auto cap_index = pat.second->p_pcre->name_index(
|
||||
vd->vd_meta.lvm_name.get());
|
||||
if (cap_index >= 0) {
|
||||
found_in_pattern = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found_in_pattern) {
|
||||
errors.emplace_back(
|
||||
lnav::console::user_message::error(
|
||||
attr_line_t("invalid value ")
|
||||
.append_quoted(lnav::roles::symbol(
|
||||
fmt::format(FMT_STRING("/{}/value/{}"),
|
||||
this->elf_name,
|
||||
vd->vd_meta.lvm_name.get()))))
|
||||
.with_reason(
|
||||
attr_line_t("no patterns have a capture named ")
|
||||
.append_quoted(vd->vd_meta.lvm_name.get()))
|
||||
.with_snippets(this->get_snippets()));
|
||||
}
|
||||
}
|
||||
|
||||
for (act_iter = vd->vd_action_list.begin();
|
||||
act_iter != vd->vd_action_list.end();
|
||||
++act_iter)
|
||||
|
@ -916,19 +916,19 @@ read_id(yajlpp_parse_context* ypc, const unsigned char* str, size_t len)
|
||||
}
|
||||
|
||||
struct json_path_container root_format_handler
|
||||
= json_path_container{json_path_handler("$schema", read_id)
|
||||
.with_synopsis(
|
||||
"The URI of the schema for this file")
|
||||
.with_description(
|
||||
"Specifies the type of this file"),
|
||||
= json_path_container{
|
||||
json_path_handler("$schema", read_id)
|
||||
.with_synopsis("The URI of the schema for this file")
|
||||
.with_description("Specifies the type of this file"),
|
||||
|
||||
yajlpp::pattern_property_handler(
|
||||
"(?<format_name>\\w+)")
|
||||
.with_description(
|
||||
"The definition of a log file format.")
|
||||
.with_obj_provider(ensure_format)
|
||||
.with_children(format_handlers)}
|
||||
.with_schema_id(DEFAULT_FORMAT_SCHEMA);
|
||||
yajlpp::pattern_property_handler(
|
||||
"(?<format_name>\\w+)")
|
||||
.with_description(
|
||||
"The definition of a log file format.")
|
||||
.with_obj_provider(ensure_format)
|
||||
.with_children(format_handlers),
|
||||
}
|
||||
.with_schema_id(DEFAULT_FORMAT_SCHEMA);
|
||||
|
||||
static void
|
||||
write_sample_file()
|
||||
|
@ -13,6 +13,11 @@
|
||||
"line": "1428634687123: 1234 abc"
|
||||
}
|
||||
],
|
||||
"value": {
|
||||
"non-existent": {
|
||||
"kind": "string"
|
||||
}
|
||||
},
|
||||
"highlights": {
|
||||
"hl1": {
|
||||
"color": "not a color",
|
||||
|
@ -1,6 +1,6 @@
|
||||
[1m[31m✘ error[0m: “abc(def” is not a valid regular expression for property “[1m/invalid_props_log/search-table/bad_table_regex/pattern[0m”
|
||||
[1m[31mreason[0m: missing )
|
||||
[36m --> [0m[1m{test_dir}/bad-config/formats/invalid-properties/format.json[0m:24
|
||||
[36m --> [0m[1m{test_dir}/bad-config/formats/invalid-properties/format.json[0m:29
|
||||
[36m | [0m[37m[40m "pattern": "abc(def" [0m
|
||||
[36m --> [0m[1m/invalid_props_log/search-table/bad_table_regex/pattern[0m
|
||||
[36m | [0m[37m[40mabc[0m[1m[7m[32m[40m([0m[37m[40mdef [0m
|
||||
@ -98,6 +98,9 @@
|
||||
[1mstd [0m = “[1m[36m^[0m[1m[32m([0m[1m[32m?[0m[1m[36m<[0mtimestamp>[1m\d[0m[1m[36m+[0m[1m[32m)[0m: [1m[32m([0m[1m[32m?[0m[1m[36m<[0mpid>[1m\w[0m[1m[36m+[0m[1m[32m)[0m [1m[32m([0m[1m[32m?[0m[1m[36m<[0mbody>[1m[36m.[0m[1m[36m*[0m[1m[32m)[0m[1m[36m$[0m”
|
||||
[1mwith-level[0m = “[1m[36m^[0m[1m[32m([0m[1m[32m?[0m[1m[36m<[0mtimestamp>[1m\d[0m[1m[36m+[0m[1m[32m)[0m\| [1m[32m([0m[1m[32m?[0m[1m[36m<[0mlevel>[1m\w[0m[1m[36m+[0m[1m[32m)[0m [1m[32m([0m[1m[32m?[0m[1m[36m<[0mbody>[1m\w[0m[1m[36m+[0m[1m[32m)[0m[1m[36m$[0m”
|
||||
|
||||
[1m[31m✘ error[0m: invalid value “[1m/invalid_props_log/value/non-existent[0m”
|
||||
[1m[31mreason[0m: no patterns have a capture named “non-existent”
|
||||
[36m --> [0m[1m{test_dir}/bad-config/formats/invalid-properties/format.json[0m:4
|
||||
[1m[31m✘ error[0m: invalid value for property “[1m/invalid_props_log/timestamp-field[0m”
|
||||
[1m[31mreason[0m: “ts” was not found in the pattern at [1m/invalid_props_log/regex/std[0m
|
||||
[36m --> [0m[1m{test_dir}/bad-config/formats/invalid-properties/format.json[0m:4
|
||||
@ -105,10 +108,10 @@
|
||||
[1mbody[0m, [1mpid[0m, [1mtimestamp[0m
|
||||
[1m[31m✘ error[0m: “not a color” is not a valid color value for property “[1m/invalid_props_log/highlights/hl1/color[0m”
|
||||
[1m[31mreason[0m: Unknown color: 'not a color'. See https://jonasjacek.github.io/colors/ for a list of supported color names
|
||||
[36m --> [0m[1m{test_dir}/bad-config/formats/invalid-properties/format.json[0m:18
|
||||
[36m --> [0m[1m{test_dir}/bad-config/formats/invalid-properties/format.json[0m:23
|
||||
[1m[31m✘ error[0m: “also not a color” is not a valid color value for property “[1m/invalid_props_log/highlights/hl1/background-color[0m”
|
||||
[1m[31mreason[0m: Unknown color: 'also not a color'. See https://jonasjacek.github.io/colors/ for a list of supported color names
|
||||
[36m --> [0m[1m{test_dir}/bad-config/formats/invalid-properties/format.json[0m:19
|
||||
[36m --> [0m[1m{test_dir}/bad-config/formats/invalid-properties/format.json[0m:24
|
||||
[1m[31m✘ error[0m: “[1mno_regexes_log[0m” is not a valid log format
|
||||
[1m[31mreason[0m: no regexes specified
|
||||
[36m --> [0m[1m{test_dir}/bad-config/formats/no-regexes/format.json[0m:4
|
||||
|
@ -26,16 +26,6 @@
|
||||
"kind": "integer",
|
||||
"description": "Line number – in the module – where log entry was emitted"
|
||||
},
|
||||
"head": {
|
||||
"kind": "string",
|
||||
"description": "<head>",
|
||||
"hidden": true
|
||||
},
|
||||
"source": {
|
||||
"kind": "string",
|
||||
"description": "request <source>",
|
||||
"hidden": true
|
||||
},
|
||||
"msg_data": {
|
||||
"kind": "xml",
|
||||
"rewriter": ";SELECT node_path FROM xpath('//*', :msg_data)"
|
||||
|
Loading…
Reference in New Issue
Block a user