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