Fix: filesystem report
[gnucomo.git] / src / gcm_input / gcm_input.cpp
index 4215aa4..f9e30d9 100644 (file)
@@ -7,7 +7,7 @@
 ***********************
 **      FILE NAME      : gcm_input.cpp
 **      SYSTEM NAME    : Gnucomo - Gnu Computer Monitoring
-**      VERSION NUMBER : $Revision: 1.11 $
+**      VERSION NUMBER : $Revision: 1.16 $
 **
 **  DESCRIPTION      :  Application to store client messages into the database
 **                      The client message contains a log file from one of the
 ********************************
 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
 **      CREATION DATE   : Aug 29, 2002
-**      LAST UPDATE     : Aug 11, 2003
+**      LAST UPDATE     : Nov 26, 2003
 **      MODIFICATIONS   : 
 **************************************************************************/
 
 /*****************************
    $Log: gcm_input.cpp,v $
-   Revision 1.11  2003-10-27 13:00:15  arjen
+   Revision 1.16  2011-03-24 10:20:37  arjen
+   Added some debug info
+
+   Revision 1.15  2007/11/14 16:19:25  arjen
+   Bugfix: Segmentation fault when reading an rpm package list
+   with empty lines.
+
+   Revision 1.14  2007/11/03 10:26:13  arjen
+   Added a new filter which can directly read the output
+   of the UNIX df command. A brief description is added in
+   the user manual.
+
+   Revision 1.13  2003/12/22 10:20:21  arjen
+   Report if the message type can not be detected.
+
+   Revision 1.12  2003/12/04 10:38:09  arjen
+   Major redesign. All input is handled through XML. Raw input data is first
+   transformed into an XML document for further processing.
+   A collection of polymorphic classes handle the transformation of various
+   input formats into XML.
+   Classifying input data is done with a finite improbability calculation.
+
+   Revision 1.11  2003/10/27 13:00:15  arjen
    Catch exceptions from the database library
 
    Revision 1.10  2003/09/03 06:58:31  arjen
 
 *****************************/
 
-static const char *RCSID = "$Id: gcm_input.cpp,v 1.11 2003-10-27 13:00:15 arjen Exp $";
-
 #include <fstream>
 
 #include <getopt.h>
+#include <unistd.h>
 
 #include "message.h"
+#include "log_filter.h"
+#include "rpm_filter.h"
+#include "df_filter.h"
+
+#include "xml_cooker.h"
 #include "syslog_cooker.h"
 #include "irix_syslog_cooker.h"
 #include "access_cooker.h"
@@ -118,9 +144,9 @@ static const char *RCSID = "$Id: gcm_input.cpp,v 1.11 2003-10-27 13:00:15 arjen
 bool verbose = false;
 bool testmode = false;
 bool incremental = false;
-std::ostream *log = &std::cerr;
+std::ostream *Log = &std::cerr;
 
-static char *Version = "gcm_input version 0.0.8 - Sep 04, 2003";
+static char Version[] = "gcm_input version 0.0.13 - Sep 22, 2020";
 
 
 /*=========================================================================
@@ -148,7 +174,7 @@ int main(int argc, char *argv[])
                        " [-s service] [-T] [-v] [-V]\n";
 
    gnucomo_config    cfg;
-   char             *config_name = "gnucomo";
+   String           config_name("gnucomo");
    std::ofstream    logfile;
 
 
@@ -225,66 +251,96 @@ int main(int argc, char *argv[])
 
    if (log_method == "file" && log_destination != "")
    {
-#if __GNUC__ == 2
-      logfile.open(log_destination, _IO_APPEND); // for gcc 2
-#else
-      logfile.open(log_destination, std::ios_base::app); // for gcc 3
-#endif
+      logfile.open(log_destination, std::ios_base::app);
       if (!logfile)
       {
          std::cerr << "Can't open logfile " << log_destination << " for writing.\n";
       }
       else
       {
-         log = &logfile;
+         Log = &logfile;
       }
    }
    verbose = verbose || level > 0;
 
    if (verbose)
    {
-      *log << "Hostname = " << hostname;
-      *log << " Arrival = " << arrival;
-      *log << " Service = " << service << "\n";
-      *log << "Config OK.\n";
+      *Log << "Hostname = " << hostname;
+      *Log << " Arrival = " << arrival;
+      *Log << " Service = " << service << "\n";
+      *Log << "Config OK.\n";
    }
 
    /*  Try to connect to the database */
 
    gnucomo_database db(&cfg);
 
-   if (db.is_connected())
-   {
+   int gcm_input_result = 0;
+
+
+   client_message      msg(&std::cin, db);
+
+   double              message_probability;
+
+   message_filter      shortcircuit(hostname, arrival, service);
+   log_filter          lf(hostname, arrival, service);
+   rpm_filter          rf(hostname, arrival, service);
+   df_filter           df(hostname, arrival, service);
 
-      client_message      msg(&std::cin, db);
-      syslog_cooker       slc;
-      irix_syslog_cooker  islc;
-      access_cooker       alc;
-      error_cooker        elc;
+   syslog_cooker       slc;
+   irix_syslog_cooker  islc;
+   access_cooker       alc;
+   error_cooker        elc;
+   xml_cooker          xlc;
+   rpm_cooker          rlc;
+   df_cooker           dlc;
 
-      msg.add_cooker(&slc);
-      msg.add_cooker(&islc);
-      msg.add_cooker(&alc);
-      msg.add_cooker(&elc);
+   msg.add_cooker(&xlc,  &shortcircuit);
+   msg.add_cooker(&slc,  &lf);
+   msg.add_cooker(&islc, &lf);
+   msg.add_cooker(&alc,  &lf);
+   msg.add_cooker(&elc,  &lf);
+   msg.add_cooker(&rlc,  &rf);
+   msg.add_cooker(&dlc,  &df);
 
-      if (msg.classify(hostname, arrival, service) > 0.9)
+   message_probability = msg.classify(hostname, arrival, service);
+   if (message_probability > 0.75)
+   {
+      try
       {
-         try
-         {
-            msg.enter();
-         }
-         catch (exception &e)
+         if (msg.enter() < 0)
          {
-            *log << "Caught an exception: " << e.what() << "\n";
+            // Can not store the input in the database. Dump the message in a file.
+
+            String spool_dir      = cfg.find_parameter("spool", "directory");
+            String pid(getpid());
+            String xmlfilename;
+
+            if (spool_dir)
+            {
+               xmlfilename = spool_dir + "/";
+            }
+            xmlfilename += "gnucomo" + pid + ".xml";
+
+            msg.saveXML(xmlfilename);
+
+            // Report the error to the log and stderr.
+            *Log << "Entering the content into the database failed. XML content stored in " + xmlfilename + "\n";
+            std::cerr << "Entering the content into the database failed. XML content stored in " + xmlfilename + "\n";
+
+            gcm_input_result = 1;
          }
       }
-      return 0;
+      catch (std::exception &e)
+      {
+         *Log << "Caught an exception: " << e.what() << "\n";
+      }
    }
    else
    {
-      *log << "gcm_input: Can not connect to database.\n";
-      *log << "Gcm_input finished at " << Now() << ".\n";
-      return 1;
+      *Log << "Cannot determine message type with sufficient certainty.\n";
    }
+
+   return gcm_input_result;
 }