tbrehm
2008-12-09 179c91c5e47c06f7e13811dacc1228b24602b2ce
commit | author | age
0d0cd9 1 <?php
V 2 /*
fb4c27 3 Copyright (c) 2007-2008, Till Brehm, projektfarm Gmbh and Oliver Vogel www.muv.com
0d0cd9 4 All rights reserved.
V 5
6 Redistribution and use in source and binary forms, with or without modification,
7 are permitted provided that the following conditions are met:
8
9     * Redistributions of source code must retain the above copyright notice,
10       this list of conditions and the following disclaimer.
11     * Redistributions in binary form must reproduce the above copyright notice,
12       this list of conditions and the following disclaimer in the documentation
13       and/or other materials provided with the distribution.
14     * Neither the name of ISPConfig nor the names of its contributors
15       may be used to endorse or promote products derived from this software without
16       specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
436ed8 29
0d0cd9 30 class monitor_core_module {
8793b3 31     /* TODO: this should be a config - var instead of a "constant" */
V 32     var $interval = 5; // do the monitoring every 5 minutes
0d0cd9 33
8793b3 34     var $module_name = 'monitor_core_module';
V 35     var $class_name = 'monitor_core_module';
36     /* No actions at this time. maybe later... */
37     var $actions_available = array();
bf47aa 38
8793b3 39     /*
V 40         This function is called when the module is loaded
41     */
42     function onLoad() {
43         global $app;
bf47aa 44
8793b3 45         /*
V 46         Annonce the actions that where provided by this module, so plugins
47         can register on them.
48         */
49         /* none at them moment */
50         //$app->plugins->announceEvents($this->module_name,$this->actions_available);
b7489f 51
8793b3 52         /*
V 53         As we want to get notified of any changes on several database tables,
54         we register for them.
b7489f 55
8793b3 56         The following function registers the function "functionname"
V 57             to be executed when a record for the table "dbtable" is
58             processed in the sys_datalog. "classname" is the name of the
59             class that contains the function functionname.
60         */
61         /* none at them moment */
62         //$app->modules->registerTableHook('mail_access','mail_module','process');
b7489f 63
8793b3 64         /*
V 65         Do the monitor every n minutes and write the result in the db
66         */
67         $min = date('i');
68         if (($min % $this->interval) == 0)
69         {
70             $this->doMonitor();
71         }
72     }
73
74     /*
75      This function is called when a change in one of the registered tables is detected.
76      The function then raises the events for the plugins.
77     */
78     function process($tablename, $action, $data) {
79         //        global $app;
80         //
81         //        switch ($tablename) {
82         //            case 'mail_access':
83         //                if($action == 'i') $app->plugins->raiseEvent('mail_access_insert',$data);
84         //                if($action == 'u') $app->plugins->raiseEvent('mail_access_update',$data);
85         //                if($action == 'd') $app->plugins->raiseEvent('mail_access_delete',$data);
86         //                break;
87         //        } // end switch
88     } // end function
89
90     /*
91     This method is called every n minutes, when the module ist loaded.
92     The method then does a system-monitoring
93     */
94     // TODO: what monitoring is done should be a config-var
95     function doMonitor()
96     {
97         /* Calls the single Monitoring steps */
98         $this->monitorServer();
99         $this->monitorDiskUsage();
100         $this->monitorMemUsage();
101         $this->monitorCpu();
102         $this->monitorServices();
103         $this->monitorMailLog();
104         $this->monitorMailWarnLog();
105         $this->monitorMailErrLog();
106         $this->monitorMessagesLog();
107         $this->monitorFreshClamLog();
108         $this->monitorClamAvLog();
109         $this->monitorIspConfigLog();
716255 110         $this->monitorSystemUpdate();
V 111         $this->monitorMailQueue();
36d307 112         $this->monitorRaid();
V 113         $this->monitorRkHunter();
8793b3 114     }
V 115
116     function monitorServer(){
117         global $app;
118         global $conf;
119
120         /* the id of the server as int */
121         $server_id = intval($conf["server_id"]);
122
123         /** The type of the data */
124         $type = 'server_load';
125
126         /*
127         Fetch the data into a array
128         */
129         $procUptime = shell_exec("cat /proc/uptime | cut -f1 -d' '");
130         $data['up_days'] = floor($procUptime/86400);
131         $data['up_hours'] = floor(($procUptime-$data['up_days']*86400)/3600);
132         $data['up_minutes'] = floor(($procUptime-$data['up_days']*86400-$data['up_hours']*3600)/60);
133
134         $data['uptime'] = shell_exec("uptime");
135
fb4c27 136         $tmp = explode(",", $data['uptime'], 4);
V 137         $tmpUser = explode(" ", trim($tmp[2]));
8793b3 138         $data['user_online'] = intval($tmpUser[0]);
V 139
fb4c27 140         $loadTmp = explode(":" , trim($tmp[3]));
8793b3 141         $load = explode(",",  $loadTmp[1]);
V 142         $data['load_1'] = floatval(trim($load[0]));
143         $data['load_5'] = floatval(trim($load[1]));
144         $data['load_15'] = floatval(trim($load[2]));
145
146         /** The state of the server-load. */
147         $state = 'ok';
148         if ($data['load_1'] > 20 ) $state = 'info';
149         if ($data['load_1'] > 50 ) $state = 'warning';
150         if ($data['load_1'] > 100 ) $state = 'critical';
151         if ($data['load_1'] > 150 ) $state = 'error';
152
153         /*
154         Insert the data into the database
155         */
156         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
157             "VALUES (".
158         $server_id . ", " .
273547 159             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 160         time() . ", " .
273547 161             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 162             "'" . $state . "'" .
V 163             ")";
bfbabf 164         $app->dbmaster->query($sql);
fb4c27 165
V 166         /* The new data is written, now we can delete the old one */
167         $this->_delOldRecords($type, 10);
8793b3 168     }
V 169
170     function monitorDiskUsage() {
171         global $app;
172         global $conf;
173
174         /* the id of the server as int */
175         $server_id = intval($conf["server_id"]);
176
177         /** The type of the data */
178         $type = 'disk_usage';
179
180         /** The state of the disk-usage */
181         $state = 'ok';
182
183         /** Fetch the data into a array */
184         $dfData = shell_exec("df");
185
186         // split into array
187         $df = explode("\n", $dfData);
188
189         /*
190          * ignore the first line, process the rest
191          */
192         for($i=1; $i <= sizeof($df); $i++){
193             if ($df[$i] != '')
194             {
195                 /*
196                  * Make a array of the data
197                  */
198                 $s = preg_split ("/[\s]+/", $df[$i]);
199                 $data[$i]['fs'] = $s[0];
200                 $data[$i]['size'] = $s[1];
201                 $data[$i]['used'] = $s[2];
202                 $data[$i]['available'] = $s[3];
203                 $data[$i]['percent'] = $s[4];
204                 $data[$i]['mounted'] = $s[5];
205                 /*
206                  * calculate the state
207                  */
208                 $usePercent = floatval($data[$i]['percent']);
209                 if ($usePercent > 75) $state = $this->_setState($state, 'info');
210                 if ($usePercent > 80) $state = $this->_setState($state, 'warning');
211                 if ($usePercent > 90) $state = $this->_setState($state, 'critical');
212                 if ($usePercent > 95) $state = $this->_setState($state, 'error');
213             }
214         }
215
216
217         /*
218         Insert the data into the database
219         */
220         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
221             "VALUES (".
222         $server_id . ", " .
273547 223             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 224         time() . ", " .
273547 225             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 226             "'" . $state . "'" .
V 227             ")";
bfbabf 228         $app->dbmaster->query($sql);
fb4c27 229
V 230         /* The new data is written, now we can delete the old one */
231         $this->_delOldRecords($type, 10);
8793b3 232     }
V 233
234
235     function monitorMemUsage()
236     {
237         global $app;
238         global $conf;
239
240         /* the id of the server as int */
241         $server_id = intval($conf["server_id"]);
242
243         /** The type of the data */
244         $type = 'mem_usage';
245
246         /*
247         Fetch the data into a array
248         */
249         $miData = shell_exec("cat /proc/meminfo");
250
251         $memInfo = explode("\n", $miData);
252
253         foreach($memInfo as $line){
254             $part = split(":", $line);
255             $key = trim($part[0]);
256             $tmp = explode(" ", trim($part[1]));
257             $value = 0;
258             if ($tmp[1] == 'kB') $value = $tmp[0] * 1024;
259             $data[$key] = $value;
260         }
261
262         /*
263          * actually this info has no state.
264          * maybe someone knows better...???...
265          */
266         $state = 'no_state';
267
268         /*
269         Insert the data into the database
270         */
271         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
272             "VALUES (".
273         $server_id . ", " .
273547 274             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 275         time() . ", " .
273547 276             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 277             "'" . $state . "'" .
V 278             ")";
bfbabf 279         $app->dbmaster->query($sql);
fb4c27 280
V 281         /* The new data is written, now we can delete the old one */
282         $this->_delOldRecords($type, 10);
8793b3 283     }
V 284
285
286     function monitorCpu()
287     {
288         global $app;
289         global $conf;
290
291         /* the id of the server as int */
292         $server_id = intval($conf["server_id"]);
293
294         /** The type of the data */
295         $type = 'cpu_info';
296
297         /*
298         Fetch the data into a array
299         */
300         $cpuData = shell_exec("cat /proc/cpuinfo");
301         $cpuInfo = explode("\n", $cpuData);
302
303         foreach($cpuInfo as $line){
304             $part = split(":", $line);
305             $key = trim($part[0]);
306             $value = trim($part[1]);
307             $data[$key] = $value;
308         }
309
310         /* the cpu has no state. It is, what it is */
311         $state = 'no_state';
312
313         /*
314         Insert the data into the database
315         */
316         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
317             "VALUES (".
318         $server_id . ", " .
273547 319             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 320         time() . ", " .
273547 321             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 322             "'" . $state . "'" .
V 323             ")";
bfbabf 324         $app->dbmaster->query($sql);
fb4c27 325
V 326         /* The new data is written, now we can delete the old one */
327         $this->_delOldRecords($type, 10);
8793b3 328     }
V 329
330
331     function monitorServices()
332     {
333         global $app;
334         global $conf;
335
336         /** the id of the server as int */
337         $server_id = intval($conf["server_id"]);
338
339         /** get the "active" Services of the server from the DB */
bfbabf 340         $services = $app->dbmaster->queryOneRecord("SELECT * FROM server WHERE server_id = " . $server_id);
8793b3 341
V 342         /* The type of the Monitor-data */
343         $type = 'services';
344
345         /** the State of the monitoring */
346         /* ok, if ALL aktive services are running,
347          * error, if not
348          * There is no other state!
349          */
350         $state = 'ok';
351
352         /* Monitor Webserver */
353         $data['webserver'] = -1; // unknown - not needed
354         if ($services['web_server'] == 1)
355         {
356             if($this->_checkTcp('localhost', 80)) {
357                 $data['webserver'] = 1;
358             } else {
359                 $data['webserver'] = 0;
360                 $state = 'error'; // because service is down
361             }
362         }
363
364         /* Monitor FTP-Server */
365         $data['ftpserver'] = -1; // unknown - not needed
366         if ($services['file_server'] == 1)
367         {
368             if($this->_checkFtp('localhost', 21)) {
369                 $data['ftpserver'] = 1;
370             } else {
371                 $data['ftpserver'] = 0;
372                 $state = 'error'; // because service is down
373             }
374         }
375
376         /* Monitor SMTP-Server */
377         $data['smtpserver'] = -1; // unknown - not needed
378         if ($services['mail_server'] == 1)
379         {
380             if($this->_checkTcp('localhost', 25)) {
381                 $data['smtpserver'] = 1;
382             } else {
383                 $data['smtpserver'] = 0;
384                 $state = 'error'; // because service is down
385             }
386         }
387
388         /* Monitor POP3-Server */
389         $data['pop3server'] = -1; // unknown - not needed
390         if ($services['mail_server'] == 1)
391         {
392             if($this->_checkTcp('localhost', 110)) {
393                 $data['pop3server'] = 1;
394             } else {
395                 $data['pop3server'] = 0;
396                 $state = 'error'; // because service is down
397             }
398         }
399
400         /* Monitor IMAP-Server */
401         $data['imapserver'] = -1; // unknown - not needed
402         if ($services['mail_server'] == 1)
403         {
404             if($this->_checkTcp('localhost', 143)) {
405                 $data['imapserver'] = 1;
406             } else {
407                 $data['imapserver'] = 0;
408                 $state = 'error'; // because service is down
409             }
410         }
411
412         /* Monitor BIND-Server */
413         $data['bindserver'] = -1; // unknown - not needed
414         if ($services['dns_server'] == 1)
415         {
416             if($this->_checkTcp('localhost', 53)) {
417                 $data['bindserver'] = 1;
418             } else {
419                 $data['bindserver'] = 0;
420                 $state = 'error'; // because service is down
421             }
422         }
423
424         /* Monitor MYSQL-Server */
425         $data['mysqlserver'] = -1; // unknown - not needed
426         if ($services['db_server'] == 1)
427         {
428             if($this->_checkTcp('localhost', 3306)) {
429                 $data['mysqlserver'] = 1;
430             } else {
431                 $data['mysqlserver'] = 0;
432                 $state = 'error'; // because service is down
433             }
434         }
435
436
437         /*
438         Insert the data into the database
439         */
440         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
441             "VALUES (".
442         $server_id . ", " .
273547 443             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 444         time() . ", " .
273547 445             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 446             "'" . $state . "'" .
V 447             ")";
bfbabf 448         $app->dbmaster->query($sql);
8793b3 449
fb4c27 450         /* The new data is written, now we can delete the old one */
V 451         $this->_delOldRecords($type, 10);
8793b3 452     }
716255 453
V 454
455     function monitorSystemUpdate(){
456         /*
fb4c27 457          *  This monitoring is expensive, so do it only once a hour
716255 458          */
V 459         $min = date('i');
fb4c27 460         if ($min != 0) return;
716255 461
V 462         /*
463          * OK - here we go...
464          */
465         global $app;
466         global $conf;
467
468         /* the id of the server as int */
469         $server_id = intval($conf["server_id"]);
470
471         /** The type of the data */
472         $type = 'system_update';
473
36d307 474         /* This monitoring is only available at debian or Ubuntu */
V 475         if(file_exists('/etc/debian_version')){
716255 476
36d307 477             /*
V 478              * first update the "update-database"
479              */
480             shell_exec('apt-get update');
716255 481
36d307 482             /*
V 483              * Then test the upgrade.
484              * if there is any output, then there is a needed update
485              */
486             $aptData = shell_exec('apt-get -s -qq dist-upgrade');
487             if ($aptData == '')
488             {
489                 /* There is nothing to update! */
490                 $state = 'ok';
491             }
492             else
493             {
494                 /* There is something to update! */
495                 $state = 'warning';
496             }
497
498             /*
499              * Fetch the output
500              */
501             $data['output'] = shell_exec('apt-get -s -q dist-upgrade');
502         }
503         else {
504             /*
505              * It is not debian/Ubuntu, so there is no data and no state
506              *
507              * no_state, NOT unknown, because "unknown" is shown as state
508              * inside the GUI. no_state is hidden.
509              *
510              * We have to write NO DATA inside the DB, because the GUI
511              * could not know, if there is any dat, or not...
512              */
513             $state = 'no_state';
514             $data['output']= '';
515         }
716255 516
V 517         /*
518          * Insert the data into the database
519          */
520         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
521             "VALUES (".
522         $server_id . ", " .
273547 523             "'" . $app->dbmaster->quote($type) . "', " .
716255 524         time() . ", " .
273547 525             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
716255 526             "'" . $state . "'" .
V 527             ")";
bfbabf 528         $app->dbmaster->query($sql);
fb4c27 529
V 530         /* The new data is written, now we can delete the old one */
531         $this->_delOldRecords($type, 0, 2);
716255 532     }
V 533
534     function monitorMailQueue(){
535         global $app;
536         global $conf;
537
538         /* the id of the server as int */
539         $server_id = intval($conf["server_id"]);
540
541         /** The type of the data */
542         $type = 'mailq';
543
544         /* Get the data from the mailq */
545         $data['output'] = shell_exec('mailq');
546
547         /*
548          *  The last line has more informations
549          */
550         $tmp = explode("\n", $data['output']);
551         $more = $tmp[sizeof($tmp) - 1];
552         $this->_getIntArray($more);
553         $data['bytes'] = $res[0];
554         $data['requests'] = $res[1];
555
556         /** The state of the mailq. */
557         $state = 'ok';
558         if ($data['requests'] > 2000 ) $state = 'info';
559         if ($data['requests'] > 5000 ) $state = 'warning';
560         if ($data['requests'] > 8000 ) $state = 'critical';
561         if ($data['requests'] > 10000 ) $state = 'error';
562
563         /*
564          * Insert the data into the database
565          */
566         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
567             "VALUES (".
568         $server_id . ", " .
273547 569             "'" . $app->dbmaster->quote($type) . "', " .
716255 570         time() . ", " .
273547 571             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
716255 572             "'" . $state . "'" .
V 573             ")";
bfbabf 574         $app->dbmaster->query($sql);
fb4c27 575
V 576         /* The new data is written, now we can delete the old one */
577         $this->_delOldRecords($type, 10);
716255 578     }
V 579
36d307 580
V 581     function monitorRaid(){
582         global $app;
583         global $conf;
584
585         /* the id of the server as int */
586         $server_id = intval($conf["server_id"]);
587
588         /** The type of the data */
589         $type = 'raid_state';
590
591         /* This monitoring is only available if mdadm is installed */
592         $location = shell_exec('which mdadm');
593         if($location != ''){
594             /*
595              * Fetch the output
596              */
597             $data['output'] = shell_exec('cat /proc/mdstat');
598
599             /*
600              * Then calc the state.
601              */
602             $tmp = explode("\n", $data['output']);
603             $state = 'ok';
fb4c27 604             for ($i = 0; $i < sizeof($tmp); $i++){
V 605                 /* fetch the next line */
606                 $line = $tmp[$i];
607
608                 if ((strpos($line, '[U_]') !== false) || (strpos($line, '[_U]') !== false))
36d307 609                 {
fb4c27 610                     /* One Disk is not working.
V 611                      * if the next line starts with "[>" or "[=" then
612                      * recovery (resync) is in state and the state is
613                      * information instead of critical
614                      */
615                     $nextLine = $tmp[$i+1];
616                     if ((strpos($nextLine, '[>') === false) && (strpos($nextLine, '[=') === false)) {
617                         $state = $this->_setState($state, 'critical');
618                     }
619                     else
620                     {
621                         $state = $this->_setState($state, 'info');
622                     }
36d307 623                 }
fb4c27 624                 if (strpos($line, '[__]') !== false)
36d307 625                 {
V 626                     /* both Disk are not working */
627                     $state = $this->_setState($state, 'error');
628                 }
629             }
630
631         }
632         else {
633             /*
634              * mdadm is not installed, so there is no data and no state
635              *
636              * no_state, NOT unknown, because "unknown" is shown as state
637              * inside the GUI. no_state is hidden.
638              *
639              * We have to write NO DATA inside the DB, because the GUI
640              * could not know, if there is any dat, or not...
641              */
642             $state = 'no_state';
643             $data['output']= '';
644         }
645
646         /*
647          * Insert the data into the database
648          */
649         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
650             "VALUES (".
651         $server_id . ", " .
273547 652             "'" . $app->dbmaster->quote($type) . "', " .
36d307 653         time() . ", " .
273547 654             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
36d307 655             "'" . $state . "'" .
V 656             ")";
bfbabf 657         $app->dbmaster->query($sql);
fb4c27 658
V 659         /* The new data is written, now we can delete the old one */
660         $this->_delOldRecords($type, 10);
36d307 661     }
V 662
663     function monitorRkHunter(){
fb4c27 664         /*
V 665          *  This monitoring is expensive, so do it only once a hour
666          */
667         $min = date('i');
668         if ($min != 0) return;
669
670         global $app;
671         global $conf;
672
673         /* the id of the server as int */
674         $server_id = intval($conf["server_id"]);
675
676         /** The type of the data */
677         $type = 'rkhunter';
678
679         /* This monitoring is only available if rkhunter is installed */
680         $location = shell_exec('which rkhunter');
681         if($location != ''){
682             /*
683              * Fetch the output
684              */
179c91 685             $data['output'] = shell_exec('rkhunter --update --checkall --nocolors --skip-keypress');
fb4c27 686
V 687             /*
688              * At this moment, there is no state (maybe later)
689              */
690             $state = 'no_state';
691         }
692         else {
693             /*
694              * rkhunter is not installed, so there is no data and no state
695              *
696              * no_state, NOT unknown, because "unknown" is shown as state
697              * inside the GUI. no_state is hidden.
698              *
699              * We have to write NO DATA inside the DB, because the GUI
700              * could not know, if there is any dat, or not...
701              */
702             $state = 'no_state';
703             $data['output']= '';
704         }
705
706         /*
707          * Insert the data into the database
708          */
709         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
710             "VALUES (".
711         $server_id . ", " .
273547 712             "'" . $app->dbmaster->quote($type) . "', " .
fb4c27 713         time() . ", " .
273547 714             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
fb4c27 715             "'" . $state . "'" .
V 716             ")";
bfbabf 717         $app->dbmaster->query($sql);
fb4c27 718
V 719         /* The new data is written, now we can delete the old one */
720         $this->_delOldRecords($type, 0, 2);
36d307 721     }
8793b3 722
V 723     function monitorMailLog()
724     {
725         global $app;
726         global $conf;
727
728         /* the id of the server as int */
729         $server_id = intval($conf["server_id"]);
730
731         /** The type of the data */
732         $type = 'log_mail';
733
734         /* Get the data of the log */
735         $data = $this->_getLogData($type);
736
737         /*
738          * actually this info has no state.
739          * maybe someone knows better...???...
740          */
741         $state = 'no_state';
742
743         /*
744         Insert the data into the database
745         */
746         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
747             "VALUES (".
748         $server_id . ", " .
273547 749             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 750         time() . ", " .
273547 751             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 752             "'" . $state . "'" .
V 753             ")";
bfbabf 754         $app->dbmaster->query($sql);
fb4c27 755
V 756         /* The new data is written, now we can delete the old one */
757         $this->_delOldRecords($type, 10);
8793b3 758     }
V 759
760     function monitorMailWarnLog()
761     {
762         global $app;
763         global $conf;
764
765         /* the id of the server as int */
766         $server_id = intval($conf["server_id"]);
767
768         /** The type of the data */
769         $type = 'log_mail_warn';
770
771         /* Get the data of the log */
772         $data = $this->_getLogData($type);
773
774         /*
775          * actually this info has no state.
776          * maybe someone knows better...???...
777          */
778         $state = 'no_state';
779
780         /*
781         Insert the data into the database
782         */
783         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
784             "VALUES (".
785         $server_id . ", " .
273547 786             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 787         time() . ", " .
273547 788             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 789             "'" . $state . "'" .
V 790             ")";
bfbabf 791         $app->dbmaster->query($sql);
fb4c27 792
V 793         /* The new data is written, now we can delete the old one */
794         $this->_delOldRecords($type, 10);
8793b3 795     }
V 796
797     function monitorMailErrLog()
798     {
799         global $app;
800         global $conf;
801
802         /* the id of the server as int */
803         $server_id = intval($conf["server_id"]);
804
805         /** The type of the data */
806         $type = 'log_mail_err';
807
808         /* Get the data of the log */
809         $data = $this->_getLogData($type);
810
811         /*
812          * actually this info has no state.
813          * maybe someone knows better...???...
814          */
815         $state = 'no_state';
816
817         /*
818         Insert the data into the database
819         */
820         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
821             "VALUES (".
822         $server_id . ", " .
273547 823             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 824         time() . ", " .
273547 825             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 826             "'" . $state . "'" .
V 827             ")";
bfbabf 828         $app->dbmaster->query($sql);
fb4c27 829
V 830         /* The new data is written, now we can delete the old one */
831         $this->_delOldRecords($type, 10);
8793b3 832     }
V 833
834
835     function monitorMessagesLog()
836     {
837         global $app;
838         global $conf;
839
840         /* the id of the server as int */
841         $server_id = intval($conf["server_id"]);
842
843         /** The type of the data */
844         $type = 'log_messages';
845
846         /* Get the data of the log */
847         $data = $this->_getLogData($type);
848
849         /*
850          * actually this info has no state.
851          * maybe someone knows better...???...
852          */
853         $state = 'no_state';
854
855         /*
856         Insert the data into the database
857         */
858         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
859             "VALUES (".
860         $server_id . ", " .
273547 861             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 862         time() . ", " .
273547 863             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 864             "'" . $state . "'" .
V 865             ")";
bfbabf 866         $app->dbmaster->query($sql);
fb4c27 867
V 868         /* The new data is written, now we can delete the old one */
869         $this->_delOldRecords($type, 10);
8793b3 870     }
V 871
872     function monitorFreshClamLog()
873     {
874         global $app;
875         global $conf;
876
877         /* the id of the server as int */
878         $server_id = intval($conf["server_id"]);
879
880         /** The type of the data */
881         $type = 'log_freshclam';
882
883         /* Get the data of the log */
884         $data = $this->_getLogData($type);
885
fb4c27 886         /* Get the data from the LAST log-Entry.
V 887          * if there can be found:
888          * WARNING: Your ClamAV installation is OUTDATED!
889          * then the clamav is outdated. This is a warning!
890          */
8793b3 891         $state = 'ok';
fb4c27 892
V 893         $tmp = explode("\n", $data);
894         $lastLog = array();
895         if ($tmp[sizeof($tmp)-1] == "")
896         {
897             /* the log ends with an empty line remove this */
898             array_pop($tmp);
899         }
900         if (strpos($tmp[sizeof($tmp)-1], "-------------") !== false)
901         {
902             /* the log ends with "-----..." remove this */
903             array_pop($tmp);
904         }
905         for ($i = sizeof($tmp) -1; $i > 0; $i--){
906             if (strpos($tmp[$i], "---------") === false){
907                 /* no delimiter found, so add this to the last-log */
908                 $lastLog[] = $tmp[$i];
909             }
910             else
911             {
912                 /* delimiter found, so there is no more line left! */
913                 break;
914             }
915         }
916
917         /*
918          * Now we have the last log in the array.
919          * Check if the outdated-string is found...
920          */
921         foreach($lastLog as $line){
922             if (strpos(strtolower($line), "outdated") !== false) {
923                  $state = $this->_setState($state, 'warning');
924             }
925         }
8793b3 926
V 927         /*
928         Insert the data into the database
929         */
930         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
931             "VALUES (".
932         $server_id . ", " .
273547 933             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 934         time() . ", " .
273547 935             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 936             "'" . $state . "'" .
V 937             ")";
bfbabf 938         $app->dbmaster->query($sql);
fb4c27 939
V 940         /* The new data is written, now we can delete the old one */
941         $this->_delOldRecords($type, 10);
8793b3 942     }
V 943
944     function monitorClamAvLog()
945     {
946         global $app;
947         global $conf;
948
949         /* the id of the server as int */
950         $server_id = intval($conf["server_id"]);
951
952         /** The type of the data */
953         $type = 'log_clamav';
954
955         /* Get the data of the log */
956         $data = $this->_getLogData($type);
957
958         // Todo: the state should be calculated.
959         $state = 'ok';
960
961         /*
962         Insert the data into the database
963         */
964         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
965             "VALUES (".
966         $server_id . ", " .
273547 967             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 968         time() . ", " .
273547 969             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 970             "'" . $state . "'" .
V 971             ")";
bfbabf 972         $app->dbmaster->query($sql);
36d307 973
fb4c27 974         /* The new data is written, now we can delete the old one */
V 975         $this->_delOldRecords($type, 10);
8793b3 976     }
V 977
978     function monitorIspConfigLog()
979     {
980         global $app;
981         global $conf;
982
983         /* the id of the server as int */
984         $server_id = intval($conf["server_id"]);
985
986         /** The type of the data */
987         $type = 'log_ispconfig';
988
989         /* Get the data of the log */
990         $data = $this->_getLogData($type);
991
992         // Todo: the state should be calculated.
993         $state = 'ok';
994
995         /*
996         Insert the data into the database
997         */
998         $sql = "INSERT INTO monitor_data (server_id, type, created, data, state) " .
999             "VALUES (".
1000         $server_id . ", " .
273547 1001             "'" . $app->dbmaster->quote($type) . "', " .
8793b3 1002         time() . ", " .
273547 1003             "'" . $app->dbmaster->quote(serialize($data)) . "', " .
8793b3 1004             "'" . $state . "'" .
V 1005             ")";
bfbabf 1006         $app->dbmaster->query($sql);
fb4c27 1007
V 1008         /* The new data is written, now we can delete the old one */
1009         $this->_delOldRecords($type, 10);
8793b3 1010     }
V 1011
1012
1013     function _getLogData($log){
1014         switch($log) {
1015             case 'log_mail':
1016                 $logfile = '/var/log/mail.log';
1017                 break;
1018             case 'log_mail_warn':
1019                 $logfile = '/var/log/mail.warn';
1020                 break;
1021             case 'log_mail_err':
1022                 $logfile = '/var/log/mail.err';
1023                 break;
1024             case 'log_messages':
1025                 $logfile = '/var/log/messages';
1026                 break;
1027             case 'log_freshclam':
1028                 $logfile = '/var/log/clamav/freshclam.log';
1029                 break;
1030             case 'log_clamav':
1031                 $logfile = '/var/log/clamav/clamav.log';
1032                 break;
1033             case 'log_ispconfig':
1034                 $logfile = '/var/log/ispconfig/ispconfig.log';
1035                 break;
1036             default:
1037                 $logfile = '';
1038                 break;
1039         }
1040
1041         // Getting the logfile content
1042         if($logfile != '') {
1043             $logfile = escapeshellcmd($logfile);
1044             if(stristr($logfile, ';')) {
1045                 $log = 'Logfile path error.';
1046             }
1047             else
1048             {
1049                 $log = '';
1050                 if(is_readable($logfile)) {
1051                     if($fd = popen("tail -n 100 $logfile", 'r')) {
1052                         while (!feof($fd)) {
1053                             $log .= fgets($fd, 4096);
1054                             $n++;
1055                             if($n > 1000) break;
1056                         }
1057                         fclose($fd);
1058                     }
1059                 } else {
1060                     $log = 'Unable to read '.$logfile;
1061                 }
1062             }
1063         }
1064
1065         return $log;
1066     }
1067
1068     function _checkTcp ($host,$port) {
1069
1070         $fp = @fsockopen ($host, $port, &$errno, &$errstr, 2);
1071
1072         if ($fp) {
1073             fclose($fp);
1074             return true;
1075         } else {
1076             return false;
1077         }
1078     }
1079
1080     function _checkUdp ($host,$port) {
1081
1082         $fp = @fsockopen ('udp://'.$host, $port, &$errno, &$errstr, 2);
1083
1084         if ($fp) {
1085             fclose($fp);
1086             return true;
1087         } else {
1088             return false;
1089         }
1090     }
1091
1092     function _checkFtp ($host,$port){
1093
1094         $conn_id = @ftp_connect($host, $port);
1095
1096         if($conn_id){
1097             @ftp_close($conn_id);
1098             return true;
1099         } else {
1100             return false;
1101         }
1102     }
1103
1104     /*
1105      Deletes Records older than n.
1106     */
1107     function _delOldRecords($type, $min, $hour=0, $days=0) {
1108         global $app;
1109
1110         $now = time();
1111         $old = $now - ($min * 60) - ($hour * 60 * 60) - ($days * 24 * 60 * 60);
1112         $sql = "DELETE FROM monitor_data " .
1113             "WHERE " .
273547 1114             "type =" . "'" . $app->dbmaster->quote($type) . "' " .
8793b3 1115             "AND " .
V 1116             "created < " . $old;
bfbabf 1117         $app->dbmaster->query($sql);
8793b3 1118     }
V 1119
1120     /*
1121      * Set the state to the given level (or higher, but not lesser).
1122      * * If the actual state is critical and you call the method with ok,
1123      *   then the state is critical.
1124      *
1125      * * If the actual state is critical and you call the method with error,
1126      *   then the state is error.
1127      */
1128     function _setState($oldState, $newState)
1129     {
1130         /*
1131          * Calculate the weight of the old state
1132          */
1133         switch ($oldState) {
1134             case 'no_state': $oldInt = 0;
1135                 break;
1136             case 'ok': $oldInt = 1;
1137                 break;
1138             case 'unknown': $oldInt = 2;
1139                 break;
1140             case 'info': $oldInt = 3;
1141                 break;
1142             case 'warning': $oldInt = 4;
1143                 break;
1144             case 'critical': $oldInt = 5;
1145                 break;
1146             case 'error': $oldInt = 6;
1147                 break;
1148         }
1149         /*
1150          * Calculate the weight of the new state
1151          */
1152         switch ($newState) {
1153             case 'no_state': $newInt = 0 ;
1154                 break;
a2e689 1155             case 'ok': $newInt = 1 ;
8793b3 1156                 break;
a2e689 1157             case 'unknown': $newInt = 2 ;
8793b3 1158                 break;
V 1159             case 'info': $newInt = 3 ;
1160                 break;
1161             case 'warning': $newInt = 4 ;
1162                 break;
1163             case 'critical': $newInt = 5 ;
1164                 break;
1165             case 'error': $newInt = 6 ;
1166                 break;
1167         }
1168
1169         /*
1170          * Set to the higher level
1171          */
1172         if ($newInt > $oldInt){
1173             return $newState;
1174         }
1175         else
1176         {
1177             return $oldState;
1178         }
1179     }
1180
716255 1181     function _getIntArray($line){
V 1182         /** The array of float found */
1183         $res = array();
1184         /* First build a array from the line */
1185         $data = explode(' ', $line);
1186         /* then check if any item is a float */
1187         foreach ($data as $item) {
1188             if ($item . '' == (int)$item . ''){
1189                 $res[] = $item;
1190             }
1191         }
1192         return $res;
1193     }
1194
8793b3 1195
0d0cd9 1196 } // end class
V 1197
1198 ?>