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