From 592ee606936fce1a3b5c212f66c3271e65a83348 Mon Sep 17 00:00:00 2001 From: Timothy Stack Date: Mon, 21 Nov 2016 11:34:12 -0800 Subject: [PATCH] [log] fix rewriting machine-oriented timestamps Fixes #371 --- src/db_sub_source.hh | 2 +- src/lnav_util.hh | 3 ++- src/logfile_sub_source.cc | 33 +++++++++++++++++---------------- src/logfile_sub_source.hh | 2 ++ src/ptimec_rt.cc | 4 ++++ src/view_curses.hh | 2 +- test/test_date_time_scanner.cc | 4 ++-- test/test_logfile.sh | 7 +++++++ 8 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/db_sub_source.hh b/src/db_sub_source.hh index 6bcce7d8..07efbfe8 100644 --- a/src/db_sub_source.hh +++ b/src/db_sub_source.hh @@ -197,7 +197,7 @@ public: date_time_scanner dts; struct timeval tv; - if (!dts.convert_to_timeval(colstr, -1, tv)) { + if (!dts.convert_to_timeval(colstr, -1, NULL, tv)) { tv.tv_sec = -1; tv.tv_usec = -1; } diff --git a/src/lnav_util.hh b/src/lnav_util.hh index d637e712..31251ff2 100644 --- a/src/lnav_util.hh +++ b/src/lnav_util.hh @@ -345,13 +345,14 @@ struct date_time_scanner { bool convert_to_timeval(const char *time_src, ssize_t time_len, + const char * const time_fmt[], struct timeval &tv_out) { struct exttm tm; if (time_len == -1) { time_len = strlen(time_src); } - if (this->scan(time_src, time_len, NULL, &tm, tv_out) != NULL) { + if (this->scan(time_src, time_len, time_fmt, &tm, tv_out) != NULL) { return true; } return false; diff --git a/src/logfile_sub_source.cc b/src/logfile_sub_source.cc index 4dc0f4c1..68a8d444 100644 --- a/src/logfile_sub_source.cc +++ b/src/logfile_sub_source.cc @@ -122,6 +122,8 @@ void logfile_sub_source::text_value_for_line(textview_curses &tc, this->lss_share_manager.invalidate_refs(); this->lss_token_value = this->lss_token_file->read_line(this->lss_token_line); + this->lss_token_shift_start = 0; + this->lss_token_shift_size = 0; log_format *format = this->lss_token_file->get_format(); @@ -153,26 +155,26 @@ void logfile_sub_source::text_value_for_line(textview_curses &tc, struct exttm adjusted_tm; char buffer[128]; const char *fmt; + ssize_t len; if (format->lf_timestamp_flags & ETF_MACHINE_ORIENTED) { format->lf_date_time.convert_to_timeval( &this->lss_token_value.c_str()[time_range.lr_start], time_range.length(), + format->get_timestamp_formats(), adjusted_time); fmt = "%Y-%m-%d %H:%M:%S.%f"; gmtime_r(&adjusted_time.tv_sec, &adjusted_tm.et_tm); adjusted_tm.et_nsec = adjusted_time.tv_usec * 1000; - ftime_fmt(buffer, sizeof(buffer), fmt, adjusted_tm); + len = ftime_fmt(buffer, sizeof(buffer), fmt, adjusted_tm); } else { adjusted_time = this->lss_token_line->get_timeval(); gmtime_r(&adjusted_time.tv_sec, &adjusted_tm.et_tm); adjusted_tm.et_nsec = adjusted_time.tv_usec * 1000; - format->lf_date_time.ftime(buffer, sizeof(buffer), adjusted_tm); + len = format->lf_date_time.ftime(buffer, sizeof(buffer), adjusted_tm); } - ssize_t len = strlen(buffer); - if (len > time_range.length()) { ssize_t padding = len - time_range.length(); @@ -184,8 +186,11 @@ void logfile_sub_source::text_value_for_line(textview_curses &tc, padding); } value_out.replace(time_range.lr_start, - strlen(buffer), - string(buffer)); + len, + buffer, + len); + this->lss_token_shift_start = time_range.lr_start; + this->lss_token_shift_size = len - time_range.length(); } } } @@ -285,6 +290,11 @@ void logfile_sub_source::text_attrs_for_line(textview_curses &lv, lv_iter->lv_origin, &view_curses::VC_STYLE, id_attrs)); } + if (this->lss_token_shift_size) { + shift_string_attrs(value_out, this->lss_token_shift_start, + this->lss_token_shift_size); + } + if (this->lss_files.size() > 1) { shift_string_attrs(value_out, 0, 1); @@ -321,16 +331,7 @@ void logfile_sub_source::text_attrs_for_line(textview_curses &lv, lr.lr_start = 0; lr.lr_end = time_offset_end; - for (string_attrs_t::iterator iter = value_out.begin(); - iter != value_out.end(); - ++iter) { - struct line_range *existing_lr = (line_range *)&iter->sa_range; - - existing_lr->lr_start += time_offset_end; - if (existing_lr->lr_end != -1) { - existing_lr->lr_end += time_offset_end; - } - } + shift_string_attrs(value_out, 0, time_offset_end); // attrs = vc.attrs_for_role(view_colors::VCR_OK); attrs = view_colors::ansi_color_pair(COLOR_CYAN, COLOR_BLACK); diff --git a/src/logfile_sub_source.hh b/src/logfile_sub_source.hh index 6411ba27..a060a290 100644 --- a/src/logfile_sub_source.hh +++ b/src/logfile_sub_source.hh @@ -595,6 +595,8 @@ private: std::string lss_token_value; string_attrs_t lss_token_attrs; std::vector lss_token_values; + int lss_token_shift_start; + int lss_token_shift_size; shared_buffer lss_share_manager; logfile::iterator lss_token_line; std::pair lss_line_size_cache[LINE_SIZE_CACHE_SIZE]; diff --git a/src/ptimec_rt.cc b/src/ptimec_rt.cc index e7c2f96a..d4459267 100644 --- a/src/ptimec_rt.cc +++ b/src/ptimec_rt.cc @@ -85,6 +85,7 @@ bool ptime_fmt(const char *fmt, struct exttm *dst, const char *str, off_t &off, FMT_CASE('I', I); FMT_CASE('d', d); FMT_CASE('e', e); + FMT_CASE('f', f); FMT_CASE('k', k); FMT_CASE('l', l); FMT_CASE('m', m); @@ -129,6 +130,7 @@ size_t ftime_fmt(char *dst, size_t len, const char *fmt, const struct exttm &tm) FTIME_FMT_CASE('I', I); FTIME_FMT_CASE('d', d); FTIME_FMT_CASE('e', e); + FTIME_FMT_CASE('f', f); FTIME_FMT_CASE('k', k); FTIME_FMT_CASE('l', l); FTIME_FMT_CASE('m', m); @@ -143,5 +145,7 @@ size_t ftime_fmt(char *dst, size_t len, const char *fmt, const struct exttm &tm) } } + dst[off_inout] = '\0'; + return (size_t) off_inout; } diff --git a/src/view_curses.hh b/src/view_curses.hh index a908f051..a657422b 100644 --- a/src/view_curses.hh +++ b/src/view_curses.hh @@ -317,7 +317,7 @@ inline void shift_string_attrs(string_attrs_t &sa, int32_t start, int32_t amount for (string_attrs_t::iterator iter = sa.begin(); iter != sa.end(); ++iter) { struct line_range *existing_lr = &iter->sa_range; - if (existing_lr->lr_start >= start) { + if (existing_lr->lr_start > start) { existing_lr->lr_start += amount; } if (existing_lr->lr_end != -1 && start < existing_lr->lr_end) { diff --git a/test/test_date_time_scanner.cc b/test/test_date_time_scanner.cc index 422dcee4..768c3605 100644 --- a/test/test_date_time_scanner.cc +++ b/test/test_date_time_scanner.cc @@ -80,12 +80,12 @@ int main(int argc, char *argv[]) date_time_scanner dts; struct timeval tv; - dts.convert_to_timeval("@40000000433225833b6e1a8c", -1, tv); + dts.convert_to_timeval("@40000000433225833b6e1a8c", -1, NULL, tv); assert(tv.tv_sec == 1127359865); assert(tv.tv_usec == 997071); memset(&tv, 0, sizeof(tv)); - dts.convert_to_timeval("@4000000043322583", -1, tv); + dts.convert_to_timeval("@4000000043322583", -1, NULL, tv); assert(tv.tv_sec == 1127359865); assert(tv.tv_usec == 0); } diff --git a/test/test_logfile.sh b/test/test_logfile.sh index 89512ba8..24dd5e87 100644 --- a/test/test_logfile.sh +++ b/test/test_logfile.sh @@ -321,3 +321,10 @@ error:logfile_bad_access_log.0:1:line did not match format access_log/regex/std error:logfile_bad_access_log.0:1: line -- 192.168.202.254 [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkboot.gz HTTP/1.0" 404 46210 "-" "gPXE/0.9.7" error:logfile_bad_access_log.0:1:partial match -- 192.168.202.254 EOF + +run_test ${lnav_test} -n -I ${test_dir} ${srcdir}/logfile_epoch.0 + +check_output "rewriting machine-oriented timestamp didn't work?" <