Till Brehm
2014-09-22 f02be96750e48859cc63f1f2b64a86a9202178b4
commit | author | age
dead5c 1 <?php
V 2
3 /*
996bad 4     Copyright (c) 2007-2011, Till Brehm, projektfarm Gmbh and Oliver Vogel www.muv.com
M 5     All rights reserved.
dead5c 6
996bad 7     Redistribution and use in source and binary forms, with or without modification,
M 8     are permitted provided that the following conditions are met:
dead5c 9
V 10  * Redistributions of source code must retain the above copyright notice,
996bad 11     this list of conditions and the following disclaimer.
dead5c 12  * Redistributions in binary form must reproduce the above copyright notice,
996bad 13     this list of conditions and the following disclaimer in the documentation
M 14     and/or other materials provided with the distribution.
dead5c 15  * Neither the name of ISPConfig nor the names of its contributors
996bad 16     may be used to endorse or promote products derived from this software without
M 17     specific prior written permission.
dead5c 18
996bad 19     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
M 20     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22     IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27     NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dead5c 29  */
V 30
31 class monitor_tools {
32
33     //** Get distribution identifier
34     //** IMPORTANT!
35     //   This is the same code as in install/lib/install.lib.php
36     //   So if you change it here, you also have to change it in there!
37     //   Please do not forget to remove the swriteln(); - lines here at this file
38     public function get_distname() {
39
40         $distname = '';
41         $distver = '';
42         $distid = '';
43         $distbaseid = '';
44
45         //** Debian or Ubuntu
46         if (file_exists('/etc/debian_version')) {
f35123 47             if (strstr(trim(file_get_contents('/etc/issue')), 'Ubuntu')) {
T 48                 if (strstr(trim(file_get_contents('/etc/issue')), 'LTS')) {
49                     $lts=" LTS";
50                 } else {
51                     $lts="";
52                 }
53
d281bb 54                 $issue=file_get_contents('/etc/issue');
C 55                 $distname = 'Ubuntu';
56                 $distid = 'debian40';
57                 $distbaseid = 'debian';
7fe908 58                 $ver = explode(' ', $issue);
d281bb 59                 $ver = array_filter($ver);
C 60                 $ver = next($ver);
7fe908 61                 $mainver = explode('.', $ver);
d281bb 62                 $mainver = array_filter($mainver);
C 63                 $mainver = current($mainver).'.'.next($mainver);
64                 switch ($mainver){
be2cbb 65                 case "14.04":
TB 66                     $relname = "(Trusty Tahr)";
67                     break;
68                 case "13.10":
69                     $relname = "(Saucy Salamander)";
70                     break;
71                 case "13.04":
72                     $relname = "(Raring Ringtail)";
73                     break;
d281bb 74                 case "12.10":
C 75                     $relname = "(Quantal Quetzal)";
7fe908 76                     break;
d281bb 77                 case "12.04":
C 78                     $relname = "(Precise Pangolin)";
7fe908 79                     break;
d281bb 80                 case "11.10":
C 81                     $relname = "(Oneiric Ocelot)";
7fe908 82                     break;
d281bb 83                 case "11.14":
C 84                     $relname = "(Natty Narwhal)";
7fe908 85                     break;
d281bb 86                 case "10.10":
C 87                     $relname = "(Maverick Meerkat)";
7fe908 88                     break;
d281bb 89                 case "10.04":
C 90                     $relname = "(Lucid Lynx)";
7fe908 91                     break;
d281bb 92                 case "9.10":
C 93                     $relname = "(Karmic Koala)";
7fe908 94                     break;
d281bb 95                 case "9.04":
C 96                     $relname = "(Jaunty Jackpole)";
7fe908 97                     break;
d281bb 98                 case "8.10":
7fe908 99                     $relname = "(Intrepid Ibex)";
MC 100                     break;
d281bb 101                 case "8.04":
C 102                     $relname = "(Hardy Heron)";
7fe908 103                     break;
d281bb 104                 case "7.10":
C 105                     $relname = "(Gutsy Gibbon)";
7fe908 106                     break;
d281bb 107                 case "7.04":
C 108                     $relname = "(Feisty Fawn)";
7fe908 109                     break;
d281bb 110                 case "6.10":
C 111                     $relname = "(Edgy Eft)";
7fe908 112                     break;
d281bb 113                 case "6.06":
C 114                     $relname = "(Dapper Drake)";
7fe908 115                     break;
d281bb 116                 case "5.10":
C 117                     $relname = "(Breezy Badger)";
7fe908 118                     break;
d281bb 119                 case "5.04":
C 120                     $relname = "(Hoary Hedgehog)";
7fe908 121                     break;
d281bb 122                 case "4.10":
C 123                     $relname = "(Warty Warthog)";
7fe908 124                     break;
d281bb 125                 default:
C 126                     $relname = "UNKNOWN";
127                 }
128                 $distver = $ver.$lts." ".$relname;
129             } elseif(trim(file_get_contents('/etc/debian_version')) == '4.0') {
dead5c 130                 $distname = 'Debian';
V 131                 $distver = '4.0';
132                 $distid = 'debian40';
133                 $distbaseid = 'debian';
134             } elseif (strstr(trim(file_get_contents('/etc/debian_version')), '5.0')) {
135                 $distname = 'Debian';
136                 $distver = 'Lenny';
137                 $distid = 'debian40';
138                 $distbaseid = 'debian';
139             } elseif (strstr(trim(file_get_contents('/etc/debian_version')), '6.0') || trim(file_get_contents('/etc/debian_version')) == 'squeeze/sid') {
140                 $distname = 'Debian';
141                 $distver = 'Squeeze/Sid';
142                 $distid = 'debian60';
143                 $distbaseid = 'debian';
82ff62 144             } elseif (strstr(trim(file_get_contents('/etc/debian_version')), '7.0') || substr(trim(file_get_contents('/etc/debian_version')),0,2) == '7.' || trim(file_get_contents('/etc/debian_version')) == 'wheezy/sid') {
996bad 145                 $distname = 'Debian';
M 146                 $distver = 'Wheezy/Sid';
d6aef1 147                 $distid = 'debian60';
996bad 148                 $distbaseid = 'debian';
dead5c 149             } else {
V 150                 $distname = 'Debian';
151                 $distver = 'Unknown';
152                 $distid = 'debian40';
153                 $distbaseid = 'debian';
154             }
155         }
156
157         //** OpenSuSE
158         elseif (file_exists('/etc/SuSE-release')) {
159             if (stristr(file_get_contents('/etc/SuSE-release'), '11.0')) {
160                 $distname = 'openSUSE';
161                 $distver = '11.0';
162                 $distid = 'opensuse110';
163                 $distbaseid = 'opensuse';
164             } elseif (stristr(file_get_contents('/etc/SuSE-release'), '11.1')) {
165                 $distname = 'openSUSE';
166                 $distver = '11.1';
167                 $distid = 'opensuse110';
168                 $distbaseid = 'opensuse';
169             } elseif (stristr(file_get_contents('/etc/SuSE-release'), '11.2')) {
170                 $distname = 'openSUSE';
171                 $distver = '11.1';
172                 $distid = 'opensuse110';
173                 $distbaseid = 'opensuse';
174             } else {
175                 $distname = 'openSUSE';
176                 $distver = 'Unknown';
177                 $distid = 'opensuse110';
178                 $distbaseid = 'opensuse';
179             }
180         }
181
182
183         //** Redhat
184         elseif (file_exists('/etc/redhat-release')) {
185
186             $content = file_get_contents('/etc/redhat-release');
187
188             if (stristr($content, 'Fedora release 9 (Sulphur)')) {
189                 $distname = 'Fedora';
190                 $distver = '9';
191                 $distid = 'fedora9';
192                 $distbaseid = 'fedora';
193             } elseif (stristr($content, 'Fedora release 10 (Cambridge)')) {
194                 $distname = 'Fedora';
195                 $distver = '10';
196                 $distid = 'fedora9';
197                 $distbaseid = 'fedora';
198             } elseif (stristr($content, 'Fedora release 10')) {
199                 $distname = 'Fedora';
200                 $distver = '11';
201                 $distid = 'fedora9';
202                 $distbaseid = 'fedora';
203             } elseif (stristr($content, 'CentOS release 5.2 (Final)')) {
204                 $distname = 'CentOS';
205                 $distver = '5.2';
206                 $distid = 'centos52';
207                 $distbaseid = 'fedora';
208             } elseif (stristr($content, 'CentOS release 5.3 (Final)')) {
209                 $distname = 'CentOS';
210                 $distver = '5.3';
211                 $distid = 'centos53';
212                 $distbaseid = 'fedora';
be2cbb 213             } elseif(stristr($content, 'CentOS Linux release 6')) {
TB 214                 $distname = 'CentOS';
215                 $distver = 'Unknown';
216                 $distid = 'centos53';
217                 $distbaseid = 'fedora';
218             } elseif(stristr($content, 'CentOS Linux release 7')) {
219                 $distname = 'CentOS';
220                 $distver = 'Unknown';
221                 $distid = 'centos53';
222                 $distbaseid = 'fedora';
dead5c 223             } else {
V 224                 $distname = 'Redhat';
225                 $distver = 'Unknown';
226                 $distid = 'fedora9';
227                 $distbaseid = 'fedora';
228             }
229         }
230
231         //** Gentoo
232         elseif (file_exists('/etc/gentoo-release')) {
233
234             $content = file_get_contents('/etc/gentoo-release');
235
236             preg_match_all('/([0-9]{1,2})/', $content, $version);
237             $distname = 'Gentoo';
238             $distver = $version[0][0] . $version[0][1];
239             $distid = 'gentoo';
240             $distbaseid = 'gentoo';
241         } else {
242             die('Unrecognized GNU/Linux distribution');
243         }
244
245         return array('name' => $distname, 'version' => $distver, 'id' => $distid, 'baseid' => $distbaseid);
246     }
247
7fe908 248     //** Email Quota
MC 249     public function monitorEmailQuota() {
250         global $conf, $app;
7cd997 251
L 252         //* Initialize data array
253         $data = array();
254
255         //* the id of the server as int
256         $server_id = intval($conf['server_id']);
257
258         //* The type of the data
259         $type = 'email_quota';
260
261         //* The state of the email_quota.
262         $state = 'ok';
996bad 263
512f11 264         $mailboxes = $app->db->queryAllRecords("SELECT email,maildir FROM mail_user WHERE server_id = $server_id");
91c381 265         if(is_array($mailboxes)) {
T 266             foreach($mailboxes as $mb) {
267                 $email = $mb['email'];
7fe908 268                 $email_parts = explode('@', $mb['email']);
512f11 269                 $filename = $mb['maildir'].'/.quotausage';
T 270                 if(file_exists($filename) && !is_link($filename)) {
91c381 271                     $quotafile = file($filename);
5e10d2 272                     preg_match('/storage.*?([0-9]+)/s', implode('',$quotafile), $storage_value);
TB 273                     $data[$email]['used'] = $storage_value[1];
274                     $app->log("Mail storage $email: " . $storage_value[1], LOGLEVEL_DEBUG);
91c381 275                     unset($quotafile);
edf806 276                 } else {
7fe908 277                     exec('du -s '.escapeshellcmd($mb['maildir']), $out);
MC 278                     $parts = explode(' ', $out[0]);
edf806 279                     $data[$email]['used'] = intval($parts[0])*1024;
T 280                     unset($out);
281                     unset($parts);
282                 }
91c381 283             }
T 284         }
996bad 285
91c381 286         unset($mailboxes);
7cd997 287
7fe908 288         //* Dovecot quota check Courier in progress lathama@gmail.com
91c381 289         /*
996bad 290                 if($dir = opendir("/var/vmail")){
M 291                         while (($quotafiles = readdir($dir)) !== false){
292                                 if(preg_match('/.\_quota$/', $quotafiles)){
293                                         $quotafile = (file("/var/vmail/" . $quotafiles));
294                                         $emailaddress = preg_replace('/_quota/',"", $quotafiles);
295                                         $emailaddress = preg_replace('/_/',"@", $emailaddress);
296                                         $data[$emailaddress]['used'] = trim($quotafile['1']);
297                                 }
298                         }
299                         closedir($dir);
300                 }
91c381 301         */
7cd997 302         $res['server_id'] = $server_id;
L 303         $res['type'] = $type;
304         $res['data'] = $data;
305         $res['state'] = $state;
7fe908 306         return $res;
MC 307     }
7cd997 308
7fe908 309     //** Filesystem Quota
dead5c 310     public function monitorHDQuota() {
V 311         global $conf;
312
7cd997 313         //* Initialize data array
dead5c 314         $data = array();
V 315
7cd997 316         //* the id of the server as int
dead5c 317         $server_id = intval($conf['server_id']);
V 318
7cd997 319         //* The type of the data
dead5c 320         $type = 'harddisk_quota';
V 321
7cd997 322         //* The state of the harddisk_quota.
dead5c 323         $state = 'ok';
V 324
7cd997 325         //* Fetch the data for all users
526b99 326         $dfData = shell_exec('repquota -au 2>/dev/null');
dead5c 327
7cd997 328         //* Split into array
dead5c 329         $df = explode("\n", $dfData);
V 330
7cd997 331         //* ignore the first 5 lines, process the rest
dead5c 332         for ($i = 5; $i <= sizeof($df); $i++) {
V 333             if ($df[$i] != '') {
7cd997 334                 //* Make a array of the data
dead5c 335                 $s = preg_split('/[\s]+/', $df[$i]);
V 336                 $username = $s[0];
337                 if (substr($username, 0, 3) == 'web') {
338                     if (isset($data['user'][$username])) {
339                         $data['user'][$username]['used'] += $s[2];
340                         $data['user'][$username]['soft'] += $s[3];
341                         $data['user'][$username]['hard'] += $s[4];
b4daeb 342                         $data['user'][$username]['files'] += $s[5];
dead5c 343                     } else {
V 344                         $data['user'][$username]['used'] = $s[2];
345                         $data['user'][$username]['soft'] = $s[3];
346                         $data['user'][$username]['hard'] = $s[4];
b4daeb 347                         $data['user'][$username]['files'] = $s[5];
dead5c 348                     }
V 349                 }
350             }
351         }
352
7cd997 353         //** Fetch the data for all users
526b99 354         $dfData = shell_exec('repquota -ag 2>/dev/null');
dead5c 355
7cd997 356         //* split into array
dead5c 357         $df = explode("\n", $dfData);
V 358
7cd997 359         //* ignore the first 5 lines, process the rest
dead5c 360         for ($i = 5; $i <= sizeof($df); $i++) {
V 361             if ($df[$i] != '') {
7cd997 362                 //* Make a array of the data
dead5c 363                 $s = preg_split('/[\s]+/', $df[$i]);
V 364                 $groupname = $s[0];
365                 if (substr($groupname, 0, 6) == 'client') {
366                     if (isset($data['group'][$groupname])) {
367                         $data['group'][$groupname]['used'] += $s[1];
368                         $data['group'][$groupname]['soft'] += $s[2];
369                         $data['group'][$groupname]['hard'] += $s[3];
370                     } else {
371                         $data['group'][$groupname]['used'] = $s[1];
372                         $data['group'][$groupname]['soft'] = $s[2];
373                         $data['group'][$groupname]['hard'] = $s[3];
374                     }
375                 }
376             }
377         }
378
7cd997 379         //* Return the Result
dead5c 380         $res['server_id'] = $server_id;
V 381         $res['type'] = $type;
382         $res['data'] = $data;
383         $res['state'] = $state;
384         return $res;
385     }
386
387     public function monitorServer() {
388         global $conf;
389
390         /* the id of the server as int */
391         $server_id = intval($conf['server_id']);
392
393         /** The type of the data */
7fe908 394
MC 395
dead5c 396         $type = 'server_load';
V 397
398         /*
996bad 399             Fetch the data into a array
dead5c 400          */
V 401         $procUptime = shell_exec("cat /proc/uptime | cut -f1 -d' '");
402         $data['up_days'] = floor($procUptime / 86400);
403         $data['up_hours'] = floor(($procUptime - $data['up_days'] * 86400) / 3600);
404         $data['up_minutes'] = floor(($procUptime - $data['up_days'] * 86400 - $data['up_hours'] * 3600) / 60);
405
406         $data['uptime'] = shell_exec('uptime');
407
408         $tmp = explode(',', $data['uptime'], 4);
409         $tmpUser = explode(' ', trim($tmp[2]));
410         $data['user_online'] = intval($tmpUser[0]);
411
412         //* New Load Average code to fix "always zero" bug in non-english distros. NEEDS TESTING
413         $loadTmp = shell_exec("cat /proc/loadavg | cut -f1-3 -d' '");
414         $load = explode(' ', $loadTmp);
415         $data['load_1'] = floatval(str_replace(',', '.', $load[0]));
416         $data['load_5'] = floatval(str_replace(',', '.', $load[1]));
417         $data['load_15'] = floatval(str_replace(',', '.', $load[2]));
418
419         /** The state of the server-load. */
420         $state = 'ok';
421         if ($data['load_1'] > 20)
422             $state = 'info';
423         if ($data['load_1'] > 50)
424             $state = 'warning';
425         if ($data['load_1'] > 100)
426             $state = 'critical';
427         if ($data['load_1'] > 150)
428             $state = 'error';
429
430         /*
431          * Return the Result
432          */
433         $res['server_id'] = $server_id;
434         $res['type'] = $type;
435         $res['data'] = $data;
436         $res['state'] = $state;
437         return $res;
438     }
439
440     public function monitorOsVer() {
441         global $conf;
442
443         /* the id of the server as int */
444         $server_id = intval($conf['server_id']);
445
446         /** The type of the data */
447         $type = 'os_info';
448
449         /*
996bad 450             Fetch the data into a array
dead5c 451          */
V 452         $dist = $this->get_distname();
453
454         $data['name'] = $dist['name'];
455         $data['version'] = $dist['version'];
456
457         /* the OS has no state. It is, what it is */
458         $state = 'no_state';
459
460         /*
461          * Return the Result
462          */
463         $res['server_id'] = $server_id;
464         $res['type'] = $type;
465         $res['data'] = $data;
466         $res['state'] = $state;
467         return $res;
468     }
469
470     public function monitorIspcVer() {
471         global $conf;
472
473         /* the id of the server as int */
474         $server_id = intval($conf['server_id']);
475
476         /** The type of the data */
477         $type = 'ispc_info';
478
479         /*
996bad 480             Fetch the data into a array
dead5c 481          */
V 482         $data['name'] = ISPC_APP_TITLE;
483         $data['version'] = ISPC_APP_VERSION;
484
485         /* the ISPC-Version has no state. It is, what it is */
486         $state = 'no_state';
def897 487
dead5c 488         /*
V 489          * Return the Result
490          */
491         $res['server_id'] = $server_id;
492         $res['type'] = $type;
493         $res['data'] = $data;
494         $res['state'] = $state;
495         return $res;
496     }
497
498     public function monitorDiskUsage() {
7fe908 499         global $app, $conf;
dead5c 500
V 501         /* the id of the server as int */
502         $server_id = intval($conf['server_id']);
503
504         /** The type of the data */
505         $type = 'disk_usage';
506
507         /** The state of the disk-usage */
508         $state = 'ok';
509
510         /** Fetch the data of ALL devices into a array (needed for monitoring!) */
615a0a 511         //$dfData = shell_exec('df -hT 2>/dev/null');
T 512         $app->uses('getconf');
7fe908 513         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
MC 514         $dfData = shell_exec('df -hT|grep -v "'.$web_config['website_basedir'].'/" 2>/dev/null');
dead5c 515
V 516         // split into array
517         $df = explode("\n", $dfData);
518
519         /*
520          * ignore the first line, process the rest
521          */
522         for ($i = 1; $i <= sizeof($df); $i++) {
523             if ($df[$i] != '') {
524                 /*
525                  * Make an array of the data
526                  */
527                 $s = preg_split('/[\s]+/', $df[$i]);
528                 $data[$i]['fs'] = $s[0];
529                 $data[$i]['type'] = $s[1];
530                 $data[$i]['size'] = $s[2];
531                 $data[$i]['used'] = $s[3];
532                 $data[$i]['available'] = $s[4];
533                 $data[$i]['percent'] = $s[5];
534                 $data[$i]['mounted'] = $s[6];
535                 /*
536                  * calculate the state
537                  */
538                 $usePercent = floatval($data[$i]['percent']);
996bad 539
9c9382 540                 //* get the free memsize
7fe908 541                 if(substr($data[$i]['available'], -1) == 'G') {
9c9382 542                     $freesize = floatval($data[$i]['available'])*1024;
7fe908 543                 } elseif(substr($data[$i]['available'], -1) == 'T') {
9c9382 544                     $freesize = floatval($data[$i]['available'])*1024*1024;
T 545                 } else {
546                     $freesize = floatval($data[$i]['available']);
547                 }
dead5c 548
V 549                 //* We don't want to check some filesystem which have no sensible filling levels
550                 switch ($data[$i]['type']) {
7fe908 551                 case 'iso9660':
MC 552                 case 'cramfs':
553                 case 'udf':
554                 case 'tmpfs':
555                 case 'devtmpfs':
556                 case 'udev':
557                     break;
558                 default:
559                     if ($usePercent > 75 && $freesize < 2000)
560                         $state = $this->_setState($state, 'info');
561                     if ($usePercent > 80 && $freesize < 1000)
562                         $state = $this->_setState($state, 'warning');
563                     if ($usePercent > 90 && $freesize < 500)
564                         $state = $this->_setState($state, 'critical');
565                     if ($usePercent > 95 && $freesize < 100)
566                         $state = $this->_setState($state, 'error');
567                     break;
dead5c 568                 }
V 569             }
570         }
571
572         /*
573          * Return the Result
574          */
575         $res['server_id'] = $server_id;
576         $res['type'] = $type;
577         $res['data'] = $data;
578         $res['state'] = $state;
579         return $res;
580     }
581
582     public function monitorMemUsage() {
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 = 'mem_usage';
590
591         /*
996bad 592             Fetch the data into a array
dead5c 593          */
V 594         $miData = shell_exec('cat /proc/meminfo');
595
596         $memInfo = explode("\n", $miData);
597
598         foreach ($memInfo as $line) {
599             $part = preg_split('/:/', $line);
600             $key = trim($part[0]);
601             $tmp = explode(' ', trim($part[1]));
602             $value = 0;
603             if ($tmp[1] == 'kB')
604                 $value = $tmp[0] * 1024;
605             $data[$key] = $value;
606         }
607
608         /*
609          * actually this info has no state.
610          * maybe someone knows better...???...
611          */
612         $state = 'no_state';
def897 613
dead5c 614         /*
V 615          * Return the Result
616          */
617         $res['server_id'] = $server_id;
618         $res['type'] = $type;
619         $res['data'] = $data;
620         $res['state'] = $state;
621         return $res;
622     }
623
624     public function monitorCpu() {
625         global $conf;
626
627         /* the id of the server as int */
628         $server_id = intval($conf['server_id']);
629
630         /** The type of the data */
631         $type = 'cpu_info';
632
633         /*
996bad 634             Fetch the data into a array
dead5c 635          */
V 636         if (file_exists('/proc/cpuinfo')) {
637             $cpuData = shell_exec('cat /proc/cpuinfo');
638             $cpuInfo = explode("\n", $cpuData);
639             $processor = 0;
640
641             foreach ($cpuInfo as $line) {
642
643                 $part = preg_split('/:/', $line);
644                 $key = trim($part[0]);
645                 $value = trim($part[1]);
646                 if ($key == 'processor')
647                     $processor = intval($value);
648                 if ($key != '')
649                     $data[$key . ' ' . $processor] = $value;
650             }
651
652             /* the cpu has no state. It is, what it is */
653             $state = 'no_state';
654         } else {
655             /*
656              * It is not Linux, so there is no data and no state
657              *
658              * no_state, NOT unknown, because "unknown" is shown as state
659              * inside the GUI. no_state is hidden.
660              *
661              * We have to write NO DATA inside the DB, because the GUI
662              * could not know, if there is any dat, or not...
663              */
664             $state = 'no_state';
665             $data['output'] = '';
666         }
667
668         /*
669          * Return the Result
670          */
671         $res['server_id'] = $server_id;
672         $res['type'] = $type;
673         $res['data'] = $data;
674         $res['state'] = $state;
675         return $res;
676     }
677
678     public function monitorServices() {
679         global $app;
680         global $conf;
681
682         /** the id of the server as int */
683         $server_id = intval($conf['server_id']);
684
eed6b3 685         /**  get the "active" Services of the server from the DB */
039b46 686         $services = $app->db->queryOneRecord('SELECT * FROM server WHERE server_id = ' . $server_id);
eed6b3 687         /*
V 688          * If the DB is down, we have to set the db to "yes".
689          * If we don't do this, then the monitor will NOT monitor, that the db is down and so the
690          * rescue-module can not try to rescue the db
691          */
692         if ($services == null) {
693             $services['db_server'] = 1;
694         }
dead5c 695
V 696         /* The type of the Monitor-data */
697         $type = 'services';
698
699         /** the State of the monitoring */
700         /* ok, if ALL active services are running,
701          * error, if not
702          * There is no other state!
703          */
704         $state = 'ok';
705
706         /* Monitor Webserver */
707         $data['webserver'] = -1; // unknown - not needed
708         if ($services['web_server'] == 1) {
709             if ($this->_checkTcp('localhost', 80)) {
710                 $data['webserver'] = 1;
711             } else {
712                 $data['webserver'] = 0;
713                 $state = 'error'; // because service is down
714             }
715         }
716
717         /* Monitor FTP-Server */
718         $data['ftpserver'] = -1; // unknown - not needed
719         if ($services['file_server'] == 1) {
720             if ($this->_checkFtp('localhost', 21)) {
721                 $data['ftpserver'] = 1;
722             } else {
723                 $data['ftpserver'] = 0;
724                 $state = 'error'; // because service is down
725             }
726         }
727
728         /* Monitor SMTP-Server */
729         $data['smtpserver'] = -1; // unknown - not needed
730         if ($services['mail_server'] == 1) {
731             if ($this->_checkTcp('localhost', 25)) {
732                 $data['smtpserver'] = 1;
733             } else {
734                 $data['smtpserver'] = 0;
735                 $state = 'error'; // because service is down
736             }
737         }
738
739         /* Monitor POP3-Server */
740         $data['pop3server'] = -1; // unknown - not needed
741         if ($services['mail_server'] == 1) {
742             if ($this->_checkTcp('localhost', 110)) {
743                 $data['pop3server'] = 1;
744             } else {
745                 $data['pop3server'] = 0;
746                 $state = 'error'; // because service is down
747             }
748         }
749
750         /* Monitor IMAP-Server */
751         $data['imapserver'] = -1; // unknown - not needed
752         if ($services['mail_server'] == 1) {
753             if ($this->_checkTcp('localhost', 143)) {
754                 $data['imapserver'] = 1;
755             } else {
756                 $data['imapserver'] = 0;
757                 $state = 'error'; // because service is down
758             }
759         }
760
761         /* Monitor BIND-Server */
762         $data['bindserver'] = -1; // unknown - not needed
763         if ($services['dns_server'] == 1) {
dfcd55 764             if ($this->_checkUdp('localhost', 53)) {
dead5c 765                 $data['bindserver'] = 1;
V 766             } else {
767                 $data['bindserver'] = 0;
768                 $state = 'error'; // because service is down
769             }
770         }
771
772         /* Monitor MySQL Server */
773         $data['mysqlserver'] = -1; // unknown - not needed
774         if ($services['db_server'] == 1) {
775             if ($this->_checkTcp('localhost', 3306)) {
776                 $data['mysqlserver'] = 1;
777             } else {
778                 $data['mysqlserver'] = 0;
779                 $state = 'error'; // because service is down
780             }
781         }
def897 782
dead5c 783         /*
V 784          * Return the Result
785          */
786         $res['server_id'] = $server_id;
787         $res['type'] = $type;
788         $res['data'] = $data;
789         $res['state'] = $state;
790         return $res;
791     }
792
793     public function monitorOpenVzHost() {
794         global $app;
795         global $conf;
796
797         /* the id of the server as int */
798         $server_id = intval($conf['server_id']);
799
800         /** The type of the data */
801         $type = 'openvz_veinfo';
802
803         /*
996bad 804             Fetch the data into a array
dead5c 805          */
V 806         $app->load(openvz_tools);
807         $openVzTools = new openvz_tools();
808         $data = $openVzTools->getOpenVzVeInfo();
809
810         /* the VE-Info has no state. It is, what it is */
811         $state = 'no_state';
812
813         /*
814          * Return the Result
815          */
816         $res['server_id'] = $server_id;
817         $res['type'] = $type;
818         $res['data'] = $data;
819         $res['state'] = $state;
820         return $res;
821     }
822
823     public function monitorOpenVzUserBeancounter() {
824         global $app;
825         global $conf;
826
827         /* the id of the server as int */
828         $server_id = intval($conf['server_id']);
829
830         /** The type of the data */
831         $type = 'openvz_beancounter';
832
833         /*
996bad 834             Fetch the data into a array
dead5c 835          */
V 836         $app->load(openvz_tools);
837         $openVzTools = new openvz_tools();
838         $data = $openVzTools->getOpenVzVeBeanCounter();
839
840         /* calculate the state of the beancounter */
841         if ($data == '') {
842             $state = 'no_state';
843         } else {
844             $state = 'ok';
845
846             /* transfer this output-string into a array */
847             $test = explode("\n", $data);
848
849             /* the first list of the output is not needed */
850             array_shift($test);
851
852             /* now process all items of the rest */
853             foreach ($test as $item) {
854                 /*
855                  * eliminate all doubled spaces and spaces at the beginning and end
856                  */
857                 while (strpos($item, '  ') !== false) {
858                     $item = str_replace('  ', ' ', $item);
859                 }
860                 $item = trim($item);
861
862                 /*
863                  * The failcounter is the LAST
864                  */
865                 if ($item != '') {
866                     $tmp = explode(' ', $item);
867                     $failCounter = $tmp[sizeof($tmp) - 1];
868                     if ($failCounter > 0)
869                         $state = 'info';
870                     if ($failCounter > 50)
871                         $state = 'warning';
872                     if ($failCounter > 200)
873                         $state = 'critical';
874                     if ($failCounter > 10000)
875                         $state = 'error';
876                 }
877             }
878         }
879
880         /*
881          * Return the Result
882          */
883         $res['server_id'] = $server_id;
884         $res['type'] = $type;
885         $res['data'] = $data;
886         $res['state'] = $state;
887         return $res;
888     }
889
890     public function monitorSystemUpdate() {
891         global $conf;
892
893         /* the id of the server as int */
894         $server_id = intval($conf['server_id']);
895
896         /** The type of the data */
897         $type = 'system_update';
898
899         /* This monitoring is only available on Debian or Ubuntu */
900         if (file_exists('/etc/debian_version')) {
901
902             /*
903              * first update the "apt database"
904              */
905             shell_exec('apt-get update');
906
907             /*
908              * Then test the upgrade.
909              * if there is any output, then there is a needed update
910              */
911             $aptData = shell_exec('apt-get -s -qq dist-upgrade');
912             if ($aptData == '') {
913                 /* There is nothing to update! */
914                 $state = 'ok';
915             } else {
916                 /*
917                  * There is something to update! this is in most cases not critical, so we can
918                  * do a system-update once a month or so...
919                  */
920                 $state = 'info';
921             }
922
923             /*
924              * Fetch the output
925              */
992797 926             $data['output'] = shell_exec('apt-get -s -q dist-upgrade');
dead5c 927         } elseif (file_exists('/etc/gentoo-release')) {
V 928
929             /*
930              * first update the portage tree
931              */
932
933             // In keeping with gentoo's rsync policy, don't update to frequently (every four hours - taken from http://www.gentoo.org/doc/en/source_mirrors.xml)
934             $do_update = true;
935             if (file_exists('/usr/portage/metadata/timestamp.chk')) {
936                 $datetime = file_get_contents('/usr/portage/metadata/timestamp.chk');
937                 $datetime = trim($datetime);
938
939                 $dstamp = strtotime($datetime);
940                 if ($dstamp) {
941                     $checkat = $dstamp + 14400; // + 4hours
942                     if (mktime() < $checkat) {
943                         $do_update = false;
944                     }
945                 }
946             }
947
948             if ($do_update) {
949                 shell_exec('emerge --sync --quiet');
950             }
951
952             /*
953              * Then test the upgrade.
954              * if there is any output, then there is a needed update
955              */
956             $emergeData = shell_exec('glsa-check -t affected');
957             if ($emergeData == '') {
958                 /* There is nothing to update! */
959                 $state = 'ok';
960                 $data['output'] = 'No unapplied GLSA\'s found on the system.';
961             } else {
962                 /* There is something to update! */
963                 $state = 'info';
964                 $data['output'] = shell_exec('glsa-check -pv --nocolor affected 2>/dev/null');
965             }
def897 966         } elseif (file_exists('/etc/SuSE-release')) {
V 967
968             /*
969              * update and find the upgrade.
970              * if there is any output, then there is a needed update
971              */
972             $aptData = shell_exec('zypper -q lu');
973             if ($aptData == '') {
974                 /* There is nothing to update! */
975                 $state = 'ok';
976             } else {
977                 /*
978                  * There is something to update! this is in most cases not critical, so we can
979                  * do a system-update once a month or so...
980                  */
981                 $state = 'info';
982             }
983
984             /*
985              * Fetch the output
986              */
8cf78b 987             $data['output'] = shell_exec('zypper lu');
dead5c 988         } else {
V 989             /*
990              * It is not Debian/Ubuntu, so there is no data and no state
991              *
992              * no_state, NOT unknown, because "unknown" is shown as state
993              * inside the GUI. no_state is hidden.
994              *
995              * We have to write NO DATA inside the DB, because the GUI
996              * could not know, if there is any dat, or not...
997              */
998             $state = 'no_state';
999             $data['output'] = '';
1000         }
1001
1002         /*
1003          * Return the Result
1004          */
1005         $res['server_id'] = $server_id;
1006         $res['type'] = $type;
1007         $res['data'] = $data;
1008         $res['state'] = $state;
1009         return $res;
1010     }
1011
1012     public function monitorMailQueue() {
1013         global $conf;
1014
1015         /* the id of the server as int */
1016         $server_id = intval($conf['server_id']);
1017
1018         /** The type of the data */
1019         $type = 'mailq';
1020
1021         /* Get the data from the mailq */
1022         $data['output'] = shell_exec('mailq');
1023
1024         /*
1025          *  The last line has more informations
1026          */
1027         $tmp = explode("\n", $data['output']);
1028         $more = $tmp[sizeof($tmp) - 1];
a7b01d 1029         $res = $this->_getIntArray($more);
dead5c 1030         $data['bytes'] = $res[0];
V 1031         $data['requests'] = $res[1];
1032
1033         /** The state of the mailq. */
1034         $state = 'ok';
1035         if ($data['requests'] > 2000)
1036             $state = 'info';
1037         if ($data['requests'] > 5000)
1038             $state = 'warning';
1039         if ($data['requests'] > 8000)
1040             $state = 'critical';
1041         if ($data['requests'] > 10000)
1042             $state = 'error';
1043
1044         /*
1045          * Return the Result
1046          */
1047         $res['server_id'] = $server_id;
1048         $res['type'] = $type;
1049         $res['data'] = $data;
1050         $res['state'] = $state;
1051         return $res;
1052     }
1053
1054     public function monitorRaid() {
1055         global $conf;
1056
1057         /* the id of the server as int */
1058         $server_id = intval($conf['server_id']);
1059
1060         /** The type of the data */
1061         $type = 'raid_state';
1062
1063         /*
1064          * We support several RAID types, but if we can't find any of them, we have no data
1065          */
1066         $state = 'no_state';
1067         $data['output'] = '';
1068
1069         /*
1070          * Check, if Software-RAID is enabled
1071          */
1072         if (file_exists('/proc/mdstat')) {
1073             /*
1074              * Fetch the output
1075              */
1076             $data['output'] = shell_exec('cat /proc/mdstat');
1077
1078             /*
1079              * Then calc the state.
1080              */
1081             $tmp = explode("\n", $data['output']);
1082             $state = 'ok';
1083             for ($i = 0; $i < sizeof($tmp); $i++) {
1084                 /* fetch the next line */
1085                 $line = $tmp[$i];
1086
992797 1087                 if ((strpos($line, 'U_]') !== false) || (strpos($line, '[_U') !== false) || (strpos($line, 'U_U') !== false)) {
dead5c 1088                     /* One Disk is not working.
V 1089                      * if the next line starts with "[>" or "[=" then
1090                      * recovery (resync) is in state and the state is
1091                      * information instead of critical
1092                      */
1093                     $nextLine = $tmp[$i + 1];
1094                     if ((strpos($nextLine, '[>') === false) && (strpos($nextLine, '[=') === false)) {
1095                         $state = $this->_setState($state, 'critical');
1096                     } else {
1097                         $state = $this->_setState($state, 'info');
1098                     }
1099                 }
1100                 if (strpos($line, '[__]') !== false) {
1101                     /* both Disk are not working */
1102                     $state = $this->_setState($state, 'error');
1103                 }
1104                 if (strpos($line, '[UU]') !== false) {
1105                     /* The disks are OK.
1106                      * if the next line starts with "[>" or "[=" then
1107                      * recovery (resync) is in state and the state is
1108                      * information instead of ok
1109                      */
1110                     $nextLine = $tmp[$i + 1];
1111                     if ((strpos($nextLine, '[>') === false) && (strpos($nextLine, '[=') === false)) {
1112                         $state = $this->_setState($state, 'ok');
1113                     } else {
1114                         $state = $this->_setState($state, 'info');
1115                     }
1116                 }
1117             }
1118         }
1119         /*
1120          * Check, if we have mpt-status installed (LSIsoftware-raid)
1121          */
1122         if (file_exists('/proc/mpt/summary')) {
1123             system('which mpt-status', $retval);
1124             if ($retval === 0) {
1125                 /*
1126                  * Fetch the output
1127                  */
dec0df 1128                 $data['output'] = shell_exec('mpt-status --autoload');
dead5c 1129
V 1130                 /*
1131                  * Then calc the state.
1132                  */
1133                 $state = 'ok';
794082 1134                 if(is_array($data['output'])) {
T 1135                     foreach ($data['output'] as $item) {
dead5c 1136                         /*
794082 1137                         * The output contains information for every RAID and every HDD.
T 1138                         * We only need the state of the RAID
1139                         */
dec0df 1140                         if (strpos($item, 'state ') !== false) {
794082 1141                             /*
T 1142                             * We found a raid, process the state of it
1143                             */
1144                             if (strpos($item, ' ONLINE ') !== false) {
1145                                 $this->_setState($state, 'ok');
1146                             } elseif (strpos($item, ' OPTIMAL ') !== false) {
1147                                 $this->_setState($state, 'ok');
1148                             } elseif (strpos($item, ' INITIAL ') !== false) {
1149                                 $this->_setState($state, 'info');
1150                             } elseif (strpos($item, ' INACTIVE ') !== false) {
1151                                 $this->_setState($state, 'critical');
1152                             } elseif (strpos($item, ' RESYNC ') !== false) {
1153                                 $this->_setState($state, 'info');
1154                             } elseif (strpos($item, ' DEGRADED ') !== false) {
1155                                 $this->_setState($state, 'critical');
1156                             } else {
1157                                 /* we don't know the state. so we set the state to critical, that the
1158                                 * admin is warned, that something is wrong
1159                                 */
1160                                 $this->_setState($state, 'critical');
1161                             }
dead5c 1162                         }
V 1163                     }
1164                 }
1165             }
1166         }
996bad 1167
a5fe27 1168         /*
X 1169         * 3ware Controller
1170         */
5fc730 1171         
a5fe27 1172         system('which tw_cli', $retval);
X 1173         if($retval === 0) {
5fc730 1174             
TB 1175             // TYPOWORX FIX | Determine Controler-ID
1176             $availableControlers = shell_exec('tw_cli info | grep -Eo "c[0-9]+');
1177             $data['output'] = shell_exec('tw_cli info ' . $availableControlers);
a5fe27 1178
X 1179             $state = 'ok';
ff6a68 1180             if(is_array($data['output'])) {
7fe908 1181                 foreach ($data['output'] as $item) {
MC 1182                     if (strpos($item, 'RAID') !== false) {
1183                         if (strpos($item, ' VERIFYING ') !== false) {
1184                             $this->_setState($state, 'info');
1185                         }
1186                         else if (strpos($item, ' MIGRATE-PAUSED ') !== false) {
1187                                 $this->_setState($state, 'info');
1188                             }
1189                         else if (strpos($item, ' MIGRATING ') !== false) {
1190                                 $this->_setState($state, 'ok');
1191                             }
1192                         else if (strpos($item, ' INITIALIZING ') !== false) {
1193                                 $this->_setState($state, 'info');
1194                             }
1195                         else if (strpos($item, ' INIT-PAUSED ') !== false) {
1196                                 $this->_setState($state, 'info');
1197                             }
1198                         else if (strpos($item, ' REBUILDING ') !== false) {
1199                                 $this->_setState($state, 'info');
1200                             }
1201                         else if (strpos($item, ' REBUILD-PAUSED ') !== false) {
1202                                 $this->_setState($state, 'warning');
1203                             }
1204                         else if (strpos($item, ' RECOVERY ') !== false) {
1205                                 $this->_setState($state, 'warning');
1206                             }
1207                         else if (strpos($item, ' DEGRADED ') !== false) {
1208                                 $this->_setState($state, 'critical');
1209                             }
1210                         else if (strpos($item, ' UNKNOWN ') !== false) {
1211                                 $this->_setState($state, 'critical');
1212                             }
1213                         else if (strpos($item, ' OK ') !== false) {
1214                                 $this->_setState($state, 'ok');
1215                             }
1216                         else if (strpos($item, ' OPTIMAL ') !== false) {
1217                                 $this->_setState($state, 'ok');
1218                             }
1219                         else {
1220                             $this->_setState($state, 'critical');
1221                         }
a5fe27 1222                     }
X 1223                 }
ff6a68 1224             }
a5fe27 1225         }
996bad 1226
dead5c 1227
V 1228         /*
1229          * Return the Result
1230          */
1231         $res['server_id'] = $server_id;
1232         $res['type'] = $type;
1233         $res['data'] = $data;
1234         $res['state'] = $state;
1235         return $res;
1236     }
1237
1238     public function monitorRkHunter() {
1239         global $conf;
1240
1241         /* the id of the server as int */
1242         $server_id = intval($conf['server_id']);
1243
1244         /** The type of the data */
1245         $type = 'rkhunter';
1246
1247         /* This monitoring is only available if rkhunter is installed */
1248         system('which rkhunter', $retval);
1249         if ($retval === 0) {
1250             /*
1251              * Fetch the output
1252              */
1253             $data['output'] = shell_exec('rkhunter --update --checkall --nocolors --skip-keypress');
1254
1255             /*
1256              * At this moment, there is no state (maybe later)
1257              */
1258             $state = 'no_state';
1259         } else {
1260             /*
1261              * rkhunter is not installed, so there is no data and no state
1262              *
1263              * no_state, NOT unknown, because "unknown" is shown as state
1264              * inside the GUI. no_state is hidden.
1265              *
1266              * We have to write NO DATA inside the DB, because the GUI
1267              * could not know, if there is any dat, or not...
1268              */
1269             $state = 'no_state';
1270             $data['output'] = '';
1271         }
1272
1273         /*
1274          * Return the Result
1275          */
1276         $res['server_id'] = $server_id;
1277         $res['type'] = $type;
1278         $res['data'] = $data;
1279         $res['state'] = $state;
1280         return $res;
1281     }
1282
1283     public function monitorFail2ban() {
1284         global $conf;
1285
1286         /* the id of the server as int */
1287         $server_id = intval($conf['server_id']);
1288
1289         /** The type of the data */
1290         $type = 'log_fail2ban';
1291
1292         /* This monitoring is only available if fail2ban is installed */
1293         system('which fail2ban-client', $retval); // Debian, Ubuntu, Fedora
1294         if ($retval !== 0)
1295             system('which fail2ban', $retval); // CentOS
1296         if ($retval === 0) {
1297             /*  Get the data of the log */
1298             $data = $this->_getLogData($type);
1299
1300             /*
1301              * At this moment, there is no state (maybe later)
1302              */
1303             $state = 'no_state';
1304         } else {
1305             /*
1306              * fail2ban is not installed, so there is no data and no state
2332b2 1307              *
T 1308              * no_state, NOT unknown, because "unknown" is shown as state
1309              * inside the GUI. no_state is hidden.
1310              *
1311              * We have to write NO DATA inside the DB, because the GUI
1312              * could not know, if there is any dat, or not...
1313              */
1314             $state = 'no_state';
1315             $data = '';
1316         }
1317
1318         /*
1319          * Return the Result
1320          */
1321         $res['server_id'] = $server_id;
1322         $res['type'] = $type;
1323         $res['data'] = $data;
1324         $res['state'] = $state;
1325         return $res;
1326     }
1327
28548b 1328     public function monitorIPTables() {
7fe908 1329         global $conf;
28548b 1330
7fe908 1331         /* the id of the server as int */
MC 1332         $server_id = intval($conf['server_id']);
28548b 1333
7fe908 1334         /** The type of the data */
MC 1335         $type = 'iptables_rules';
28548b 1336
7fe908 1337         /* This monitoring is only available if fail2ban is installed */
MC 1338         system('which iptables', $retval); // Debian, Ubuntu, Fedora
1339         if ($retval === 0) {
1340             /*  Get the data of the log */
1341             $data['output'] = '<h2>iptables -S (ipv4)</h2>'.shell_exec('iptables -S 2>/dev/null');
87dd10 1342
7fe908 1343             /*
996bad 1344                          * At this moment, there is no state (maybe later)
M 1345                          */
7fe908 1346             $state = 'no_state';
MC 1347         } else {
1348             $state = 'no_state';
1349             $data = '';
1350         }
28548b 1351
L 1352
7fe908 1353         /* This monitoring is only available if fail2ban is installed */
MC 1354         system('which ip6tables', $retval); // Debian, Ubuntu, Fedora
1355         if ($retval === 0) {
1356             /*  Get the data of the log */
1357             $data['output'] .= '<br><h2>ip6tables -S (ipv6)</h2>'.shell_exec('ip6tables -S 2>/dev/null');
996bad 1358
7fe908 1359             /*
996bad 1360                          * At this moment, there is no state (maybe later)
M 1361                          */
7fe908 1362             $state = 'no_state';
MC 1363         } else {
1364             $state = 'no_state';
1365             $data = '';
1366         }
996bad 1367
7fe908 1368         /*
996bad 1369                  * Return the Result
M 1370                  */
7fe908 1371         $res['server_id'] = $server_id;
MC 1372         $res['type'] = $type;
1373         $res['data'] = $data;
1374         $res['state'] = $state;
1375         return $res;
1376     }
28548b 1377
dead5c 1378     public function monitorSysLog() {
f63bda 1379         global $app;
dead5c 1380         global $conf;
V 1381
1382         /* the id of the server as int */
1383         $server_id = intval($conf['server_id']);
1384
1385         /** The type of the data */
1386         $type = 'sys_log';
1387
1388         /*
1389          * is there any warning or error for this server?
1390          */
1391         $state = 'ok';
1392         $dbData = $app->dbmaster->queryAllRecords('SELECT loglevel FROM sys_log WHERE server_id = ' . $server_id . ' AND loglevel > 0');
1393         if (is_array($dbData)) {
1394             foreach ($dbData as $item) {
1395                 if ($item['loglevel'] == 1)
1396                     $state = $this->_setState($state, 'warning');
1397                 if ($item['loglevel'] == 2)
1398                     $state = $this->_setState($state, 'error');
1399             }
1400         }
1401
1402         /** There is no monitor-data because the data is in the sys_log table */
1403         $data['output'] = '';
1404
1405         /*
1406          * Return the Result
1407          */
1408         $res['server_id'] = $server_id;
1409         $res['type'] = $type;
1410         $res['data'] = $data;
1411         $res['state'] = $state;
1412         return $res;
1413     }
1414
1415     public function monitorMailLog() {
1416         global $conf;
1417
1418         /* the id of the server as int */
1419         $server_id = intval($conf['server_id']);
1420
1421         /** The type of the data */
1422         $type = 'log_mail';
1423
1424         /* Get the data of the log */
1425         $data = $this->_getLogData($type);
1426
1427         /*
1428          * actually this info has no state.
1429          * maybe someone knows better...???...
1430          */
1431         $state = 'no_state';
1432
1433         /*
1434          * Return the Result
1435          */
1436         $res['server_id'] = $server_id;
1437         $res['type'] = $type;
1438         $res['data'] = $data;
1439         $res['state'] = $state;
1440         return $res;
1441     }
1442
1443     public function monitorMailWarnLog() {
1444         global $conf;
1445
1446         /* the id of the server as int */
1447         $server_id = intval($conf['server_id']);
1448
1449         /** The type of the data */
1450         $type = 'log_mail_warn';
1451
1452         /* Get the data of the log */
1453         $data = $this->_getLogData($type);
1454
1455         /*
1456          * actually this info has no state.
1457          * maybe someone knows better...???...
1458          */
1459         $state = 'no_state';
1460
1461         /*
1462          * Return the Result
1463          */
1464         $res['server_id'] = $server_id;
1465         $res['type'] = $type;
1466         $res['data'] = $data;
1467         $res['state'] = $state;
1468         return $res;
1469     }
1470
1471     public function monitorMailErrLog() {
1472         global $conf;
1473
1474         /* the id of the server as int */
1475         $server_id = intval($conf['server_id']);
1476
1477         /** The type of the data */
1478         $type = 'log_mail_err';
1479
1480         /* Get the data of the log */
1481         $data = $this->_getLogData($type);
1482
1483         /*
1484          * actually this info has no state.
1485          * maybe someone knows better...???...
1486          */
1487         $state = 'no_state';
1488
1489         /*
1490          * Return the Result
1491          */
1492         $res['server_id'] = $server_id;
1493         $res['type'] = $type;
1494         $res['data'] = $data;
1495         $res['state'] = $state;
1496         return $res;
1497     }
1498
1499     public function monitorMessagesLog() {
1500         global $conf;
1501
1502         /* the id of the server as int */
1503         $server_id = intval($conf['server_id']);
1504
1505         /** The type of the data */
1506         $type = 'log_messages';
1507
1508         /* Get the data of the log */
1509         $data = $this->_getLogData($type);
1510
1511         /*
1512          * actually this info has no state.
1513          * maybe someone knows better...???...
1514          */
1515         $state = 'no_state';
1516
1517         /*
1518          * Return the Result
1519          */
1520         $res['server_id'] = $server_id;
1521         $res['type'] = $type;
1522         $res['data'] = $data;
1523         $res['state'] = $state;
1524         return $res;
1525     }
1526
1527     public function monitorISPCCronLog() {
1528         global $conf;
1529
1530         /* the id of the server as int */
1531         $server_id = intval($conf['server_id']);
1532
1533         /** The type of the data */
1534         $type = 'log_ispc_cron';
1535
1536         /* Get the data of the log */
1537         $data = $this->_getLogData($type);
1538
1539         /*
1540          * actually this info has no state.
1541          * maybe someone knows better...???...
1542          */
1543         $state = 'no_state';
1544
1545         /*
1546          * Return the Result
1547          */
1548         $res['server_id'] = $server_id;
1549         $res['type'] = $type;
1550         $res['data'] = $data;
1551         $res['state'] = $state;
1552         return $res;
1553     }
1554
1555     public function monitorFreshClamLog() {
1556         global $conf;
1557
1558         /* the id of the server as int */
1559         $server_id = intval($conf['server_id']);
1560
1561         /** The type of the data */
1562         $type = 'log_freshclam';
1563
1564         /* Get the data of the log */
1565         $data = $this->_getLogData($type);
1566
1567         /* Get the data from the LAST log-Entry.
1568          * if there can be found:
1569          * WARNING: Your ClamAV installation is OUTDATED!
1570          * then the clamav is outdated. This is a warning!
1571          */
1572         $state = 'ok';
1573
1574         $tmp = explode("\n", $data);
1575         $lastLog = array();
1576         if ($tmp[sizeof($tmp) - 1] == '') {
1577             /* the log ends with an empty line remove this */
1578             array_pop($tmp);
1579         }
1580         if (strpos($tmp[sizeof($tmp) - 1], '-------------') !== false) {
1581             /* the log ends with "-----..." remove this */
1582             array_pop($tmp);
1583         }
1584         for ($i = sizeof($tmp) - 1; $i > 0; $i--) {
1585             if (strpos($tmp[$i], '---------') === false) {
1586                 /* no delimiter found, so add this to the last-log */
1587                 $lastLog[] = $tmp[$i];
1588             } else {
1589                 /* delimiter found, so there is no more line left! */
1590                 break;
1591             }
1592         }
1593
1594         /*
1595          * Now we have the last log in the array.
1596          * Check if the outdated-string is found...
1597          */
18b050 1598         $clamav_outdated_warning = false;
TB 1599         $clamav_bytecode_updated = false;
dead5c 1600         foreach ($lastLog as $line) {
18b050 1601             if (stristr($line,'outdated')) {
TB 1602                 $clamav_outdated_warning = true;
dead5c 1603             }
18b050 1604             if(stristr($line,'main.cld is up to date')) {
TB 1605                 $clamav_bytecode_updated = true;
1606             }
1607         }
1608         
1609         //* Warn when clamav is outdated and main.cld update failed.
1610         if($clamav_outdated_warning == true && $clamav_bytecode_updated == false) {
1611             $state = $this->_setState($state, 'info');
dead5c 1612         }
V 1613
1614         /*
1615          * Return the Result
1616          */
1617         $res['server_id'] = $server_id;
1618         $res['type'] = $type;
1619         $res['data'] = $data;
1620         $res['state'] = $state;
1621         return $res;
1622     }
1623
1624     public function monitorClamAvLog() {
1625         global $conf;
1626
1627         /* the id of the server as int */
1628         $server_id = intval($conf['server_id']);
1629
1630         /** The type of the data */
1631         $type = 'log_clamav';
1632
1633         /* Get the data of the log */
1634         $data = $this->_getLogData($type);
1635
1636         // Todo: the state should be calculated.
1637         $state = 'ok';
1638
1639         /*
1640          * Return the Result
1641          */
1642         $res['server_id'] = $server_id;
1643         $res['type'] = $type;
1644         $res['data'] = $data;
1645         $res['state'] = $state;
1646         return $res;
1647     }
1648
1649     public function monitorIspConfigLog() {
1650         global $conf;
1651
1652         /* the id of the server as int */
1653         $server_id = intval($conf['server_id']);
1654
1655         /** The type of the data */
1656         $type = 'log_ispconfig';
1657
1658         /* Get the data of the log */
1659         $data = $this->_getLogData($type);
1660
1661         // Todo: the state should be calculated.
1662         $state = 'ok';
1663
1664         /*
1665          * Return the Result
1666          */
1667         $res['server_id'] = $server_id;
1668         $res['type'] = $type;
1669         $res['data'] = $data;
1670         $res['state'] = $state;
1671         return $res;
1672     }
1673
1674     public function _getLogData($log) {
1675         global $conf;
1676
1677         $dist = '';
1678         $logfile = '';
1679
1680         if (@is_file('/etc/debian_version')) {
1681             $dist = 'debian';
1682         } elseif (@is_file('/etc/redhat-release')) {
1683             $dist = 'redhat';
1684         } elseif (@is_file('/etc/SuSE-release')) {
1685             $dist = 'suse';
1686         } elseif (@is_file('/etc/gentoo-release')) {
1687             $dist = 'gentoo';
1688         }
1689
1690         switch ($log) {
7fe908 1691         case 'log_mail':
MC 1692             if ($dist == 'debian') {
1693                 $logfile = '/var/log/mail.log';
1694             } elseif ($dist == 'redhat') {
1695                 $logfile = '/var/log/maillog';
1696             } elseif ($dist == 'suse') {
1697                 $logfile = '/var/log/mail.info';
1698             } elseif ($dist == 'gentoo') {
1699                 $logfile = '/var/log/maillog';
1700             }
1701             break;
1702         case 'log_mail_warn':
1703             if ($dist == 'debian') {
1704                 $logfile = '/var/log/mail.warn';
1705             } elseif ($dist == 'redhat') {
1706                 $logfile = '/var/log/maillog';
1707             } elseif ($dist == 'suse') {
1708                 $logfile = '/var/log/mail.warn';
1709             } elseif ($dist == 'gentoo') {
1710                 $logfile = '/var/log/maillog';
1711             }
1712             break;
1713         case 'log_mail_err':
1714             if ($dist == 'debian') {
1715                 $logfile = '/var/log/mail.err';
1716             } elseif ($dist == 'redhat') {
1717                 $logfile = '/var/log/maillog';
1718             } elseif ($dist == 'suse') {
1719                 $logfile = '/var/log/mail.err';
1720             } elseif ($dist == 'gentoo') {
1721                 $logfile = '/var/log/maillog';
1722             }
1723             break;
1724         case 'log_messages':
1725             if ($dist == 'debian') {
1726                 $logfile = '/var/log/syslog';
1727             } elseif ($dist == 'redhat') {
1728                 $logfile = '/var/log/messages';
1729             } elseif ($dist == 'suse') {
1730                 $logfile = '/var/log/messages';
1731             } elseif ($dist == 'gentoo') {
1732                 $logfile = '/var/log/messages';
1733             }
1734             break;
1735         case 'log_ispc_cron':
1736             if ($dist == 'debian') {
1737                 $logfile = $conf['ispconfig_log_dir'] . '/cron.log';
1738             } elseif ($dist == 'redhat') {
1739                 $logfile = $conf['ispconfig_log_dir'] . '/cron.log';
1740             } elseif ($dist == 'suse') {
1741                 $logfile = $conf['ispconfig_log_dir'] . '/cron.log';
1742             } elseif ($dist == 'gentoo') {
1743                 $logfile = '/var/log/cron';
1744             }
1745             break;
1746         case 'log_freshclam':
1747             if ($dist == 'debian') {
1748                 $logfile = '/var/log/clamav/freshclam.log';
1749             } elseif ($dist == 'redhat') {
1750                 $logfile = (is_file('/var/log/clamav/freshclam.log') ? '/var/log/clamav/freshclam.log' : '/var/log/freshclam.log');
1751             } elseif ($dist == 'suse') {
1752                 $logfile = '/var/log/freshclam.log';
1753             } elseif ($dist == 'gentoo') {
1754                 $logfile = '/var/log/clamav/freshclam.log';
1755             }
1756             break;
1757         case 'log_clamav':
1758             if ($dist == 'debian') {
1759                 $logfile = '/var/log/clamav/clamav.log';
1760             } elseif ($dist == 'redhat') {
1761                 $logfile = (is_file('/var/log/clamav/clamd.log') ? '/var/log/clamav/clamd.log' : '/var/log/maillog');
1762             } elseif ($dist == 'suse') {
1763                 $logfile = '/var/log/clamd.log';
1764             } elseif ($dist == 'gentoo') {
1765                 $logfile = '/var/log/clamav/clamd.log';
1766             }
1767             break;
1768         case 'log_fail2ban':
1769             if ($dist == 'debian') {
1770                 $logfile = '/var/log/fail2ban.log';
1771             } elseif ($dist == 'redhat') {
1772                 $logfile = '/var/log/fail2ban.log';
1773             } elseif ($dist == 'suse') {
1774                 $logfile = '/var/log/fail2ban.log';
1775             } elseif ($dist == 'gentoo') {
1776                 $logfile = '/var/log/fail2ban.log';
1777             }
1778             break;
1779         case 'log_ispconfig':
1780             if ($dist == 'debian') {
1781                 $logfile = $conf['ispconfig_log_dir'] . '/ispconfig.log';
1782             } elseif ($dist == 'redhat') {
1783                 $logfile = $conf['ispconfig_log_dir'] . '/ispconfig.log';
1784             } elseif ($dist == 'suse') {
1785                 $logfile = $conf['ispconfig_log_dir'] . '/ispconfig.log';
1786             } elseif ($dist == 'gentoo') {
1787                 $logfile = $conf['ispconfig_log_dir'] . '/ispconfig.log';
1788             }
1789             break;
1790         default:
1791             $logfile = '';
1792             break;
dead5c 1793         }
V 1794
1795         // Getting the logfile content
1796         if ($logfile != '') {
1797             $logfile = escapeshellcmd($logfile);
1798             if (stristr($logfile, ';') or substr($logfile, 0, 9) != '/var/log/' or stristr($logfile, '..')) {
1799                 $log = 'Logfile path error.';
1800             } else {
1801                 $log = '';
1802                 if (is_readable($logfile)) {
1803                     $fd = popen('tail -n 100 ' . $logfile, 'r');
1804                     if ($fd) {
1805                         while (!feof($fd)) {
1806                             $log .= fgets($fd, 4096);
1807                             $n++;
1808                             if ($n > 1000)
1809                                 break;
1810                         }
1811                         fclose($fd);
1812                     }
1813                 } else {
1814                     $log = 'Unable to read ' . $logfile;
1815                 }
1816             }
1817         }
1818
1819         return $log;
1820     }
1821
1822     private function _checkTcp($host, $port) {
e5c5af 1823         /* Try to open a connection */
dead5c 1824         $fp = @fsockopen($host, $port, $errno, $errstr, 2);
V 1825
1826         if ($fp) {
8bbcc1 1827             /*
e5c5af 1828              * We got a connection, this means, everything is O.K.
V 1829              * But maybe we are able to do more deep testing?
8bbcc1 1830              */
e5c5af 1831             if ($port == 80) {
V 1832                 /*
1833                  * Port 80 means, testing APACHE
1834                  * So we can do a deepter test and try to get data over this connection.
1835                  * (if apache hangs, we get a connection but a timeout by trying to GET the data!)
1836                  */
8cf78b 1837                 // fwrite($fp, "GET / HTTP/1.0\r\n\r\n");
T 1838                 $out = "GET / HTTP/1.1\r\n";
1839                 $out .= "Host: localhost\r\n";
1840                 $out .= "User-Agent: Mozilla/5.0 (ISPConfig monitor)\r\n";
1841                 $out .= "Accept: application/xml,application/xhtml+xml,text/html\r\n";
1842                 $out .= "Connection: Close\r\n\r\n";
1843                 fwrite($fp, $out);
e5c5af 1844                 stream_set_timeout($fp, 5); // Timeout after 5 seconds
V 1845                 $res = fread($fp, 10);  // try to get 10 bytes (enough to test!)
1846                 $info = stream_get_meta_data($fp);
1847                 if ($info['timed_out']) {
1848                     return false; // Apache was not able to send data over this connection
1849                 }
eed6b3 1850             }
e5c5af 1851
V 1852             /* The connection is no longer needed */
1853             fclose($fp);
1854             /* We are able to establish a connection */
1855             return true;
dead5c 1856         } else {
e5c5af 1857             /* We are NOT able to establish a connection */
V 1858             return false;
dead5c 1859         }
V 1860     }
1861
1862     private function _checkUdp($host, $port) {
1863
1864         $fp = @fsockopen('udp://' . $host, $port, $errno, $errstr, 2);
1865
1866         if ($fp) {
1867             fclose($fp);
1868             return true;
1869         } else {
1870             return false;
1871         }
1872     }
1873
1874     private function _checkFtp($host, $port) {
1875
1876         $conn_id = @ftp_connect($host, $port);
1877
1878         if ($conn_id) {
1879             @ftp_close($conn_id);
1880             return true;
1881         } else {
1882             return false;
1883         }
1884     }
eed6b3 1885
e5c5af 1886     /**
V 1887      * Set the state to the given level (or higher, but not lesser).
1888      * * If the actual state is critical and you call the method with ok,
1889      *   then the state is critical.
1890      *
1891      * * If the actual state is critical and you call the method with error,
1892      *   then the state is error.
1893      */
1894     private function _setState($oldState, $newState) {
1895         /*
1896          * Calculate the weight of the old state
1897          */
1898         switch ($oldState) {
7fe908 1899         case 'no_state': $oldInt = 0;
MC 1900             break;
1901         case 'ok': $oldInt = 1;
1902             break;
1903         case 'unknown': $oldInt = 2;
1904             break;
1905         case 'info': $oldInt = 3;
1906             break;
1907         case 'warning': $oldInt = 4;
1908             break;
1909         case 'critical': $oldInt = 5;
1910             break;
1911         case 'error': $oldInt = 6;
1912             break;
e5c5af 1913         }
V 1914         /*
1915          * Calculate the weight of the new state
1916          */
1917         switch ($newState) {
7fe908 1918         case 'no_state': $newInt = 0;
MC 1919             break;
1920         case 'ok': $newInt = 1;
1921             break;
1922         case 'unknown': $newInt = 2;
1923             break;
1924         case 'info': $newInt = 3;
1925             break;
1926         case 'warning': $newInt = 4;
1927             break;
1928         case 'critical': $newInt = 5;
1929             break;
1930         case 'error': $newInt = 6;
1931             break;
e5c5af 1932         }
V 1933
1934         /*
1935          * Set to the higher level
1936          */
1937         if ($newInt > $oldInt) {
1938             return $newState;
1939         } else {
1940             return $oldState;
1941         }
1942     }
dead5c 1943
V 1944     private function _getIntArray($line) {
7fe908 1945
dead5c 1946         /** The array of float found */
V 1947         $res = array();
1948         /* First build a array from the line */
1949         $data = explode(' ', $line);
1950         /* then check if any item is a float */
1951         foreach ($data as $item) {
1952             if ($item . '' == (int) $item . '') {
1953                 $res[] = $item;
1954             }
1955         }
1956         return $res;
1957     }
1958
1959 }
1960
7fe908 1961 ?>