3 /**********************************************************************************
4 ** (c) Copyright 2002, Brenno J.S.A.A.F. de Winter, De Winter Information Solutions
5 ** This is free software; you can redistribute it and/or modify it under the
6 ** terms of the GNU General Public License, see the file COPYING.
7 ***********************************************************************************/
12 AUTHOR : Brenno J.S.A.A.F. de Winter
13 De Winter Information Solutions
14 COPYRIGHT : 2002 - De Winter Information Solutions,
15 Brenno J.S.A.A.F. de Winter
18 First : November 8th 2002
19 Gnucomo-0.0.3: December 6th 2002
21 $Log: gcm_daemon.php,v $
22 Revision 1.14 2003-09-01 06:51:07 arjen
23 Accept command argument '-c config' to use an alternate
24 gnucomo configuration.
26 Revision 1.13 2003/08/14 10:22:42 arjen
29 Revision 1.12 2003/08/05 07:46:37 arjen
30 BUGFIX: Print an error message if a parameter does not have
33 Revision 1.11 2003/07/09 07:25:02 arjen
34 Gcm_daemon gathers statistics on parameters, notifications, etc. for all objects.
36 Revision 1.10 2003/03/29 08:33:58 arjen
37 In phpclasses/db.class.php: Added the database connection string as
38 an argument to the function copy_db_class.
39 Fixed the PHP member function db::db_connect(). The Postgres connection
40 string is now passed as an argument to that function.
42 Revision 1.9 2003/02/21 08:37:59 arjen
43 Added new table to the database: log_adv_daemon_email.
48 // $Id: gcm_daemon.php,v 1.14 2003-09-01 06:51:07 arjen Exp $
50 ini_set('include_path', '.:./classes:../phpclasses');
51 ini_set('html_errors', 'false');
53 //Tell the log that we're up.
54 define_syslog_variables();
56 require_once "gnucomo_config.php";
57 require_once "db.class.php";
58 require_once "gnucomo.process_log.php";
60 // Set the standard variables //
62 $project_name = "gnucomo"; // name of the entire project
63 $app_name = "gcm_daemon"; // name of the application running
64 $developrelease = "FALSE"; // Indicates if special debug settings are needed
65 $db_version = 42; // The db_version indicates what the level of
66 // the database should be. If the database is
67 // old an update will be generated.
68 $gcmd_version = 5; // This value indicates the active version of
69 // the gcm_daemon, which is saved in the database.
70 // Log records that were not recognized before
71 // will now be recognized. The version doesn't
72 // mean anything in the overall gnucomo project.
74 //Avoid time-limit issues
77 // Scan the command arguments
79 for ($argi = 1; $argi < $argc; $argi++)
85 $project_name = $argv[$argi];
89 echo "Usage: gcm_daemon [-c configname]\n";
95 // Read the database settings //
96 $class_settings = new gnucomo_config();
97 if (!$class_settings->read($project_name))
99 echo "Can not read Gnucomo configuration file for $project_name.\n";
103 openlog("gnucomo", LOG_PID, LOG_DAEMON);
104 syslog(LOG_INFO, "gcm_daemon started");
106 //Open an connection to the database
107 $dbms_type = $class_settings->find_parameter("database", "type");
108 $dbms_host = $class_settings->find_parameter("database", "host");
109 $dbms_name = $class_settings->find_parameter("database", "name");
110 $dbms_user = $class_settings->find_parameter("gcm_daemon", "user");
111 $dbms_password = $class_settings->find_parameter("gcm_daemon", "password");
113 db_select($dbms_type);
115 $dbms->db_host = $dbms_host;
116 $dbms->db_name = $dbms_name;
117 $dbms->db_user = $dbms_user;
118 $dbms->db_password = $dbms_password;
119 $dbms->db_connect($class_settings->database());
121 if ($dbms->have_db_connection() == "FALSE")
123 exit ("Database connection failed.");
127 // The database connection has been made.
128 $dbms_working = copy_db_class($dbms, $class_settings->database());
131 // Verify if the database is up-to-date by checking the versionnumber
133 $local_sql = "SELECT setting_value FROM db_value WHERE setting = 'db_version' ";
134 $dbms->query($local_sql);
136 if ($dbms->fetch_row() == "TRUE")
138 $active_version = $dbms->db_result_row[0];
140 // Update the database to the most recent version.
142 if ($active_version < $db_version)
144 include ("gnucomo_db_version.php");
149 syslog (LOG_INFO, "Couldn't initialize database version. Is this a gnucomo database?");
150 die ("Couldn't initialize database version.\n");
153 // If there is a new gcm_daemon_version the logrecords that couldn't be
154 // understood can be reprocessed. For this reason processed is now changed
155 // to false again for not recognized records.
157 $local_sql = "SELECT setting_value FROM db_value
158 WHERE setting = 'gcm_daemon_version'";
159 $dbms->query($local_sql);
161 if ($dbms->fetch_row() == "TRUE")
163 if ($dbms->db_result_row[0] < $gcmd_version)
165 //Reactive log-records that weren't understood earlier.
167 $local_sql = "UPDATE log SET processed = false
168 WHERE logid NOT IN (SELECT DISTINCT logid FROM log_adv)";
169 $dbms->query($local_sql);
171 //Update de gcm_daemon version in the database
172 $local_sql = "UPDATE db_value SET setting_value = '".$gcmd_version;
173 $local_sql .= "' WHERE setting = 'gcm_daemon_version'";
174 $dbms->query($local_sql);
180 // Now we loop the tasks that we have to do.
186 // Gather the statistics for each object
188 $obj_result = $dbms->query("SELECT objectid FROM object");
189 for ($obj = 0; $obj < $dbms->num_rows($obj_result); $obj++)
191 $object = $dbms->fetch_object($obj_result, $obj);
192 echo "Gathering statistics for object " . $object->objectid . "\n";
193 GatherStatistics($object->objectid);
196 //At this place we start processing new log-lines
199 find_notifications();
201 $keep_running = false;
203 } while ($keep_running == true);
205 //Tell the log that we're ending our efforts in a nice way
207 syslog (LOG_INFO, "gcm_daemon ended nicely");
209 function process_log ()
212 /* This function will walk through the log-records that haven't been processed
213 * first a snapshot will be created of a the non-processed records.
214 * sequentially each record will dealt with. By doing that changes will be made
215 * in several log_adv_xxx tables
221 global $dbms_working;
222 global $class_settings;
224 // Find records in log that still have to be processed.
226 $local_sql = "SELECT setting_value FROM db_value WHERE setting = 'log_processing'";
227 $dbms->query($local_sql);
229 if ($dbms->fetch_row() == "TRUE")
231 $last_log = $dbms->db_result_row[0];
234 //Query the log-table
235 $local_sql = "SELECT * FROM log WHERE logid > CAST(".$last_log." AS BIGINT)
237 $dbms->query($local_sql);
239 //Update the log-statistics in the object-table
240 $local_statistics_db = copy_db_class($dbms, $class_settings->database());
241 $local_findobject_db = copy_db_class($dbms, $class_settings->database());
244 $local_upper_row = $dbms->num_rows() + $last_log + 1;
245 $local_sql = "SELECT COUNT(logid), objectid from log WHERE logid > CAST(". $last_log .
246 " AS BIGINT) AND logid < CAST (" . $local_upper_row . " AS BIGINT) GROUP BY objectid";
247 $local_statistics_db->query ($local_sql);
250 for ($i = 1; $i <= $local_statistics_db->num_rows(); $i++)
252 $local_object_row = $local_statistics_db->fetch_row();
254 $local_sql = "UPDATE object SET log_count = log_count + " .
255 $local_statistics_db->db_result_row[0] . " WHERE objectid = '" .
256 $local_statistics_db->db_result_row[1] . "'";
258 $local_findobject_db->query($local_sql);
263 if ($dbms->num_rows() > 0)
266 //Create a database connection for changes in the database.
267 $dbms_changes = copy_db_class($dbms, $class_settings->database());
268 if ($dbms_changes->have_db_connection() == 'TRUE')
272 $local_sql_statistics = "";
273 $local_object_os = "";
274 $local_object_os_version = "";
276 while ($local_counter < $dbms->num_rows())
279 $local_return_row = $dbms->fetch_row();
280 if ($local_return_row == 'TRUE')
282 // Work on active rows
283 $local_log_id = $dbms->db_result_row[0];
285 $local_sql_findobject = "SELECT os, os_version FROM object
286 WHERE objectid = '".$dbms->db_result_row[1]."'";
287 $local_findobject_db->query($local_sql_findobject);
288 $local_findobject_result = $local_findobject_db->fetch_row();
289 if ($local_findobject_result == 'TRUE')
292 // Now work on the OS again
293 $local_object_os = $local_findobject_db->db_result_row[0];
294 if ($local_object_os == "")
296 $local_object_os = "Linux";
297 $local_object_os_version = "Unknown assuming Linux";
301 $local_object_os_version = $local_findobject_db->db_result_row[1];
305 switch (strtolower($local_object_os))
308 $local_process_return = linux_log ();
311 syslog (LOG_INFO, "Couldn't find suitable OS for processing the logline");
315 if ($local_process_return != 'TRUE')
317 $local_process_return = 'FALSE';
330 // Register that the logrecords have been processed.
331 $local_sql = "UPDATE db_value SET setting_value = '"
332 .$local_log_id."' where setting = 'log_processing'";
333 $dbms->query($local_sql);
336 // Update the statistics for the object-table
342 syslog (LOG_INFO, "Couldn't clone database connection.");
343 die ("Couldn't reconnect to the database.\n");
350 * Update a single statistic for some object.
351 * If it does not yet exist, it will be created.
354 function UpdateStatistic($objectid, $name, $value)
358 $result = $dbms->query("SELECT objectid FROM object_statistics WHERE
359 objectid='$objectid' AND statname='$name'");
360 if ($dbms->num_rows() == 0)
362 $dbms->query("INSERT INTO object_statistics VALUES
363 ('$objectid', '$name', '$value')");
367 $dbms->query("UPDATE object_statistics SET statvalue='$value' WHERE
368 statname='$name' AND objectid='$objectid'");
373 * Gather the statistics for a single object ($objectid).
374 * We count the number of parameters, removed parameters, notifications
375 * closed notifications and log entries. The totals of these are
376 * maintained in a separate table: object_statistics.
379 function GatherStatistics($objectid)
383 // Gather statistics on parameters
385 $r = $dbms->query("SELECT paramid FROM parameter WHERE objectid=CAST('"
386 . $objectid . "' AS BIGINT)");
387 $nr_parameters = $dbms->num_rows($r);
389 $removed_parameters = 0;
390 for ($p = 0; $p < $nr_parameters; $p++)
392 $param = pg_fetch_object($r, $p);
393 $qry ="select change_nature from history where paramid= CAST('";
394 $qry .= $param->paramid . "' AS BIGINT) order by modified desc";
395 $rhist = $dbms->query($qry);
396 if ($dbms->num_rows($rhist) == 0)
398 echo "ERROR: No history for parameter id " . $param->paramid . "\n";
402 $hist = $dbms->fetch_object($rhist, 0);
403 if ($hist->change_nature == "REMOVED")
405 $removed_parameters++;
410 UpdateStatistic($objectid, 'parameters', $nr_parameters);
411 UpdateStatistic($objectid, 'removed_parameters', $removed_parameters);
413 // Gather statistics on notifications
415 $r = $dbms->query("SELECT count(notificationid) FROM notification WHERE
416 objectid = CAST('" . $objectid . "' AS BIGINT)");
417 $cnt = $dbms->fetch_object($r, 0);
418 UpdateStatistic($objectid, 'notifications', $cnt->count);
420 $r = $dbms->query("SELECT count(notificationid) FROM notification WHERE
421 objectid = CAST('" . $objectid . "' AS BIGINT) AND statuscode ='cls'");
422 $cnt = $dbms->fetch_object($r, 0);
423 UpdateStatistic($objectid, 'closed_notifications', $cnt->count);
425 // Gather statistics on log entries
427 $r = $dbms->query("SELECT count(logid) FROM log WHERE
428 objectid = CAST('" . $objectid . "' AS BIGINT)");
429 $cnt = $dbms->fetch_object($r, 0);
430 UpdateStatistic($objectid, 'logs', $cnt->count);
434 function find_notifications () {
437 * Do something with notification checks.
445 // Find checks that have to be executed.
446 $local_sql = "select * from notification_check where
447 age(last_execution) > time_between_executions";
448 $dbms->query($local_sql);
450 for ($i=0; $i<$dbms->num_rows(); $i++)
452 // A check has been found that has to be executed