1 /**************************************************************************
2 ** (c) Copyright 2002, Andromeda Technology & Automation
3 ** This is free software; you can redistribute it and/or modify it under the
4 ** terms of the GNU General Public License, see the file COPYING.
5 ***************************************************************************
6 ** MODULE INFORMATION *
7 ***********************
8 ** FILE NAME : gcm_input.cpp
9 ** SYSTEM NAME : Gnucomo - Gnu Computer Monitoring
10 ** VERSION NUMBER : $Revision: 1.8 $
12 ** DESCRIPTION : Application to store client messages into the database
13 ** The client message contains a log file from one of the
14 ** system logs. Gcm_input parses the log file and enters
15 ** the raw data into the 'log' table of the gnucomo database.
17 ** The system log may arrive in one of several forms:
18 ** 1. Log file (archived or not) from a client machine.
19 ** 2. Log file from a client system, arriving in a clear Email.
20 ** 3. Log file from a client machine, arriving in an
23 ** additional information we need that may not be availble in
24 ** the content of the log is:
25 ** - FQDN of the client.
26 ** - Time of arrival of the log
27 ** - Service that created the log.
29 ** If the log arrives in an Email, these items probably are
30 ** available in the mail header. Otherwise, they have to be
31 ** provided as command line arguments.
33 ** Command line arguments:
34 ** -c <name> Configuration name (default = gnucomo).
35 ** -d <date> Date and time of log arrival.
36 ** -h <hostname> FQDN of the client.
37 ** -i Incremental - partial list of parameters.
38 ** -s <service> Service that created the log.
39 ** -T Test mode. Do not alter the database.
40 ** -v Verbose (debug) output.
41 ** -V Print version and exit.
46 ***************************************************************************
47 ** ADMINISTRATIVE INFORMATION *
48 ********************************
49 ** ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
50 ** CREATION DATE : Aug 29, 2002
51 ** LAST UPDATE : Aug 11, 2003
53 **************************************************************************/
55 /*****************************
56 $Log: gcm_input.cpp,v $
57 Revision 1.8 2003-08-16 15:30:19 arjen
58 Fixed a gcc 2 vs. gcc 3 problem
60 Revision 1.7 2003/08/14 10:28:37 arjen
61 Use parameters from a new section 'logging' with three configuration parameters:
62 method - Output method to use for logging.
63 destination - Name of the log output destination.
64 level - Log level: Verbose output if greater than 0.
66 Revision 1.6 2003/08/11 16:56:16 arjen
67 Different kinds of log files are parsed by a collection of objects
68 of different classes, derived from the base class line_cooker
69 Depending on the message content or the message_type element in
70 XML, one of these objects is selected.
72 Logrunner is integrated with gcm_input. Although its functionality
73 is still limited, a connection between logrunner and gcm_input
76 Revision 1.5 2003/08/05 08:11:06 arjen
77 Added two configuration parameters:
78 logfile - Log to this file instead of stderr.
79 verbosity - Verbose output if greater than 0.
80 Added '-i' option for incremental parameter updates
82 Revision 1.4 2003/03/29 08:42:00 arjen
83 Exit without reading any input if the database connection fails.
85 Revision 1.3 2002/11/09 08:04:27 arjen
86 Added a reference to the GPL
88 Revision 1.2 2002/11/04 10:13:36 arjen
89 Use proper namespace for iostream classes
91 Revision 1.1 2002/10/05 10:25:49 arjen
92 Creation of gcm_input and a first approach to a web interface
94 *****************************/
96 static const char *RCSID = "$Id: gcm_input.cpp,v 1.8 2003-08-16 15:30:19 arjen Exp $";
103 #include "syslog_cooker.h"
104 #include "irix_syslog_cooker.h"
105 #include "access_cooker.h"
106 #include "error_cooker.h"
108 bool verbose = false;
109 bool testmode = false;
110 bool incremental = false;
111 std::ostream *log = &std::cerr;
113 static char *Version = "gcm_input version 0.0.7 - Jul 24, 2003";
116 /*=========================================================================
118 ** SYNOPSIS : int main(int argc, char *argv[])
122 ** DESCRIPTION : Parse command line arguments and establish a connection
124 ** When we have a database connection, parse the log file
131 ** LAST MODIFIED : Aug 11, 2003
132 **=========================================================================
135 int main(int argc, char *argv[])
137 const char *usage = "Usage: gcm_input [-c configname] [-h hostname] [-i] [-d date]"
138 " [-s service] [-T] [-v] [-V]\n";
141 char *config_name = "gnucomo";
142 std::ofstream logfile;
145 /* Parse command line arguments */
148 String hostname(""), service("");
152 while ((option = getopt(argc, argv, "c:h:d:s:iTvV")) != -1)
157 config_name = optarg;
165 arrival = String(optarg);
166 if (!arrival.proper())
168 std::cerr << "gcm_input: Invalid date string: " << optarg << ".\n";
190 std::cout << Version << "\n";
199 /* Get the configuration file */
201 if (!cfg.read(config_name))
203 std::cerr << "Can not read Gnucomo configuration file for " << config_name << ".\n";
207 String log_method = cfg.find_parameter("logging", "method");
208 String log_destination = cfg.find_parameter("logging", "destination");
209 int level = cfg.find_parameter("gcm_input", "level");
211 if (log_method == "file" && log_destination != "")
213 std::cerr << "Logging to " << log_destination << ".\n";
215 logfile.open(log_destination, _IO_APPEND); // for gcc 2
217 logfile.open(log_destination, std::ios_base::app); // for gcc 3
221 std::cerr << "Can't open logfile " << log_destination << " for writing.\n";
226 verbose = verbose || level > 0;
230 *log << "Gcm_input starting at " << Now() << ".\n";
234 *log << "Hostname = " << hostname;
235 *log << " Arrival = " << arrival;
236 *log << " Service = " << service << "\n";
237 *log << "Config OK.\n";
240 /* Try to connect to the database */
242 gnucomo_database db(&cfg);
244 if (db.is_connected())
247 client_message msg(&std::cin, db);
249 irix_syslog_cooker islc;
253 msg.add_cooker(&slc);
254 msg.add_cooker(&islc);
255 msg.add_cooker(&alc);
256 msg.add_cooker(&elc);
258 if (msg.classify(hostname, arrival, service) > 0.9)
262 *log << "Gcm_input finished at " << Now() << ".\n";
267 *log << "gcm_input: Can not connect to database.\n";
268 *log << "Gcm_input finished at " << Now() << ".\n";