#!/usr/bin/env php <?php # chdir(__DIR__); $FLAG_DEBUG = 0; $VERSION = "0.0.1"; // ---MARK---INCLUDE-CHECKS---START--- if (!file_exists(__DIR__."/include_checks.php")) { echo "ERROR: File 'include_checks.php' does not exist yet..\n"; echo "Run the ../installer.php first!\n"; exit(1); } if (!include __DIR__."/include_checks.php") { echo "ERROR: Include of generated 'include_checks.php' failed.\n"; echo "Check its generation by installer or run the installer again.\n"; exit(2); } // ---MARK---INCLUDE-CHECKS---END // -------------------------------------------------------------------- // // FUNCTIONS // // -------------------------------------------------------------------- /** * Call $oMonitor-><METHODNAME> with 1 or 2 params. * This function was introduced to shorten the code. * * @param string $sMethod method name of appmonitor class * @param mixed $value * @param mixed $value2 * @return void */ function _set(string $sMethod, mixed $value = null, mixed $value2 = null) { global $oMonitor; if (!isset($value)) { _wd("SKIP \$oMonitor->$sMethod(<no_value>)"); } else { if (!isset($value2)) { _wd("calling \$oMonitor->$sMethod('$value')"); $oMonitor->$sMethod($value); } else { _wd("calling \$oMonitor->$sMethod('$value', '$value2')"); $oMonitor->$sMethod($value, $value2); } } } /** * Write debug output if FLAG_DEBUG is true (use -v or --verbose on command line) * @param string $s message to show; a prefix "DEBUG:" will be added in front * @return void */ function _wd($s): void { global $FLAG_DEBUG; if ($FLAG_DEBUG) { // echo "DEBUG: $s\n"; fwrite(STDERR, "DEBUG: $s\n"); } } /** * Show help text * @return void */ function _showHelp(): void { global $VERSION; $_self = basename(__FILE__); echo "IML Appmonitor as CLI client $VERSION This client performs appmonitor checks and puts the results as JSON to stdout. You can use the compiled binary on non PHP systems. (c) 2025 Institute for Medical education * University of Bern !!! This tool is in alpha stadium !!! SYNTAX: $_self [OPTIONS] -i <INIFILE> OPTIONS: -h, --help Print this help and exit -i, --ini Set an INI File to parse -l, --list list available checks and exit; --ini will be ignored -m, --modules list available Php modules in this binary -v, --verbose Verbose output -V, --version Show version and exit "; } // -------------------------------------------------------------------- // // MAIN // // -------------------------------------------------------------------- // put params to $ARGS if ($argc > 1) { parse_str(implode('&', array_slice($argv, 1)), $ARGS); } // check params if (isset($ARGS['-v']) || isset($ARGS['--verbose'])) { $FLAG_DEBUG = 1; } _wd("CLI ARGS: " . print_r($ARGS ?? [], 1)); // show version if (isset($ARGS['-V']) || isset($ARGS['--version'])) { _wd("Showing version"); echo "$VERSION\n"; exit(0); } // show help if (isset($ARGS['-h']) || isset($ARGS['--help'])) { _wd("Showing help"); _showHelp(); exit(0); } // ---------------------------------------------------------------------- _wd("Initializing appmonitor class"); $oMonitor = new appmonitor(); // show builtin checks if (isset($ARGS['-l']) || isset($ARGS['--list'])) { _wd("Showing checks"); echo implode("\n", $oMonitor->listChecks()); exit(0); } // show builtin modules if (isset($ARGS['-m']) || isset($ARGS['--modules'])) { _wd("Showing php modules"); $aMods=get_loaded_extensions(); sort($aMods); echo implode("\n", $aMods); exit(0); } $inifile = $ARGS["--ini"] ?? ($ARGS["-i"] ?? ""); if (!$inifile) { echo "ERROR: Set an INI File using -i=<FILE> (or --ini=<FILE>).\n"; exit(1); } _wd("Using ini file '$inifile'."); if (!file_exists($inifile)) { echo "ERROR: INI File '$inifile' does not exist.\n"; exit(1); } $aIni = parse_ini_file($inifile, true); if (!is_array($aIni)) { echo "ERROR: INI File '$inifile' could not be parsed.\n"; exit(1); } _wd("Parsed INI data: " . print_r($aIni, 1)); // ---------------------------------------------------------------------- // set metadata _set("setHost", $aIni['meta']['host'] ?? null); _set("setWebsite", $aIni['meta']['website'] ?? null); _set("setTtl", $aIni['meta']['ttl'] ?? null); foreach ($aIni['notifications']['email'] ?? [] as $sValue) { _set("addEmail", $sValue); } foreach ($aIni['notifications']['slack'] ?? [] as $sValue) { $aArray = json_decode($sValue, 1); $sChannel = array_keys($aArray)[0]; $sWebhook = array_values($aArray)[0]; _set("addSlackWebhook", $sChannel, $sWebhook); } // loop over checks $aChecks = $aIni; unset($aChecks["meta"]); unset($aChecks["notifications"]); $aArray=[]; foreach ($aChecks as $sKey => $aCheck) { $aChecks[$sKey]['name'] = $aCheck['name'] ?? $sKey; if ($aCheck['params']) { $aArray = json_decode($aCheck['params'], 1); if (!is_array($aArray)) { echo "ERROR: key 'params' for check [$sKey] must be JSON.\n"; echo "Value in $inifile: $aCheck[params]\n"; exit(1); } } $aAddCheck=[ "name" => $aCheck['name'] ?? $sKey, "description" => $aCheck['description'], "check" => [ "function" => $aCheck['function'], "params" => $aArray ?? [], ], ]; foreach(["group", "parent", "worstresult"] as $sCustomKey) { if (isset($aCheck[$sCustomKey])) { $aAddCheck[$sCustomKey] = $aCheck[$sCustomKey]; } } _wd("Execute Check '$sKey': " . print_r($aAddCheck, 1)); $oMonitor->addCheck($aAddCheck); /* $oMonitor->addCheck( [ "name" => "hello plugin", "description" => "Test a plugin ... plugins/checks/hello.php", "check" => [ "function" => "Hello", "params" => [ "message" => "Here I am", ], ], ] ); */ } // ---------------------------------------------------------------------- // send the response _wd("Setting result"); $oMonitor->setResult(); _wd("Send response"); $oMonitor->render();