mirror of
https://github.com/tstack/lnav
synced 2024-11-01 21:40:34 +00:00
[docs] add some more text to arch docs and other tweaks
This commit is contained in:
parent
43bb384199
commit
0f238f7972
@ -57,7 +57,7 @@ log format has matched yet, each line will be passed through the log format
|
||||
regular expressions to try and find a match. Each line that is read is added
|
||||
to an index
|
||||
|
||||
### Why is `mmap()` not used?
|
||||
#### Why is `mmap()` not used?
|
||||
|
||||
Note that file contents are consumed using `pread(2)`/`read(2)` and not
|
||||
`mmap(2)` since `mmap(2)` does not react well to files changing out from
|
||||
@ -71,10 +71,21 @@ As files are being indexed, if a matching format is found, the file is
|
||||
it is added to the [logfile_sub_source](src/logfile_sub_source.hh), which
|
||||
collates all log messages together into a single index.
|
||||
|
||||
## Log Formats
|
||||
|
||||
[log_format](src/log_format.hh) instances are used to parse lines from files
|
||||
into `logline` objects. The majority of log formats are
|
||||
[external_log_format](src/log_format_ext.hh) objects that are create from
|
||||
[JSON format definitions](https://lnav.readthedocs.io/en/latest/formats.html).
|
||||
The built-in definitions are located in the [formats](src/formats) directory.
|
||||
Log formats that cannot be handled through a simple regular expression are
|
||||
implemented in the [log_format_impls.cc](src/log_format_impls.cc) file.
|
||||
|
||||
## User Interface
|
||||
|
||||
[![lnav TUI](docs/lnav-tui.png)](https://whimsical.com/lnav-tui-MQjXc7Vx23BxQTHrnuNp5F)
|
||||
|
||||
The lnav text-user-interface is built on top of the basic drawing functionality
|
||||
of [ncurses](https://invisible-island.net/ncurses/announce.html). However,
|
||||
|
||||
provided by [ncurses](https://invisible-island.net/ncurses/announce.html).
|
||||
However, the higher-level functionality of panels, widgets, and such is not
|
||||
used.
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 360 KiB |
@ -208,3 +208,33 @@ const char *date_time_scanner::scan(const char *time_dest,
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void date_time_scanner::to_localtime(time_t t, exttm &tm_out)
|
||||
{
|
||||
if (t < (24 * 60 * 60)) {
|
||||
// Don't convert and risk going past the epoch.
|
||||
return;
|
||||
}
|
||||
|
||||
if (t < this->dts_local_offset_valid ||
|
||||
t >= this->dts_local_offset_expiry) {
|
||||
time_t new_gmt;
|
||||
|
||||
localtime_r(&t, &tm_out.et_tm);
|
||||
#ifdef HAVE_STRUCT_TM_TM_ZONE
|
||||
tm_out.et_tm.tm_zone = nullptr;
|
||||
#endif
|
||||
tm_out.et_tm.tm_isdst = 0;
|
||||
|
||||
new_gmt = tm2sec(&tm_out.et_tm);
|
||||
this->dts_local_offset_cache = t - new_gmt;
|
||||
this->dts_local_offset_valid = t;
|
||||
this->dts_local_offset_expiry = t + (EXPIRE_TIME - 1);
|
||||
this->dts_local_offset_expiry -=
|
||||
this->dts_local_offset_expiry % EXPIRE_TIME;
|
||||
}
|
||||
else {
|
||||
time_t adjust_gmt = t - this->dts_local_offset_cache;
|
||||
gmtime_r(&adjust_gmt, &tm_out.et_tm);
|
||||
}
|
||||
}
|
||||
|
@ -39,12 +39,15 @@
|
||||
|
||||
#include "time_util.hh"
|
||||
|
||||
/**
|
||||
* Scans a timestamp string to discover the date-time format using the custom
|
||||
* ptimec parser. Once a format is found, it is locked in so that the next
|
||||
* time a timestamp needs to be scanned, the format does not have to be
|
||||
* rediscovered. The discovered date-time format can also be used to convert
|
||||
* an exttm struct to a string using the ftime() method.
|
||||
*/
|
||||
struct date_time_scanner {
|
||||
date_time_scanner() : dts_keep_base_tz(false),
|
||||
dts_local_time(false),
|
||||
dts_local_offset_cache(0),
|
||||
dts_local_offset_valid(0),
|
||||
dts_local_offset_expiry(0) {
|
||||
date_time_scanner() {
|
||||
this->clear();
|
||||
};
|
||||
|
||||
@ -55,6 +58,9 @@ struct date_time_scanner {
|
||||
this->dts_fmt_len = -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unlock this scanner so that the format is rediscovered.
|
||||
*/
|
||||
void unlock() {
|
||||
this->dts_fmt_lock = -1;
|
||||
this->dts_fmt_len = -1;
|
||||
@ -72,44 +78,17 @@ struct date_time_scanner {
|
||||
* every call, so we cache the result and only call it again if the
|
||||
* requested time falls outside of a fifteen minute range.
|
||||
*/
|
||||
void to_localtime(time_t t, struct exttm &tm_out) {
|
||||
if (t < (24 * 60 * 60)) {
|
||||
// Don't convert and risk going past the epoch.
|
||||
return;
|
||||
}
|
||||
void to_localtime(time_t t, struct exttm &tm_out);
|
||||
|
||||
if (t < this->dts_local_offset_valid ||
|
||||
t >= this->dts_local_offset_expiry) {
|
||||
time_t new_gmt;
|
||||
|
||||
localtime_r(&t, &tm_out.et_tm);
|
||||
#ifdef HAVE_STRUCT_TM_TM_ZONE
|
||||
tm_out.et_tm.tm_zone = nullptr;
|
||||
#endif
|
||||
tm_out.et_tm.tm_isdst = 0;
|
||||
|
||||
new_gmt = tm2sec(&tm_out.et_tm);
|
||||
this->dts_local_offset_cache = t - new_gmt;
|
||||
this->dts_local_offset_valid = t;
|
||||
this->dts_local_offset_expiry = t + (EXPIRE_TIME - 1);
|
||||
this->dts_local_offset_expiry -=
|
||||
this->dts_local_offset_expiry % EXPIRE_TIME;
|
||||
}
|
||||
else {
|
||||
time_t adjust_gmt = t - this->dts_local_offset_cache;
|
||||
gmtime_r(&adjust_gmt, &tm_out.et_tm);
|
||||
}
|
||||
};
|
||||
|
||||
bool dts_keep_base_tz;
|
||||
bool dts_local_time;
|
||||
time_t dts_base_time;
|
||||
bool dts_keep_base_tz{false};
|
||||
bool dts_local_time{false};
|
||||
time_t dts_base_time{0};
|
||||
struct exttm dts_base_tm;
|
||||
int dts_fmt_lock;
|
||||
int dts_fmt_len;
|
||||
time_t dts_local_offset_cache;
|
||||
time_t dts_local_offset_valid;
|
||||
time_t dts_local_offset_expiry;
|
||||
int dts_fmt_lock{-1};
|
||||
int dts_fmt_len{-1};
|
||||
time_t dts_local_offset_cache{0};
|
||||
time_t dts_local_offset_valid{0};
|
||||
time_t dts_local_offset_expiry{0};
|
||||
|
||||
static const int EXPIRE_TIME = 15 * 60;
|
||||
|
||||
|
@ -36,6 +36,12 @@
|
||||
|
||||
namespace humanize {
|
||||
|
||||
/**
|
||||
* Format the given size as a human-friendly string.
|
||||
*
|
||||
* @param value The value to format.
|
||||
* @return The formatted string.
|
||||
*/
|
||||
std::string file_size(ssize_t value);
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Generated by re2c 2.0.3 on Wed Jan 27 16:33:33 2021 */
|
||||
/* Generated by re2c 2.0.3 on Sat Feb 13 21:35:28 2021 */
|
||||
#line 1 "../../lnav/src/data_scanner_re.re"
|
||||
/**
|
||||
* Copyright (c) 2015, Timothy Stack
|
||||
@ -53,7 +53,7 @@ bool data_scanner::tokenize2(pcre_context &pc, data_token_t &token_out)
|
||||
static const unsigned char *EMPTY = (const unsigned char *) "";
|
||||
pcre_input &pi = this->ds_pcre_input;
|
||||
struct _YYCURSOR {
|
||||
const YYCTYPE operator*() const {
|
||||
YYCTYPE operator*() const {
|
||||
if (this->val < this->lim) {
|
||||
return *val;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ bool data_scanner::tokenize2(pcre_context &pc, data_token_t &token_out)
|
||||
static const unsigned char *EMPTY = (const unsigned char *) "";
|
||||
pcre_input &pi = this->ds_pcre_input;
|
||||
struct _YYCURSOR {
|
||||
const YYCTYPE operator*() const {
|
||||
YYCTYPE operator*() const {
|
||||
if (this->val < this->lim) {
|
||||
return *val;
|
||||
}
|
||||
|
@ -62,9 +62,9 @@ bool files_sub_source::list_input_handle_key(listview_curses &lv, int ch)
|
||||
auto& lss = lnav_data.ld_log_source;
|
||||
auto &lf = fc.fc_files[sel];
|
||||
|
||||
lss.find_data(lf) | [&lss](auto ld) {
|
||||
lss.find_data(lf) | [](auto ld) {
|
||||
ld->set_visibility(true);
|
||||
lss.text_filters_changed();
|
||||
lnav_data.ld_log_source.text_filters_changed();
|
||||
};
|
||||
|
||||
if (lf->get_format() != nullptr) {
|
||||
|
@ -792,7 +792,7 @@ static void write_sample_file()
|
||||
extract_metadata(sf.data(), sf.length(), meta);
|
||||
snprintf(path, sizeof(path), "formats/default/%s.lnav", meta.sm_name.c_str());
|
||||
auto script_path = dotlnav_path() / path;
|
||||
if (statp(script_path, &st) == 0 && (size_t) st.st_size == sf.length()) {
|
||||
if (statp(script_path, &st) == 0 && st.st_size == sf.length()) {
|
||||
// Assume it's the right contents and move on...
|
||||
continue;
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ void pcrepp::find_captures(const char *pattern)
|
||||
}
|
||||
}
|
||||
|
||||
ensure(this->p_capture_count == this->p_captures.size());
|
||||
ensure((size_t) this->p_capture_count == this->p_captures.size());
|
||||
}
|
||||
|
||||
bool pcrepp::match(pcre_context &pc, pcre_input &pi, int options) const
|
||||
|
@ -129,7 +129,7 @@ int main(int argc, char *argv[])
|
||||
printf(" { \"%s\", ptime_f%d, ftime_f%d },\n", argv[lpc], lpc, lpc);
|
||||
}
|
||||
printf("\n");
|
||||
printf(" { NULL, NULL }\n");
|
||||
printf(" { nullptr, nullptr, nullptr }\n");
|
||||
printf("};\n");
|
||||
|
||||
printf("const char *PTIMEC_FORMAT_STR[] = {\n");
|
||||
@ -137,7 +137,7 @@ int main(int argc, char *argv[])
|
||||
printf(" \"%s\",\n", argv[lpc]);
|
||||
}
|
||||
printf("\n");
|
||||
printf(" NULL\n");
|
||||
printf(" nullptr\n");
|
||||
printf("};\n");
|
||||
|
||||
return retval;
|
||||
|
@ -47,13 +47,13 @@
|
||||
#include "base/time_util.hh"
|
||||
|
||||
#define PTIME_CONSUME(amount, block) \
|
||||
if ((off_inout + amount) > len) { \
|
||||
if ((off_inout + (amount)) > len) { \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
block \
|
||||
\
|
||||
off_inout += amount;
|
||||
off_inout += (amount);
|
||||
|
||||
#define PTIME_APPEND(ch) \
|
||||
if ((off_inout + 2) >= len) { \
|
||||
|
@ -514,13 +514,13 @@ CREATE TABLE lnav_view_filters (
|
||||
text_filter::type_t type,
|
||||
pair<string, auto_mem<pcre>> pattern) {
|
||||
auto view_index = lnav_view_t(rowid >> 32);
|
||||
int filter_index = rowid & 0xffffffffLL;
|
||||
auto filter_index = rowid & 0xffffffffLL;
|
||||
textview_curses &tc = lnav_data.ld_views[view_index];
|
||||
text_sub_source *tss = tc.get_sub_source();
|
||||
filter_stack &fs = tss->get_filters();
|
||||
auto iter = fs.begin();
|
||||
for (; iter != fs.end(); ++iter) {
|
||||
if ((*iter)->get_index() == filter_index) {
|
||||
if ((*iter)->get_index() == (size_t) filter_index) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user