3be6fe2921a01d6eebf81f7314296c43f5d65f1f
[gnucomo.git] / src / gcm_daemon / gcm_daemon.php
1 #!/usr/bin/php
2 <?PHP
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 ***********************************************************************************/
8
9
10 /* 
11    NAME         : gcm_daemon
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
16    
17    * DATES * 
18    First        : November 8th 2002
19    Gnucomo-0.0.3: December 6th 2002
20
21 */
22
23 // $Id: gcm_daemon.php,v 1.8 2003-02-16 08:24:06 arjen Exp $
24
25 ini_set('include_path', '.:./classes:../phpclasses');
26
27 //Tell the log that we're up.
28 define_syslog_variables();
29 openlog("gnucomo", LOG_PID, LOG_DAEMON);
30 syslog(LOG_INFO, "gcm_daemon started");
31
32 require_once "gnucomo_config.php";
33 require_once "db.class.php";
34 require_once "gnucomo.process_log.php";
35
36 // Set the standard variables //
37 $project_name   = "gnucomo";    //name of the entire project
38 $app_name       = "gcm_daemon"; //name of the application running
39 $developrelease = "TRUE";      //Indicates if special debug settings are needed
40 $db_version     = 31;           //The db_version indicates what the level of 
41                                 //the database should be. If the database is 
42                                 //old an update will be generated.
43 $gcmd_version   = 3;            //This value indicates the active version of the gcm_daemon,
44                                 //which is saved in the database. Log records that were not
45                                 //recognized before will now be recognized. The version doesn't
46                                 //mean anything in the overall gnucomo project.
47
48 //Avoid time-limit issues
49 set_time_limit(0);
50
51
52 // Read the database settings //
53 $class_settings = new gnucomo_config();
54 $class_settings->read($project_name);
55 $class_settings->database();
56
57 //Open an connection to the database
58 $dbms_type = $class_settings->find_parameter("database", "type");
59 $dbms_host = $class_settings->find_parameter("database", "host");
60 $dbms_name = $class_settings->find_parameter("database", "name");
61 $dbms_user = $class_settings->find_parameter("gcm_daemon", "user");
62 $dbms_password = $class_settings->find_parameter("gcm_daemon", "password");
63
64 db_select($dbms_type);
65 $dbms = new db();
66 $dbms->db_host = $dbms_host;
67 $dbms->db_name = $dbms_name;
68 $dbms->db_user = $dbms_user;
69 $dbms->db_password = $dbms_password;
70 $dbms->db_connect();
71
72 if ($dbms->have_db_connection() == "FALSE") {
73   exit ("Database connection failed.");
74 } else {
75   //The database connection has been made.
76   $dbms_working = copy_db_class($dbms);
77 }
78
79 //Verify if the database is up-to-date by checking the versionnumber
80 $local_sql = "SELECT setting_value FROM db_value WHERE setting = 'db_version' ";
81 $dbms->query($local_sql);
82
83 if ($dbms->fetch_row() == "TRUE") {
84   $active_version = $dbms->db_result_row[0];
85  
86   //Update the database to the most recent version.
87   if ($active_version < $db_version) { 
88      include ("gnucomo_db_version.php");
89   }
90 } else {
91   syslog (LOG_INFO, "Couldn't initialize database version. Is this a gnucomo database?");
92   die ("Couldn't initialize database version.\n");
93 }
94
95 //If there is a new gcm_daemon_version the logrecords that couldn't be understood can be
96 //reprocessed. For this reason processed is now changed to false again for not recognized
97 //records.
98 $local_sql = "SELECT setting_value FROM db_value WHERE setting = 'gcm_daemon_version'";
99 $dbms->query($local_sql);
100
101 if ($dbms->fetch_row() == "TRUE") {
102    if ($dbms->db_result_row[0] < $gcmd_version) {
103       //Reactive log-records that weren't understood earlier.
104       $local_sql = "UPDATE log SET processed = false WHERE logid NOT IN (SELECT DISTINCT logid FROM log_adv)";
105       $dbms->query($local_sql);
106
107       //Update de gcm_daemon version in the database
108       $local_sql = "UPDATE db_value SET setting_value = '".$gcmd_version;
109       $local_sql .= "' WHERE setting = 'gcm_daemon_version'";
110       $dbms->query($local_sql);
111
112    }
113       
114 }
115
116 //Now we loop the tasks that we have to do.
117
118
119 do {
120
121   //At this place we start processing new log-lines 
122   process_log ();
123   notificationstats();
124
125   $keep_running = 'FALSE';
126
127 } while ($keep_running == 'TRUE');
128
129 //Tell the log that we're ending our efforts in a nice way
130 syslog (LOG_INFO, "gcm_daemon ended nicely");
131
132 function process_log () {
133  
134  /* This function will walk through the log-records that haven't been processed
135   * first a snapshot will be created of a the non-processed records. 
136   * sequentially each record will dealt with. By doing that changes will be made
137   * in several log_adv_xxx tables
138   * INPUT  : NONE
139   * OUTPUT : NONE
140   */
141   global $dbms;
142   global $dbms_working;
143
144   //Find records in log that still have to be processed.
145
146   $local_sql = "SELECT setting_value FROM db_value WHERE setting = 'log_processing'";
147   $dbms->query($local_sql);
148
149   if ($dbms->fetch_row() == "TRUE") {
150      $last_log = $dbms->db_result_row[0];
151   }
152   
153   //Query the log-table
154   $local_sql = "SELECT * FROM log WHERE logid > CAST(".$last_log." AS BIGINT) order by logid";
155   $dbms->query($local_sql);
156
157   //Update the log-statistics in the object-table 
158   $local_statistics_db = copy_db_class($dbms);
159   $local_findobject_db = copy_db_class($dbms);
160
161   //Make totals 
162   $local_upper_row = $dbms->num_rows() + $last_log + 1;
163   $local_sql = "SELECT COUNT(logid), objectid from log WHERE logid > CAST(". $last_log .
164       " AS BIGINT) AND logid < CAST (" . $local_upper_row . " AS BIGINT) GROUP BY objectid";
165   $local_statistics_db->query ($local_sql);
166
167   //Loop the objects
168   for ($i = 1; $i <= $local_statistics_db->num_rows(); $i++) {
169       $local_object_row = $local_statistics_db->fetch_row();
170       $local_sql = "UPDATE object SET log_count = log_count + " . 
171           $local_statistics_db->db_result_row[0] . " WHERE objectid = '" .
172           $local_statistics_db->db_result_row[1] . "'";
173       $local_findobject_db->query($local_sql);  
174   }
175
176   $local_counter = 0;
177
178   if ($dbms->num_rows() > 0) {
179
180     //Create a database connection for changes in the database.
181     $dbms_changes = copy_db_class($dbms);
182     if ($dbms_changes->have_db_connection() == 'TRUE') {
183
184        $local_sql               = 0 ;     
185        $local_sql_statistics    = "";
186        $local_object_os         = "";
187        $local_object_os_version = "";
188
189        while ($local_counter < $dbms->num_rows()) {
190
191          $local_return_row = $dbms->fetch_row();
192          if ($local_return_row == 'TRUE') {
193             //Work on active rows
194             $local_log_id = $dbms->db_result_row[0];
195
196             $local_sql_findobject = "SELECT os, os_version FROM object WHERE objectid = '".$dbms->db_result_row[1]."'";
197             $local_findobject_db->query($local_sql_findobject);
198             $local_findobject_result = $local_findobject_db->fetch_row();
199             if ($local_findobject_result == 'TRUE') {
200                 
201                 //Now work on the OS again
202                 $local_object_os = $local_findobject_db->db_result_row[0];
203                 if  ($local_object_os == "") {
204                     $local_object_os = "Linux";
205                     $local_object_os_version = "Unknown assuming Linux";
206                 } else {
207                   $local_object_os_version = $local_findobject_db->db_result_row[1];
208                 }
209              }
210
211             switch (strtolower($local_object_os)) {
212               case "linux":
213                 $local_process_return = linux_log ();
214                 break;
215               default:
216                 syslog (LOG_INFO, "Couldn't find suitable OS for processing the logline");
217                 break;
218              }
219             
220             if ($local_process_return <> 'TRUE') {
221                $local_process_return = 'FALSE';
222             }
223
224          } else {
225
226            break;
227
228          }
229          $local_counter++;
230        } 
231        
232        //Register that the logrecords have been processed.
233        $local_sql = "UPDATE db_value SET setting_value = '".$local_log_id."' where setting = 'log_processing'";
234        $dbms->query($local_sql);
235        
236
237        //Update the statistics for the object-table
238        
239
240      } else {
241        syslog (LOG_INFO, "Couldn't clone database connection.");
242        die ("Couldn't reconnect to the database.\n");
243     }     
244    }
245
246 }
247
248 function notificationstats () {
249
250 /* This routine will determine how many new notifications have arrived and will
251  * update the statistics in the object-table to keep the performance acceptable
252  * INPUT  : NONE
253  * OUTPUT : NONE
254  */
255             
256  global $dbms;
257
258  //Find records in log that still have to be processed.
259  $local_sql = "SELECT setting_value FROM db_value WHERE setting = 'last_notification'";
260  $dbms->query($local_sql);
261  $local_dbms = copy_db_class($dbms);
262
263  //Determine the last notification
264  if ($dbms->fetch_row() == "TRUE") {
265     $last_notification = $dbms->db_result_row[0];
266  }
267  
268  //Determine how many records we are going to analyse.
269  $local_sql = "SELECT MAX(notificationid) FROM notification " .
270    "WHERE notificationid > CAST ('" . $last_notification . "' AS BIGINT)";
271  $dbms->query($local_sql);  
272
273  //Only process data if there are new notifications
274  if ($dbms->fetch_row() == "TRUE") {
275   if (intval($dbms->db_result_row[0])>0) {
276      $local_upper = $dbms->db_result_row[0] + 1;
277      $local_max   = $dbms->db_result_row[0];
278      $local_sql   = "SELECT COUNT(objectid), objectid FROM notification " .
279        "WHERE notificationid > CAST ('" .  $last_notification ."' AS BIGINT) " .
280        "AND   notificationid < CAST ('" .  $local_upper .
281        "' AS BIGINT) GROUP BY objectid";
282      $dbms->query($local_sql);
283
284
285      for ($i=0; $i < $dbms->num_rows(); $i++) {
286        $dbms->fetch_row();
287     
288        $local_sql = "UPDATE object SET notification_count = notification_count + " . $dbms->db_result_row[0] .
289          " WHERE objectid = '" . $dbms->db_result_row[1] . "'";
290       $local_dbms->query($local_sql); 
291      }  
292
293      $local_sql = "UPDATE db_value SET setting_value = '" . $local_max . 
294        "' WHERE setting = 'last_notification'";
295      $dbms->query($local_sql);  
296   }   
297  } 
298 }
299
300 ?>
301