Skip to content
Snippets Groups Projects
Commit 47da8adf authored by Axel Hahn's avatar Axel Hahn
Browse files

added appmonitor checks

parent b1ccadba
No related branches found
No related tags found
No related merge requests found
<?php
define("RESULT_OK", 0);
define("RESULT_WARNING", 1);
define("RESULT_ERROR", 2);
define("RESULT_UNKNOWN", 255);
/**
* APPMONITOR 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>
* OTHER PARTIES PROVIDE THE PROGRAM ?AS IS? WITHOUT WARRANTY OF ANY KIND, <br>
* EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED <br>
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE <br>
* ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. <br>
* SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY <br>
* SERVICING, REPAIR OR CORRECTION.<br>
* <br>
* --------------------------------------------------------------------------------<br>
* <br>
* --- HISTORY:<br>
* 2014-10-24 0.5 axel.hahn@iml.unibe.ch<br>
* --------------------------------------------------------------------------------<br>
* @version 0.5
* @author Axel Hahn
* @link TODO
* @license GPL
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL 3.0
* @package IML-Appmonitor
*/
class appmonitorcheck {
// ----------------------------------------------------------------------
// CONFIG
// ----------------------------------------------------------------------
/**
* config container
* @var array
*/
private $_aConfig = array();
/**
* data of all checks
* @var array
*/
private $_aData = array();
// ----------------------------------------------------------------------
// CONSTRUCTOR
// ----------------------------------------------------------------------
/**
* constructor (nothing)
*/
public function __construct() {
}
// ----------------------------------------------------------------------
// PRIVATE FUNCTIONS
// ----------------------------------------------------------------------
/**
* create basic array values for metadata
* @return boolean
*/
private function _createDefaultMetadata() {
$this->_aData = array(
"name" => $this->_aConfig["name"],
"description" => $this->_aConfig["description"],
"result" => RESULT_UNKNOWN,
"value" => false,
);
return true;
}
/**
* set a result value of a check
* @param type $iResult
* @return type
*/
private function _setResult($iResult) {
return $this->_aData["result"] = (int) $iResult;
}
/**
* set a result value of a check
* @param type $iResult
* @return type
*/
private function _setOutput($s) {
return $this->_aData["value"] = (string) $s;
}
/**
* set result and output
* @param type $iResult
* @param type $s
* @return boolean
*/
private function _setReturn($iResult, $s) {
$this->_setResult($iResult);
$this->_setOutput($s);
return true;
}
private function _checkArrayKeys($aConfig, $sKeyList) {
foreach (explode(",", $sKeyList) as $sKey) {
if (!array_key_exists($sKey, $aConfig)) {
die('ERROR in ' . __CLASS__ . "<br>array requires the keys [$sKeyList] - but key '$sKey' was not found in config array <pre>" . print_r($aConfig, true));
}
if (is_null($aConfig[$sKey])) {
die('ERROR in ' . __CLASS__ . "<br> key '$sKey' is empty in config array <pre>" . print_r($aConfig, true));
}
}
return true;
}
// ----------------------------------------------------------------------
// PUBLIC FUNCTIONS
// ----------------------------------------------------------------------
/**
* perform a check
* @param type $aConfig
* Array
* (
* [name] => Dummy
* [description] => Dummy Test
* [check] => array(
* [function] => [check function] // i.e. Simple
* [params] => [array] // optional; arguments for Check function
* // its keys depend on the function
* )
* )
*
* @return array
*/
public function makeCheck($aConfig) {
$this->_checkArrayKeys($aConfig, "name,description,check");
$this->_checkArrayKeys($aConfig["check"], "function");
$this->_aConfig = $aConfig;
$this->_createDefaultMetadata();
$sCheck = "check" . $this->_aConfig["check"]["function"];
if (!method_exists($this, $sCheck)) {
die(__CLASS__ . " check not found: $sCheck <pre>" . print_r($aConfig, true));
}
$aParams = array_key_exists("params", $this->_aConfig["check"]) ? $this->_aConfig["check"]["params"] : array();
// call the check ...
call_user_func(array($this, $sCheck), $aParams);
// echo "<pre>"; print_r($this->listChecks()); die();
// ... and send response
return $this->respond();
}
/**
* list all available check functions. This is a helper class you cann call
* to get an overview overbuilt in functions. You get a flat array with
* all function names.
* @return array
*/
public function listChecks() {
$aReturn = array();
$class = new ReflectionClass($this);
foreach ($class->getMethods(ReflectionMethod::IS_PRIVATE) as $oReflectionMethod) {
if (strpos($oReflectionMethod->name, "check") === 0) {
$aReturn[] = (string) $oReflectionMethod->name;
}
}
return $aReturn;
}
/**
* final call of class: send response (data array)
* @return type
*/
public function respond() {
return $this->_aData;
}
// ----------------------------------------------------------------------
// CHECK FUNCTIONS (private)
// ----------------------------------------------------------------------
/**
* most simple check: set values
* @return type
*/
private function checkSimple($aParams) {
$aHelp = array(
"result" => "(integer) result value",
"value" => "(string) explaination"
);
$this->_checkArrayKeys($aParams, "result,value");
return $this->_setReturn((int) $aParams["result"], $aParams["value"]);
}
/**
* make http request and test response body
* @param array $aParams
* array(
* "url" url to fetch
* "contains" string that must exist in response body
* )
*/
private function checkHttpContent($aParams, $iTimeout = 5) {
$this->_checkArrayKeys($aParams, "url,contains");
if (!function_exists("curl_init")) {
die("ERROR: PHP CURL module is not installed.");
}
$ch = curl_init($aParams["url"]);
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"] . '.');
} else {
if (!strpos($res, $aParams["contains"]) === false) {
$this->_setReturn(RESULT_OK, 'OK: The text "' . $aParams["contains"] . '" was found in response of ' . $aParams["url"] . '.');
} else {
$this->_setReturn(RESULT_ERROR, 'ERROR: The text ' . $aParams["contains"] . ' was NOT found in response of ' . $aParams["url"] . '.');
}
}
return $res;
}
/**
* check mysql connection to a database
* @param array $aParams
* array(
* "server"
* "user"
* "password"
* "db"
* )
*/
private function checkMysqlConnect($aParams) {
$this->_checkArrayKeys($aParams, "server,user,password,db");
$db = mysqli_connect(
$aParams["server"], $aParams["user"], $aParams["password"], $aParams["db"]
);
if ($db) {
$this->_setReturn(RESULT_OK, "OK: Mysql database " . $aParams["db"] . " was connected");
return true;
} else {
$this->_setReturn(RESULT_ERROR, "ERROR: Mysql database " . $aParams["db"] . " was not connected. " . mysqli_connect_error());
return false;
}
}
/**
* check sqlite connection
* @param array $aParams
* array(
* "db"
* )
* @return boolean
*/
private 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.");
return false;
}
try {
// $db = new SQLite3($sqliteDB);
// $db = new PDO("sqlite:".$sqliteDB);
$o = new PDO("sqlite:" . $aParams["db"]);
$this->_setReturn(RESULT_OK, "OK: Sqlite database " . $aParams["db"] . " was connected");
return true;
} catch (Exception $exc) {
$this->_setReturn(RESULT_ERROR, "ERROR: Sqlite database " . $aParams["db"] . " was not connected. " . mysqli_connect_error());
return false;
}
}
/**
* check if system is listening to a given port
* @param array $aParams
* array(
* "port"
* )
* @return boolean
*/
private function checkListeningIp($aParams) {
$this->_checkArrayKeys($aParams, "port");
$sResult = exec('netstat -tulen | grep ":' . $aParams["port"] . ' "');
if ($sResult) {
$this->_setReturn(RESULT_OK, "OK: Port " . $aParams["port"] . " was found: " . $sResult);
return true;
} else {
$this->_setReturn(RESULT_ERROR, "ERROR: Port " . $aParams["port"] . " is not in use.");
return false;
}
}
}
<?php
/**
* APPMONITOR CLIENT<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>
* OTHER PARTIES PROVIDE THE PROGRAM ?AS IS? WITHOUT WARRANTY OF ANY KIND, <br>
* EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED <br>
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE <br>
* ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. <br>
* SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY <br>
* SERVICING, REPAIR OR CORRECTION.<br>
* <br>
* --------------------------------------------------------------------------------<br>
* <br>
* --- HISTORY:<br>
* 2014-10-24 0.5 axel.hahn@iml.unibe.ch<br>
* --------------------------------------------------------------------------------<br>
* @version 0.5
* @author Axel Hahn
* @link TODO
* @license GPL
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL 3.0
* @package IML-Appmonitor
*/
class appmonitor {
/**
* config: default ttl for server before requesting the client check again
* value is in seconds
* @var int
*/
private $_iDefaultTtl = 300;
/**
* internal counter: greatest return value of all checks
* @var type
*/
private $_iMaxResult = false;
/**
* responded metadata of a website
* @see _createDefaultMetadata()
* @var array
*/
private $_aMeta = array();
/**
* repended array of all checks
* @see addCheck()
* @var array
*/
private $_aChecks = array();
/**
* @var array
*/
private $_aMustKeysChecks = array("name", "description", "result", "value");
/**
* constructor: init data
*/
public function __construct() {
$this->_createDefaultMetadata();
}
// ----------------------------------------------------------------------
// private function
// ----------------------------------------------------------------------
/**
* create basic array values for metadata
* @return boolean
*/
private function _createDefaultMetadata() {
$this->_aMeta = array(
"host" => false,
"website" => false,
"ttl" => false,
"ts" => (int) date("U"),
"result" => false
);
// fill with default values
$this->setHost();
$this->setWebsite();
$this->setTTL();
return true;
}
// ----------------------------------------------------------------------
// setter
// ----------------------------------------------------------------------
/**
* set a host for metadata
* @param string $s hostname
* @return bool
*/
public function setHost($s = false) {
if (!$s) {
$s = php_uname("n");
}
return $this->_aMeta["host"] = $s;
}
/**
* set a vhost for metadata
* @param string $sNewHost hostname
* @return bool
*/
public function setWebsite($s = false) {
if (!$s) {
$s = $_SERVER["HTTP_HOST"];
}
return $this->_aMeta["website"] = $s;
}
/**
* set a ttl value for
* @param int $iTTl TTL value in sec
* @return boolean
*/
public function setTTL($iTTl = false) {
if (!$iTTl) {
$iTTl = $this->_iDefaultTtl;
}
return $this->_aMeta["ttl"] = $iTTl;
}
/**
* set final result in meta data; if no value was given then it
* sets the biggest value of any check.
* @param integer $iResult set resultcode
* @return boolean
*/
public function setResult($iResult = false) {
if ($iResult === false) {
$iResult = $this->_iMaxResult; // see addCheck()
}
return $this->_aMeta["result"] = $iResult;
}
/**
* add a check array;
* @param type $aJob
* @return type
*/
public function addCheck($aJob = array()) {
require_once 'appmonitor-checks.class.php';
$oCheck = new appmonitorcheck();
// print_r($aJob); die();
$aCheck = $oCheck->makecheck($aJob);
if (!$this->_iMaxResult || $aCheck["result"] > $this->_iMaxResult) {
$this->_iMaxResult = $aCheck["result"];
}
return $this->_aChecks[] = $aCheck;
}
// ----------------------------------------------------------------------
// getter
// ----------------------------------------------------------------------
/**
* list all available check functions. This is a helper class you cann call
* to get an overview overbuilt in functions. You get a flat array with
* all function names.
* @return array
*/
public function listChecks() {
require_once 'appmonitor-checks.class.php';
$oCheck = new appmonitorcheck();
return $oCheck->listChecks();
}
// ----------------------------------------------------------------------
// checks
// ----------------------------------------------------------------------
/**
* verify array values and abort with all found errors
*/
private function _checkData() {
$aErrors = array();
if (!count($this->_aChecks)) {
$aErrors[] = "No checks have been defined.";
}
if ($this->_aMeta["result"] === false) {
$aErrors[] = "method setResult was not used to set a final result for all checks.";
}
if (count($aErrors)) {
echo "<h1>Errors detected</h1><ol><li>" . implode("<li>", $aErrors) . "</ol><hr>";
echo "<pre>" . print_r($this->_generateOutputArray(), true) . "</pre><hr>";
die("ABORT");
}
}
// ----------------------------------------------------------------------
// output
// ----------------------------------------------------------------------
/**
* get full array for response with metadata and Checks
* @return type
*/
private function _generateOutputArray() {
return array(
"meta" => $this->_aMeta,
"checks" => $this->_aChecks,
);
}
/**
* output appmonitor values as JSON
* @param bool $bPretty turn on pretty print; default is false
* @param bool $bHighlight print syntax highlighted html code; $bPretty must be true to enable
*/
public function render($bPretty = false, $bHighlight = false) {
$this->_checkData();
// JSON_PRETTY_PRINT reqires PHP 5.4
if (!defined('JSON_PRETTY_PRINT')) {
$bPretty=false;
}
if (!$bPretty) {
$bHighlight=false;
$sOut = json_encode($this->_generateOutputArray());
} else {
$sOut = json_encode($this->_generateOutputArray(), JSON_PRETTY_PRINT);
if ($bHighlight) {
$aMsg=array(
0=>"OK",
1=>"WARNING",
2=>"ERROR",
255=>"UNKNOWN"
);
foreach(array_keys($aMsg) as $iCode){
$sOut = preg_replace('/(\"result\":\ '.$iCode.')/', '$1 <span class="result'.$iCode.'"> &lt;--- '.$aMsg[$iCode].' </span>', $sOut);
}
$sOut = preg_replace('/:\ \"(.*)\"/U', ': "<span style="color:#66e;">$1</span>"', $sOut);
$sOut = preg_replace('/:\ ([0-9]*)/', ': <span style="color:#3a3; font-weight: bold;">$1</span>', $sOut);
$sOut = preg_replace('/\"(.*)\":/U', '"<span style="color:#e90;">$1</span>":', $sOut);
$sOut = preg_replace('/([{\[])/', '$1<blockquote>', $sOut);
$sOut = preg_replace('/([}\]])/', '</blockquote>$1', $sOut);
$sOut = str_replace(' ', '', $sOut);
// $sOut = preg_replace('/([{}])/', '<span style="color:#a00; ">$1</span>', $sOut);
// $sOut = preg_replace('/([\[\]])/', '<span style="color:#088; ">$1</span>', $sOut);
$sOut = '<!DOCTYPE html><html><head>'
. '<style>'
. 'body{background:#282830; color:#9ac; font-family: verdana,arial;}'
. 'blockquote{background:rgba(215,180,255,0.03); border-left: 5px solid #222; margin-top: 0; padding: 0; ;}'
. 'blockquote blockquote:hover{border-color: #345; }'
. 'blockquote blockquote blockquote:hover{border-color: #808;}'
. 'pre{background:#222; padding: 1em; border-radius: 1em;}'
. '.result0{background:#080; border-right: 1em solid #0f0;}'
. '.result1{background:#860; border-right: 1em solid #fc0;}'
. '.result2{background:#800; border-right: 1em solid #f00;}'
. '.result255{background:#666; border-right: 1em solid #ccc;}'
. '</style>'
. '<title>'.__CLASS__.'</title>'
. '</head><body>'
. '<h1>'.__CLASS__.' :: debug</h1>'
. '<pre>'
. $sOut
. '</pre></body></html>';
}
}
if (!$bHighlight) {
header('Content-type: application/json');
header('Cache-Control: cache');
header('max-age: ' . $this->_aMeta["ttl"]);
}
echo $sOut;
return $sOut;
}
}
<?php
require_once('appmonitor-client.class.php');
$oMonitor = new appmonitor();
$oMonitor->addCheck(
array(
"name" => "simple",
"description" => "Very simple test",
"check" => array(
"function" => "Simple",
"params" => array(
"result" => 0,
"value" => "The appmonitor client is reachable.",
),
),
)
);
require_once '../../config/inc_projects_config.php';
$sSqlitefile=$aConfig['dataDir'].'/database/logs.db';
$oMonitor->addCheck(
array(
"name" => "Sqlite DB for action logs",
"description" => "Connect sqlite db ". basename($sSqlitefile),
"check" => array(
"function" => "SqliteConnect",
"params" => array(
"db"=>$sSqlitefile
),
),
)
);
// Gesamt-Ergebnis - ohne Param=aut. max. Wert nehmen
$oMonitor->setResult();
// Ausgabe
$oMonitor->render();
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment