New options added:
authorarjen <arjen>
Mon, 10 Dec 2007 16:12:37 +0000 (16:12 +0000)
committerarjen <arjen>
Mon, 10 Dec 2007 16:12:37 +0000 (16:12 +0000)
 -l <file>: Read input from logfile <file>.
 -s <file>: Use <file> 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

index 1e92471..66381d5 100644 (file)
@@ -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 =
    "<hostname> 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 <name>: specify alternative configuration name, default is \'gnucomo\'\n"
+   " -l <file>: Read input from logfile <file>.\n"
    " -p <number>: set IP port number to connect to\n"
-   " -c <file>: specify alternative configuration file, default is \'logrunner.conf\'\n"
+   " -s <file>: Use <file> 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<LogFile>     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, "</gcmt:raw>\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<LogFile>::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<LogFile>::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++;
       }