diff --git a/docs/source/hotkeys.rst b/docs/source/hotkeys.rst index ead250b4..a227e8d5 100644 --- a/docs/source/hotkeys.rst +++ b/docs/source/hotkeys.rst @@ -209,6 +209,8 @@ Display log_line column * - |ks| p |ke| - Toggle the display of the log parser results + * - |ks| . |ke| + - Toggle the display of the log file names * - |ks| Tab |ke| - Cycle through colums to graph in the SQL result view * - |ks| Ctrl |ke| + |ks| l |ke| diff --git a/src/filesystem/path.h b/src/filesystem/path.h index 58d8a712..54711172 100644 --- a/src/filesystem/path.h +++ b/src/filesystem/path.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/src/help.txt b/src/help.txt index 4a4c5e4b..903f3664 100644 --- a/src/help.txt +++ b/src/help.txt @@ -295,6 +295,9 @@ Display options means it has sped up. You can use the "s/S" hotkeys to scan through the slow downs. + . In the log view, toggle the display of filenames showing + where each log line comes from. + i View/leave a histogram of the log messages over time. The histogram counts the number of displayed log lines for each bucket of time. The diff --git a/src/hotkeys.cc b/src/hotkeys.cc index a5eb93d7..b6e29681 100644 --- a/src/hotkeys.cc +++ b/src/hotkeys.cc @@ -985,6 +985,11 @@ void handle_paging_key(int ch) tc->reload_data(); break; + case '.': + lnav_data.ld_log_source.toggle_filename(); + tc->reload_data(); + break; + case 'i': if (toggle_view(&lnav_data.ld_views[LNV_HISTOGRAM])) { lnav_data.ld_rl_view->set_alt_value( diff --git a/src/logfile.hh b/src/logfile.hh index a565ae95..8f00316e 100644 --- a/src/logfile.hh +++ b/src/logfile.hh @@ -48,6 +48,7 @@ #include "log_format.hh" #include "text_format.hh" #include "shared_buffer.hh" +#include "filesystem/path.h" class logfile; class logline_observer; @@ -137,12 +138,17 @@ public: /** @return The filename as given in the constructor. */ const std::string &get_filename() const { return this->lf_filename; }; + /** @return The filename as given in the constructor, excluding the path prefix. */ + const std::string &get_basename() const { return this->lf_basename; }; + int get_fd() const { return this->lf_line_buffer.get_fd(); }; /** @param filename The new filename for this log file. */ void set_filename(const std::string &filename) { this->lf_filename = filename; + filesystem::path p(filename); + this->lf_basename = p.filename(); }; const std::string &get_content_id() const { return this->lf_content_id; }; @@ -406,6 +412,7 @@ protected: logfile_activity lf_activity; bool lf_valid_filename; std::string lf_filename; + std::string lf_basename; std::string lf_content_id; struct stat lf_stat; std::unique_ptr lf_format; diff --git a/src/logfile_sub_source.cc b/src/logfile_sub_source.cc index d36cec13..10ed09a1 100644 --- a/src/logfile_sub_source.cc +++ b/src/logfile_sub_source.cc @@ -192,8 +192,22 @@ void logfile_sub_source::text_value_for_line(textview_curses &tc, } } - // Insert space for the file/search-hit markers. - value_out.insert(0, 1, ' '); + if (this->lss_flags & F_FILENAME || this->lss_flags & F_BASENAME) { + size_t file_offset_end; + std::string name; + if (this->lss_flags & F_FILENAME) { + file_offset_end = this->lss_filename_width; + name = this->lss_token_file->get_filename(); + } else { + file_offset_end = this->lss_basename_width; + name = this->lss_token_file->get_basename(); + } + value_out.insert(0, file_offset_end - name.size() + 1, ' '); + value_out.insert(0, name); + } else { + // Insert space for the file/search-hit markers. + value_out.insert(0, 1, ' '); + } if (this->lss_flags & F_TIME_OFFSET) { int64_t start_millis, curr_millis; @@ -331,9 +345,23 @@ void logfile_sub_source::text_attrs_for_line(textview_curses &lv, lr, &view_curses::VC_STYLE, A_REVERSE)); } } + value_out.push_back(string_attr(lr, &view_curses::VC_STYLE, vc.attrs_for_ident( this->lss_token_file->get_filename()))); + if (this->lss_flags & F_FILENAME || this->lss_flags & F_BASENAME) { + size_t file_offset_end = (this->lss_flags & F_FILENAME) ? + this->lss_filename_width : + this->lss_basename_width ; + + shift_string_attrs(value_out, 0, file_offset_end); + + lr.lr_start = 0; + lr.lr_end = file_offset_end + 1; + value_out.push_back(string_attr(lr, &view_curses::VC_STYLE, vc.attrs_for_ident( + this->lss_token_file->get_filename()))); + } + if (this->lss_flags & F_TIME_OFFSET) { time_offset_end = 13; lr.lr_start = 0; @@ -468,6 +496,8 @@ bool logfile_sub_source::rebuild_index(bool force) this->lss_index.clear(); this->lss_filtered_index.clear(); this->lss_longest_line = 0; + this->lss_basename_width = 0; + this->lss_filename_width = 0; } if (retval || force) { @@ -482,6 +512,10 @@ bool logfile_sub_source::rebuild_index(bool force) } this->lss_longest_line = std::max( this->lss_longest_line, lf->get_longest_line_length()); + this->lss_basename_width = std::max( + this->lss_basename_width, lf->get_basename().size());; + this->lss_filename_width = std::max( + this->lss_filename_width, lf->get_filename().size());; } if (full_sort) { diff --git a/src/logfile_sub_source.hh b/src/logfile_sub_source.hh index 7c8900c8..33ddb9c4 100644 --- a/src/logfile_sub_source.hh +++ b/src/logfile_sub_source.hh @@ -97,6 +97,21 @@ public: this->clear_line_size_cache(); }; + void toggle_filename(void) { + // NONE -> F_BASENAME -> F_FILENAME -> NONE ... + if (this->lss_flags & F_BASENAME) { + // F_BASENAME -> F_FILENAME + this->lss_flags ^= F_BASENAME | F_FILENAME; + } else if (this->lss_flags & F_FILENAME) { + // F_FILENAME -> NONE + this->lss_flags ^= F_FILENAME; + } else { + // NONE -> F_BASENAME + this->lss_flags ^= F_BASENAME; + } + this->clear_line_size_cache(); + }; + void set_time_offset(bool enabled) { if (enabled) this->lss_flags |= F_TIME_OFFSET; @@ -109,6 +124,14 @@ public: return (bool) (this->lss_flags & F_TIME_OFFSET); }; + bool is_filename_enabled(void) const { + return (bool) (this->lss_flags & F_FILENAME); + }; + + bool is_basename_enabled(void) const { + return (bool) (this->lss_flags & F_BASENAME); + }; + logline::level_t get_min_log_level(void) const { return this->lss_min_log_level; }; @@ -491,11 +514,15 @@ private: enum { B_SCRUB, B_TIME_OFFSET, + B_FILENAME, + B_BASENAME, }; enum { F_SCRUB = (1L << B_SCRUB), F_TIME_OFFSET = (1L << B_TIME_OFFSET), + F_FILENAME = (1L << B_FILENAME), + F_BASENAME = (1L << B_BASENAME), }; struct __attribute__((__packed__)) indexed_content { @@ -614,6 +641,8 @@ private: ll <= this->lss_max_log_time); }; + size_t lss_basename_width = 0; + size_t lss_filename_width = 0; unsigned long lss_flags; bool lss_force_rebuild; std::vector lss_files; diff --git a/test/expected_help.txt b/test/expected_help.txt index 7fdec9e6..97a3a45a 100644 --- a/test/expected_help.txt +++ b/test/expected_help.txt @@ -295,6 +295,9 @@ Display options means it has sped up. You can use the "s/S" hotkeys to scan through the slow downs. + . In the log view, toggle the display of filenames showing + where each log line comes from. + i View/leave a histogram of the log messages over time. The histogram counts the number of displayed log lines for each bucket of time. The