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