Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
58 changes: 56 additions & 2 deletions src/all_logs_vtab.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -433,6 +436,7 @@ std::unique_ptr<lnav_rs_ext::FindLogResultJson>
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) {
Expand Down Expand Up @@ -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
Expand Down
14 changes: 13 additions & 1 deletion src/all_logs_vtab.hh
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#ifdef HAVE_RUST_DEPS
namespace lnav_rs_ext {
struct FindLogResultJson;
enum class StmtLevel : std::uint8_t;
}
#endif

Expand Down Expand Up @@ -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<lnav_rs_ext::FindLogResultJson> 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:
Expand Down
9 changes: 7 additions & 2 deletions src/log_data_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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),
Expand Down
8 changes: 5 additions & 3 deletions src/log_stmt_stats.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
17 changes: 17 additions & 0 deletions src/log_stmt_vtab.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ enum class log_stmt_col : uint8_t {
function_name,
qualified_name,
block_id,
level,
pattern,
path,
schema,
Expand All @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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"})
Expand Down
12 changes: 6 additions & 6 deletions src/third-party/lnav-rs-ext/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 25 additions & 6 deletions src/third-party/lnav-rs-ext/lnav_rs_ext.cxx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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 {
Expand Down
Loading
Loading