From 47a7b5ce022765bead29b93c53c039497677d57f Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Sat, 19 Nov 2016 19:06:12 +0000 Subject: [PATCH 1/5] fix std::remove call in path.h It's trying to use std::remove from cstdio. Apparently path.h isn't currently used for anything, since it didn't even compile ... --- src/filesystem/path.h | 1 + 1 file changed, 1 insertion(+) 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 From 9ffbc1ac46f78171aa4b5dcad41eb8aee4046f20 Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Sat, 19 Nov 2016 16:54:53 +0000 Subject: [PATCH 2/5] make '.' toggle prefixing each log line with filename Mostly addresses #277. I won't claim it fully closes it, because there are at least two ways it could be improved: 1. It doesn't draw a nice coloured divider in the column after the filename, and that would provide maximum visual clarity and consistency with the existing presentation. 2. It would be nice if the filenames weren't shown on every single line, but only on the first line of a contiguous chunk of log lines from a single file (or on the top line of the screen if the first line of the chunk was already scrolled off the top). 3. It doesn't yet include the filename in the text copied to the clipboard when the 'c' hotkey is pressed. --- docs/source/hotkeys.rst | 2 ++ src/help.txt | 3 +++ src/hotkeys.cc | 5 +++++ src/logfile.hh | 7 +++++++ src/logfile_sub_source.cc | 5 +++++ src/logfile_sub_source.hh | 11 +++++++++++ 6 files changed, 33 insertions(+) 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/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..5f38d3b4 100644 --- a/src/logfile_sub_source.cc +++ b/src/logfile_sub_source.cc @@ -192,6 +192,11 @@ void logfile_sub_source::text_value_for_line(textview_curses &tc, } } + if (this->lss_flags & F_FILENAME) { + value_out.insert(0, 1, ' '); + value_out.insert(0, this->lss_token_file->get_filename()); + } + // Insert space for the file/search-hit markers. value_out.insert(0, 1, ' '); diff --git a/src/logfile_sub_source.hh b/src/logfile_sub_source.hh index 7c8900c8..2a7b5382 100644 --- a/src/logfile_sub_source.hh +++ b/src/logfile_sub_source.hh @@ -97,6 +97,11 @@ public: this->clear_line_size_cache(); }; + void toggle_filename(void) { + this->lss_flags ^= F_FILENAME; + this->clear_line_size_cache(); + }; + void set_time_offset(bool enabled) { if (enabled) this->lss_flags |= F_TIME_OFFSET; @@ -109,6 +114,10 @@ public: return (bool) (this->lss_flags & F_TIME_OFFSET); }; + bool is_filename_enabled(void) const { + return (bool) (this->lss_flags & F_FILENAME); + }; + logline::level_t get_min_log_level(void) const { return this->lss_min_log_level; }; @@ -491,11 +500,13 @@ private: enum { B_SCRUB, B_TIME_OFFSET, + B_FILENAME, }; enum { F_SCRUB = (1L << B_SCRUB), F_TIME_OFFSET = (1L << B_TIME_OFFSET), + F_FILENAME = (1L << B_FILENAME), }; struct __attribute__((__packed__)) indexed_content { From 81974c6bdcfc2878cc8bce1430871d190c8bdfd2 Mon Sep 17 00:00:00 2001 From: Phil Hord Date: Tue, 27 Mar 2018 15:31:44 -0700 Subject: [PATCH 3/5] Fix filename column width and attributes Display the basename instead of the whole path for each file when the filename column is displayed. Make the column the same width all the time, taking the maximum basename width of all loaded files and padding with spaces. Also fix the attributes when the filename column is displayed. Insert the correct filename-matching color for as many characters as we add for the filename column. Use the full filename when looking up the color because we don't want files in different paths to have the same color, and we don't want the color to change based on whether we are displaying the base or the whole filename. --- src/logfile_sub_source.cc | 22 ++++++++++++++++++---- src/logfile_sub_source.hh | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/logfile_sub_source.cc b/src/logfile_sub_source.cc index 5f38d3b4..acd33b3e 100644 --- a/src/logfile_sub_source.cc +++ b/src/logfile_sub_source.cc @@ -193,13 +193,15 @@ void logfile_sub_source::text_value_for_line(textview_curses &tc, } if (this->lss_flags & F_FILENAME) { + auto file_offset_end = this->lss_basename_width + 1; + auto const & basename = this->lss_token_file->get_basename(); + value_out.insert(0, file_offset_end - basename.size(), ' '); + value_out.insert(0, basename); + } else { + // Insert space for the file/search-hit markers. value_out.insert(0, 1, ' '); - value_out.insert(0, this->lss_token_file->get_filename()); } - // 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; @@ -336,6 +338,15 @@ void logfile_sub_source::text_attrs_for_line(textview_curses &lv, lr, &view_curses::VC_STYLE, A_REVERSE)); } } + + if (this->lss_flags & F_FILENAME) { + auto file_offset_end = 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()))); @@ -473,6 +484,7 @@ 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; } if (retval || force) { @@ -487,6 +499,8 @@ 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());; } if (full_sort) { diff --git a/src/logfile_sub_source.hh b/src/logfile_sub_source.hh index 2a7b5382..de2bd974 100644 --- a/src/logfile_sub_source.hh +++ b/src/logfile_sub_source.hh @@ -625,6 +625,7 @@ private: ll <= this->lss_max_log_time); }; + size_t lss_basename_width = 0; unsigned long lss_flags; bool lss_force_rebuild; std::vector lss_files; From 4d4ac9b8b0eb891d66336af6e247036ebd113334 Mon Sep 17 00:00:00 2001 From: Phil Hord Date: Tue, 27 Mar 2018 15:58:44 -0700 Subject: [PATCH 4/5] Add another filename mode to show file path Add a separate BASENAME bit to distinguish from the FILENAME bit. When BASENAME is active show the base filename in the filename column. When FILENAME is active show the whole path for each filename. Cycle through the three modes with toggle_filename() still. Note that we are never in both FILENAME and BASENAME mode. The user can cycle through the three modes by pressing the hotkey an extra time. First press shows the basename, second press shows the full path (filename), and the third press hides the filename column again. --- src/logfile_sub_source.cc | 37 ++++++++++++++++++++++++++----------- src/logfile_sub_source.hh | 19 ++++++++++++++++++- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/logfile_sub_source.cc b/src/logfile_sub_source.cc index acd33b3e..10ed09a1 100644 --- a/src/logfile_sub_source.cc +++ b/src/logfile_sub_source.cc @@ -192,11 +192,18 @@ void logfile_sub_source::text_value_for_line(textview_curses &tc, } } - if (this->lss_flags & F_FILENAME) { - auto file_offset_end = this->lss_basename_width + 1; - auto const & basename = this->lss_token_file->get_basename(); - value_out.insert(0, file_offset_end - basename.size(), ' '); - value_out.insert(0, basename); + 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, ' '); @@ -339,17 +346,22 @@ void logfile_sub_source::text_attrs_for_line(textview_curses &lv, } } - if (this->lss_flags & F_FILENAME) { - auto file_offset_end = this->lss_basename_width; + 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); - 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()))); } - 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; @@ -485,6 +497,7 @@ bool logfile_sub_source::rebuild_index(bool force) this->lss_filtered_index.clear(); this->lss_longest_line = 0; this->lss_basename_width = 0; + this->lss_filename_width = 0; } if (retval || force) { @@ -501,6 +514,8 @@ bool logfile_sub_source::rebuild_index(bool force) 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 de2bd974..33ddb9c4 100644 --- a/src/logfile_sub_source.hh +++ b/src/logfile_sub_source.hh @@ -98,7 +98,17 @@ public: }; void toggle_filename(void) { - this->lss_flags ^= F_FILENAME; + // 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(); }; @@ -118,6 +128,10 @@ public: 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; }; @@ -501,12 +515,14 @@ private: 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 { @@ -626,6 +642,7 @@ private: }; size_t lss_basename_width = 0; + size_t lss_filename_width = 0; unsigned long lss_flags; bool lss_force_rebuild; std::vector lss_files; From 95e294decb31526c88882f50f041ea912a82aea2 Mon Sep 17 00:00:00 2001 From: Phil Hord Date: Tue, 27 Mar 2018 16:36:57 -0700 Subject: [PATCH 5/5] fix failing unit test The help output changed with the toggle-filenames option, but the test for help wasn't updated. Maybe the help needs to be updated a bit to include the two filename column modes, now that I think about it. But we should discuss the merits of that first, I suppose. --- test/expected_help.txt | 3 +++ 1 file changed, 3 insertions(+) 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