diff --git a/public_html/appmonitor/check-appmonitor-server.php b/public_html/appmonitor/check-appmonitor-server.php new file mode 100644 index 0000000000000000000000000000000000000000..35bd349c19fbc23d7ad74f95f86ca27976a372a1 --- /dev/null +++ b/public_html/appmonitor/check-appmonitor-server.php @@ -0,0 +1,45 @@ +<?php +/* ______________________________________________________________________ + * + * A P P M O N I T O R :: CLIENT - CHECK + * ______________________________________________________________________ + * + * This is the check file for the appmonitor server installation + * Have a look to the docs/client-php.md and index.sample.php + * to write your own checks + * + * @author: Axel Hahn + * ---------------------------------------------------------------------- + * 2019-04-29 aded check for ssl cert; removed a check + * 2019-05-17 aded check http to config- and tmp dir + * 2021-11-nn removed all checks ... created as single files + * 2022-03-28 put checks into plugins/apps/ + */ + +$sApproot = str_replace('\\', '/', dirname(__DIR__)); + +require_once($sApproot.'/client/classes/appmonitor-client.class.php'); + +// require_once('classes/client_all_in_one.php'); +$oMonitor = new appmonitor(); +$oMonitor->setWebsite('Appmonitor server'); + +// how often the server should ask for updates +$oMonitor->setTTL(300); +$oMonitor->addTag('monitoring'); + + +// a general include ... the idea is to a file with the same actions on all +// installations and hosts that can be deployed by a software delivery service +// (Puppet, Ansible, ...) +@include 'general_include.php'; + +// include default checks for an application +@require 'plugins/apps/iml-appmonitor-server.php'; + +// ---------------------------------------------------------------------- + +$oMonitor->setResult(); +$oMonitor->render(); + +// ---------------------------------------------------------------------- diff --git a/public_html/appmonitor/classes/appmonitor-client.class.php b/public_html/appmonitor/classes/appmonitor-client.class.php index ec21adcff914a8cfe77327899dff1edfab3c4311..711c8e457f2bdd56708d42c8d2a611d6d8a1cf4f 100644 --- a/public_html/appmonitor/classes/appmonitor-client.class.php +++ b/public_html/appmonitor/classes/appmonitor-client.class.php @@ -32,15 +32,16 @@ if (!class_exists('appmonitorcheck')){ * --------------------------------------------------------------------------------<br> * <br> * --- HISTORY:<br> - * 2014-10-24 0.5 axel.hahn@iml.unibe.ch<br> - * 2014-11-21 0.6 axel.hahn@iml.unibe.ch removed meta::ts <br> - * 2018-08-23 0.50 axel.hahn@iml.unibe.ch show version<br> - * 2018-08-24 0.51 axel.hahn@iml.unibe.ch method to show local status page<br> - * 2018-08-27 0.52 axel.hahn@iml.unibe.ch add pdo connect (starting with mysql)<br> - * 2018-11-05 0.58 axel.hahn@iml.unibe.ch additional flag in http check to show content<br> - * 2019-05-31 0.87 axel.hahn@iml.unibe.ch add timeout as param in connective checks (http, tcp, databases)<br> + * 2014-10-24 0.5 axel.hahn@iml.unibe.ch<br> + * 2014-11-21 0.6 axel.hahn@iml.unibe.ch removed meta::ts <br> + * 2018-08-23 0.50 axel.hahn@iml.unibe.ch show version<br> + * 2018-08-24 0.51 axel.hahn@iml.unibe.ch method to show local status page<br> + * 2018-08-27 0.52 axel.hahn@iml.unibe.ch add pdo connect (starting with mysql)<br> + * 2018-11-05 0.58 axel.hahn@iml.unibe.ch additional flag in http check to show content<br> + * 2019-05-31 0.87 axel.hahn@iml.unibe.ch add timeout as param in connective checks (http, tcp, databases)<br> + * 2020-05-03 0.110 axel.hahn@iml.unibe.ch update renderHtmloutput<br> * --------------------------------------------------------------------------------<br> - * @version 0.99 + * @version 0.111 * @author Axel Hahn * @link TODO * @license GPL @@ -54,7 +55,7 @@ class appmonitor { * value is in seconds * @var int */ - protected $_sVersion = 'php-client-v0.109'; + protected $_sVersion = 'php-client-v0.111'; /** * config: default ttl for server before requesting the client check again @@ -481,34 +482,44 @@ class appmonitor { . '</div>' . 'Host: ' . (isset($aData['meta']['host']) ? '<span class="string">' . $aData['meta']['host'] .'</span>' : '?').'<br>' . 'Website: ' . (isset($aData['meta']['website']) ? '<span class="string">' . $aData['meta']['website'].'</span>' : '?').'<br>' - // . 'Status: ' . (isset($aData['meta']['result']) ? '<span class="result'.$aData['meta']['result'].'">'. $aMsg[$aData['meta']['result']].'</span>' : '?').'<br>' . 'Execution time: ' . (isset($aData['meta']['time']) ? '<span class="float">' . $aData['meta']['time'] .'</span>' : '?').'<br>' + . 'Client: ' . (isset($aData['meta']['version']) ? '<span class="float">' . $aData['meta']['version'] .'</span>' : '?').'<br>' .'<h2>Checks</h2>' ; if (isset($aData['checks'][0]) && count($aData['checks'])){ foreach($aData['checks'] as $aCheck){ - $sOut.= '<span class="result'.$aCheck['result'].'"> <strong>'.$aCheck['name'].'</strong></span> <br>' - . $aCheck['description'].'<br>' - // . '<span class="result'.$aCheck['result'].'">'.$aCheck['value'].'</span><br>' - . $aCheck['value'].'<br>' - . 'Execution time: ' . $aCheck['time'].'<br>' - . 'Status: ' . $aMsg[$aCheck['result']].'<br>' - . '<br>' + $sOut.= '' + . '<span class="result'.$aCheck['result'].'"> <strong>'.$aCheck['name'].'</strong></span> <br>' + . '<div class="check">' + . '<div class="description">' + . $aCheck['description'].'<br>' + . $aCheck['value'].'<br>' + . '</div>' + . 'Execution time: ' . (isset($aCheck['time']) ? $aCheck['time'] : ' - ').'<br>' + . 'Group: ' . (isset($aCheck['group']) ? $aCheck['group'] : '-').'<br>' + . 'parent: ' . (isset($aCheck['parent']) ? $aCheck['parent']: '-').'<br>' + . 'Status: ' . $aMsg[$aCheck['result']].'<br>' + . '</div>' ; } } - $sOut.= '<hr>List of farbcodes: '; + $sOut.= '<h2>List of farbcodes</h2>'; foreach ($aMsg as $i=>$sText){ $sOut.= '<span class="result'.$i.'">'. $sText.'</span> '; } + $sOut.='<h2>Raw result data</h2><pre>'.json_encode($aData, JSON_PRETTY_PRINT).'</pre>'; $sOut = '<!DOCTYPE html><html><head>' . '<style>' . 'body{background:#fff; color:#444; font-family: verdana,arial; margin: 3em;}' - . '.result0{background:#aca; border-left: 1em solid #080; padding: 0 0.5em; }' - . '.result1{background:#ccc; border-left: 1em solid #aaa; padding: 0 0.5em; }' - . '.result2{background:#fc9; border-left: 1em solid #860; padding: 0 0.5em; }' - . '.result3{background:#f88; border-left: 1em solid #f00; padding: 0 0.5em; }' + . 'h1{color:#346;}' + . 'h2{color:#569; margin-top: 1.5em;}' + . '.check{border: 1px solid; padding: 0.4em; margin-bottom: 2em;}' + . '.description{font-style: italic; padding: 0.4em 1em;}' + . '.result0{background:#aca; border-left: 1em solid #080; padding: 0.5em; }' + . '.result1{background:#ccc; border-left: 1em solid #aaa; padding: 0.5em; }' + . '.result2{background:#fc9; border-left: 1em solid #860; padding: 0.5em; }' + . '.result3{background:#f88; border-left: 1em solid #f00; padding: 0.5em; }' . '</style>' . '<title>' . __CLASS__ . '</title>' . '</head><body>' diff --git a/public_html/appmonitor/example.json b/public_html/appmonitor/example.json deleted file mode 100644 index b856bf639168b05d9db88cbf7d02e2183a19ae4c..0000000000000000000000000000000000000000 --- a/public_html/appmonitor/example.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "meta": { - "host": "my-computer", - "website": "localhost", - "ttl": 300, - "result": 1 - }, - "checks": [ - { - "name": "simple ok", - "description": "Very simple test", - "result": 0, - "value": "The appmonitor client is reachable." - }, - { - "name": "simple unknown", - "description": "a dummy test with unknown status", - "result": 1, - "value": "any message" - }, - { - "name": "simple warning", - "description": "a dummy warning", - "result": 2, - "value": "warning message" - }, - { - "name": "dummy error", - "description": "a dummy error test", - "result": 3, - "value": "ERROR: the error message was not found" - } - ] -} \ No newline at end of file diff --git a/public_html/appmonitor/general_include.sample.php b/public_html/appmonitor/general_include.sample.php deleted file mode 100644 index f5ebae3bc79239323bd852a7089391aca87c881f..0000000000000000000000000000000000000000 --- a/public_html/appmonitor/general_include.sample.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/* ______________________________________________________________________ - * - * A P P M O N I T O R :: CLIENT - CHECK :: GENERAL INCLUDE - * ______________________________________________________________________ - * - * The idea behind is to a file with the same actions on all your - * installations and hosts that can be deployed by a software delivery service - * (Puppet, Ansible, ...) - * - * Instruction: - * (1) copy sample file to general_include.php and enable wished features below - * (2) in your checks enable it by - * @include 'general_include.php'; - * see index.sample.php too - * - * @author: Axel Hahn - * ---------------------------------------------------------------------- - * 2018-06-30 v0.1 - */ - -// ---------------------------------------------------------------------- -// SECURITY STUFF ... protect access to monitoring data -// ---------------------------------------------------------------------- - -// --- check an IP range of allowed clients -/* -$oMonitor->checkIp(array( - '127.0.0.1', - '::1', - '192.168.', -)); - */ - -// --- check a token -// an incoming request must have the param ?token=123 -// $oMonitor->checkToken('token', '123'); - - -// ---------------------------------------------------------------------- -// NOTIFICATION -// ---------------------------------------------------------------------- - -// $oMonitor->addEmail('sysadmin@example.com'); -// $oMonitor->addSlackWebhook(array("mywebhook"=> "https://hooks.slack.com/services/(...)")); - diff --git a/public_html/appmonitor/git_update_appmonitor.sh b/public_html/appmonitor/git_update_appmonitor.sh new file mode 100644 index 0000000000000000000000000000000000000000..fdc069e9af8ee466adb82c9be0e220efa504cd5d --- /dev/null +++ b/public_html/appmonitor/git_update_appmonitor.sh @@ -0,0 +1,175 @@ +#!/bin/bash +# ====================================================================== +# +# UPDATE APPMONITOR CLIENT +# +# requires git, rsync +# +# ---------------------------------------------------------------------- +# 2022-04-11 <axel.hahn@iml.unibe.ch> first lines +# 2022-04-12 <axel.hahn@iml.unibe.ch> add help; exclude unneeded files +# 2022-05-03 <axel.hahn@iml.unibe.ch> create general_include.php +# ====================================================================== + +# ---------------------------------------------------------------------- +# CONFIG +# ---------------------------------------------------------------------- + +readonly git_repo_url="https://github.com/iml-it/appmonitor.git" +readonly line="____________________________________________________________" +readonly version="0.3" + +git_target=/tmp/git_data__appmonitor +client_from="${git_target}/public_html/client" +client_to="." + +cd $( dirname "$0" ) || exit 1 + +# ---------------------------------------------------------------------- +# FUNCTIONS +# ---------------------------------------------------------------------- + +# Create a missing file from sample file +# +# global $client_from source dir with git repo data +# global $client_to target dir +# +# param string source file (containing .sample); relative to $client_from +function _fileupdate(){ + local _myfile=$1 + local _newfile=${_myfile//.sample/} + echo -n "Update $client_from/$_myfile --> $client_to/$_newfile ... " + + if [ ! -f "$client_to/$_newfile" ]; then + echo -n "copy ... " + cp "$client_from/$_myfile" "$client_to/$_newfile" || exit 2 + echo "OK" + else + echo "already exists - SKIP " + fi + +} + +# get data from a repo with git clone or git pull +# param string url of public .git repo +# param string local directory where to clone it +function _gitUpdate(){ + local _url=$1 + local _dirgit=$2 + local _rc=0 + if [ -d "$_dirgit" ]; then + cd "$_dirgit" || exit 1 + _logBefore=$( git log -1 ); + echo "Update local data from repo... with git pull " + git pull + _logAfter=$( git log -1 ); + if [ "$_logBefore" != "$_logAfter" ]; then + _rc=1 + fi + cd - >/dev/null || exit 1 + else + echo "Cloning..." + git clone "$_url" "$_dirgit" + _rc=$? + fi + return $_rc +} + + +# ---------------------------------------------------------------------- +# MAIN +# ---------------------------------------------------------------------- + +cat <<ENDOFHEADER + + +-----------------------------------+ + | | + | INSTALLER | | + | + | Appmonitor client | + | UPDATER | | + | | + +--------------------------- v$version --+ + +ENDOFHEADER + +case "$1" in + -h|--help) + cat <<ENDOFHELP + + This is a helper script to get the files of the IML Appmonitor + client part only. + + This script clones and updates the repository in the /tmp + directory and syncs the client files of it to a given directory. + + In the first run it works like an installer. + On additional runs it updates the files. + + USAGE: + + $0 [target path] + + default target is [.] (current directory) + + $0 -h|--help + + Show this help. + +ENDOFHELP + exit 0 + ;; + *) + if test -n "$1" + then + if ! test -d "$1" + then + echo "ERROR: target dir [$1] does not exist." + exit 1 + fi + echo "set target to $1" + client_to="$1" + fi +esac + +which rsync >/dev/null || exit 1 +which git >/dev/null || exit 1 + +echo $line +echo ">>> #1 of 3 >>> update local git data" +echo +echo "URL $git_repo_url" +echo "TO $git_target" +if ! _gitUpdate "$git_repo_url" "$git_target" +then + echo ERROR occured :-/ + exit 1 +fi +echo + + +echo $line +echo ">>> #2 of 3 >>> Sync files of Appmonitor client" +echo +echo "FROM $client_from/*" +echo "TO $client_to" +rsync -rav \ + --exclude "build" \ + --exclude "*.sample.*" \ + --exclude "example.json" \ + --exclude "check-appmonitor-server.php" \ + $client_from/* "$client_to" +echo + +_fileupdate general_include.sample.php + +echo $line +echo ">>> #3 of 3 >>> Diff" +echo +diff -r "$client_from" "$client_to" +echo + + +echo $line +echo done. + +# ---------------------------------------------------------------------- diff --git a/public_html/appmonitor/index.sample.php b/public_html/appmonitor/index.sample.php deleted file mode 100644 index e3894bb4a0714724714b574d0236845557e1c977..0000000000000000000000000000000000000000 --- a/public_html/appmonitor/index.sample.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php -/* ______________________________________________________________________ - * - * A P P M O N I T O R :: CLIENT - CHECK :: SAMPLE - * ______________________________________________________________________ - * - * this is a sample file for the appmonitor client - * copy the sample file to index.php and modify it as needed (see ../readme.md). - * - */ - -require_once('classes/appmonitor-client.class.php'); -$oMonitor = new appmonitor(); - -// set a name with application name and environment or hostname -$oMonitor->setWebsite('[My CMS on host XY]'); - -// how often the server should ask for updates -$oMonitor->setTTL(300); - -// a general include ... the idea is to a file with the same actions on all -// installations and hosts that can be deployed by a software delivery service -// (Puppet, Ansible, ...) -@include 'general_include.php'; - -// add any tag to add it in the filter list in the server web gui -// $oMonitor->addTag('cms'); -// $oMonitor->addTag('production'); - -// ---------------------------------------------------------------------- - -// include default checks for an application -// @require 'plugins/apps/[name-of-app].php'; - -// add a few custom checks -// $oMonitor->addCheck(...) -$oMonitor->addCheck( - array( - "name" => "hello plugin", - "description" => "Test a plugin ... plugins/checks/hello.php", - "check" => array( - "function" => "Hello", - "params" => array( - "message" => "Here I am", - ), - ), - ) -); - -// ---------------------------------------------------------------------- - -$oMonitor->setResult(); -$oMonitor->render(); - -// ---------------------------------------------------------------------- diff --git a/public_html/appmonitor/plugins/apps/iml-appmonitor-server.php b/public_html/appmonitor/plugins/apps/iml-appmonitor-server.php index 603be84aa5f1c778173c701f4501a238c1a50bac..d4e9614be774e3530791c6541d72bc211a854bd2 100644 --- a/public_html/appmonitor/plugins/apps/iml-appmonitor-server.php +++ b/public_html/appmonitor/plugins/apps/iml-appmonitor-server.php @@ -64,6 +64,22 @@ $oMonitor->addCheck( ), ) ); + +$oMonitor->addCheck( + array( + "name" => "PHP modules", + "description" => "Check needed PHP modules", + // "group" => "folder", + "check" => array( + "function" => "Phpmodules", + "params" => array( + "required" => ["curl"], + "optional" => [], + ), + ), + ) +); + // ---------------------------------------------------------------------- // protect dirs against web access // specialty: if the test results in an error, the total result switches diff --git a/public_html/appmonitor/plugins/checks/cert.php b/public_html/appmonitor/plugins/checks/cert.php index f75e60b877735da9f840a9a5c776c4c0d2f4e6e6..ec5cca3331719fcdc170ad2bc92ba4a514702f30 100644 --- a/public_html/appmonitor/plugins/checks/cert.php +++ b/public_html/appmonitor/plugins/checks/cert.php @@ -29,7 +29,7 @@ * "function" => "Cert", * "params" => array( * "url" => "https://www.example.com", - * "warning" => "21", + * "warning" => "30", * ), * ), * ) @@ -37,6 +37,8 @@ * ____________________________________________________________________________ * * 2021-10-26 <axel.hahn@iml.unibe.ch> + * 2022-05-02 <axel.hahn@iml.unibe.ch> set warning to 21 days (old value was 30); add "critical" param + * 2022-05-03 <axel.hahn@iml.unibe.ch> critical limit is a warning only (because app is still functional) * */ class checkCert extends appmonitorcheck{ @@ -55,7 +57,8 @@ class checkCert extends appmonitorcheck{ * array( * "url" optional: url to connect check; default: own protocol + server * "verify" optional: flag for verification of certificate or check for expiration only; default=true (=verification is on) - * "warning" optional: count of days to warn; default=30 + * "warning" optional: count of days to warn; default=21 (=3 weeks) + * "critical" optional: count of days to raise critical; default=5 * ) * @return boolean */ @@ -64,8 +67,9 @@ class checkCert extends appmonitorcheck{ ? $aParams["url"] : 'http'. ($_SERVER['HTTPS'] ? 's' : '') . '://' . $_SERVER['SERVER_NAME'] .':' . $_SERVER['SERVER_PORT'] ; - $bVerify = isset($aParams["verify"]) ? !!$aParams["verify"] : true; - $iWarn = isset($aParams["warning"]) ? (int)($aParams["warning"]) : 30; + $bVerify = isset($aParams["verify"]) ? !!$aParams["verify"] : true; + $iWarn = isset($aParams["warning"]) ? (int)($aParams["warning"]) : 21; + $iCrtitcal = isset($aParams["critical"]) ? (int)($aParams["critical"]) : 5; $sMessage="Checked url: $sUrl ... "; $certinfo=$this->_certGetInfos($sUrl, $bVerify); @@ -91,7 +95,7 @@ class checkCert extends appmonitorcheck{ . ' to '.date("Y-m-d H:i", $certinfo['validTo_time_t']).' ' . ( $iDaysleft ? "($iDaysleft days left)" : "expired since ".(-$iDaysleft)." days.") ; - if ($iDaysleft<0) { + if ($iDaysleft<=0) { return [ RESULT_ERROR, 'Expired! ' . $sMessage @@ -100,7 +104,10 @@ class checkCert extends appmonitorcheck{ if ($iDaysleft<=$iWarn) { return [ RESULT_WARNING, - 'Expires soon. ' . $sMessage + ($iDaysleft<=$iCrtitcal + ? 'Expires very soon! ' + : 'Expires soon. ' + ). $sMessage ]; } // echo '<pre>'; diff --git a/public_html/appmonitor/plugins/checks/phpmodules.php b/public_html/appmonitor/plugins/checks/phpmodules.php new file mode 100644 index 0000000000000000000000000000000000000000..6f40ba054819294542910d2826f25db6a384b42a --- /dev/null +++ b/public_html/appmonitor/plugins/checks/phpmodules.php @@ -0,0 +1,88 @@ +<?php +/** + * ____________________________________________________________________________ + * + * _____ _____ __ _____ _ _ + * | | | | ___ ___ ___| |___ ___|_| |_ ___ ___ + * |- -| | | | |__ | .'| . | . | | | | . | | | _| . | _| + * |_____|_|_|_|_____| |__,| _| _|_|_|_|___|_|_|_|_| |___|_| + * |_| |_| + * _ _ _ + * ___| |_|___ ___| |_ + * | _| | | -_| | _| + * |___|_|_|___|_|_|_| + * + * ____________________________________________________________________________ + * + * CHECK IF NEEDED PHP MODULES ARE INSTALLED + * ____________________________________________________________________________ + * + * 2022-05-06 <axel.hahn@iml.unibe.ch> first lines + * + */ +class checkPhpmodules extends appmonitorcheck{ + /** + * get default group of this check + * @param array $aParams + * @return array + */ + public function getGroup(){ + return 'service'; + } + + /** + * check if system is listening to a given port + * @param array $aParams + * array( + * required array list of required php modules + * optional array optional: list of optional php modules + * ) + * @return boolean + */ + public function run($aParams) { + $sOut=''; + $bHasError=false; + $bHasWarning=false; + // $this->_checkArrayKeys($aParams, "required"); + + // --- get all modules + $aAllMods=get_loaded_extensions(false); + + // --- check required modules + if(isset($aParams['required']) && count($aParams['required'])){ + $sOut.='Required: '; + foreach($aParams['required'] as $sMod){ + $sOut.=$sMod.'='; + if(!array_search($sMod, $aAllMods)===false){ + $sOut.='OK;'; + } else { + $bHasError=true; + $sOut.='MISS;'; + } + } + } + // --- check optional modules + if(isset($aParams['optional']) && count($aParams['optional'])){ + $sOut.=($sOut ? '|' : '') . 'Optional: '; + foreach($aParams['optional'] as $sMod){ + $sOut.=$sMod.'='; + if(!array_search($sMod, $aAllMods)===false){ + $sOut.='OK;'; + } else { + $bHasWarning=true; + $sOut.='MISS;'; + } + } + } + + // --- return result + if($bHasError){ + return [RESULT_ERROR, "ERROR: " . $sOut]; + } + if($bHasWarning){ + return [RESULT_WARNING, "WARNING: " . $sOut]; + } + return [RESULT_OK, "OK: " . $sOut]; + } + +}