[docs] add some more text to arch docs and other tweaks

This commit is contained in:
Timothy Stack 2021-02-13 23:08:40 -08:00
parent 43bb384199
commit 0f238f7972
13 changed files with 83 additions and 57 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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) { \

View File

@ -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;
}
}