Skip to content
Snippets Groups Projects
Commit c698f2f2 authored by hahn's avatar hahn
Browse files

Update components font-awesome (change icon syntax from fontawesome 4 --> 5), jquery

action button (build, deploy, ...) have the color of the target phase
Update appmonitor class files
parent 238315b0
No related branches found
No related tags found
No related merge requests found
<?php
if(!defined('RESULT_OK')){
define("RESULT_OK", 0);
define("RESULT_UNKNOWN", 1);
define("RESULT_WARNING", 2);
define("RESULT_ERROR", 3);
}
/**
* APPMONITOR CLIENT CHECKS<br>
* ____________________________________________________________________________
*
* _____ _____ __ _____ _ _
* | | | | ___ ___ ___| |___ ___|_| |_ ___ ___
* |- -| | | | |__ | .'| . | . | | | | . | | | _| . | _|
* |_____|_|_|_|_____| |__,| _| _|_|_|_|___|_|_|_|_| |___|_|
* |_| |_|
* _ _ _
* ___| |_|___ ___| |_
* | _| | | -_| | _|
* |___|_|_|___|_|_|_|
*
* ____________________________________________________________________________
*
* APPMONITOR :: CLASS FOR CLIENT TEST FUNCTIONS<br>
* <br>
* THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE <br>
* LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR <br>
......@@ -24,8 +40,14 @@ define("RESULT_ERROR", 3);
* 2015-04-08 0.9 axel.hahn@iml.unibe.ch added sochket test: checkPortTcp<br>
* 2018-06-29 0.24 axel.hahn@iml.unibe.ch add file and directory checks<br>
* 2018-07-17 0.42 axel.hahn@iml.unibe.ch add port on mysqli check<br>
* 2018-07-26 0.46 axel.hahn@iml.unibe.ch fix mysql connection check with empty port param<br>
* 2018-08-14 0.47 axel.hahn@iml.unibe.ch appmonitor client: use timeout of 5 sec for tcp socket connections<br>
* 2018-08-15 0.49 axel.hahn@iml.unibe.ch cert check: added flag to skip verification<br>
* 2018-08-23 0.50 axel.hahn@iml.unibe.ch replace mysqli connect with mysqli real connect (to use a timeout)<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>
* --------------------------------------------------------------------------------<br>
* @version 0.9
* @version 0.77
* @author Axel Hahn
* @link TODO
* @license GPL
......@@ -41,18 +63,27 @@ class appmonitorcheck {
* config container
* @var array
*/
private $_aConfig = array();
protected $_aConfig = array();
/**
* data of all checks
* @var array
*/
private $_aData = array();
protected $_aData = array();
// protected $_units = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
/**
* flat array with units for sizes
* @var array
*/
protected $_units = array( 'B', 'KB', 'MB', 'GB', 'TB');
/**
* timeout in sec for tcp socket connections
* @var type
*/
protected $_iTimeoutTcp=5;
// ----------------------------------------------------------------------
// CONSTRUCTOR
// ----------------------------------------------------------------------
......@@ -72,13 +103,15 @@ class appmonitorcheck {
* create basic array values for metadata
* @return boolean
*/
private function _createDefaultMetadata() {
protected function _createDefaultMetadata() {
$this->_aData = array(
"name" => $this->_aConfig["name"],
"description" => $this->_aConfig["description"],
"result" => RESULT_UNKNOWN,
"value" => false,
"type" => false,
"time" => false,
);
return true;
}
......@@ -88,7 +121,7 @@ class appmonitorcheck {
* @param type $iResult
* @return type
*/
private function _setResult($iResult) {
protected function _setResult($iResult) {
return $this->_aData["result"] = (int) $iResult;
}
......@@ -97,7 +130,7 @@ class appmonitorcheck {
* @param type $iResult
* @return type
*/
private function _setOutput($s) {
protected function _setOutput($s) {
return $this->_aData["value"] = (string) $s;
}
......@@ -107,13 +140,13 @@ class appmonitorcheck {
* @param type $s
* @return boolean
*/
private function _setReturn($iResult, $s) {
protected function _setReturn($iResult, $s) {
$this->_setResult($iResult);
$this->_setOutput($s);
return true;
}
private function _checkArrayKeys($aConfig, $sKeyList) {
protected function _checkArrayKeys($aConfig, $sKeyList) {
foreach (explode(",", $sKeyList) as $sKey) {
if (!array_key_exists($sKey, $aConfig)) {
header('HTTP/1.0 503 Service Unavailable');
......@@ -204,16 +237,21 @@ class appmonitorcheck {
* helper function: read certificate data
* called in checkCert()
* @param string $sUrl url to connect
* @param boolean $bVerifyCert flag: verify certificate; default: no check
* @return array
*/
protected function _certGetInfos($sUrl) {
protected function _certGetInfos($sUrl, $bVerifyCert) {
$iTimeout=10;
$aUrldata=parse_url($sUrl);
$sHost = isset($aUrldata['host']) ? $aUrldata['host'] : false;
$iPort = isset($aUrldata['port']) ? $aUrldata['port'] : ((isset($aUrldata['scheme']) && $aUrldata['scheme'] === 'https') ? 443 : false);
$get = stream_context_create(array("ssl" => array("capture_peer_cert" => TRUE)));
$aSsl=array('capture_peer_cert' => true);
if($bVerifyCert){
$aSsl['verify_peer']=false;
$aSsl['verify_peer_name']=false;
};
$get = stream_context_create(array('ssl' => $aSsl));
if(!$get){
return array('_error' => 'Error: Cannot create stream_context');
}
......@@ -221,7 +259,7 @@ class appmonitorcheck {
$errstr="stream_socket_client failed.";
$read = stream_socket_client("ssl://$sHost:$iPort", $errno, $errstr, $iTimeout, STREAM_CLIENT_CONNECT, $get);
if(!$read){
return array('_error' => "Error $errno: $errstr; cannot create stream_context to ssl://$sHost:$iPort");
return array('_error' => "Error $errno: $errstr; cannot create stream_socket_client with given stream_context to ssl://$sHost:$iPort; you can try to set the flag [verify] to false to check expiration date only.");
}
$cert = stream_context_get_params($read);
if(!$cert){
......@@ -238,26 +276,28 @@ class appmonitorcheck {
* @param array $aParams
* 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
* )
* @return boolean
*/
private function checkCert($aParams) {
protected function checkCert($aParams) {
$sUrl = isset($aParams["url"])
? $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;
$sMessage="Checked url: $sUrl ... ";
$certinfo=$this->_certGetInfos($sUrl);
$certinfo=$this->_certGetInfos($sUrl, $bVerify);
if(isset($certinfo['_error'])){
$this->_setReturn(RESULT_ERROR, $certinfo['_error'] . $sMessage);
return true;
}
$sDNS=isset($certinfo['extensions']['subjectAltName']) ? $certinfo['extensions']['subjectAltName'] : false;
$sHost=parse_url($url,PHP_URL_HOST);
$sHost=parse_url($sUrl,PHP_URL_HOST);
if(strstr($sDNS, 'DNS:'.$sHost)===false){
$this->_setReturn(RESULT_ERROR, 'Wrong certificate: '.$sHost.' is not listed as DNS alias in ['.$sDNS.'] ' . $sMessage);
return true;
......@@ -278,7 +318,9 @@ class appmonitorcheck {
return true;
}
// echo '<pre>';
$this->_setReturn(RESULT_OK, 'OK, is valid. ' . $sMessage);
$this->_setReturn(RESULT_OK, 'OK. '
.($bVerify ? 'Certificate is valid. ' : '(Verification is disabled; Check for expiration only.) ' )
. $sMessage);
return true;
}
......@@ -302,7 +344,7 @@ class appmonitorcheck {
}
$power=0;
foreach($this->_units as $sUnit){
if (preg_match('/^[0-9\.]*'.$sUnit.'/', $sValue)){
if (preg_match('/^[0-9\.\ ]*'.$sUnit.'/', $sValue)){
$i=preg_replace('/([0-9\.]*).*/', '$1', $sValue);
$iReal=$i*pow(1024, $power);
// die("FOUND: $sValue with unit ${sUnit} - 1024^$power * $i = $iReal");
......@@ -325,7 +367,7 @@ class appmonitorcheck {
* )
* @return boolean
*/
private function checkDiskfree($aParams) {
protected function checkDiskfree($aParams) {
$this->_checkArrayKeys($aParams, "directory", "critical");
$sDirectory = $aParams["directory"];
......@@ -378,7 +420,7 @@ class appmonitorcheck {
* )
* @return boolean
*/
private function checkFile($aParams) {
protected function checkFile($aParams) {
$aOK = array();
$aErrors = array();
$this->_checkArrayKeys($aParams, "filename");
......@@ -413,42 +455,235 @@ class appmonitorcheck {
return true;
}
/**
* compare function for 2 values
* @param any $verifyValue search value
* @param string $sCompare compare function; it is one of
* IS -
* GE - greater or equal
* GT - greater
* @param any $value existing value
* @return boolean
*/
protected function _compare($value, $sCompare, $verifyValue){
switch ($sCompare){
case "IS":
return $value===$verifyValue;
break;
case "GE":
return $value>=$verifyValue;
break;
case "GT":
return $value>$verifyValue;
break;
case "HAS":
return !!(strstr($value, $verifyValue)!==false);
break;
default:
die("FATAL ERROR: a compare function [$sCompare] is not implemented (yet).");
break;
}
return false;
}
/**
* make http request and test response body
* @param array $aParams
* array(
* "url" url to fetch
* "contains" string that must exist in response body
* url string url to fetch
* headeronly boolean optional flag to fetch http response herader only; default: false = returns header and body
* follow boolean optional flag to follow a location; default: false = do not follow
* status integer test for an expected http status code; if none is given then test fails on status 400 and greater
* headercontains string test for a string in the http response header; it returns OK if the text was found
* headernotcontains string test for a string in the http response header; it returns OK if the text was not found
* headerregex string test for a regex in the http response header; it returns OK if the regex matches; example: "headerregex"=>"/lowercasematch/i"
* bodycontains string test for a string in the http response body; it returns OK if the text was found
* bodynotcontains string test for a string in the http response body; it returns OK if the text was not found
* bodyregex string test for a regex in the http response body; it returns OK if the regex matches; example: "headerregex"=>"/lowercasematch/i"
* )
* @param integer $iTimeout value in sec; default: 5sec
*/
private function checkHttpContent($aParams, $iTimeout = 5) {
$this->_checkArrayKeys($aParams, "url,contains");
protected function checkHttpContent($aParams, $iTimeout = 5) {
$this->_checkArrayKeys($aParams, "url");
if (!function_exists("curl_init")) {
header('HTTP/1.0 503 Service Unavailable');
die("ERROR: PHP CURL module is not installed.");
}
$bShowContent = (isset($aParams["content"]) && $aParams["content"]) ? true : false;
$ch = curl_init($aParams["url"]);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, isset($aParams["headeronly"]) && $aParams["headeronly"]);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, isset($aParams["follow"]) && $aParams["follow"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, $iTimeout);
$res = curl_exec($ch);
curl_close($ch);
if (!$res) {
$this->_setReturn(RESULT_ERROR, 'ERROR: failed to fetch ' . $aParams["url"] . '.');
return false;
}
$sOut='';
$bError=false;
$aInfos = curl_getinfo($ch);
/*
Array
(
[url] => https://www.iml.unibe.ch/
[content_type] => text/html; charset=utf-8
[http_code] => 200
[header_size] => 926
[request_size] => 55
[filetime] => -1
[ssl_verify_result] => 20
[redirect_count] => 0
[total_time] => 1.812
[namelookup_time] => 0
[connect_time] => 0
[pretransfer_time] => 0.015
[size_upload] => 0
[size_download] => 94654
[speed_download] => 52237
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => -1
[starttransfer_time] => 1.812
[redirect_time] => 0
[redirect_url] =>
[primary_ip] => 130.92.30.80
[certinfo] => Array
(
)
[primary_port] => 443
[local_ip] => 130.92.79.49
[local_port] => 63597
)
*/
curl_close($ch);
$aTmp=explode("\r\n\r\n", $res, 2);
$sHttpHeader=$aTmp[0];
$sHttpBody=isset($aTmp[1]) ? $aTmp[1] : false;
// ---------- check functions
// --- http status code
$sOut.="Http status: ".$aInfos['http_code']." - ";
if(isset($aParams["status"])){
if($aInfos['http_code'] === $aParams["status"]){
$sOut.="compare OK<br>";
} else {
$sOut.="compare failed<br>";
$bError=true;
}
} else {
if($aInfos['http_code'] >= 400){
$sOut.="Error page detected<br>";
$bError=true;
} else {
$sOut.="request successful<br>";
}
}
// --- http header
if(isset($aParams["headercontains"]) && $aParams["headercontains"]){
$sOut.="Http header contains &quot;".$aParams["headercontains"]."&quot; - ";
if(!strstr($sHttpHeader, $aParams["headercontains"])===false){
$sOut.="compare OK<br>";
} else {
$sOut.="compare failed<br>";
$bError=true;
}
}
if(isset($aParams["headernotcontains"]) && $aParams["headernotcontains"]){
$sOut.="Http header does not contain &quot;".$aParams["headernotcontains"]."&quot; - ";
if(strstr($sHttpHeader, $aParams["headernotcontains"])===false){
$sOut.="compare OK<br>";
} else {
$sOut.="compare failed<br>";
$bError=true;
}
}
if(isset($aParams["headerregex"]) && $aParams["headerregex"]){
$sOut.="Http header regex test &quot;".$aParams["headerregex"]."&quot; - ";
try{
$bRegex=preg_match($aParams["headerregex"], $sHttpHeader);
if($bRegex){
$sOut.="compare OK<br>";
} else {
$sOut.="compare failed<br>";
$bError=true;
}
}
catch(Exception $e){
$sOut.="Wrong REGEX<br>" . print_r($e, 1).'<br>';
$bError=true;
}
}
// --- http body
if(isset($aParams["bodycontains"]) && $aParams["bodycontains"]){
$sOut.="Http body contains &quot;".$aParams["bodycontains"]."&quot; - ";
if(!strstr($sHttpBody, $aParams["bodycontains"])===false){
$sOut.="compare OK<br>";
} else {
$sOut.="compare failed<br>";
$bError=true;
}
}
if(isset($aParams["bodynotcontains"]) && $aParams["bodynotcontains"]){
$sOut.="Http body does not contain &quot;".$aParams["bodynotcontains"]."&quot; - ";
if(strstr($sHttpBody, $aParams["bodynotcontains"])===false){
$sOut.="compare OK<br>";
} else {
if (!strpos($res, $aParams["contains"]) === false) {
$this->_setReturn(RESULT_OK, 'OK: The text "' . $aParams["contains"] . '" was found in response of ' . $aParams["url"] . '.');
$sOut.="compare failed<br>";
$bError=true;
}
}
if(isset($aParams["bodyregex"]) && $aParams["bodyregex"]){
$sOut.="Http body regex test &quot;".$aParams["bodyregex"]."&quot; - ";
try{
$bRegex=preg_match($aParams["bodyregex"], $sHttpBody);
if($bRegex){
$sOut.="compare OK<br>";
} else {
$this->_setReturn(RESULT_ERROR, 'ERROR: The text ' . $aParams["contains"] . ' was NOT found in response of ' . $aParams["url"] . '.');
$sOut.="compare failed<br>";
$bError=true;
}
}
catch(Exception $e){
$sOut.="Wrong REGEX<br>" . print_r($e, 1).'<br>';
$bError=true;
}
}
return $res;
if (!$bError) {
$this->_setReturn(RESULT_OK,
'OK: http check "' . $aParams["url"] . '".<br>'.$sOut
);
} else {
$this->_setReturn(RESULT_ERROR,
'ERROR: http check "' . $aParams["url"] . '".<br>'.$sOut
);
}
/*
echo '<pre>';
echo $sOut."<hr>";
echo "<hr>HEADER: ".htmlentities($sHttpHeader)."<hr>";
print_r($aParams); print_r($aInfos);
// echo htmlentities($sHttpBody);
die();
*/
return true;
}
/**
* check mysql connection to a database using mysqli
* check mysql connection to a database using mysqli realconnect
* @param array $aParams
* array(
* "server"
......@@ -458,18 +693,65 @@ class appmonitorcheck {
* "port" <<< optional
* )
*/
private function checkMysqlConnect($aParams) {
protected function checkMysqlConnect($aParams) {
$this->_checkArrayKeys($aParams, "server,user,password,db");
$mysqli=mysqli_init();
if(!$mysqli){
$this->_setReturn(RESULT_ERROR, 'ERROR: mysqli_init failed.');
return false;
}
if (!$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, $this->_iTimeoutTcp)) {
$this->_setReturn(RESULT_ERROR, 'ERROR: setting mysqli_init failed.');
return false;
}
$db = (isset($aParams["port"]) && $aParams["port"])
? mysqli_connect($aParams["server"], $aParams["user"], $aParams["password"], $aParams["db"], $aParams["port"])
: mysqli_connect($aParams["server"], $aParams["user"], $aParams["password"], $aParams["db"])
? $mysqli->real_connect($aParams["server"], $aParams["user"], $aParams["password"], $aParams["db"], $aParams["port"])
: $mysqli->real_connect($aParams["server"], $aParams["user"], $aParams["password"], $aParams["db"])
;
if ($db) {
$this->_setReturn(RESULT_OK, "OK: Mysql database " . $aParams["db"] . " was connected");
mysqli_close($db);
$mysqli->close();
return true;
} else {
$this->_setReturn(RESULT_ERROR, "ERROR: Mysql database " . $aParams["db"] . " was not connected. " . mysqli_connect_error());
$this->_setReturn(RESULT_ERROR, "ERROR: Mysql database " . $aParams["db"] . " was not connected. Error ".mysqli_connect_errno() .": ". mysqli_connect_error());
return false;
}
}
/**
* check connection to a database using pdo
* see http://php.net/manual/en/pdo.drivers.php
*
* @param array $aParams
* array(
* "connect"
* "password"
* "user"
* )
*/
protected function checkPdoConnect($aParams) {
$this->_checkArrayKeys($aParams, "connect,user,password");
try{
$db = new PDO(
$aParams['connect'],
$aParams['user'],
$aParams['password'],
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
// timeout
// Not all drivers support this option; mysqli does
PDO::ATTR_TIMEOUT => $this->_iTimeoutTcp,
// mssql
// PDO::SQLSRV_ATTR_QUERY_TIMEOUT => $this->_iTimeoutTcp,
)
);
$this->_setReturn(RESULT_OK, "OK: Database was connected with PDO " . $aParams['connect']);
$db=null;
return true;
} catch(PDOException $e) {
$this->_setReturn(RESULT_ERROR, "ERROR: Database was not connected " . $aParams['connect'] . " was not connected. Error ".$e->getMessage());
return false;
}
}
......@@ -483,7 +765,7 @@ class appmonitorcheck {
* )
* @return boolean
*/
private function checkPortTcp($aParams) {
protected function checkPortTcp($aParams) {
$this->_checkArrayKeys($aParams, "port");
$sHost = array_key_exists('host', $aParams) ? $aParams['host'] : '127.0.0.1';
......@@ -496,6 +778,16 @@ class appmonitorcheck {
$this->_setReturn(RESULT_UNKNOWN, "ERROR: $sHost:$iPort was not checked. socket_create() failed: " . socket_strerror(socket_last_error()));
return false;
}
// set socket timeout
socket_set_option(
$socket,
SOL_SOCKET, // socket level
SO_SNDTIMEO, // timeout option
array(
"sec"=>$this->_iTimeoutTcp, // timeout in seconds
"usec"=>0
)
);
$result = socket_connect($socket, $sHost, $iPort);
if ($result === false) {
......@@ -510,16 +802,32 @@ class appmonitorcheck {
}
/**
* most simple check: set values
* most simple check: set given values
* Use this function to add a counter
*
* @param array $aParams
* array(
* "result" integer; RESUL_nn
* array keys:
* "result" integer; RESULT_nn
* "value" description text
* )
*
* brainstorming for a future release
*
* "counter" optioal: array of counter values
* - "label" string: a label
* - "value" a number
* - "unit" string: unit, i.e. ms, MB/s
* - "type" one of counter | bars | bars-stacked | lines | ... ??
*
*/
private function checkSimple($aParams) {
protected function checkSimple($aParams) {
$this->_checkArrayKeys($aParams, "result,value");
return $this->_setReturn((int) $aParams["result"], $aParams["value"]);
$this->_setReturn((int) $aParams["result"], $aParams["value"]);
foreach(array('type', 'count', 'visual') as $sMyKey){
if(isset($aParams[$sMyKey])){
$this->_aData[$sMyKey]=$aParams[$sMyKey];
}
}
return true;
}
/**
......@@ -530,7 +838,7 @@ class appmonitorcheck {
* )
* @return boolean
*/
private function checkSqliteConnect($aParams) {
protected function checkSqliteConnect($aParams) {
$this->_checkArrayKeys($aParams, "db");
if (!file_exists($aParams["db"])) {
$this->_setReturn(RESULT_ERROR, "ERROR: Sqlite database file " . $aParams["db"] . " does not exist.");
......
<?php
/**
* APPMONITOR CLIENT<br>
* ____________________________________________________________________________
*
* _____ _____ __ _____ _ _
* | | | | ___ ___ ___| |___ ___|_| |_ ___ ___
* |- -| | | | |__ | .'| . | . | | | | . | | | _| . | _|
* |_____|_|_|_|_____| |__,| _| _|_|_|_|___|_|_|_|_| |___|_|
* |_| |_|
* _ _ _
* ___| |_|___ ___| |_
* | _| | | -_| | _|
* |___|_|_|___|_|_|_|
*
* ____________________________________________________________________________
*
* APPMONITOR :: CLASS FOR CLIENT CHECKS<br>
* <br>
* THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE <br>
* LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR <br>
......@@ -17,8 +31,12 @@
* --- 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>
* --------------------------------------------------------------------------------<br>
* @version 0.6
* @version 0.85
* @author Axel Hahn
* @link TODO
* @license GPL
......@@ -32,27 +50,39 @@ class appmonitor {
* value is in seconds
* @var int
*/
private $_iDefaultTtl = 300;
protected $_sVersion = 'php-client-v0.85';
/**
* config: default ttl for server before requesting the client check again
* value is in seconds
* @var int
*/
protected $_iDefaultTtl = 300;
/**
* internal counter: greatest return value of all checks
* @var type
*/
private $_iMaxResult = false;
protected $_iMaxResult = false;
/**
* responded metadata of a website
* @see _createDefaultMetadata()
* @var array
*/
private $_aMeta = array();
protected $_aMeta = array();
/**
* repended array of all checks
* @see addCheck()
* @var array
*/
private $_aChecks = array();
protected $_aChecks = array();
/**
* for time measurements: start time
* @var type
*/
protected $_iStart = false;
/**
......@@ -63,21 +93,22 @@ class appmonitor {
}
// ----------------------------------------------------------------------
// private function
// protected function
// ----------------------------------------------------------------------
/**
* create basic array values for metadata
* @return boolean
*/
private function _createDefaultMetadata() {
protected function _createDefaultMetadata() {
$this->_iStart = microtime(true);
$this->_aMeta = array(
"host" => false,
"website" => false,
"ttl" => false,
"result" => false,
"time" => false
"time" => false,
"version" => $this->_sVersion,
);
// fill with default values
......@@ -92,7 +123,9 @@ class appmonitor {
// ----------------------------------------------------------------------
/**
* set a host for metadata
* set the physical hostname for metadata; if no host is given then
* the php_uname("n") will be used to set one.
*
* @param string $s hostname
* @return bool
*/
......@@ -104,7 +137,14 @@ class appmonitor {
}
/**
* set a vhost for metadata
* set a name for this website or application and its environment
* (dev, test, prod);
*
* If you have several application in subdirectories, i.e. /blog, /shop...
* then you should the path or any description to identify them too
*
* if no argument is given the name of HTTP_HOST will be used
*
* @param string $sNewHost hostname
* @return bool
*/
......@@ -116,7 +156,9 @@ class appmonitor {
}
/**
* set a ttl value for
* set a ttl value in seconds to define how long a server should not
* ask again for a new status of this instance
*
* @param int $iTTl TTL value in sec
* @return boolean
*/
......@@ -152,8 +194,15 @@ class appmonitor {
// print_r($aJob); die();
$aCheck = $oCheck->makecheck($aJob);
if (!$this->_iMaxResult || $aCheck["result"] > $this->_iMaxResult) {
$this->_iMaxResult = $aCheck["result"];
// limit error code
// echo "DEBUG ".$aCheck["name"].": ".$aCheck["result"]."\n";
$iMyResult=isset($aJob['worstresult'])
? min($aCheck["result"], $aJob['worstresult'])
: $aCheck["result"]
;
if (!$this->_iMaxResult || $iMyResult > $this->_iMaxResult) {
$this->_iMaxResult = $iMyResult;
}
return $this->_aChecks[] = $aCheck;
}
......@@ -282,7 +331,7 @@ class appmonitor {
/**
* verify array values and abort with all found errors
*/
private function _checkData() {
protected function _checkData() {
$aErrors = array();
if (!count($this->_aChecks)) {
......@@ -293,19 +342,28 @@ class appmonitor {
$aErrors[] = "method setResult was not used to set a final result for all checks.";
}
if (count($aErrors)) {
header('HTTP/1.0 503 Service Unavailable');
echo "<h1>Errors detected</h1><ol><li>" . implode("<li>", $aErrors) . "</ol><hr>";
echo "<pre>" . print_r($this->getResults(), true) . "</pre><hr>";
die("ABORT");
$this->abort(
'<h2>Error: client check is not complete</h2><p>Found errors:</p><ol><li>' . implode('<li>', $aErrors) . '</ol><br><br>'
// .'Dump of your data so far:<pre>' . json_encode($this->getResults(), JSON_PRETTY_PRINT) . '</pre><hr>'
);
}
return true;
}
// ----------------------------------------------------------------------
// output
// ----------------------------------------------------------------------
/**
* stop processing the client checks and abort with an error
* @param string $sMessage
*/
public function abort($sMessage){
header('HTTP/1.0 503 Service Unavailable');
die('<h1>503 Service Unavailable</h1>'.$sMessage);
}
/**
* get full array for response with metadata and Checks
* @return type
......@@ -384,5 +442,79 @@ class appmonitor {
echo $sOut;
return $sOut;
}
/**
* output appmonitor client status as single html page
*
* @example <code>
* ob_start();<br>
* require __DIR__ . '/appmonitor/client/index.php';
* $sJson=ob_get_contents();
* ob_end_clean();
* $oMonitor->renderHtmloutput($sJson);
* </code>
*
* @param string $sJson JSON of client output
*/
public function renderHtmloutput($sJson) {
header('Content-type: text/html');
header('Cache-Control: cache');
header('max-age: ' . $this->_aMeta["ttl"]);
$aMsg = array(
0 => "OK",
1 => "UNKNOWN",
2 => "WARNING",
3 => "ERROR"
);
// $sOut = print_r($sJson, 1);
$aData= json_decode($sJson, 1);
// ----- Ausgabe human readable
$sOut='';
$sOut.='<h2>Metadata</h2>'
. '<div class="meta'.(isset($aData['meta']['result']) ? ' result'.$aData['meta']['result'] : '' ) .'">'
. 'Status: ' . (isset($aData['meta']['result']) ? $aMsg[$aData['meta']['result']] : '?').'<br>'
. '</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>'
.'<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.= '<hr>List of farbcodes: ';
foreach ($aMsg as $i=>$sText){
$sOut.= '<span class="result'.$i.'">'. $sText.'</span> ';
}
$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; }'
. '</style>'
. '<title>' . __CLASS__ . '</title>'
. '</head><body>'
. '<h1>' . __CLASS__ . ' :: client status</h1>'
. $sOut
. '</body></html>';
echo $sOut;
return $sOut;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment