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