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