From 8102b9f38e5b1a998adac2641fa2bd2706563c02 Mon Sep 17 00:00:00 2001 From: arjen Date: Mon, 10 Dec 2007 16:12:37 +0000 Subject: [PATCH] New options added: -l : Read input from logfile . -s : Use as the status file instead of the default. -v Verbose output Output debug information only when the -v option is added on the command line. Buffer overflow problem with input lines of more than 4096 characters fixed. --- src/gcm_input/logrunner.cpp | 103 +++++++++++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 26 deletions(-) diff --git a/src/gcm_input/logrunner.cpp b/src/gcm_input/logrunner.cpp index 1e92471..66381d5 100644 --- a/src/gcm_input/logrunner.cpp +++ b/src/gcm_input/logrunner.cpp @@ -2,7 +2,7 @@ * logrunner.c * (c) Peter Roozemaal, feb 2003 * - * $Id: logrunner.cpp,v 1.5 2007-11-21 15:23:32 arjen Exp $ + * $Id: logrunner.cpp,v 1.6 2007-12-10 16:12:37 arjen Exp $ * * 1) compile, * 2) Add 'logfile' elements to the gnucomo configuration file @@ -51,8 +51,11 @@ static const char* const usage = " is the gnucomo data collection server\n" "Options are:\n" " -1: one-shot; stop after a single pass over one of the configured logfiles\n" + " -c : specify alternative configuration name, default is \'gnucomo\'\n" + " -l : Read input from logfile .\n" " -p : set IP port number to connect to\n" - " -c : specify alternative configuration file, default is \'logrunner.conf\'\n" + " -s : Use as the status file instead of the default.\n" + " -v Verbose output\n" "If no hostname is specified, logrunner sends output to stdout\n"; class LogFile { @@ -110,7 +113,6 @@ public: void add_filter(String filter_expression) { filter.push_back(filter_expression); - std::cerr << "add_filter, filter size is " << filter.size() << "\n"; } void do_file(); @@ -119,14 +121,15 @@ public: static std::list logs_to_run; String confname = "gnucomo"; -static const char* statusname = "/var/lib/logrunner.status"; -static const char* newstatusname = "/var/lib/logrunner.status.new"; +static char* statusname = "/var/lib/logrunner.status"; +static char* newstatusname = "/var/lib/logrunner.status.new"; static const char *hostname = NULL; static int port = 2996; /* random magic number */ static int out_stream = 1; static int oneshot = 0; +static int verbose = 0; static int something_has_changed = 0; @@ -191,6 +194,7 @@ void xsend(const char* str) void xml_header(String type) { + struct hostent *host; char buffer[256]; *buffer = 0; gethostname(buffer, sizeof(buffer)); @@ -248,7 +252,10 @@ void LogFile::do_file() close(fd); fd = -1; } - std::cerr << "@@@ logfile: logrotate detected: " << name << "\n"; + if (verbose) + { + std::cerr << "@@@ logfile: logrotate detected: " << name << "\n"; + } inode = statinfo.st_ino; position = 0; } @@ -262,10 +269,15 @@ void LogFile::do_file() std::cerr << "!!! logfile: open failed: " << name << ", " << strerror(errno) << "\n"; return; } - std::cerr << "*** logfile: opened: " << name; - std::cerr << "\n*** logfile: resumed read from position "; - std::cerr << (long) lseek(fd, position, SEEK_SET) << "\n"; - std::cerr << "This logfile has " << filter.size() << " filters.\n"; + lseek(fd, position, SEEK_SET); + + if (verbose) + { + std::cerr << "*** logfile: opened: " << name; + std::cerr << "\n*** logfile: resumed read from position "; + std::cerr << position << "\n"; + std::cerr << "This logfile has " << filter.size() << " filters.\n"; + } } copy_data(); @@ -275,9 +287,10 @@ void LogFile::copy_data() { char buffer[4096]; int ndata; + String logline(""); /* read data and dump to output */ - ndata = read(fd, buffer, sizeof(buffer)); + ndata = read(fd, buffer, sizeof(buffer)-1); if ( ndata > 0 ) { xml_header(type); @@ -301,9 +314,9 @@ void LogFile::copy_data() // Another line found - make the split. *nextline++ = '\0'; - String logline(line); + logline += line; - // See if have to select the host and apply filters to this log entry + // See if we have to select the host and apply filters to this log entry bool filtered_out = false; @@ -330,12 +343,22 @@ void LogFile::copy_data() write(out_stream, logline, ~logline); write(out_stream, "\n", 12); } - else + else if (verbose) { - std::cerr << logline << " is filtred out.\n"; + std::cerr << logline << " is filtered out.\n"; } line = nextline; + logline = ""; + } + else + { + // We have a buffer full of data but no newline. + // Flush the buffer into logline and continue reading. + + nextline[0] = '\0'; + logline += line; + line = nextline; } } if (line != nextline) @@ -345,7 +368,7 @@ void LogFile::copy_data() } position += ndata - (nextline - line); ndata -= line - buffer; - ndata += read(fd, buffer + (nextline - line), sizeof(buffer) - (nextline - line)); + ndata += read(fd, buffer + (nextline - line), sizeof(buffer) - 1 - (nextline - line)); } xml_footer(); something_has_changed = 1; @@ -366,7 +389,10 @@ void write_status_file() std::list::iterator lf = logs_to_run.begin(); while (lf != logs_to_run.end()) { - std::cerr << "Write status for " << lf->pathname() << "\n"; + if (verbose) + { + std::cerr << "Write status for " << lf->pathname() << "\n"; + } statusfile << lf->status() << "\n"; lf++; } @@ -413,7 +439,10 @@ void read_status() { if (lf->pathname() == String(buffer)) { - std::cerr << "Read status for " << lf->pathname() << "\n"; + if (verbose) + { + std::cerr << "Read status for " << lf->pathname() << "\n"; + } lf->update_status(ino, pos); } lf++; @@ -443,10 +472,13 @@ void read_config(gnucomo_config cfg) logfilename = cfg.find_parameter("logfile", "name", l); while (logfilename != String("")) { - std::cerr << "Configuration for logfile " << logfilename << "\n"; logfiletype = cfg.find_parameter("logfile", "type", l); fromhost = cfg.find_parameter("logfile", "fromhost", l); - std::cerr << "LogFile " << logfilename << " of type " << logfiletype << " from host " << fromhost << "\n"; + if (verbose) + { + std::cerr << "LogFile " << logfilename << " of type " + << logfiletype << " from host " << fromhost << "\n"; + } LogFile lf(logfilename, logfiletype, fromhost); @@ -454,7 +486,6 @@ void read_config(gnucomo_config cfg) String exp = cfg.find_parameter("logfile", "filter", l, f); while (exp != "") { - std::cerr << "Adding filter " << exp << "\n"; lf.add_filter(exp); f++; @@ -462,20 +493,20 @@ void read_config(gnucomo_config cfg) } logs_to_run.push_back(lf); - std::cerr << "Logfile added to list.\n"; l++; logfilename = cfg.find_parameter("logfile", "name", l); - std::cerr << "Next logfile = " << logfilename << "\n"; } } void process_options(int argc, char* argv[]) { - const char* const options = "1c:p:"; + const char* const options = "1c:l:p:s:v"; int opt; + String logfilename; + opt = getopt(argc, argv, options); while ( opt != -1 ) { @@ -487,9 +518,21 @@ void process_options(int argc, char* argv[]) case 'c': confname = strdup(optarg); break; + case 'l': + logfilename = optarg; + break; case 'p': port = atoi(optarg); break; + case 's': + statusname = strdup(optarg); + newstatusname = (char *)malloc(strlen(statusname) + 6); + strcpy(newstatusname, statusname); + strcat(newstatusname, ".new"); + break; + case 'v': + verbose = 1; + break; default: fputs(usage, stderr); exit(2); @@ -507,6 +550,12 @@ void process_options(int argc, char* argv[]) fputs(usage, stderr); exit(2); } + + if (logfilename) + { + LogFile lf(logfilename, String("system log"), String("")); + logs_to_run.push_back(lf); + } } int main(int argc, char* argv[]) @@ -523,7 +572,10 @@ int main(int argc, char* argv[]) exit(1); } - read_config(cfg); + if (logs_to_run.empty()) + { + read_config(cfg); + } read_status(); set_signal_handler(); @@ -533,7 +585,6 @@ int main(int argc, char* argv[]) std::list::iterator lf = logs_to_run.begin(); while (lf != logs_to_run.end() && !(something_has_changed && oneshot)) { - std::cerr << "Scanning logfile " << lf->pathname() << "\n"; lf->do_file(); lf++; } -- 2.11.0