diff --git a/NEWS b/NEWS index 5f6be20f..ede20084 100644 --- a/NEWS +++ b/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'. diff --git a/src/formats/alb_log.json b/src/formats/alb_log.json index c4543754..06dca842 100644 --- a/src/formats/alb_log.json +++ b/src/formats/alb_log.json @@ -19,7 +19,7 @@ "kind": "string", "identifier": true }, - "alb": { + "elb": { "kind": "string", "identifier": true }, diff --git a/src/formats/engine_log.json b/src/formats/engine_log.json index 6320cf98..eeea2e80 100644 --- a/src/formats/engine_log.json +++ b/src/formats/engine_log.json @@ -17,10 +17,6 @@ "logger": { "kind": "string", "identifier": true - }, - "thread": { - "kind": "string", - "identifier": true } }, "level-field": "level", diff --git a/src/formats/strace_log.json b/src/formats/strace_log.json index 3f31ba87..46c3a442 100644 --- a/src/formats/strace_log.json +++ b/src/formats/strace_log.json @@ -20,9 +20,6 @@ "identifier": true, "rewriter": ":pipe-line-to explain-syscall.sh ${syscall}" }, - "args": { - "kind": "string" - }, "rc": { "kind": "integer", "foreign-key": true diff --git a/src/log_format.cc b/src/log_format.cc index 6a4378aa..b9932de5 100644 --- a/src/log_format.cc +++ b/src/log_format.cc @@ -1769,7 +1769,7 @@ external_log_format::build(std::vector& 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& 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) diff --git a/src/log_format_loader.cc b/src/log_format_loader.cc index f8c9268c..7f307edc 100644 --- a/src/log_format_loader.cc +++ b/src/log_format_loader.cc @@ -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( - "(?\\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( + "(?\\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() diff --git a/test/bad-config/formats/invalid-properties/format.json b/test/bad-config/formats/invalid-properties/format.json index db547bcd..dd18b38f 100644 --- a/test/bad-config/formats/invalid-properties/format.json +++ b/test/bad-config/formats/invalid-properties/format.json @@ -13,6 +13,11 @@ "line": "1428634687123: 1234 abc" } ], + "value": { + "non-existent": { + "kind": "string" + } + }, "highlights": { "hl1": { "color": "not a color", diff --git a/test/expected/test_format_loader.sh_3f1d6f35e8a9ae4fd3e91ffaa82a037b5a847ab7.err b/test/expected/test_format_loader.sh_3f1d6f35e8a9ae4fd3e91ffaa82a037b5a847ab7.err index 55f0cda8..69a66d99 100644 --- a/test/expected/test_format_loader.sh_3f1d6f35e8a9ae4fd3e91ffaa82a037b5a847ab7.err +++ b/test/expected/test_format_loader.sh_3f1d6f35e8a9ae4fd3e91ffaa82a037b5a847ab7.err @@ -1,6 +1,6 @@ ✘ error: “abc(def” is not a valid regular expression for property “/invalid_props_log/search-table/bad_table_regex/pattern” reason: missing ) - --> {test_dir}/bad-config/formats/invalid-properties/format.json:24 + --> {test_dir}/bad-config/formats/invalid-properties/format.json:29  |  "pattern": "abc(def"   --> /invalid_props_log/search-table/bad_table_regex/pattern  | abc(def  @@ -98,6 +98,9 @@ std  = “^(?<timestamp>\d+): (?<pid>\w+) (?<body>.*)$” with-level = “^(?<timestamp>\d+)\| (?<level>\w+) (?<body>\w+)$” +✘ error: invalid value “/invalid_props_log/value/non-existent” + reason: no patterns have a capture named “non-existent” + --> {test_dir}/bad-config/formats/invalid-properties/format.json:4 ✘ error: invalid value for property “/invalid_props_log/timestamp-field” reason: “ts” was not found in the pattern at /invalid_props_log/regex/std  --> {test_dir}/bad-config/formats/invalid-properties/format.json:4 @@ -105,10 +108,10 @@ body, pid, timestamp ✘ error: “not a color” is not a valid color value for property “/invalid_props_log/highlights/hl1/color” reason: Unknown color: 'not a color'. See https://jonasjacek.github.io/colors/ for a list of supported color names - --> {test_dir}/bad-config/formats/invalid-properties/format.json:18 + --> {test_dir}/bad-config/formats/invalid-properties/format.json:23 ✘ error: “also not a color” is not a valid color value for property “/invalid_props_log/highlights/hl1/background-color” reason: Unknown color: 'also not a color'. See https://jonasjacek.github.io/colors/ for a list of supported color names - --> {test_dir}/bad-config/formats/invalid-properties/format.json:19 + --> {test_dir}/bad-config/formats/invalid-properties/format.json:24 ✘ error: “no_regexes_log” is not a valid log format reason: no regexes specified  --> {test_dir}/bad-config/formats/no-regexes/format.json:4 diff --git a/test/formats/xmlmsg/format.json b/test/formats/xmlmsg/format.json index b557ed62..912c4c5d 100644 --- a/test/formats/xmlmsg/format.json +++ b/test/formats/xmlmsg/format.json @@ -26,16 +26,6 @@ "kind": "integer", "description": "Line number – in the module – where log entry was emitted" }, - "head": { - "kind": "string", - "description": "", - "hidden": true - }, - "source": { - "kind": "string", - "description": "request ", - "hidden": true - }, "msg_data": { "kind": "xml", "rewriter": ";SELECT node_path FROM xpath('//*', :msg_data)"