mirror of
https://github.com/tstack/lnav.git
synced 2024-10-26 13:16:11 +03:00
commit
f3a85327ab
15
.gitignore
vendored
15
.gitignore
vendored
@ -1,2 +1,15 @@
|
||||
autom4te.cache
|
||||
|
||||
Makefile
|
||||
TESTS_ENVIRONMENT
|
||||
config.status
|
||||
src/.deps/
|
||||
src/Makefile
|
||||
src/bin2c
|
||||
src/config.h
|
||||
src/help.c
|
||||
src/libdiag.a
|
||||
src/lnav
|
||||
src/stamp-h1
|
||||
src/static-libs/
|
||||
test/.deps/
|
||||
test/Makefile
|
||||
|
94
src/lnav.cc
94
src/lnav.cc
@ -41,10 +41,10 @@
|
||||
#include <time.h>
|
||||
#include <glob.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
@ -1966,6 +1966,7 @@ static void looper(void)
|
||||
"access_log",
|
||||
"syslog_log",
|
||||
"generic_log",
|
||||
"glog_log",
|
||||
"strace_log",
|
||||
|
||||
"line_number",
|
||||
@ -2361,6 +2362,96 @@ private:
|
||||
pcrecpp::RE alt_regex;
|
||||
};
|
||||
|
||||
class glog_log_table : public log_vtab_impl {
|
||||
public:
|
||||
|
||||
glog_log_table()
|
||||
: log_vtab_impl("glog_log"),
|
||||
slt_regex(
|
||||
"\\s*([IWECF])([0-9]*) ([0-9:.]*)" // level, date
|
||||
"\\s*([0-9]*)" // thread
|
||||
"\\s*(.*:[0-9]*)\\]" // filename:number
|
||||
"\\s*(.*)"
|
||||
) {
|
||||
};
|
||||
|
||||
void get_columns(vector<vtab_column> &cols) {
|
||||
cols.push_back(vtab_column("glog_level", "text"));
|
||||
cols.push_back(vtab_column("timestamp", "text"));
|
||||
cols.push_back(vtab_column("thread", "text"));
|
||||
cols.push_back(vtab_column("file", "text"));
|
||||
cols.push_back(vtab_column("message", "text"));
|
||||
};
|
||||
|
||||
void extract(const std::string &line,
|
||||
int column,
|
||||
sqlite3_context *ctx) {
|
||||
string level, date, time, thread, file, message = "0";
|
||||
|
||||
if (!this->slt_regex.FullMatch(line,
|
||||
&level,
|
||||
&date,
|
||||
&time,
|
||||
&thread,
|
||||
&file,
|
||||
&message
|
||||
)) {
|
||||
fprintf(stderr, "bad match! %s\n", line.c_str());
|
||||
}
|
||||
struct tm log_time;
|
||||
time_t now = ::time(NULL);
|
||||
stringstream timestamp;
|
||||
char buf[128];
|
||||
switch (column) {
|
||||
case 0:
|
||||
sqlite3_result_text(ctx,
|
||||
level.c_str(),
|
||||
level.length(),
|
||||
SQLITE_TRANSIENT);
|
||||
break;
|
||||
case 1:
|
||||
localtime_r(&now, &log_time); // need year data
|
||||
strptime(date.data(), "%m%d", &log_time);
|
||||
strftime(buf, sizeof(buf), "%Y-%m-%d", &log_time);
|
||||
// C++11 can do this much more nicely:
|
||||
//timestamp << std::put_time(&log_time, "%Y-%m-%d ");
|
||||
timestamp
|
||||
<< buf
|
||||
<< " "
|
||||
<< time;
|
||||
sqlite3_result_text(ctx,
|
||||
timestamp.str().c_str(),
|
||||
timestamp.str().length(),
|
||||
SQLITE_TRANSIENT);
|
||||
break;
|
||||
case 2:
|
||||
sqlite3_result_text(ctx,
|
||||
thread.c_str(),
|
||||
thread.length(),
|
||||
SQLITE_TRANSIENT);
|
||||
break;
|
||||
case 3:
|
||||
sqlite3_result_text(ctx,
|
||||
file.c_str(),
|
||||
file.length(),
|
||||
SQLITE_TRANSIENT);
|
||||
break;
|
||||
case 4:
|
||||
sqlite3_result_text(ctx,
|
||||
message.c_str(),
|
||||
message.length(),
|
||||
SQLITE_TRANSIENT);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "bad match! %s\n", line.c_str());
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
pcrecpp::RE slt_regex;
|
||||
};
|
||||
|
||||
class strace_log_table : public log_vtab_impl {
|
||||
public:
|
||||
|
||||
@ -2684,6 +2775,7 @@ int main(int argc, char *argv[])
|
||||
lnav_data.ld_vtab_manager->register_vtab(new log_vtab_impl("syslog_log"));
|
||||
lnav_data.ld_vtab_manager->register_vtab(new log_vtab_impl("generic_log"));
|
||||
lnav_data.ld_vtab_manager->register_vtab(new access_log_table());
|
||||
lnav_data.ld_vtab_manager->register_vtab(new glog_log_table());
|
||||
lnav_data.ld_vtab_manager->register_vtab(new strace_log_table());
|
||||
lnav_data.ld_vtab_manager->register_vtab(new log_data_table());
|
||||
|
||||
|
@ -362,6 +362,67 @@ class generic_log_format : public log_format {
|
||||
|
||||
log_format::register_root_format<generic_log_format> generic_log_instance;
|
||||
|
||||
class glog_log_format : public log_format {
|
||||
string get_name() { return "glog_log"; };
|
||||
|
||||
bool scan(vector < logline > &dst,
|
||||
off_t offset,
|
||||
char *prefix,
|
||||
int len) {
|
||||
bool retval = false;
|
||||
struct tm log_time;
|
||||
short millis = 0;
|
||||
time_t now;
|
||||
char *rest;
|
||||
|
||||
now = time(NULL);
|
||||
localtime_r(&now, &log_time);
|
||||
|
||||
log_time.tm_isdst = 0;
|
||||
|
||||
if ((rest = strptime(prefix + 1,
|
||||
"%m%d %H:%M:%S.",
|
||||
&log_time)) != NULL) {
|
||||
logline::level_t ll = logline::LEVEL_UNKNOWN;
|
||||
time_t log_gmt;
|
||||
|
||||
millis = atoi(rest) / 1000;
|
||||
|
||||
switch (*prefix) {
|
||||
case 'I': // info
|
||||
ll = logline::LEVEL_INFO;
|
||||
break;
|
||||
case 'W': // warning
|
||||
ll = logline::LEVEL_WARNING;
|
||||
break;
|
||||
case 'E': // error
|
||||
ll = logline::LEVEL_ERROR;
|
||||
break;
|
||||
case 'C': // critical
|
||||
ll = logline::LEVEL_CRITICAL;
|
||||
break;
|
||||
case 'F': // fatal
|
||||
ll = logline::LEVEL_CRITICAL;
|
||||
break;
|
||||
}
|
||||
log_gmt = tm2sec(&log_time);
|
||||
dst.push_back(logline(offset, log_gmt, millis, ll));
|
||||
|
||||
retval = true;
|
||||
}
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
auto_ptr<log_format> specialized() {
|
||||
auto_ptr<log_format> retval((log_format *)new glog_log_format(*this));
|
||||
|
||||
return retval;
|
||||
};
|
||||
};
|
||||
|
||||
log_format::register_root_format<glog_log_format> glog_instance;
|
||||
|
||||
class strace_log_format : public log_format {
|
||||
string get_name() { return "strace_log"; };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user