diff --git a/NEWS.md b/NEWS.md index a2c838e10c..945bf561cd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -322,6 +322,13 @@ Features: `schema` column with the `log_msg_schema` of the messages logged by each statement, so they can be found with a `log_msg_schema = …` constraint. +* The `source_log_stmt()` table-valued function has a new + `level` column with the level of the messages logged by + each statement, as log2src determined it from the logging + call (e.g. `warning` for `log.warn(...)`), or NULL when it + could not tell, like for a `printf()`. When a message + matches more than one statement equally well, the one with + the same level as the message is now chosen. Interface Changes: * Moving horizontally now defaults to moving to the diff --git a/src/all_logs_vtab.cc b/src/all_logs_vtab.cc index 5c7fbca3ca..11f67dc845 100644 --- a/src/all_logs_vtab.cc +++ b/src/all_logs_vtab.cc @@ -362,8 +362,11 @@ all_logs_vtab::extract(const log_cursor::extract_context& ec, #ifdef HAVE_RUST_DEPS auto find_res = unmatched ? nullptr - : find_statement( - line, sa, sub_values, ec.is_column_used(this->alv_values_meta)); + : find_statement(line, + sa, + sub_values, + lf->begin()[line_number].get_msg_level(), + ec.is_column_used(this->alv_values_meta)); if (find_res != nullptr) { char schema_buf[hasher::STRING_SIZE]; statement_schema(string_fragment::from(find_res->src), @@ -433,6 +436,7 @@ std::unique_ptr all_logs_vtab::find_statement(const shared_buffer_ref& sbr, const string_attrs_t& sa, const logline_value_vector& values, + log_level_t level, bool extract_variables) { if (!sbr.get_metadata().m_valid_utf) { @@ -466,9 +470,59 @@ all_logs_vtab::find_statement(const shared_buffer_ref& sbr, return lnav_rs_ext::find_log_statement_json( file_rust_str, lineno, + to_stmt_level(level), rust::Str(body_sf.data(), body_sf.length()), find_options); } + +lnav_rs_ext::StmtLevel +all_logs_vtab::to_stmt_level(log_level_t level) +{ + switch (level) { + case LEVEL_TRACE: + return lnav_rs_ext::StmtLevel::trace; + case LEVEL_DEBUG5: + case LEVEL_DEBUG4: + case LEVEL_DEBUG3: + case LEVEL_DEBUG2: + case LEVEL_DEBUG: + return lnav_rs_ext::StmtLevel::debug; + case LEVEL_INFO: + case LEVEL_STATS: + case LEVEL_NOTICE: + return lnav_rs_ext::StmtLevel::info; + case LEVEL_WARNING: + return lnav_rs_ext::StmtLevel::warning; + case LEVEL_ERROR: + return lnav_rs_ext::StmtLevel::error; + case LEVEL_CRITICAL: + case LEVEL_FATAL: + return lnav_rs_ext::StmtLevel::fatal; + default: + return lnav_rs_ext::StmtLevel::unknown; + } +} + +log_level_t +all_logs_vtab::from_stmt_level(lnav_rs_ext::StmtLevel level) +{ + switch (level) { + case lnav_rs_ext::StmtLevel::trace: + return LEVEL_TRACE; + case lnav_rs_ext::StmtLevel::debug: + return LEVEL_DEBUG; + case lnav_rs_ext::StmtLevel::info: + return LEVEL_INFO; + case lnav_rs_ext::StmtLevel::warning: + return LEVEL_WARNING; + case lnav_rs_ext::StmtLevel::error: + return LEVEL_ERROR; + case lnav_rs_ext::StmtLevel::fatal: + return LEVEL_FATAL; + default: + return LEVEL_UNKNOWN; + } +} #endif bool diff --git a/src/all_logs_vtab.hh b/src/all_logs_vtab.hh index e1096b9e4c..3fc69c060f 100644 --- a/src/all_logs_vtab.hh +++ b/src/all_logs_vtab.hh @@ -43,6 +43,7 @@ #ifdef HAVE_RUST_DEPS namespace lnav_rs_ext { struct FindLogResultJson; +enum class StmtLevel : std::uint8_t; } #endif @@ -139,13 +140,24 @@ public: /** * Finds the source statement that logged a message, or nullptr. The * sbr is the message, sa and values are what the format's annotate() - * gave for it. + * gave for it, and level is the message's level, which breaks ties + * between statements that match equally well. */ static std::unique_ptr find_statement( const shared_buffer_ref& sbr, const string_attrs_t& sa, const logline_value_vector& values, + log_level_t level, bool extract_variables); + + /** + * The level of a message as log2src tells them apart. The levels it + * doesn't have are folded into the nearest one it does. + */ + static lnav_rs_ext::StmtLevel to_stmt_level(log_level_t level); + + /** The level of a log statement found by log2src. */ + static log_level_t from_stmt_level(lnav_rs_ext::StmtLevel level); #endif private: diff --git a/src/log_data_helper.cc b/src/log_data_helper.cc index f5eefa9bc7..c4ac53dc83 100644 --- a/src/log_data_helper.cc +++ b/src/log_data_helper.cc @@ -33,6 +33,8 @@ #include "log_data_helper.hh" +#include "all_logs_vtab.hh" + #include "base/ansi_scrubber.hh" #include "base/attr_line.builder.hh" #include "config.h" @@ -268,8 +270,11 @@ log_data_helper::parse_body() } this->ldh_src_ref = std::nullopt; this->ldh_src_vars.clear(); - auto find_res - = lnav_rs_ext::find_log_statement(file_rust_str, lineno, body_rust_str); + auto find_res = lnav_rs_ext::find_log_statement( + file_rust_str, + lineno, + all_logs_vtab::to_stmt_level(this->ldh_line->get_msg_level()), + body_rust_str); if (find_res != nullptr) { this->ldh_src_ref = lnav::src_ref{ std::filesystem::path((std::string) find_res->src.file), diff --git a/src/log_stmt_stats.cc b/src/log_stmt_stats.cc index 567338b432..f4a227b146 100644 --- a/src/log_stmt_stats.cc +++ b/src/log_stmt_stats.cc @@ -311,6 +311,7 @@ struct stmt_map { const shared_buffer_ref& sbr, const string_attrs_t& sa, const logline_value_vector& values, + log_level_t level, match_scratch& ms) { #ifdef HAVE_RUST_DEPS @@ -325,7 +326,7 @@ struct stmt_map { } } - auto res = all_logs_vtab::find_statement(sbr, sa, values, true); + auto res = all_logs_vtab::find_statement(sbr, sa, values, level, true); if (res == nullptr) { return; } @@ -370,14 +371,15 @@ struct stmt_map { format->annotate(lf, line_number, sa, values); - auto find_res = all_logs_vtab::find_statement(sbr, sa, values, false); + auto find_res = all_logs_vtab::find_statement( + sbr, sa, values, ll->get_msg_level(), false); if (find_res == nullptr) { return NO_STATEMENT; } auto id = this->intern_cached( ms.ms_cache, ms.ms_arena, find_res->src, find_res->pattern); - this->sample_vars(id, sbr, sa, values, ms); + this->sample_vars(id, sbr, sa, values, ll->get_msg_level(), ms); return id; #else return NO_STATEMENT; diff --git a/src/log_stmt_vtab.cc b/src/log_stmt_vtab.cc index e25e487123..09ff719c78 100644 --- a/src/log_stmt_vtab.cc +++ b/src/log_stmt_vtab.cc @@ -48,6 +48,7 @@ enum class log_stmt_col : uint8_t { function_name, qualified_name, block_id, + level, pattern, path, schema, @@ -67,6 +68,7 @@ CREATE TABLE lnav_db.source_log_stmt ( function_name TEXT, qualified_name TEXT, block_id INTEGER, + level TEXT, pattern TEXT, path TEXT, schema TEXT, @@ -132,6 +134,17 @@ CREATE TABLE lnav_db.source_log_stmt ( case log_stmt_col::block_id: to_sqlite(ctx, (int64_t) stmt.src.block_id); break; + case log_stmt_col::level: + if (stmt.level == lnav_rs_ext::StmtLevel::unknown) { + sqlite3_result_null(ctx); + } else { + const auto& name + = level_names[all_logs_vtab::from_stmt_level( + stmt.level)]; + sqlite3_result_text( + ctx, name.data(), name.length(), SQLITE_STATIC); + } + break; case log_stmt_col::pattern: to_sqlite(ctx, (std::string) stmt.pattern); break; @@ -247,6 +260,10 @@ register_log_stmt_vtab(sqlite3* db) "An ID for the innermost block containing the " "statement. Statements in the same file with the " "same ID are in the same block."}) + .with_result({"level", + "The level of the messages logged by this " + "statement, or NULL if it could not be " + "determined, like for a printf()"}) .with_result({"pattern", "The pattern used to match log messages from this " "log statement"}) diff --git a/src/third-party/lnav-rs-ext/Cargo.lock b/src/third-party/lnav-rs-ext/Cargo.lock index 43249457f4..a255d77c5e 100644 --- a/src/third-party/lnav-rs-ext/Cargo.lock +++ b/src/third-party/lnav-rs-ext/Cargo.lock @@ -799,7 +799,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -1258,7 +1258,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -1396,7 +1396,7 @@ checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "log2src" version = "0.1.0" -source = "git+https://github.com/tstack/log2src.git?branch=caching1#c654a6151bdee4d6d38474fbe76503521d6b19dc" +source = "git+https://github.com/tstack/log2src.git?branch=caching1#d841076479ddac452b529787f5f2ab6463c5635e" dependencies = [ "aho-corasick", "bincode", @@ -1905,7 +1905,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2222,7 +2222,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2706,7 +2706,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] diff --git a/src/third-party/lnav-rs-ext/lnav_rs_ext.cxx.cc b/src/third-party/lnav-rs-ext/lnav_rs_ext.cxx.cc index 2e508606e7..9f5f603f64 100644 --- a/src/third-party/lnav-rs-ext/lnav_rs_ext.cxx.cc +++ b/src/third-party/lnav-rs-ext/lnav_rs_ext.cxx.cc @@ -853,6 +853,7 @@ namespace lnav_rs_ext { struct PollResult; struct ExecError; struct ExecResult; + enum class StmtLevel : ::std::uint8_t; enum class LnavLogLevel : ::std::uint8_t; struct StartExtResult; } @@ -999,6 +1000,9 @@ struct FindLogResult final { // `src` as `find_log_statement_json()` gives it, which the schema hashes. ::rust::String src_json; ::rust::String pattern; + // The statement's level, or `unknown` if log2src could not tell, + // like for a `printf()`. + ::lnav_rs_ext::StmtLevel level; ::rust::Vec<::lnav_rs_ext::VarPair> variables; using IsRelocatable = ::std::true_type; @@ -1118,6 +1122,21 @@ struct ExecResult final { }; #endif // CXXBRIDGE1_STRUCT_lnav_rs_ext$ExecResult +#ifndef CXXBRIDGE1_ENUM_lnav_rs_ext$StmtLevel +#define CXXBRIDGE1_ENUM_lnav_rs_ext$StmtLevel +// The level of a log statement or message, as far as log2src can +// tell them apart. +enum class StmtLevel : ::std::uint8_t { + unknown = 0, + trace = 1, + debug = 2, + info = 3, + warning = 4, + error = 5, + fatal = 6, +}; +#endif // CXXBRIDGE1_ENUM_lnav_rs_ext$StmtLevel + #ifndef CXXBRIDGE1_ENUM_lnav_rs_ext$LnavLogLevel #define CXXBRIDGE1_ENUM_lnav_rs_ext$LnavLogLevel enum class LnavLogLevel : ::std::uint8_t { @@ -1190,9 +1209,9 @@ void lnav_rs_ext$cxxbridge1$205$discover_srcs() noexcept; void lnav_rs_ext$cxxbridge1$205$get_status(::lnav_rs_ext::ExtProgress *return$) noexcept; -::lnav_rs_ext::FindLogResult *lnav_rs_ext$cxxbridge1$205$find_log_statement(::rust::Str file, ::std::size_t line, ::rust::Str body) noexcept; +::lnav_rs_ext::FindLogResult *lnav_rs_ext$cxxbridge1$205$find_log_statement(::rust::Str file, ::std::size_t line, ::lnav_rs_ext::StmtLevel level, ::rust::Str body) noexcept; -::lnav_rs_ext::FindLogResultJson *lnav_rs_ext$cxxbridge1$205$find_log_statement_json(::rust::Str file, ::std::size_t line, ::rust::Str body, ::lnav_rs_ext::FindLogOptions const &options) noexcept; +::lnav_rs_ext::FindLogResultJson *lnav_rs_ext$cxxbridge1$205$find_log_statement_json(::rust::Str file, ::std::size_t line, ::lnav_rs_ext::StmtLevel level, ::rust::Str body, ::lnav_rs_ext::FindLogOptions const &options) noexcept; void lnav_rs_ext$cxxbridge1$205$get_log_statements_for(::rust::Str file, ::rust::Vec<::lnav_rs_ext::FindLogResult> *return$) noexcept; @@ -1229,12 +1248,12 @@ ::lnav_rs_ext::ExtProgress get_status() noexcept { return ::std::move(return$.value); } -::std::unique_ptr<::lnav_rs_ext::FindLogResult> find_log_statement(::rust::Str file, ::std::size_t line, ::rust::Str body) noexcept { - return ::std::unique_ptr<::lnav_rs_ext::FindLogResult>(lnav_rs_ext$cxxbridge1$205$find_log_statement(file, line, body)); +::std::unique_ptr<::lnav_rs_ext::FindLogResult> find_log_statement(::rust::Str file, ::std::size_t line, ::lnav_rs_ext::StmtLevel level, ::rust::Str body) noexcept { + return ::std::unique_ptr<::lnav_rs_ext::FindLogResult>(lnav_rs_ext$cxxbridge1$205$find_log_statement(file, line, level, body)); } -::std::unique_ptr<::lnav_rs_ext::FindLogResultJson> find_log_statement_json(::rust::Str file, ::std::size_t line, ::rust::Str body, ::lnav_rs_ext::FindLogOptions const &options) noexcept { - return ::std::unique_ptr<::lnav_rs_ext::FindLogResultJson>(lnav_rs_ext$cxxbridge1$205$find_log_statement_json(file, line, body, options)); +::std::unique_ptr<::lnav_rs_ext::FindLogResultJson> find_log_statement_json(::rust::Str file, ::std::size_t line, ::lnav_rs_ext::StmtLevel level, ::rust::Str body, ::lnav_rs_ext::FindLogOptions const &options) noexcept { + return ::std::unique_ptr<::lnav_rs_ext::FindLogResultJson>(lnav_rs_ext$cxxbridge1$205$find_log_statement_json(file, line, level, body, options)); } ::rust::Vec<::lnav_rs_ext::FindLogResult> get_log_statements_for(::rust::Str file) noexcept { diff --git a/src/third-party/lnav-rs-ext/lnav_rs_ext.cxx.hh b/src/third-party/lnav-rs-ext/lnav_rs_ext.cxx.hh index 764c7bd0de..58acfc2a8a 100644 --- a/src/third-party/lnav-rs-ext/lnav_rs_ext.cxx.hh +++ b/src/third-party/lnav-rs-ext/lnav_rs_ext.cxx.hh @@ -817,6 +817,7 @@ namespace lnav_rs_ext { struct PollResult; struct ExecError; struct ExecResult; + enum class StmtLevel : ::std::uint8_t; enum class LnavLogLevel : ::std::uint8_t; struct StartExtResult; } @@ -963,6 +964,9 @@ struct FindLogResult final { // `src` as `find_log_statement_json()` gives it, which the schema hashes. ::rust::String src_json; ::rust::String pattern; + // The statement's level, or `unknown` if log2src could not tell, + // like for a `printf()`. + ::lnav_rs_ext::StmtLevel level; ::rust::Vec<::lnav_rs_ext::VarPair> variables; using IsRelocatable = ::std::true_type; @@ -1082,6 +1086,21 @@ struct ExecResult final { }; #endif // CXXBRIDGE1_STRUCT_lnav_rs_ext$ExecResult +#ifndef CXXBRIDGE1_ENUM_lnav_rs_ext$StmtLevel +#define CXXBRIDGE1_ENUM_lnav_rs_ext$StmtLevel +// The level of a log statement or message, as far as log2src can +// tell them apart. +enum class StmtLevel : ::std::uint8_t { + unknown = 0, + trace = 1, + debug = 2, + info = 3, + warning = 4, + error = 5, + fatal = 6, +}; +#endif // CXXBRIDGE1_ENUM_lnav_rs_ext$StmtLevel + #ifndef CXXBRIDGE1_ENUM_lnav_rs_ext$LnavLogLevel #define CXXBRIDGE1_ENUM_lnav_rs_ext$LnavLogLevel enum class LnavLogLevel : ::std::uint8_t { @@ -1113,9 +1132,9 @@ void discover_srcs() noexcept; ::lnav_rs_ext::ExtProgress get_status() noexcept; -::std::unique_ptr<::lnav_rs_ext::FindLogResult> find_log_statement(::rust::Str file, ::std::size_t line, ::rust::Str body) noexcept; +::std::unique_ptr<::lnav_rs_ext::FindLogResult> find_log_statement(::rust::Str file, ::std::size_t line, ::lnav_rs_ext::StmtLevel level, ::rust::Str body) noexcept; -::std::unique_ptr<::lnav_rs_ext::FindLogResultJson> find_log_statement_json(::rust::Str file, ::std::size_t line, ::rust::Str body, ::lnav_rs_ext::FindLogOptions const &options) noexcept; +::std::unique_ptr<::lnav_rs_ext::FindLogResultJson> find_log_statement_json(::rust::Str file, ::std::size_t line, ::lnav_rs_ext::StmtLevel level, ::rust::Str body, ::lnav_rs_ext::FindLogOptions const &options) noexcept; ::rust::Vec<::lnav_rs_ext::FindLogResult> get_log_statements_for(::rust::Str file) noexcept; diff --git a/src/third-party/lnav-rs-ext/src/lib.rs b/src/third-party/lnav-rs-ext/src/lib.rs index 560dbe3317..2b595c7aa4 100644 --- a/src/third-party/lnav-rs-ext/src/lib.rs +++ b/src/third-party/lnav-rs-ext/src/lib.rs @@ -6,13 +6,14 @@ mod ext_access; use crate::ext_access::{set_login_otp, start_server, stop_server}; use crate::ffi::{ get_lnav_log_level, notify_completion, notify_pollers, ExtError, ExtProgress, FindLogOptions, - FindLogResult, FindLogResultJson, LnavLogLevel, SourceDetails, StartExtResult, Status, VarPair, + FindLogResult, FindLogResultJson, LnavLogLevel, SourceDetails, StartExtResult, Status, + StmtLevel, VarPair, }; use cxx::UniquePtr; use log::{Level, Log, Metadata, Record}; use log2src::{ - Cache, LogError, LogMapping, LogMatchOptions, LogMatcher, LogRefBuilder, ProgressTracker, - ProgressUpdate, SourceRef, VariablePair, WorkInfo, + Cache, LogError, LogLevel, LogMapping, LogMatchOptions, LogMatcher, LogRefBuilder, + ProgressTracker, ProgressUpdate, SourceRef, VariablePair, WorkInfo, }; use miette::Diagnostic; use prqlc::{DisplayOptions, Target}; @@ -234,6 +235,9 @@ mod ffi { /// `src` as `find_log_statement_json()` gives it, which the schema hashes. pub src_json: String, pub pattern: String, + /// The statement's level, or `unknown` if log2src could not tell, + /// like for a `printf()`. + pub level: StmtLevel, pub variables: Vec, } @@ -320,6 +324,19 @@ mod ffi { pub error: ExecError, } + /// The level of a log statement or message, as far as log2src can + /// tell them apart. + #[derive(Debug)] + enum StmtLevel { + unknown, + trace, + debug, + info, + warning, + error, + fatal, + } + enum LnavLogLevel { trace, debug, @@ -369,10 +386,16 @@ mod ffi { fn get_status() -> ExtProgress; - fn find_log_statement(file: &str, line: usize, body: &str) -> UniquePtr; + fn find_log_statement( + file: &str, + line: usize, + level: StmtLevel, + body: &str, + ) -> UniquePtr; fn find_log_statement_json( file: &str, line: usize, + level: StmtLevel, body: &str, options: &FindLogOptions, ) -> UniquePtr; @@ -584,6 +607,7 @@ impl From<&SourceRef> for FindLogResult { }, src_json: src_json(value), pattern: value.pattern_str.to_string(), + level: value.level.into(), variables: vec![], } } @@ -599,11 +623,45 @@ impl FindLogResult { } } -fn find_log_statement(file: &str, lineno: usize, body: &str) -> UniquePtr { +impl From for StmtLevel { + fn from(value: LogLevel) -> Self { + match value { + LogLevel::Trace => StmtLevel::trace, + LogLevel::Debug => StmtLevel::debug, + LogLevel::Info => StmtLevel::info, + LogLevel::Warn => StmtLevel::warning, + LogLevel::Error => StmtLevel::error, + LogLevel::Fatal => StmtLevel::fatal, + LogLevel::Unknown => StmtLevel::unknown, + } + } +} + +impl From for LogLevel { + fn from(value: StmtLevel) -> Self { + match value { + StmtLevel::trace => LogLevel::Trace, + StmtLevel::debug => LogLevel::Debug, + StmtLevel::info => LogLevel::Info, + StmtLevel::warning => LogLevel::Warn, + StmtLevel::error => LogLevel::Error, + StmtLevel::fatal => LogLevel::Fatal, + _ => LogLevel::Unknown, + } + } +} + +fn find_log_statement( + file: &str, + lineno: usize, + level: StmtLevel, + body: &str, +) -> UniquePtr { let log_matcher = LOG_MATCHER.read().unwrap(); let log_ref = LogRefBuilder::new() .with_file(if file.is_empty() { None } else { Some(file) }) .with_lineno(if file.is_empty() { None } else { Some(lineno) }) + .with_log_level(Some(level.into())) .with_body(Some(body)) .build(body); @@ -650,6 +708,7 @@ fn src_json(src_ref: &SourceRef) -> String { fn find_log_statement_json( file: &str, lineno: usize, + level: StmtLevel, body: &str, options: &FindLogOptions, ) -> UniquePtr { @@ -657,10 +716,10 @@ fn find_log_statement_json( let log_ref = LogRefBuilder::new() .with_file(if file.is_empty() { None } else { Some(file) }) .with_lineno(if file.is_empty() { None } else { Some(lineno) }) + .with_log_level(Some(level.into())) .with_body(Some(body)) .build(body); - if let Some(LogMapping { variables, src_ref: Some(src_ref), diff --git a/test/expected/test_cmds.sh_b6a3bb78e9d60e5e1f5ce5b18e40d2f1662707ab.out b/test/expected/test_cmds.sh_b6a3bb78e9d60e5e1f5ce5b18e40d2f1662707ab.out index c0cc41330b..e8358249d5 100644 --- a/test/expected/test_cmds.sh_b6a3bb78e9d60e5e1f5ce5b18e40d2f1662707ab.out +++ b/test/expected/test_cmds.sh_b6a3bb78e9d60e5e1f5ce5b18e40d2f1662707ab.out @@ -5360,6 +5360,9 @@ For support questions, email: block_id An ID for the innermost block containing the statement. Statements in the same file with the same ID are in the same block. + level The level of the messages logged + by this statement, or NULL if it could not be + determined, like for a printf() pattern The pattern used to match log messages from this log statement path The path to the source file diff --git a/test/expected/test_log2src.sh_039d47fea76d38d62a65f8c4f3ac9d45d3dd2997.out b/test/expected/test_log2src.sh_039d47fea76d38d62a65f8c4f3ac9d45d3dd2997.out index 8feb2ed70f..120b18c90d 100644 --- a/test/expected/test_log2src.sh_039d47fea76d38d62a65f8c4f3ac9d45d3dd2997.out +++ b/test/expected/test_log2src.sh_039d47fea76d38d62a65f8c4f3ac9d45d3dd2997.out @@ -1,4 +1,4 @@ -{"log_line":0,"log_msg_src":{"file":"{test_dir}/log2src/java/com/example/net/Server.java","begin_line":10,"end_line":10,"name":"Server","qualified_name":"com.example.net.Server.Server","block_id":215,"language":"Java"},"log_msg_format":"(?s)^constructing server on port (.+)$","log_msg_values":[{"expr":"port","value":"8080"}]} -{"log_line":1,"log_msg_src":{"file":"{test_dir}/log2src/java/com/example/net/Server.java","begin_line":14,"end_line":14,"name":"handle","qualified_name":"com.example.net.Server.handle","block_id":323,"language":"Java"},"log_msg_format":"(?s)^handling request from (.+)$","log_msg_values":[{"expr":"client","value":"10.0.0.1"}]} -{"log_line":2,"log_msg_src":{"file":"{test_dir}/log2src/java/com/example/net/Server.java","begin_line":15,"end_line":15,"name":"handle","qualified_name":"com.example.net.Server.handle","block_id":410,"language":"Java"},"log_msg_format":"(?s)^client (.+) is slow$","log_msg_values":[{"expr":"client","value":"10.0.0.1"}]} +{"log_line":0,"log_msg_src":{"file":"{test_dir}/log2src/java/com/example/net/Server.java","begin_line":10,"end_line":10,"name":"Server","qualified_name":"com.example.net.Server.Server","block_id":215,"language":"Java"},"log_msg_format":"(?s)^constructing server on port (.*)$","log_msg_values":[{"expr":"port","value":"8080"}]} +{"log_line":1,"log_msg_src":{"file":"{test_dir}/log2src/java/com/example/net/Server.java","begin_line":14,"end_line":14,"name":"handle","qualified_name":"com.example.net.Server.handle","block_id":323,"language":"Java"},"log_msg_format":"(?s)^handling request from (.*)$","log_msg_values":[{"expr":"client","value":"10.0.0.1"}]} +{"log_line":2,"log_msg_src":{"file":"{test_dir}/log2src/java/com/example/net/Server.java","begin_line":15,"end_line":15,"name":"handle","qualified_name":"com.example.net.Server.handle","block_id":410,"language":"Java"},"log_msg_format":"(?s)^client (.*) is slow$","log_msg_values":[{"expr":"client","value":"10.0.0.1"}]} {"log_line":3,"log_msg_src":{"file":"{test_dir}/log2src/java/com/example/net/Server.java","begin_line":21,"end_line":21,"name":"run","qualified_name":"com.example.net.Server.Inner.run","block_id":520,"language":"Java"},"log_msg_format":"(?s)^inner worker failed$","log_msg_values":[]} diff --git a/test/expected/test_log2src.sh_0c143666863b534b0dccb8c3122919752929908f.out b/test/expected/test_log2src.sh_0c143666863b534b0dccb8c3122919752929908f.out deleted file mode 100644 index cabc962e1a..0000000000 --- a/test/expected/test_log2src.sh_0c143666863b534b0dccb8c3122919752929908f.out +++ /dev/null @@ -1,4 +0,0 @@ -{"begin_line":10,"end_line":10,"language":"Java","function_name":"Server","qualified_name":"com.example.net.Server.Server","block_id":215,"pattern":"(?s)^constructing server on port (.+)$","path":"{test_dir}/log2src/java/com/example/net/Server.java"} -{"begin_line":14,"end_line":14,"language":"Java","function_name":"handle","qualified_name":"com.example.net.Server.handle","block_id":323,"pattern":"(?s)^handling request from (.+)$","path":"{test_dir}/log2src/java/com/example/net/Server.java"} -{"begin_line":15,"end_line":15,"language":"Java","function_name":"handle","qualified_name":"com.example.net.Server.handle","block_id":410,"pattern":"(?s)^client (.+) is slow$","path":"{test_dir}/log2src/java/com/example/net/Server.java"} -{"begin_line":21,"end_line":21,"language":"Java","function_name":"run","qualified_name":"com.example.net.Server.Inner.run","block_id":520,"pattern":"(?s)^inner worker failed$","path":"{test_dir}/log2src/java/com/example/net/Server.java"} diff --git a/test/expected/test_log2src.sh_7afad25dfbecb3e452e744c6bb0999d28f5da258.out b/test/expected/test_log2src.sh_7afad25dfbecb3e452e744c6bb0999d28f5da258.out index 1a15898a7a..e1a86587cb 100644 --- a/test/expected/test_log2src.sh_7afad25dfbecb3e452e744c6bb0999d28f5da258.out +++ b/test/expected/test_log2src.sh_7afad25dfbecb3e452e744c6bb0999d28f5da258.out @@ -1,5 +1,5 @@ {"log_line":0,"log_msg_src":{"file":"{test_dir}/log2src/python/log_example.py","begin_line":19,"end_line":19,"name":"main","qualified_name":"main","block_id":407,"language":"Python"},"log_msg_format":"(?s)^debug message: initializing demo .$","log_msg_values":[]} -{"log_line":1,"log_msg_src":{"file":"{test_dir}/log2src/python/log_example.py","begin_line":20,"end_line":21,"name":"main","qualified_name":"main","block_id":407,"language":"Python"},"log_msg_format":"(?s)^info message:\\nprocessing started -- (.+)$","log_msg_values":[{"expr":"sys.argv[0]","value":"log_example.py"}]} +{"log_line":1,"log_msg_src":{"file":"{test_dir}/log2src/python/log_example.py","begin_line":20,"end_line":21,"name":"main","qualified_name":"main","block_id":407,"language":"Python"},"log_msg_format":"(?s)^info message:\\nprocessing started -- (.*)$","log_msg_values":[{"expr":"sys.argv[0]","value":"log_example.py"}]} {"log_line":3,"log_msg_src":{"file":"{test_dir}/log2src/python/log_example.py","begin_line":22,"end_line":22,"name":"main","qualified_name":"main","block_id":407,"language":"Python"},"log_msg_format":"(?s)^warning message:\\nlow disk space$","log_msg_values":[]} {"log_line":5,"log_msg_src":{"file":"{test_dir}/log2src/python/log_example.py","begin_line":23,"end_line":23,"name":"main","qualified_name":"main","block_id":407,"language":"Python"},"log_msg_format":"(?s)^error message: failed to open resource$","log_msg_values":[]} {"log_line":6,"log_msg_src":{"file":"{test_dir}/log2src/python/log_example.py","begin_line":27,"end_line":27,"name":"main","qualified_name":"main","block_id":802,"language":"Python"},"log_msg_format":"(?s)^exception message: caught unexpected error$","log_msg_values":[]} diff --git a/test/expected/test_log2src.sh_0c143666863b534b0dccb8c3122919752929908f.err b/test/expected/test_log2src.sh_bf7839112be395d89ad262e05b3e69493ea371ed.err similarity index 100% rename from test/expected/test_log2src.sh_0c143666863b534b0dccb8c3122919752929908f.err rename to test/expected/test_log2src.sh_bf7839112be395d89ad262e05b3e69493ea371ed.err diff --git a/test/expected/test_log2src.sh_bf7839112be395d89ad262e05b3e69493ea371ed.out b/test/expected/test_log2src.sh_bf7839112be395d89ad262e05b3e69493ea371ed.out new file mode 100644 index 0000000000..866595b925 --- /dev/null +++ b/test/expected/test_log2src.sh_bf7839112be395d89ad262e05b3e69493ea371ed.out @@ -0,0 +1,4 @@ +{"begin_line":10,"end_line":10,"language":"Java","function_name":"Server","qualified_name":"com.example.net.Server.Server","block_id":215,"level":"info","pattern":"(?s)^constructing server on port (.*)$","path":"{test_dir}/log2src/java/com/example/net/Server.java"} +{"begin_line":14,"end_line":14,"language":"Java","function_name":"handle","qualified_name":"com.example.net.Server.handle","block_id":323,"level":"debug","pattern":"(?s)^handling request from (.*)$","path":"{test_dir}/log2src/java/com/example/net/Server.java"} +{"begin_line":15,"end_line":15,"language":"Java","function_name":"handle","qualified_name":"com.example.net.Server.handle","block_id":410,"level":"warning","pattern":"(?s)^client (.*) is slow$","path":"{test_dir}/log2src/java/com/example/net/Server.java"} +{"begin_line":21,"end_line":21,"language":"Java","function_name":"run","qualified_name":"com.example.net.Server.Inner.run","block_id":520,"level":"error","pattern":"(?s)^inner worker failed$","path":"{test_dir}/log2src/java/com/example/net/Server.java"} diff --git a/test/expected/test_log2src.sh_fdb818f636cb8557d4f651fa4b548e502a50aece.err b/test/expected/test_log2src.sh_ef96a0e9c1aa2630c9af568d27ffa0eff2db85a8.err similarity index 100% rename from test/expected/test_log2src.sh_fdb818f636cb8557d4f651fa4b548e502a50aece.err rename to test/expected/test_log2src.sh_ef96a0e9c1aa2630c9af568d27ffa0eff2db85a8.err diff --git a/test/expected/test_log2src.sh_ef96a0e9c1aa2630c9af568d27ffa0eff2db85a8.out b/test/expected/test_log2src.sh_ef96a0e9c1aa2630c9af568d27ffa0eff2db85a8.out new file mode 100644 index 0000000000..8bcf0f8649 --- /dev/null +++ b/test/expected/test_log2src.sh_ef96a0e9c1aa2630c9af568d27ffa0eff2db85a8.out @@ -0,0 +1,5 @@ +{"begin_line":19,"end_line":19,"language":"Python","function_name":"main","qualified_name":"main","block_id":407,"level":"debug","pattern":"(?s)^debug message: initializing demo .$","path":"{test_dir}/log2src/python/log_example.py"} +{"begin_line":20,"end_line":21,"language":"Python","function_name":"main","qualified_name":"main","block_id":407,"level":"info","pattern":"(?s)^info message:\\nprocessing started -- (.*)$","path":"{test_dir}/log2src/python/log_example.py"} +{"begin_line":22,"end_line":22,"language":"Python","function_name":"main","qualified_name":"main","block_id":407,"level":"warning","pattern":"(?s)^warning message:\\nlow disk space$","path":"{test_dir}/log2src/python/log_example.py"} +{"begin_line":23,"end_line":23,"language":"Python","function_name":"main","qualified_name":"main","block_id":407,"level":"error","pattern":"(?s)^error message: failed to open resource$","path":"{test_dir}/log2src/python/log_example.py"} +{"begin_line":27,"end_line":27,"language":"Python","function_name":"main","qualified_name":"main","block_id":802,"level":"error","pattern":"(?s)^exception message: caught unexpected error$","path":"{test_dir}/log2src/python/log_example.py"} diff --git a/test/expected/test_log2src.sh_fdb818f636cb8557d4f651fa4b548e502a50aece.out b/test/expected/test_log2src.sh_fdb818f636cb8557d4f651fa4b548e502a50aece.out deleted file mode 100644 index d853503090..0000000000 --- a/test/expected/test_log2src.sh_fdb818f636cb8557d4f651fa4b548e502a50aece.out +++ /dev/null @@ -1,5 +0,0 @@ -{"begin_line":19,"end_line":19,"language":"Python","function_name":"main","qualified_name":"main","block_id":407,"pattern":"(?s)^debug message: initializing demo .$","path":"{test_dir}/log2src/python/log_example.py"} -{"begin_line":20,"end_line":21,"language":"Python","function_name":"main","qualified_name":"main","block_id":407,"pattern":"(?s)^info message:\\nprocessing started -- (.+)$","path":"{test_dir}/log2src/python/log_example.py"} -{"begin_line":22,"end_line":22,"language":"Python","function_name":"main","qualified_name":"main","block_id":407,"pattern":"(?s)^warning message:\\nlow disk space$","path":"{test_dir}/log2src/python/log_example.py"} -{"begin_line":23,"end_line":23,"language":"Python","function_name":"main","qualified_name":"main","block_id":407,"pattern":"(?s)^error message: failed to open resource$","path":"{test_dir}/log2src/python/log_example.py"} -{"begin_line":27,"end_line":27,"language":"Python","function_name":"main","qualified_name":"main","block_id":802,"pattern":"(?s)^exception message: caught unexpected error$","path":"{test_dir}/log2src/python/log_example.py"} diff --git a/test/test_log2src.sh b/test/test_log2src.sh index bc115c5f78..f6f2c45dbf 100644 --- a/test/test_log2src.sh +++ b/test/test_log2src.sh @@ -23,7 +23,7 @@ run_cap_test ${lnav_test} -n \ # which differs from one checkout to another. run_cap_test ${lnav_test} -nN \ -c ":add-source-path ${test_dir}/log2src/python" \ - -c ";SELECT begin_line, end_line, language, function_name, qualified_name, block_id, pattern, path FROM source_log_stmt('log_example.py')" \ + -c ";SELECT begin_line, end_line, language, function_name, qualified_name, block_id, level, pattern, path FROM source_log_stmt('log_example.py')" \ -c ":write-jsonlines-to -" run_cap_test ${lnav_test} -n \ @@ -34,7 +34,7 @@ run_cap_test ${lnav_test} -n \ run_cap_test ${lnav_test} -nN \ -c ":add-source-path ${test_dir}/log2src/java" \ - -c ";SELECT begin_line, end_line, language, function_name, qualified_name, block_id, pattern, path FROM source_log_stmt('Server.java')" \ + -c ";SELECT begin_line, end_line, language, function_name, qualified_name, block_id, level, pattern, path FROM source_log_stmt('Server.java')" \ -c ":write-jsonlines-to -" # log_stmt_stats counts the same messages per statement as grouping