Some more miscellaneous fixes:

* lnav.cc: Move the view when J/K are pressed.
   Handle 'too many files' situations better.
 * line_buffer.cc: Increase some of the file
   size constants.
pull/48/merge
Timothy Stack 12 years ago
parent c26e58c9ee
commit a476e27701

@ -150,7 +150,8 @@ through the file.
K Like 'J' except it toggles the mark on the
previous line.
c Copy the marked text to the X selection buffer.
c Copy the marked text to the X11 selection buffer or OS X
clipboard.
C Clear all marked lines.

@ -21,7 +21,7 @@
using namespace std;
static const size_t DEFAULT_LINE_BUFFER_SIZE = 256 * 1024;
static const size_t MAX_LINE_BUFFER_SIZE = 2 * DEFAULT_LINE_BUFFER_SIZE;
static const size_t MAX_LINE_BUFFER_SIZE = 16 * DEFAULT_LINE_BUFFER_SIZE;
static const size_t DEFAULT_INCREMENT = 1024;
static const size_t MAX_COMPRESSED_BUFFER_SIZE = 32 * 1024 * 1024;

@ -129,6 +129,10 @@ public:
return retval;
};
bool is_visible(vis_line_t line) {
return (this->get_top() <= line && line <= this->get_bottom());
};
/**
* Shift the value of top by the given value.
*

@ -110,6 +110,12 @@ bool check_experimental(const char *feature_name)
return false;
}
/**
* Compute the path to a file in the user's '.lnav' directory.
*
* @param sub The path to the file in the '.lnav' directory.
* @return The full path
*/
string dotlnav_path(const char *sub)
{
string retval;
@ -122,6 +128,9 @@ string dotlnav_path(const char *sub)
snprintf(hpath, sizeof(hpath), "%s/.lnav/%s", home, sub);
retval = hpath;
}
else {
retval = sub;
}
return retval;
}
@ -132,6 +141,9 @@ void sqlite_close_wrapper(void *mem)
sqlite3_close((sqlite3*)mem);
}
/**
* Observer for loading progress that updates the bottom status bar.
*/
class loading_observer
: public logfile_sub_source::observer {
public:
@ -251,9 +263,13 @@ void rebuild_indexes(bool force)
if ((*iter)->get_format() != NULL) {
logfile *lf = *iter;
iter = tss->tss_files.erase(iter);
lnav_data.ld_log_source.insert_file(lf);
force = true;
if (lnav_data.ld_log_source.insert_file(lf)) {
iter = tss->tss_files.erase(iter);
force = true;
}
else {
++iter;
}
}
else {
++iter;
@ -827,20 +843,24 @@ static void handle_paging_key(int ch)
}
break;
case 'J':
// TODO: if they scroll up, we should start marking again from the top.
// We should also scroll down as the continue to mark stuff. If they
// move somewhere else in the file, we should also start marking from
// the top again.
if (lss) {
if (lnav_data.ld_last_user_mark.find(tc) == lnav_data.ld_last_user_mark.end()) {
if (lnav_data.ld_last_user_mark.find(tc) == lnav_data.ld_last_user_mark.end() ||
!tc->is_visible(vis_line_t(lnav_data.ld_last_user_mark[tc]))) {
lnav_data.ld_last_user_mark[tc] = tc->get_top();
}
else if (lnav_data.ld_last_user_mark[tc] + 1 > tc->get_bottom()) {
flash();
break; // XXX
}
else {
lnav_data.ld_last_user_mark[tc] += 1;
vis_line_t height;
unsigned long width;
tc->get_dimensions(height, width);
if (lnav_data.ld_last_user_mark[tc] > tc->get_bottom() - 2 &&
tc->get_top() + height < tc->get_inner_height()) {
tc->shift_top(vis_line_t(1));
}
if (lnav_data.ld_last_user_mark[tc] + 1 >= tc->get_inner_height()) {
break;
}
lnav_data.ld_last_user_mark[tc] += 1;
}
lss->toggle_user_mark(&textview_curses::BM_USER,
vis_line_t(lnav_data.ld_last_user_mark[tc]));
@ -848,20 +868,30 @@ static void handle_paging_key(int ch)
}
break;
case 'K':
// TODO: scroll up with the selection
if (lss) {
if (lnav_data.ld_last_user_mark.find(tc) == lnav_data.ld_last_user_mark.end()) {
lnav_data.ld_last_user_mark[tc] = tc->get_top();
int new_mark;
if (lnav_data.ld_last_user_mark.find(tc) == lnav_data.ld_last_user_mark.end() ||
!tc->is_visible(vis_line_t(lnav_data.ld_last_user_mark[tc]))) {
lnav_data.ld_last_user_mark[tc] = -1;
new_mark = tc->get_top();
}
else {
new_mark = lnav_data.ld_last_user_mark[tc];
}
lss->toggle_user_mark(&textview_curses::BM_USER,
vis_line_t(lnav_data.ld_last_user_mark[tc]));
if (lnav_data.ld_last_user_mark[tc] - 1 < 0) {
flash();
}
else {
lnav_data.ld_last_user_mark[tc] -= 1;
}
vis_line_t(new_mark));
if (new_mark == tc->get_top()) {
tc->shift_top(vis_line_t(-1));
}
if (new_mark > 0) {
lnav_data.ld_last_user_mark[tc] = new_mark - 1;
}
else {
lnav_data.ld_last_user_mark[tc] = new_mark;
flash();
}
tc->reload_data();
}
break;
@ -1453,6 +1483,13 @@ static pcre *xpcre_compile(const char *pattern, int options = 0)
return retval;
}
/**
* Callback used to keep track of the timestamps for the top and bottom lines
* in the log view. This function is intended to be used as the callback
* function in a view_action.
*
* @param lv The listview object that contains the log
*/
static void update_times(void *, listview_curses *lv)
{
if (lv == &lnav_data.ld_views[LNV_LOG] && lv->get_inner_height() > 0) {
@ -2569,6 +2606,7 @@ int main(int argc, char *argv[])
DEFAULT_FILES.insert(make_pair(LNF_SYSLOG, string("var/log/messages")));
DEFAULT_FILES.insert(make_pair(LNF_SYSLOG, string("var/log/system.log")));
DEFAULT_FILES.insert(make_pair(LNF_SYSLOG, string("var/log/syslog")));
DEFAULT_FILES.insert(make_pair(LNF_SYSLOG, string("var/log/syslog.log")));
init_lnav_commands(lnav_commands);
@ -2592,7 +2630,7 @@ int main(int argc, char *argv[])
lnav_data.ld_looping = true;
lnav_data.ld_mode = LNM_PAGING;
lnav_data.ld_debug_log_name = "/dev/null"; // XXX change to /dev/null
lnav_data.ld_debug_log_name = "/dev/null";
while ((c = getopt(argc, argv, "harsd:V")) != -1) {
switch (c) {
case 'h':

@ -1,3 +1,6 @@
/**
* @file log_format_impls.cc
*/
#include <stdio.h>
@ -108,6 +111,19 @@ class syslog_log_format : public log_format {
return SCRUB_PATTERN;
}
static pcrepp &error_pattern(void) {
static pcrepp ERROR_PATTERN("(?:failed|failure|error)", PCRE_CASELESS);
return ERROR_PATTERN;
}
static pcrepp &warning_pattern(void) {
static pcrepp WARNING_PATTERN(
"(?:warn|not responding|init: cannot execute)", PCRE_CASELESS);
return WARNING_PATTERN;
}
string get_name() { return "syslog_log"; };
void scrub(string &line) {
@ -144,17 +160,15 @@ class syslog_log_format : public log_format {
if ((rest = strptime(prefix,
"%b %d %H:%M:%S",
&log_time)) != NULL) {
pcre_context_static<20> context;
pcre_input pi(prefix, 0, len);
logline::level_t ll = logline::LEVEL_UNKNOWN;
time_t log_gmt;
if (strcasestr(prefix, "failed") != NULL ||
strcasestr(prefix, "failure") != NULL ||
strcasestr(prefix, "error") != NULL) {
if (error_pattern().match(context, pi)) {
ll = logline::LEVEL_ERROR;
}
else if (strcasestr(prefix, "warn") != NULL ||
strcasestr(prefix, "not responding") != NULL ||
strcasestr(prefix, "init: cannot execute") != NULL) {
else if (warning_pattern().match(context, pi)) {
ll = logline::LEVEL_WARNING;
}
log_gmt = tm2sec(&log_time);

@ -1,5 +1,11 @@
#ifndef __logfile_controller_hh
#define __logfile_controller_hh
/**
* @file logfile_sub_source.hh
*/
#ifndef __logfile_sub_source_hh
#define __logfile_sub_source_hh
#include <limits.h>
#include <map>
#include <list>
@ -43,6 +49,10 @@ protected:
std::string lf_id;
};
/**
* Delegate class that merges the contents of multiple log files into a single
* source of data for a text view.
*/
class logfile_sub_source
: public text_sub_source {
public:
@ -124,7 +134,7 @@ public:
this->lss_user_marks[bm].clear();
};
void insert_file(logfile *lf)
bool insert_file(logfile *lf)
{
std::vector<logfile_data>::iterator existing;
@ -134,12 +144,18 @@ public:
this->lss_files.end(),
logfile_data_eq(NULL));
if (existing == this->lss_files.end()) {
if (this->lss_files.size() >= MAX_FILES) {
return false;
}
this->lss_files.push_back(logfile_data(lf));
this->lss_index.clear();
}
else {
existing->ld_file = lf;
}
return true;
};
void remove_file(logfile *lf)
@ -232,9 +248,10 @@ public:
content_line_t at(vis_line_t vl) { return this->lss_index[vl]; };
private:
static const size_t MAX_LINES_PER_FILE = 4 * 1024 * 1024;
static const size_t MAX_FILES = INT_MAX / MAX_LINES_PER_FILE;
private:
enum {
B_SCRUB,
B_TIME_OFFSET,

Loading…
Cancel
Save