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