[session] store file visibility

This commit is contained in:
Timothy Stack 2020-10-28 21:23:25 -07:00
parent c22c78220c
commit 8b38bb0970
11 changed files with 268 additions and 146 deletions

View File

@ -489,9 +489,10 @@ public:
void promote_file(const shared_ptr<logfile> &lf) {
if (lnav_data.ld_log_source.insert_file(lf)) {
log_info("promoting text file to log file: %s",
lf->get_filename().c_str());
log_format *format = lf->get_format();
log_info("promoting text file to log file: %s (%s)",
lf->get_filename().c_str(),
lf->get_content_id().c_str());
auto *format = lf->get_format();
if (format->lf_is_self_describing) {
log_vtab_impl *vt = format->get_vtab_impl();
@ -499,6 +500,12 @@ public:
lnav_data.ld_vtab_manager->register_vtab(vt);
}
}
auto iter = session_data.sd_file_states.find(lf->get_filename());
if (iter != session_data.sd_file_states.end()) {
log_debug("found state for log file");
lf->set_visibility(iter->second.fs_is_visible);
}
}
else {
this->closed_file(lf);
@ -624,7 +631,7 @@ void rebuild_indexes()
[](auto& lf) {
log_info("Hiding duplicate file: %s",
lf->get_filename().c_str());
lf->hide();
lf->mark_as_duplicate();
});
reload = true;
}
@ -1896,10 +1903,10 @@ static void looper()
if (!lnav_data.ld_session_loaded) {
load_session();
if (lnav_data.ld_session_save_time) {
if (session_data.sd_save_time) {
std::string ago;
ago = time_ago(lnav_data.ld_session_save_time);
ago = time_ago(session_data.sd_save_time);
lnav_data.ld_rl_view->set_value(
("restored session from " ANSI_BOLD_START) +
ago +

View File

@ -245,7 +245,6 @@ struct _lnav_data {
std::map<std::string, std::list<session_pair_t>> ld_session_id;
time_t ld_session_time;
time_t ld_session_load_time;
time_t ld_session_save_time;
const char * ld_program_name;
const char * ld_debug_log_name;

View File

@ -391,19 +391,19 @@ static void config_error_reporter(const yajlpp_parse_context &ypc,
}
static struct json_path_container key_command_handlers = {
json_path_handler("command")
yajlpp::property_handler("command")
.with_synopsis("<command>")
.with_description("The command to execute for the given key sequence.")
.with_pattern("[:|;].*")
.FOR_FIELD(key_command, kc_cmd),
json_path_handler("alt-msg")
yajlpp::property_handler("alt-msg")
.with_synopsis("<msg>")
.with_description("The help message to display after the key is pressed.")
.FOR_FIELD(key_command, kc_alt_msg)
};
static struct json_path_container keymap_def_handlers = {
json_path_handler(pcrepp("(?<key_seq>(?:x[0-9a-f]{2})+)"))
yajlpp::pattern_property_handler("(?<key_seq>(?:x[0-9a-f]{2})+)")
.with_description("The hexadecimal encoding of key codes to map to a command.")
.with_obj_provider<key_command, key_map>([](const yajlpp_provider_context &ypc, key_map *km) {
key_command &retval = km->km_seq_to_cmd[ypc.ypc_extractor.get_substr("key_seq")];
@ -419,7 +419,7 @@ static struct json_path_container keymap_def_handlers = {
};
static struct json_path_container keymap_defs_handlers = {
json_path_handler(pcrepp("(?<keymap_name>[\\w\\-]+)"))
yajlpp::pattern_property_handler("(?<keymap_name>[\\w\\-]+)")
.with_description("The keymap definitions")
.with_obj_provider<key_map, _lnav_config>([](const yajlpp_provider_context &ypc, _lnav_config *root) {
key_map &retval = root->lc_ui_keymaps[ypc.ypc_extractor.get_substr("keymap_name")];
@ -434,7 +434,7 @@ static struct json_path_container keymap_defs_handlers = {
};
static struct json_path_container global_var_handlers = {
json_path_handler(pcrepp("(?<var_name>\\w+)"))
yajlpp::pattern_property_handler("(?<var_name>\\w+)")
.with_synopsis("<name>")
.with_description(
"A global variable definition. Global variables can be referenced "
@ -449,11 +449,11 @@ static struct json_path_container global_var_handlers = {
static struct json_path_container style_config_handlers =
json_path_container{
json_path_handler("semantic")
yajlpp::property_handler("semantic")
.with_description(
"Pick a color based on the text being highlighted")
.FOR_FIELD(style_config, sc_semantic),
json_path_handler("color")
yajlpp::property_handler("color")
.with_synopsis("#hex|color_name")
.with_description(
"The foreground color value for this style. The value can be "
@ -463,7 +463,7 @@ static struct json_path_container style_config_handlers =
.with_example("Green")
.with_example("$black")
.FOR_FIELD(style_config, sc_color),
json_path_handler("background-color")
yajlpp::property_handler("background-color")
.with_synopsis("#hex|color_name")
.with_description(
"The foreground color value for this style. The value can be "
@ -472,83 +472,83 @@ static struct json_path_container style_config_handlers =
.with_example("#2d2a2e")
.with_example("Green")
.FOR_FIELD(style_config, sc_background_color),
json_path_handler("underline")
yajlpp::property_handler("underline")
.with_description("Indicates that the text should be underlined.")
.FOR_FIELD(style_config, sc_underline),
json_path_handler("bold")
yajlpp::property_handler("bold")
.with_description("Indicates that the text should be bolded.")
.FOR_FIELD(style_config, sc_bold),
}
.with_definition_id("style");
static struct json_path_container theme_styles_handlers = {
json_path_handler("identifier")
yajlpp::property_handler("identifier")
.with_description("Styling for identifiers in logs")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_identifier;
})
.with_children(style_config_handlers),
json_path_handler("text")
yajlpp::property_handler("text")
.with_description("Styling for plain text")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_text;
})
.with_children(style_config_handlers),
json_path_handler("alt-text")
yajlpp::property_handler("alt-text")
.with_description("Styling for plain text when alternating")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_alt_text;
})
.with_children(style_config_handlers),
json_path_handler("error")
yajlpp::property_handler("error")
.with_description("Styling for error messages")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_error;
})
.with_children(style_config_handlers),
json_path_handler("ok")
yajlpp::property_handler("ok")
.with_description("Styling for success messages")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_ok;
})
.with_children(style_config_handlers),
json_path_handler("warning")
yajlpp::property_handler("warning")
.with_description("Styling for warning messages")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_warning;
})
.with_children(style_config_handlers),
json_path_handler("hidden")
yajlpp::property_handler("hidden")
.with_description("Styling for hidden fields in logs")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_hidden;
})
.with_children(style_config_handlers),
json_path_handler("adjusted-time")
yajlpp::property_handler("adjusted-time")
.with_description("Styling for timestamps that have been adjusted")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_adjusted_time;
})
.with_children(style_config_handlers),
json_path_handler("skewed-time")
yajlpp::property_handler("skewed-time")
.with_description("Styling for timestamps ")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_skewed_time;
})
.with_children(style_config_handlers),
json_path_handler("offset-time")
yajlpp::property_handler("offset-time")
.with_description("Styling for hidden fields")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_offset_time;
})
.with_children(style_config_handlers),
json_path_handler("popup")
yajlpp::property_handler("popup")
.with_description("Styling for popup windows")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_popup;
})
.with_children(style_config_handlers),
json_path_handler("scrollbar")
yajlpp::property_handler("scrollbar")
.with_description("Styling for scrollbars")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_scrollbar;
@ -557,80 +557,80 @@ static struct json_path_container theme_styles_handlers = {
};
static struct json_path_container theme_syntax_styles_handlers = {
json_path_handler("keyword")
yajlpp::property_handler("keyword")
.with_description("Styling for keywords in source files")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_keyword;
})
.with_children(style_config_handlers),
json_path_handler("string")
yajlpp::property_handler("string")
.with_description("Styling for single/double-quoted strings in text")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_string;
})
.with_children(style_config_handlers),
json_path_handler("comment")
yajlpp::property_handler("comment")
.with_description("Styling for comments in source files")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_comment;
})
.with_children(style_config_handlers),
json_path_handler("doc-directive")
yajlpp::property_handler("doc-directive")
.with_description("Styling for documentation directives in source files")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_doc_directive;
})
.with_children(style_config_handlers),
json_path_handler("variable")
yajlpp::property_handler("variable")
.with_description("Styling for variables in text")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_variable;
})
.with_children(style_config_handlers),
json_path_handler("symbol")
yajlpp::property_handler("symbol")
.with_description("Styling for symbols in source files")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_symbol;
})
.with_children(style_config_handlers),
json_path_handler("number")
yajlpp::property_handler("number")
.with_description("Styling for numbers in source files")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_number;
})
.with_children(style_config_handlers),
json_path_handler("re-special")
yajlpp::property_handler("re-special")
.with_description("Styling for special characters in regular expressions")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_re_special;
})
.with_children(style_config_handlers),
json_path_handler("re-repeat")
yajlpp::property_handler("re-repeat")
.with_description("Styling for repeats in regular expressions")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_re_repeat;
})
.with_children(style_config_handlers),
json_path_handler("diff-delete")
yajlpp::property_handler("diff-delete")
.with_description("Styling for deleted lines in diffs")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_diff_delete;
})
.with_children(style_config_handlers),
json_path_handler("diff-add")
yajlpp::property_handler("diff-add")
.with_description("Styling for added lines in diffs")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_diff_add;
})
.with_children(style_config_handlers),
json_path_handler("diff-section")
yajlpp::property_handler("diff-section")
.with_description("Styling for diffs")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_diff_section;
})
.with_children(style_config_handlers),
json_path_handler("file")
yajlpp::property_handler("file")
.with_description("Styling for file names in source files")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_file;
@ -639,43 +639,43 @@ static struct json_path_container theme_syntax_styles_handlers = {
};
static struct json_path_container theme_status_styles_handlers = {
json_path_handler("text")
yajlpp::property_handler("text")
.with_description("Styling for status bars")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_status;
})
.with_children(style_config_handlers),
json_path_handler("warn")
yajlpp::property_handler("warn")
.with_description("Styling for warnings in status bars")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_warn_status;
})
.with_children(style_config_handlers),
json_path_handler("alert")
yajlpp::property_handler("alert")
.with_description("Styling for alerts in status bars")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_alert_status;
})
.with_children(style_config_handlers),
json_path_handler("active")
yajlpp::property_handler("active")
.with_description("Styling for activity in status bars")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_active_status;
})
.with_children(style_config_handlers),
json_path_handler("inactive")
yajlpp::property_handler("inactive")
.with_description("Styling for inactive status bars")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_inactive_status;
})
.with_children(style_config_handlers),
json_path_handler("title")
yajlpp::property_handler("title")
.with_description("Styling for title sections of status bars")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_status_title;
})
.with_children(style_config_handlers),
json_path_handler("subtitle")
yajlpp::property_handler("subtitle")
.with_description("Styling for subtitle sections of status bars")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
return &root->lt_style_status_subtitle;
@ -684,7 +684,7 @@ static struct json_path_container theme_status_styles_handlers = {
};
static struct json_path_container theme_log_level_styles_handlers = {
json_path_handler(pcrepp("(?<level>trace|debug5|debug4|debug3|debug2|debug|info|stats|notice|warning|error|critical|fatal)"))
yajlpp::pattern_property_handler("(?<level>trace|debug5|debug4|debug3|debug2|debug|info|stats|notice|warning|error|critical|fatal)")
.with_obj_provider<style_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
style_config &sc = root->lt_level_styles[
string2level(ypc.ypc_extractor.get_substr_i("level").get())];
@ -700,12 +700,12 @@ static struct json_path_container theme_log_level_styles_handlers = {
};
static struct json_path_container highlighter_handlers = {
json_path_handler("pattern")
yajlpp::property_handler("pattern")
.with_synopsis("regular expression")
.with_description("The regular expression to highlight")
.FOR_FIELD(highlighter_config, hc_regex),
json_path_handler("style")
yajlpp::property_handler("style")
.with_description("The styling for the text that matches the associated pattern")
.with_obj_provider<style_config, highlighter_config>([](const yajlpp_provider_context &ypc, highlighter_config *root) {
return &root->hc_style;
@ -714,7 +714,7 @@ static struct json_path_container highlighter_handlers = {
};
static struct json_path_container theme_highlights_handlers = {
json_path_handler(pcrepp("(?<highlight_name>\\w+)"))
yajlpp::pattern_property_handler("(?<highlight_name>\\w+)")
.with_obj_provider<highlighter_config, lnav_theme>([](const yajlpp_provider_context &ypc, lnav_theme *root) {
highlighter_config &hc = root->lt_highlights[
ypc.ypc_extractor.get_substr_i("highlight_name").get()];
@ -730,7 +730,7 @@ static struct json_path_container theme_highlights_handlers = {
};
static struct json_path_container theme_vars_handlers = {
json_path_handler(pcrepp("(?<var_name>\\w+)"))
yajlpp::pattern_property_handler("(?<var_name>\\w+)")
.with_synopsis("name")
.with_description("A theme variable definition")
.with_path_provider<lnav_theme>([](struct lnav_theme *lt, vector<string> &paths_out) {
@ -742,33 +742,33 @@ static struct json_path_container theme_vars_handlers = {
};
static struct json_path_container theme_def_handlers = {
json_path_handler("vars")
yajlpp::property_handler("vars")
.with_description("Variables definitions that are used in this theme.")
.with_children(theme_vars_handlers),
json_path_handler("styles")
yajlpp::property_handler("styles")
.with_description("Styles for log messages.")
.with_children(theme_styles_handlers),
json_path_handler("syntax-styles")
yajlpp::property_handler("syntax-styles")
.with_description("Styles for syntax highlighting in text files.")
.with_children(theme_syntax_styles_handlers),
json_path_handler("status-styles")
yajlpp::property_handler("status-styles")
.with_description("Styles for the user-interface components.")
.with_children(theme_status_styles_handlers),
json_path_handler("log-level-styles")
yajlpp::property_handler("log-level-styles")
.with_description("Styles for each log message level.")
.with_children(theme_log_level_styles_handlers),
json_path_handler("highlights")
yajlpp::property_handler("highlights")
.with_description("Styles for text highlights.")
.with_children(theme_highlights_handlers),
};
static struct json_path_container theme_defs_handlers = {
json_path_handler(pcrepp("(?<theme_name>[\\w\\-]+)"))
yajlpp::pattern_property_handler("(?<theme_name>[\\w\\-]+)")
.with_obj_provider<lnav_theme, _lnav_config>([](const yajlpp_provider_context &ypc, _lnav_config *root) {
lnav_theme &lt = root->lc_ui_theme_defs[ypc.ypc_extractor.get_substr("theme_name")];
@ -783,19 +783,19 @@ static struct json_path_container theme_defs_handlers = {
};
static struct json_path_container ui_handlers = {
json_path_handler("clock-format")
yajlpp::property_handler("clock-format")
.with_synopsis("format")
.with_description("The format for the clock displayed in "
"the top-left corner using strftime(3) conversions")
.with_example("%a %b %d %H:%M:%S %Z")
.FOR_FIELD(_lnav_config, lc_ui_clock_format),
json_path_handler("dim-text")
yajlpp::property_handler("dim-text")
.with_synopsis("bool")
.with_description("Reduce the brightness of text (useful for xterms). "
"This setting can be useful when running in an xterm "
"where the white color is very bright.")
.FOR_FIELD(_lnav_config, lc_ui_dim_text),
json_path_handler("default-colors")
yajlpp::property_handler("default-colors")
.with_synopsis("bool")
.with_description(
"Use default terminal background and foreground colors "
@ -803,18 +803,18 @@ static struct json_path_container ui_handlers = {
"can be useful when transparent background or alternate color "
"theme terminal is used.")
.FOR_FIELD(_lnav_config, lc_ui_default_colors),
json_path_handler("keymap")
yajlpp::property_handler("keymap")
.with_synopsis("keymap_name")
.with_description("The name of the keymap to use.")
.FOR_FIELD(_lnav_config, lc_ui_keymap),
json_path_handler("theme")
yajlpp::property_handler("theme")
.with_synopsis("theme_name")
.with_description("The name of the theme to use.")
.FOR_FIELD(_lnav_config, lc_ui_theme),
json_path_handler("theme-defs")
yajlpp::property_handler("theme-defs")
.with_description("Theme definitions.")
.with_children(theme_defs_handlers),
json_path_handler("keymap-defs")
yajlpp::property_handler("keymap-defs")
.with_description("Keymap definitions.")
.with_children(keymap_defs_handlers)};
@ -842,11 +842,11 @@ struct json_path_container lnav_config_handlers = json_path_container {
.with_synopsis("The URI of the schema for this file")
.with_description("Specifies the type of this file"),
json_path_handler("ui")
yajlpp::property_handler("ui")
.with_description("User-interface settings")
.with_children(ui_handlers),
json_path_handler("global")
yajlpp::property_handler("global")
.with_description("Global variable definitions")
.with_children(global_var_handlers)
}

View File

@ -353,13 +353,13 @@ static int create_search_table(yajlpp_parse_context *ypc, const unsigned char *s
static struct json_path_container pattern_handlers = {
json_path_handler("pattern")
yajlpp::property_handler("pattern")
.with_synopsis("<message-regex>")
.with_description(
"The regular expression to match a log message and capture fields.")
.with_min_length(1)
.FOR_FIELD(external_log_format::pattern, p_string),
json_path_handler("module-format")
yajlpp::property_handler("module-format")
.with_synopsis("<bool>")
.with_description(
"If true, this pattern will only be used to parse message bodies "
@ -392,48 +392,48 @@ static const json_path_handler_base::enum_value_t TRANSFORM_ENUM[] = {
};
static struct json_path_container line_format_handlers = {
json_path_handler("field")
yajlpp::property_handler("field")
.with_synopsis("<field-name>")
.with_description("The name of the field to substitute at this position")
.with_min_length(1)
.FOR_FIELD(external_log_format::json_format_element, jfe_value),
json_path_handler("default-value")
yajlpp::property_handler("default-value")
.with_synopsis("<string>")
.with_description("The default value for this position if the field is null")
.FOR_FIELD(external_log_format::json_format_element, jfe_default_value),
json_path_handler("timestamp-format")
yajlpp::property_handler("timestamp-format")
.with_synopsis("<string>")
.with_min_length(1)
.with_description("The strftime(3) format for this field")
.FOR_FIELD(external_log_format::json_format_element, jfe_ts_format),
json_path_handler("min-width")
yajlpp::property_handler("min-width")
.with_min_value(0)
.with_synopsis("<size>")
.with_description("The minimum width of the field")
.FOR_FIELD(external_log_format::json_format_element, jfe_min_width),
json_path_handler("max-width")
yajlpp::property_handler("max-width")
.with_min_value(0)
.with_synopsis("<size>")
.with_description("The maximum width of the field")
.FOR_FIELD(external_log_format::json_format_element, jfe_max_width),
json_path_handler("align")
yajlpp::property_handler("align")
.with_synopsis("left|right")
.with_description("Align the text in the column to the left or right side")
.with_enum_values(ALIGN_ENUM)
.FOR_FIELD(external_log_format::json_format_element, jfe_align),
json_path_handler("overflow")
yajlpp::property_handler("overflow")
.with_synopsis("abbrev|truncate|dot-dot")
.with_description("Overflow style")
.with_enum_values(OVERFLOW_ENUM)
.FOR_FIELD(external_log_format::json_format_element, jfe_overflow),
json_path_handler("text-transform")
yajlpp::property_handler("text-transform")
.with_synopsis("none|uppercase|lowercase|capitalize")
.with_description("Text transformation")
.with_enum_values(TRANSFORM_ENUM)
@ -453,92 +453,92 @@ static const json_path_handler_base::enum_value_t KIND_ENUM[] = {
};
static struct json_path_container scale_handlers = {
json_path_handler(pcrepp("(?<scale>.*)"))
yajlpp::pattern_property_handler("(?<scale>.*)")
.with_synopsis("[*,/]<unit>")
.FOR_FIELD(scaling_factor, sf_value)
};
static struct json_path_container unit_handlers = {
json_path_handler("field")
yajlpp::property_handler("field")
.with_synopsis("<field-name>")
.with_description("The name of the field that contains the units for this field")
.FOR_FIELD(external_log_format::value_def, vd_unit_field),
json_path_handler("scaling-factor")
yajlpp::property_handler("scaling-factor")
.with_description("Transforms the numeric value by the given factor")
.with_obj_provider(scaling_factor_provider)
.with_children(scale_handlers),
};
static struct json_path_container value_def_handlers = {
json_path_handler("kind")
yajlpp::property_handler("kind")
.with_synopsis("string|integer|float|boolean|json|quoted")
.with_description("The type of data in the field")
.with_enum_values(KIND_ENUM)
.FOR_FIELD(external_log_format::value_def, vd_kind),
json_path_handler("collate")
yajlpp::property_handler("collate")
.with_synopsis("<function>")
.with_description("The collating function to use for this column")
.FOR_FIELD(external_log_format::value_def, vd_collate),
json_path_handler("unit")
yajlpp::property_handler("unit")
.with_description("Unit definitions for this field")
.with_children(unit_handlers),
json_path_handler("identifier")
yajlpp::property_handler("identifier")
.with_synopsis("<bool>")
.with_description("Indicates whether or not this field contains an identifier that should be highlighted")
.FOR_FIELD(external_log_format::value_def, vd_identifier),
json_path_handler("foreign-key")
yajlpp::property_handler("foreign-key")
.with_synopsis("<bool>")
.with_description("Indicates whether or not this field should be treated as a foreign key for row in another table")
.FOR_FIELD(external_log_format::value_def, vd_foreign_key),
json_path_handler("hidden")
yajlpp::property_handler("hidden")
.with_synopsis("<bool>")
.with_description("Indicates whether or not this field should be hidden")
.FOR_FIELD(external_log_format::value_def, vd_hidden),
json_path_handler("action-list#")
yajlpp::property_handler("action-list#")
.with_synopsis("<string>")
.with_description("Actions to execute when this field is clicked on")
.FOR_FIELD(external_log_format::value_def, vd_action_list),
json_path_handler("rewriter")
yajlpp::property_handler("rewriter")
.with_synopsis("<command>")
.with_description("A command that will rewrite this field when pretty-printing")
.FOR_FIELD(external_log_format::value_def, vd_rewriter),
json_path_handler("description")
yajlpp::property_handler("description")
.with_synopsis("<string>")
.with_description("A description of the field")
.FOR_FIELD(external_log_format::value_def, vd_description)
};
static struct json_path_container highlighter_def_handlers = {
json_path_handler("pattern")
yajlpp::property_handler("pattern")
.with_synopsis("<regex>")
.with_description("A regular expression to highlight in logs of this format.")
.FOR_FIELD(external_log_format::highlighter_def, hd_pattern),
json_path_handler("color")
yajlpp::property_handler("color")
.with_synopsis("#<hex>|<name>")
.with_description("The color to use when highlighting this pattern.")
.FOR_FIELD(external_log_format::highlighter_def, hd_color),
json_path_handler("background-color")
yajlpp::property_handler("background-color")
.with_synopsis("#<hex>|<name>")
.with_description("The background color to use when highlighting this pattern.")
.FOR_FIELD(external_log_format::highlighter_def, hd_background_color),
json_path_handler("underline")
yajlpp::property_handler("underline")
.with_synopsis("<enabled>")
.with_description("Highlight this pattern with an underline.")
.FOR_FIELD(external_log_format::highlighter_def, hd_underline),
json_path_handler("blink")
yajlpp::property_handler("blink")
.with_synopsis("<enabled>")
.with_description("Highlight this pattern by blinking.")
.FOR_FIELD(external_log_format::highlighter_def, hd_blink)
@ -563,12 +563,12 @@ static const json_path_handler_base::enum_value_t LEVEL_ENUM[] = {
};
static struct json_path_container sample_handlers = {
json_path_handler("line")
yajlpp::property_handler("line")
.with_synopsis("<log-line>")
.with_description("A sample log line that should match a pattern in this format.")
.FOR_FIELD(external_log_format::sample, s_line),
json_path_handler("level")
yajlpp::property_handler("level")
.with_enum_values(LEVEL_ENUM)
.with_description("The expected level for this sample log line.")
.FOR_FIELD(external_log_format::sample, s_level)
@ -583,15 +583,15 @@ static const json_path_handler_base::enum_value_t TYPE_ENUM[] = {
};
static struct json_path_container regex_handlers = {
json_path_handler(pcrepp(R"((?<pattern_name>[^/]+))"))
yajlpp::pattern_property_handler(R"((?<pattern_name>[^/]+))")
.with_description("The set of patterns used to match log messages")
.with_obj_provider(pattern_provider)
.with_children(pattern_handlers),
};
static struct json_path_container level_handlers = {
json_path_handler(
pcrepp("(?<level>trace|debug[2345]?|info|stats|notice|warning|error|critical|fatal)"))
yajlpp::pattern_property_handler(
"(?<level>trace|debug[2345]?|info|stats|notice|warning|error|critical|fatal)")
.add_cb(read_levels)
.add_cb(read_level_int)
.with_synopsis("<pattern|integer>")
@ -600,14 +600,14 @@ static struct json_path_container level_handlers = {
};
static struct json_path_container value_handlers = {
json_path_handler(pcrepp("(?<value_name>[^/]+)"))
yajlpp::pattern_property_handler("(?<value_name>[^/]+)")
.with_description("The set of values captured by the log message patterns")
.with_obj_provider(value_def_provider)
.with_children(value_def_handlers)
};
static struct json_path_container highlight_handlers = {
json_path_handler(pcrepp(R"((?<highlight_name>[^/]+))"))
yajlpp::pattern_property_handler(R"((?<highlight_name>[^/]+))")
.with_description("The definition of a highlight")
.with_obj_provider<external_log_format::highlighter_def, external_log_format>([](const yajlpp_provider_context &ypc, external_log_format *root) {
return &(root->elf_highlighter_patterns[ypc.get_substr_i(0)]);
@ -633,13 +633,13 @@ static struct json_path_container search_table_def_handlers = {
};
static struct json_path_container search_table_handlers = {
json_path_handler(pcrepp("\\w+"))
yajlpp::pattern_property_handler("\\w+")
.with_description("The set of search tables to be automatically defined")
.with_children(search_table_def_handlers)
};
struct json_path_container format_handlers = {
json_path_handler("regex")
yajlpp::property_handler("regex")
.with_description("The set of regular expressions used to match log messages")
.with_children(regex_handlers),
@ -676,26 +676,26 @@ struct json_path_container format_handlers = {
.with_description("The name of the module field in the log message pattern"),
json_path_handler("opid-field", read_format_field)
.with_description("The name of the operation-id field in the log message pattern"),
json_path_handler("ordered-by-time")
yajlpp::property_handler("ordered-by-time")
.with_synopsis("<bool>")
.with_description("Indicates that the order of messages in the file is time-based.")
.FOR_FIELD(log_format, lf_time_ordered),
json_path_handler("level")
yajlpp::property_handler("level")
.with_description("The map of level names to patterns or integer values")
.with_children(level_handlers),
json_path_handler("value")
yajlpp::property_handler("value")
.with_description("The set of value definitions")
.with_children(value_handlers),
json_path_handler("action")
yajlpp::property_handler("action")
.with_children(action_handlers),
json_path_handler("sample#")
yajlpp::property_handler("sample#")
.with_description("An array of sample log messages to be tested against the log message patterns")
.with_obj_provider(sample_provider)
.with_children(sample_handlers),
json_path_handler("line-format#")
yajlpp::property_handler("line-format#")
.with_description("The display format for JSON-encoded log messages")
.with_obj_provider(line_format_provider)
.add_cb(read_json_constant)
@ -704,11 +704,11 @@ struct json_path_container format_handlers = {
.with_description("Search tables to automatically define for this log format")
.with_children(search_table_handlers),
json_path_handler("highlights")
yajlpp::property_handler("highlights")
.with_description("The set of highlight definitions")
.with_children(highlight_handlers),
json_path_handler("file-type")
yajlpp::property_handler("file-type")
.with_synopsis("text|json|csv")
.with_description("The type of file that contains the log messages")
.with_enum_values(TYPE_ENUM)
@ -739,7 +739,7 @@ struct json_path_container root_format_handler = json_path_container {
.with_synopsis("The URI of the schema for this file")
.with_description("Specifies the type of this file"),
json_path_handler(pcrepp("(?<format_name>\\w+)"))
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)

View File

@ -127,6 +127,12 @@ bool logfile::exists() const
this->lf_stat.st_size <= st.st_size;
}
void logfile::reset_state()
{
this->clear_time_offset();
this->lf_is_visible = this->lf_options.loo_is_visible;
}
void logfile::set_format_base_time(log_format *lf)
{
time_t file_time = this->lf_line_buffer.get_file_time();

View File

@ -267,6 +267,13 @@ public:
this->adjust_content_time(-1, tv);
};
void mark_as_duplicate() {
this->hide();
this->lf_options.loo_is_visible = false;
}
void reset_state();
bool is_time_adjusted() const {
return (this->lf_time_offset.tv_sec != 0 ||
this->lf_time_offset.tv_usec != 0);

View File

@ -55,6 +55,8 @@
using namespace std;
struct session_data_t session_data;
static const char *LOG_METADATA_NAME = "log_metadata.db";
static const char *BOOKMARK_TABLE_DEF = R"(
@ -713,18 +715,6 @@ static void load_time_bookmarks()
}
}
static int read_save_time(yajlpp_parse_context *ypc, long long value)
{
lnav_data.ld_session_save_time = value;
return 1;
}
static int read_time_offset(yajlpp_parse_context *ypc, int value)
{
return 1;
}
static int read_files(yajlpp_parse_context *ypc, const unsigned char *str, size_t len)
{
return 1;
@ -841,16 +831,36 @@ static struct json_path_container view_def_handlers = {
};
static struct json_path_container view_handlers = {
json_path_handler(pcrepp("([^/]+)"))
yajlpp::pattern_property_handler("([^/]+)")
.with_children(view_def_handlers)
};
static struct json_path_container file_state_handlers = {
yajlpp::property_handler("visible")
.with_description("Indicates whether the file is visible or not")
.FOR_FIELD(file_state, fs_is_visible),
};
static struct json_path_container file_states_handlers = {
yajlpp::pattern_property_handler(R"((?<filename>[^/]+))")
.with_description("Map of file names to file state objects")
.with_obj_provider<file_state, void>([](const auto& ypc, auto *root) {
auto fn = ypc.get_substr("filename");
return &session_data.sd_file_states[fn];
})
.with_children(file_state_handlers),
};
static struct json_path_container view_info_handlers = {
json_path_handler("save-time", read_save_time),
json_path_handler("time-offset", read_time_offset),
yajlpp::property_handler("save-time")
.FOR_FIELD(session_data_t, sd_save_time),
yajlpp::property_handler("time-offset")
.FOR_FIELD(session_data_t, sd_time_offset),
json_path_handler("files#", read_files),
json_path_handler("views")
.with_children(view_handlers)
yajlpp::property_handler("file-states")
.with_children(file_states_handlers),
yajlpp::property_handler("views")
.with_children(view_handlers),
};
void load_session()
@ -861,10 +871,11 @@ void load_session()
auto_fd fd;
lnav_data.ld_session_load_time = pair.first.second;
lnav_data.ld_session_save_time = pair.first.second;
session_data.sd_save_time = pair.first.second;
const string &view_info_name = pair.second;
yajlpp_parse_context ypc(view_info_name, &view_info_handlers);
ypc.with_obj(session_data);
handle = yajl_alloc(&ypc.ypc_callbacks, nullptr, &ypc);
load_time_bookmarks();
@ -883,6 +894,35 @@ void load_session()
yajl_complete_parse(handle);
}
yajl_free(handle);
bool log_changes = false, text_changes = false;
for (auto& lf : lnav_data.ld_active_files.fc_files) {
auto iter = session_data.sd_file_states.find(lf->get_filename());
if (iter == session_data.sd_file_states.end()) {
continue;
}
log_debug("found state for file: %s %d",
lf->get_content_id().c_str(),
iter->second.fs_is_visible);
lf->set_visibility(iter->second.fs_is_visible);
if (!iter->second.fs_is_visible) {
if (lf->get_format() != nullptr) {
log_changes = true;
} else {
text_changes = true;
}
}
}
if (log_changes) {
lnav_data.ld_log_source.text_filters_changed();
}
if (text_changes) {
lnav_data.ld_text_source.text_filters_changed();
}
};
}
@ -1266,7 +1306,7 @@ static void save_session_with_id(const std::string session_id)
yajlpp_map root_map(handle);
root_map.gen("save-time");
root_map.gen((long long) time(NULL));
root_map.gen((long long) time(nullptr));
root_map.gen("time-offset");
root_map.gen(lnav_data.ld_log_source.is_time_offset_enabled());
@ -1281,6 +1321,23 @@ static void save_session_with_id(const std::string session_id)
}
}
root_map.gen("file-states");
{
yajlpp_map file_states(handle);
for (auto &lf : lnav_data.ld_active_files.fc_files) {
file_states.gen(lf->get_filename());
{
yajlpp_map file_state(handle);
file_state.gen("visible");
file_state.gen(lf->is_visible());
}
}
}
root_map.gen("views");
{
@ -1413,7 +1470,7 @@ void save_session()
opt_session_id | [](auto &session_id) {
save_session_with_id(session_id);
};
for (const auto pair : lnav_data.ld_session_id) {
for (const auto& pair : lnav_data.ld_session_id) {
if (opt_session_id && pair.first == opt_session_id.value()) {
continue;
}
@ -1428,6 +1485,7 @@ void reset_session()
save_session();
lnav_data.ld_session_time = time(nullptr);
session_data.sd_file_states.clear();
for (auto &tc : lnav_data.ld_views) {
auto &hmap = tc.get_highlights();
@ -1442,10 +1500,8 @@ void reset_session()
}
}
for (auto ld : lnav_data.ld_log_source) {
shared_ptr<logfile> lf = ld->get_file();
lf->clear_time_offset();
for (const auto& lf : lnav_data.ld_active_files.fc_files) {
lf->reset_state();
}
lnav_data.ld_log_source.set_marked_only(false);

View File

@ -32,6 +32,21 @@
#ifndef _session_data_hh
#define _session_data_hh
#include <map>
#include <string>
struct file_state {
bool fs_is_visible{true};
};
struct session_data_t {
uint64_t sd_save_time{0};
bool sd_time_offset{false};
std::map<std::string, file_state> sd_file_states;
};
extern struct session_data_t session_data;
void init_session();
void load_session();
void save_session();

View File

@ -42,27 +42,27 @@
using namespace std;
static struct json_path_container term_color_rgb_handler = {
json_path_handler("r")
yajlpp::property_handler("r")
.FOR_FIELD(rgb_color, rc_r),
json_path_handler("g")
yajlpp::property_handler("g")
.FOR_FIELD(rgb_color, rc_g),
json_path_handler("b")
yajlpp::property_handler("b")
.FOR_FIELD(rgb_color, rc_b)
};
static struct json_path_container term_color_handler = {
json_path_handler("colorId")
yajlpp::property_handler("colorId")
.FOR_FIELD(term_color, xc_id),
json_path_handler("name")
yajlpp::property_handler("name")
.FOR_FIELD(term_color, xc_name),
json_path_handler("rgb")
yajlpp::property_handler("rgb")
.with_obj_provider<rgb_color, term_color>(
[](const auto &pc, term_color *xc) { return &xc->xc_color; })
.with_children(term_color_rgb_handler)
};
static struct json_path_container root_color_handler = {
json_path_handler("#")
yajlpp::property_handler("#")
.with_obj_provider<term_color, vector<term_color>>(
[](const yajlpp_provider_context &ypc, vector<term_color> *palette) {
palette->resize(ypc.ypc_index + 1);

View File

@ -481,4 +481,16 @@ struct json_path_container {
std::vector<json_path_handler> jpc_children;
};
namespace yajlpp {
inline json_path_handler property_handler(const std::string &path)
{
return {path};
}
inline json_path_handler pattern_property_handler(const std::string &path)
{
return {pcrepp(path)};
}
}
#endif

View File

@ -6,6 +6,26 @@ export HOME="./sessions"
rm -rf "./sessions"
mkdir -p $HOME
run_test ${lnav_test} -n \
-c ":reset-session" \
-c ":goto 0" \
-c ":hide-file" \
-c ":save-session" \
${test_dir}/logfile_access_log.*
check_output "hiding file is not working" <<EOF
10.112.81.15 - - [15/Feb/2013:06:00:31 +0000] "-" 400 0 "-" "-"
EOF
run_test ${lnav_test} -n \
-c ":load-session" \
${test_dir}/logfile_access_log.*
check_output "hidden file was not saved in session" <<EOF
10.112.81.15 - - [15/Feb/2013:06:00:31 +0000] "-" 400 0 "-" "-"
EOF
run_test ${lnav_test} -nq \
-c ":reset-session" \
-c ";update access_log set log_mark = 1 where sc_bytes > 60000" \