Skip to content
Snippets Groups Projects
Commit e73f24dd authored by Hahn Axel (hahn)'s avatar Hahn Axel (hahn)
Browse files

update appmonitor client

parent 66116c2a
Branches
No related tags found
1 merge request!76update appmonitor client
Showing
with 954 additions and 84 deletions
......@@ -42,8 +42,10 @@ if (!class_exists('appmonitorcheck')) {
* 2020-05-03 0.110 axel.hahn@iml.unibe.ch update renderHtmloutput<br>
* 2023-07-06 0.128 axel.hahn@unibe.ch update httpcontent check<br>
* 2024-07-19 0.137 axel.hahn@unibe.ch php 8 only: use typed variables
* 2024-11-22 0.141 axel.hahn@unibe.ch Set client version to server version after updating http, mysqli and app checks
* 2025-01-02 0.149 axel.hahn@unibe.ch add getChecks method
* --------------------------------------------------------------------------------<br>
* @version 0.137
* @version 0.149
* @author Axel Hahn
* @link TODO
* @license GPL
......@@ -57,7 +59,7 @@ class appmonitor
* Name and Version number
* @var string
*/
protected string $_sVersion = 'php-client-v0.137';
protected string $_sVersion = 'php-client-v0.149';
/**
* config: default ttl for server before requesting the client check again
......@@ -402,6 +404,15 @@ class appmonitor
die('<h1>503 Service Unavailable</h1>' . $sMessage);
}
/**
* Get array with executed checks
* @return array
*/
public function getChecks(): array
{
return $this->_aChecks;
}
/**
* Get full array for response with metadata and checks
* @return array
......
......@@ -29,6 +29,9 @@
# 2022-05-03 0.3 <axel.hahn@iml.unibe.ch> create general_include.php
# 2024-07-25 0.4 <axel.hahn@iml.unibe.ch> update quoting and comments
# 2024-07-31 0.5 <axel.hahn@iml.unibe.ch> Show more helpful information; wait on 1st install; added param -n
# 2024-12-23 0.6 <axel.hahn@iml.unibe.ch> remove which command. Maybe it is not installed on a shared hoster.
# 2024-12-26 0.7 <axel.hahn@iml.unibe.ch> rsync test with --version instead of -V (for compatibility with older versions)
# 2025-01-06 0.8 <axel.hahn@iml.unibe.ch> git test with --version instead of -v (for compatibility with older versions)
# ======================================================================
# ----------------------------------------------------------------------
......@@ -38,7 +41,7 @@
readonly git_repo_url="https://github.com/iml-it/appmonitor.git"
readonly docs_url="https://os-docs.iml.unibe.ch/appmonitor/PHP_client/index.html"
readonly line="______________________________________________________________________________"
readonly version="0.5"
readonly version="0.8"
git_target=/tmp/git_data__appmonitor
client_from="${git_target}/public_html/client"
......@@ -168,8 +171,11 @@ ENDOFHELP
fi
esac
which rsync >/dev/null || exit 1
which git >/dev/null || exit 1
# which rsync >/dev/null || exit 1
# which git >/dev/null || exit 1
rsync --version >/dev/null || exit 1
git --version >/dev/null || exit 1
test -f general_include.php && isUpdate=1
......@@ -221,6 +227,7 @@ rsync -rav \
--exclude "example.json" \
--exclude "check-appmonitor-server.php" \
--exclude "local.php" \
--exclude "git_update_appmonitor.sh" \
$client_from/* "$client_to"
echo
......@@ -260,5 +267,6 @@ echo "Documentation: $docs_url"
echo
echo $line
echo done.
cp -rp "$client_from/git_update_appmonitor.sh" "$client_to"
# ----------------------------------------------------------------------
<?php
/* ______________________________________________________________________
*
* A P P M O N I T O R :: CLIENT - CHECK
* ______________________________________________________________________
*
* Check for a Concrete5 instance.
* CMS https://www.concrete5.org/
*
* It checks
* - the write access to the config file
* - the write access to the file storage
* - connect to mysql database (which is read from config)
* - ssl certificate (on https request only)
*
* @author: Axel Hahn - https://www.axel-hahn.de/
* ----------------------------------------------------------------------
* 2018-06-30 v1.0 ah
* 2019-05-24 v1.01 ah detect include or standalone mode
* 2024-11-18 v1.02 <axel.hahn@unibe.ch> integrate in appmonitor repository
* 2024-11-22 v1.03 <axel.hahn@unibe.ch> send 400 instead of 503 on error
* 2024-12-21 v1.04 ah short array syntax; add php-modules and parent
* 2025-01-06 v1.05 ah add df
*/
// ----------------------------------------------------------------------
// Init
// ----------------------------------------------------------------------
$aAppDefaults = [
"name" => "Concrete5 CMS",
"tags" => ["concrete5", "cms"],
"df" => [
"warning" => "100MB",
"critical" => "10MB"
]
];
require 'inc_appcheck_start.php';
// ----------------------------------------------------------------------
// Read Concrete5 specific config items
// ----------------------------------------------------------------------
$sConfigfile = $sApproot . '/application/config/database.php';
if (!file_exists($sConfigfile)) {
header('HTTP/1.0 400 Bad request');
die('ERROR: Config file was not found. Use ?rel=[subdir] to set the correct subdir to find /application/config/database.php.');
}
$aConfig = include($sConfigfile);
$sActive = $aConfig['default-connection'];
if (!isset($aConfig['connections'][$sActive])) {
header('HTTP/1.0 400 Bad request');
die('ERROR: Config file application/config/database.php was read - but database connection could not be detected from it in connections -> ' . $sActive . '.');
}
// print_r($aConfig['connections'][$sActive]); die();
$aDb = $aConfig['connections'][$sActive];
// ----------------------------------------------------------------------
// checks
// ----------------------------------------------------------------------
// required php modules
// see https://documentation.concretecms.org/developers/introduction/system-requirements
$oMonitor->addCheck(
[
"name" => "PHP modules",
"description" => "Check needed PHP modules",
// "group" => "folder",
"check" => [
"function" => "Phpmodules",
"params" => [
"required" => [
"PDO",
"curl",
"dom",
"fileinfo",
"gd",
"iconv",
"mbstring",
"pdo_mysql",
"xml",
"zip"
],
"optional" => [],
],
],
]
);
$oMonitor->addCheck(
[
"name" => "config file",
"description" => "The config file must be readable and writable",
"check" => [
"function" => "File",
"params" => [
"filename" => $sConfigfile,
"file" => true,
"readable" => true,
"writable" => true,
],
],
]
);
$oMonitor->addCheck(
[
"name" => "check file storage",
"description" => "The file storage must be writable",
"check" => [
"function" => "File",
"params" => [
"filename" => "$sApproot/application/files",
"dir" => true,
"writable" => true,
],
],
]
);
$sPdoConnectString = "mysql:host=$aDb[server];port=3306;dbname=$aDb[database];";
$oMonitor->addCheck(
[
"name" => "Mysql Master",
"description" => "Connect mysql server " . $aDb['server'] . " as user " . $aDb['username'] . " to scheme " . $aDb['database'],
"parent" => "config file",
"check" => [
"function" => "PdoConnect",
"params" => [
"connect" => $sPdoConnectString,
"user" => $aDb['username'],
"password" => $aDb['password'],
],
],
]
);
if (isset($aAppDefaults['df'])) {
$oMonitor->addCheck(
[
"name" => "check disk space",
"description" => "The file storage must have some space left - warn: " . $aAppDefaults["df"]['warning'] . "/ critical: " . $aAppDefaults["df"]['critical'],
"parent" => "check file storage",
"check" => [
"function" => "Diskfree",
"params" => [
"directory" => "$sApproot/application",
"warning" => $aAppDefaults["df"]['warning'],
"critical" => $aAppDefaults["df"]['critical'],
],
],
]
);
}
// ----------------------------------------------------------------------
require 'inc_appcheck_end.php';
// ----------------------------------------------------------------------
<?php
/* ______________________________________________________________________
*
* A P P M O N I T O R :: CLIENT - CHECK
* ______________________________________________________________________
*
* Check for a Dokuwiki instance.
* https://www.dokuwiki.org/
*
* @author: Axel Hahn - https://www.axel-hahn.de/
* ----------------------------------------------------------------------
* 2024-12-23 v1.00 ah initial version
* 2024-12-26 v1.01 ah fix directory checks
* 2025-01-06 v1.02 ah add df
*/
// ----------------------------------------------------------------------
// Init
// ----------------------------------------------------------------------
$aAppDefaults = [
"name" => "Dokuwiki",
"tags" => ["dokuwiki", "wiki"],
"df" => [
"warning" => "100MB",
"critical" => "10MB"
]
];
require 'inc_appcheck_start.php';
// ----------------------------------------------------------------------
// Read Concrete5 specific config items
// ----------------------------------------------------------------------
$sConfigfile = "$sApproot/conf/local.php";
if (!file_exists($sConfigfile)) {
header('HTTP/1.0 400 Bad request');
die('ERROR: Config file was not found. Use ?rel=[subdir] to set the correct subdir to find /conf/local.php.');
}
// ----------------------------------------------------------------------
// checks
// ----------------------------------------------------------------------
// required php modules
// see https://www.dokuwiki.org/install:php
$oMonitor->addCheck(
[
"name" => "PHP modules",
"description" => "Check needed PHP modules",
// "group" => "folder",
"check" => [
"function" => "Phpmodules",
"params" => [
"required" => [
"json",
"pcre",
"session",
],
"optional" => [
"bz2",
"gd",
"intl",
"mbstring",
"openssl",
"zlib"
],
],
],
]
);
$oMonitor->addCheck(
[
"name" => "config file",
"description" => "The config file must be readable and writable",
"check" => [
"function" => "File",
"params" => [
"filename" => $sConfigfile,
"file" => true,
"readable" => true,
"writable" => true,
],
],
]
);
foreach (['lib/tpl/', 'lib/plugins/',] as $sDir) {
$oMonitor->addCheck(
[
"name" => "check read dir $sDir",
"description" => "The directory $sDir must be readable",
"group" => "folder",
"check" => [
"function" => "File",
"params" => [
"filename" => "$sApproot/$sDir",
"dir" => true,
"readable" => true,
],
],
]
);
}
foreach (['data/attic', 'data/cache', 'data/index', 'data/locks', 'data/log', 'data/media', 'data/meta', 'data/pages', 'data/tmp',] as $sDir) {
$oMonitor->addCheck(
[
"name" => "check writable dir $sDir",
"description" => "The directory $sDir must be readable and writable",
"group" => "folder",
"check" => [
"function" => "File",
"params" => [
"filename" => "$sApproot/$sDir",
"dir" => true,
"readable" => true,
"writable" => true,
],
],
]
);
}
if (isset($aAppDefaults['df'])) {
$oMonitor->addCheck(
[
"name" => "check disk space",
"description" => "The file storage must have some space left - warn: " . $aAppDefaults["df"]['warning'] . "/ critical: " . $aAppDefaults["df"]['critical'],
"check" => [
"function" => "Diskfree",
"params" => [
"directory" => "$sApproot/data",
"warning" => $aAppDefaults["df"]['warning'],
"critical" => $aAppDefaults["df"]['critical'],
],
],
]
);
}
// ----------------------------------------------------------------------
require 'inc_appcheck_end.php';
// ----------------------------------------------------------------------
......@@ -13,12 +13,28 @@
* 2021-11-nn removed all checks ... created as single files
* 2022-03-28 move checks into plugins/apps/
* 2024-07-23 php 8: short array syntax
* 2024-12-28 added check for custom config and url file (if they exist)
*/
// ----------------------------------------------------------------------
// files and dirs
// ----------------------------------------------------------------------
$oMonitor->addCheck(
[
"name" => "PHP modules",
"description" => "Check needed PHP modules",
// "group" => "folder",
"check" => [
"function" => "Phpmodules",
"params" => [
"required" => ["curl"],
"optional" => [],
],
],
]
);
$oMonitor->addCheck(
[
"name" => "write to ./tmp/",
......@@ -49,48 +65,74 @@ $oMonitor->addCheck(
],
]
);
$oMonitor->addCheck(
[
"name" => "check config file",
"description" => "The config file must be writable",
"description" => "The default config file must be readable",
"parent" => "write to ./config/",
// "group" => "file",
"check" => [
"function" => "File",
"params" => [
"filename" => "$sApproot/server/config/appmonitor-server-config.json",
"filename" => "$sApproot/server/config/appmonitor-server-config-defaults.json",
"file" => true,
"writable" => true,
"readable" => true,
],
],
]
);
$oMonitor->addCheck(
[
"name" => "PHP modules",
"description" => "Check needed PHP modules",
// "group" => "folder",
"check" => [
"function" => "Phpmodules",
"params" => [
"required" => ["curl"],
"optional" => [],
if (is_file("$sApproot/server/config/appmonitor-server-config.json")) {
$oMonitor->addCheck(
[
"name" => "check custom config file",
"description" => "The custom config file must be readable and writable",
"parent" => "write to ./config/",
// "group" => "file",
"check" => [
"function" => "File",
"params" => [
"filename" => "$sApproot/server/config/appmonitor-server-config.json",
"file" => true,
"readable" => true,
"writable" => true,
],
],
],
]
);
]
);
}
if (is_file("$sApproot/server/config/appmonitor-server-urls.json")) {
$oMonitor->addCheck(
[
"name" => "check url file",
"description" => "The url config file must be readable and writable",
"parent" => "write to ./config/",
// "group" => "file",
"check" => [
"function" => "File",
"params" => [
"filename" => "$sApproot/server/config/appmonitor-server-urls.json",
"file" => true,
"readable" => true,
"writable" => true,
],
],
]
);
}
// ----------------------------------------------------------------------
// protect dirs against web access
// specialty: if the test results in an error, the total result switches
// to WARNING -> see worstresult value
// ----------------------------------------------------------------------
$sBaseUrl = 'http'.(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ? 's' : '')
.'://'.$_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT']
.dirname(dirname($_SERVER['REQUEST_URI']));
$sBaseUrl = 'http' . (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ? 's' : '')
. '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT']
. dirname(dirname($_SERVER['REQUEST_URI']));
foreach(['server/config', 'server/tmp'] as $sMyDir){
foreach (['server/config', 'server/tmp'] as $sMyDir) {
$oMonitor->addCheck(
[
"name" => "http to $sMyDir",
......@@ -111,15 +153,15 @@ foreach(['server/config', 'server/tmp'] as $sMyDir){
// ----------------------------------------------------------------------
// count of current projects
// ----------------------------------------------------------------------
require_once($sApproot.'/server/classes/appmonitor-server.class.php');
$oServer=new appmonitorserver();
$iCount=count($oServer->getAppIds());
require_once($sApproot . '/server/classes/appmonitor-server.class.php');
$oServer = new appmonitorserver();
$iCount = count($oServer->getAppIds());
$oMonitor->addCheck(
[
"name" => "appcounter",
"description" => "Monitored apps",
"group" => "monitor",
"parent" => "check config file",
"parent" => false,
"check" => [
"function" => "Simple",
"params" => [
......@@ -134,11 +176,11 @@ $oMonitor->addCheck(
// ----------------------------------------------------------------------
// check running service
// ----------------------------------------------------------------------
require_once($sApproot.'/server/classes/tinyservice.class.php');
require_once($sApproot . '/server/classes/tinyservice.class.php');
ob_start();
$oService = new tinyservice("$sApproot/server/service.php", 15, "$sApproot/server/tmp");
$sIsStopped=$oService->canStart();
$out=ob_get_contents();
$sIsStopped = $oService->canStart();
$out = ob_get_contents();
ob_clean();
$oMonitor->addCheck(
[
......@@ -149,13 +191,13 @@ $oMonitor->addCheck(
"function" => "Simple",
"params" => [
"result" => ($sIsStopped ? RESULT_WARNING : RESULT_OK),
"value" => ($sIsStopped
? "Info: Service is NOT running. Apps are checked interactively only (if the appmonitor web ui is running). | Output: $out"
"value" => ($sIsStopped
? "Info: Service is NOT running. Apps are checked interactively only (if the appmonitor web ui is running). | Output: $out"
: "OK, service is running. | Output: $out"
)
],
],
"worstresult" => RESULT_OK
"worstresult" => RESULT_OK
]
);
// ----------------------------------------------------------------------
......
......@@ -5,9 +5,29 @@
* ______________________________________________________________________
*/
include 'shared_check_ssl.php';
// $bStandalone was set in inc_appcheck_start.php
// send response if client was not initialized there
if($bStandalone){
if ($bStandalone) {
if(count($oMonitor->getChecks())==0){
$oMonitor->addCheck(
[
"name" => "Simple",
"description" => "Welcome to a simple app check. This is just a quick winner.",
"check" => [
"function" => "Simple",
"params" => [
"result" => RESULT_OK,
"value" => "Create a custom check and add all checks you need to test the ability to run the application",
],
],
]
);
}
$oMonitor->setResult();
$oMonitor->render();
}
......
......@@ -9,32 +9,54 @@
// CHECK IF THE APPROOT IS SET
// ----------------------------------------------------------------------
if (!$sApproot) {
header('HTTP/1.0 503 Service Unavailable');
echo "<h1>503 Service Unavailable</h1>";
echo 'ERROR:'.PHP_EOL;
echo '$sApproot was not set. Define it before including the application check.'.PHP_EOL;
echo 'Set the base folder of your application installation.'.PHP_EOL;
echo PHP_EOL;
echo 'Example:'.PHP_EOL;
echo '$sApproot = $_SERVER[\'DOCUMENT_ROOT\'];'.PHP_EOL;
echo '$sApproot = $_SERVER[\'DOCUMENT_ROOT\'].\'/myapp\';'.PHP_EOL;
die();
}
// initialize client and set very basic metadata ... if needed
$bStandalone=!(class_exists('appmonitor') && isset($oMonitor));
if($bStandalone){
require_once(__DIR__.'/../../classes/appmonitor-client.class.php');
$bStandalone = !(class_exists('appmonitor') && isset($oMonitor));
if ($bStandalone) {
require_once __DIR__ . '/../../classes/appmonitor-client.class.php';
$oMonitor = new appmonitor();
$oMonitor->setWebsite('Wordpress Instance');
@include __DIR__.'/../../general_include.php';
}
if (!isset($sApproot) || empty($sApproot)) {
$sApproot = $_SERVER['DOCUMENT_ROOT'];
if (isset($_GET['rel'])) {
$sApproot .= str_replace('..', '__', $_GET['rel']);
if (!is_dir($sApproot)) {
header('HTTP/1.0 400 Bad request');
die('ERROR: The given rel dir does not exist below webroot.');
}
}
}
// ----------------------------------------------------------------------
// FUNCTIONS
// ----------------------------------------------------------------------
// --- set values coming from app plugins defaults & GET params
// "name"
// "host"
// "tags"
// "dfw", "dfc"
$aAppDefaults['name'] = (isset($_GET['name']) && $_GET['name']) ? $_GET['name'] : $aAppDefaults['name'];
$aAppDefaults['host'] = $_GET['host']
? explode(',', $_GET['host'])
: ($_SERVER['HTTP_HOST'] ?? '');
$aAppDefaults['tags'] = $_GET['tags'] ? explode(',', $_GET['tags']) : $aAppDefaults['tags'];
$aAppDefaults['df']['warning'] = (isset($_GET['dfw']) && $_GET['dfw']) ? $_GET['dfw'] : $aAppDefaults['df']['warning'] ?? false;
$aAppDefaults['df']['critical'] = (isset($_GET['dfc']) && $_GET['dfc']) ? $_GET['dfc'] : $aAppDefaults['df']['critical'] ?? false;
if($aAppDefaults['df']['warning'] == false && $aAppDefaults['df']['critical'] == false) {
unset($aAppDefaults['df']);
}
if ($aAppDefaults['name']) {
$oMonitor->setWebsite($aAppDefaults['name']);
}
if ($aAppDefaults['host']) {
$oMonitor->setHost($aAppDefaults['host']);
}
;
if (isset($aAppDefaults['tags']) && is_array($aAppDefaults['tags']) && count($aAppDefaults['tags']) > 0) {
foreach ($aAppDefaults['tags'] as $sTag) {
$oMonitor->addTag($sTag);
}
}
@include __DIR__ . '/../../general_include.php';
}
// ----------------------------------------------------------------------
<?php
/* ______________________________________________________________________
*
* A P P M O N I T O R :: CLIENT - CHECK
* ______________________________________________________________________
*
* Check for a Matomo instance.
* Open Analytics platform - https://matomo.org/
*
* It checks
* - the write access to the config file
* - connect to matomo database (which is read from config)
* - ssl certificate (on https request only)
*
* @author: Axel Hahn - https://www.axel-hahn.de/
* ----------------------------------------------------------------------
* 2018-06-30 v1.0
* 2019-05-24 v1.01 detect include or standalone mode
* 2019-05-24 v1.02 detect include or standalone mode
* 2024-12-20 v1.03 <axel.hahn@unibe.ch> integrate in appmonitor repository
* 2024-12-21 v1.04 ah add php-modules and parent
* 2025-01-06 v1.05 ah add checks for writable dirs; add df
*/
// ----------------------------------------------------------------------
// Init
// ----------------------------------------------------------------------
$aAppDefaults = [
"name" => "Matomo web statistics",
"tags" => ["matomo", "statistics"],
"df" => [
"warning" => "100MB",
"critical" => "10MB"
]
];
require 'inc_appcheck_start.php';
// ----------------------------------------------------------------------
// Read Matomo specific config items
// ----------------------------------------------------------------------
$sConfigfile = $sApproot . '/config/config.ini.php';
if (!file_exists($sConfigfile)) {
header('HTTP/1.0 400 Bad request');
die('ERROR: Config file was not found. Set a correct $sApproot pointing to Matomo install dir.');
}
$aConfig = parse_ini_file($sConfigfile, true);
// ----------------------------------------------------------------------
// checks
// ----------------------------------------------------------------------
// required php modules
// see https://matomo.org/faq/on-premise/matomo-requirements/
$oMonitor->addCheck(
[
"name" => "PHP modules",
"description" => "Check needed PHP modules",
// "group" => "folder",
"check" => [
"function" => "Phpmodules",
"params" => [
"required" => [
"PDO",
"curl",
"gd",
"mbstring",
"pdo_mysql",
"xml",
],
"optional" => [],
],
],
]
);
$oMonitor->addCheck(
[
"name" => "config file",
"description" => "The config file must be readable and writable",
"check" => [
"function" => "File",
"params" => [
"filename" => $sConfigfile,
"file" => true,
"writable" => true,
],
],
]
);
$oMonitor->addCheck(
[
"name" => "Mysql Connect",
"description" => "Connect mysql server " . $aConfig['database']['host'] . " as user " . $aConfig['database']['username'] . " to scheme " . $aConfig['database']['dbname'],
"parent" => "config file",
"check" => [
"function" => "MysqlConnect",
"params" => [
"server" => $aConfig['database']['host'],
"user" => $aConfig['database']['username'],
"password" => $aConfig['database']['password'],
"db" => $aConfig['database']['dbname'],
],
],
]
);
// directory list from system check
foreach (['/tmp', '/tmp/assets', '/tmp/cache', '/tmp/climulti', '/tmp/latest', '/tmp/logs', '/tmp/sessions', '/tmp/tcpdf', '/tmp/templates_c'] as $sDir) {
$oMonitor->addCheck(
[
"name" => "check writable dir $sDir",
"description" => "The directory $sDir must be readable and writable",
"group" => "folder",
"check" => [
"function" => "File",
"params" => [
"filename" => "$sApproot/$sDir",
"dir" => true,
"readable" => true,
"writable" => true,
],
],
]
);
}
if (isset($aAppDefaults['df'])) {
$oMonitor->addCheck(
[
"name" => "check disk space",
"description" => "The file storage must have some space left - warn: " . $aAppDefaults["df"]['warning'] . "/ critical: " . $aAppDefaults["df"]['critical'],
"check" => [
"function" => "Diskfree",
"params" => [
"directory" => $sApproot,
"warning" => $aAppDefaults["df"]['warning'],
"critical" => $aAppDefaults["df"]['critical'],
],
],
]
);
}
// ----------------------------------------------------------------------
require 'inc_appcheck_end.php';
// ----------------------------------------------------------------------
\ No newline at end of file
<?php
/* ______________________________________________________________________
*
* A P P M O N I T O R :: CLIENT - CHECK
* ______________________________________________________________________
*
* Check for a Nextcloud instance.
*
* It checks
* - the read + write access to the config file
* - connect to database (which is read from config)
* - the read + write access to data dir
* - free disk space on data dir
* - ssl certificate (on https request only)
*
* @author: Axel Hahn - https://www.axel-hahn.de/
* ----------------------------------------------------------------------
* 2025-01-02 v1.0
*/
// ----------------------------------------------------------------------
// Init
// ----------------------------------------------------------------------
$aAppDefaults = [
"name" => "Nextcloud",
"tags" => ["nextcloud", "share"],
"df" => [
"warning" => "1GB",
"critical" => "100MB"
]
];
require 'inc_appcheck_start.php';
// ----------------------------------------------------------------------
// Read Nextcloud specific config items
// ----------------------------------------------------------------------
$sConfigfile = "$sApproot/config/config.php";
if (!file_exists($sConfigfile)) {
header('HTTP/1.0 400 Bad request');
die('ERROR: Config file was not found. Use ?rel=/NAME or similiar to set a relative install dir.');
}
if (!include "$sConfigfile") {
header('HTTP/1.0 400 Bad request');
die('ERROR: Unable to read config file.');
}
// now $CONFIG is available ...
/*
Array
(
[instanceid] => ocw...
[passwordsalt] => cNs...
[secret] => kFdQXw2w...
[trusted_domains] => Array
(
[0] => https://www.example.com
)
[datadirectory] => /home/httpd/cloud/data
[dbtype] => mysql
[version] => 30.0.4.1
[overwrite.cli.url] => https://www.example.com/cloud
[dbname] => nextcloud
[dbhost] => 127.0.0.1
[dbport] =>
[dbtableprefix] => oc_
[mysql.utf8mb4] => 1
[dbuser] => mydbuser
[dbpassword] => 516px9kcc...
[installed] => 1
[maintenance] =>
[theme] =>
[loglevel] => 2
[mail_smtpmode] => smtp
[mail_sendmailmode] => smtp
)
*/
if (!isset($CONFIG) || !is_array($CONFIG)) {
header('HTTP/1.0 400 Bad request');
die('ERROR: Config file was found but has unexpected format.');
}
// ----------------------------------------------------------------------
// checks
// ----------------------------------------------------------------------
// required php modules
// see https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html
// doesn't show needed modules
/*
$oMonitor->addCheck(
[
"name" => "PHP modules",
"description" => "Check needed PHP modules",
// "group" => "folder",
"check" => [
"function" => "Phpmodules",
"params" => [
"required" => [
"PDO",
"curl",
"gd",
"mbstring",
"pdo_mysql",
"xml",
],
"optional" => [],
],
],
]
);
*/
$oMonitor->addCheck(
[
"name" => "config file",
"description" => "The config file must be readable and writable",
"check" => [
"function" => "File",
"params" => [
"filename" => $sConfigfile,
"file" => true,
"readable" => true,
"writable" => true,
],
],
]
);
$oMonitor->addCheck(
[
"name" => "Version",
"description" => "Nextcloud version",
"parent" => "config file",
"check" => [
"function" => "Simple",
"params" => [
"result" => RESULT_OK,
"value" => $CONFIG['version'] ?? "??",
"count" => $CONFIG['version'] ?? "??",
"visual" => "simple"
],
],
]
);
$oMonitor->addCheck(
[
"name" => "maintenance",
"description" => "Is maintenance mode enabled?",
"parent" => "config file",
"check" => [
"function" => "Simple",
"params" => [
"result" => $CONFIG['maintenance'] ? RESULT_ERROR : RESULT_OK,
"value" => $CONFIG['maintenance'] ? "enabled - public access is denied" : "disabled (OK)",
],
],
]
);
// ----------------------------------------------------------------------
// database
// ----------------------------------------------------------------------
if($CONFIG['dbtype'] == "mysql"){
$oMonitor->addCheck(
[
"name" => "Mysql Connect",
// "description" => "Connect mysql server " . $aConfig['database']['host'] . " as user " . $aConfig['database']['username'] . " to scheme " . $aConfig['database']['dbname'],
"description" => "Connect mysql server",
"parent" => "config file",
"check" => [
"function" => "MysqlConnect",
"params" => [
"server" => $CONFIG['dbhost'],
"user" => $CONFIG['dbuser'],
"password" => $CONFIG['dbpassword'],
"db" => $CONFIG['dbname'],
"port" => $CONFIG['dbport'],
],
],
]
);
}
// ----------------------------------------------------------------------
// data directory
// ----------------------------------------------------------------------
$oMonitor->addCheck(
[
"name" => "data dir",
"description" => "Data directory must be readable and writable",
"parent" => "config file",
"check" => [
"function" => "File",
"params" => [
"filename" => $CONFIG['datadirectory'],
"dir" => true,
"readable" => true,
"writable" => true,
],
],
]
);
if (isset($aAppDefaults['df'])) {
$oMonitor->addCheck(
[
"name" => "check disk space",
"description" => "The file storage must have some space left - warn: " . $aAppDefaults["df"]['warning'] . "/ critical: " . $aAppDefaults["df"]['critical'],
"parent" => "data dir",
"check" => [
"function" => "Diskfree",
"params" => [
"directory" => $CONFIG['datadirectory'],
"warning" => $aAppDefaults["df"]['warning'],
"critical" => $aAppDefaults["df"]['critical'],
],
],
]
);
}
// ----------------------------------------------------------------------
require 'inc_appcheck_end.php';
// ----------------------------------------------------------------------
......@@ -18,7 +18,7 @@
// ----------------------------------------------------------------------
// check certificate - only if https is used
// ----------------------------------------------------------------------
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']){
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) {
$oMonitor->addCheck(
[
"name" => "Certificate check",
......
......@@ -20,8 +20,24 @@
* 2019-05-24 v0.02 detect include or standalone mode
* 2019-05-24 v0.03 detect include or standalone mode
* 2024-07-31 v0.04 first version for wordpress check in plugins/apps/
* 2024-11-21 v0.05 use shared_check_sl
* 2024-11-22 v0.07 <axel.hahn@unibe.ch> send 400 instead of 503 on error
* 2024-12-21 v0.08 ah add php-modules and parent
* 2025-01-06 v1.05 ah add df
*/
// ----------------------------------------------------------------------
// Init
// ----------------------------------------------------------------------
$aAppDefaults = [
"name" => "Wordpress",
"tags" => ["wordpress", "blog"],
"df" => [
"warning" => "100MB",
"critical" => "10MB"
]
];
require 'inc_appcheck_start.php';
......@@ -31,23 +47,62 @@ require 'inc_appcheck_start.php';
$sConfigfile = $sApproot . '/wp-config.php';
if (!file_exists($sConfigfile)) {
header('HTTP/1.0 503 Service Unavailable');
die('ERROR: Config file [wp-config.php] was not found. Set a correct $sApproot pointing to wordpress install dir.');
header('HTTP/1.0 400 Bad request');
die('ERROR: Config file [wp-config.php] was not found. Set a correct app root pointing to wordpress install dir.');
}
require($sConfigfile);
$aDb=[
'server' => DB_HOST,
'username' => DB_USER,
'password' => DB_PASSWORD,
'database' => DB_NAME,
// 'port' => ??,
];
$aDb = [
'server' => DB_HOST,
'username' => DB_USER,
'password' => DB_PASSWORD,
'database' => DB_NAME,
// 'port' => ??,
];
// ----------------------------------------------------------------------
// checks
// ----------------------------------------------------------------------
// required php modules
// see https://ertano.com/required-php-modules-for-wordpress/
$oMonitor->addCheck(
[
"name" => "PHP modules",
"description" => "Check needed PHP modules",
// "group" => "folder",
"check" => [
"function" => "Phpmodules",
"params" => [
"required" => [
// "cmath",
"cli",
"curl",
"date",
"dom",
"fileinfo",
"filter",
"gd",
"gettext",
"hash",
"iconv",
"imagick",
"json",
// "libsodium",
"mysql",
"openssl",
"pcre",
// "opcache",
// "readline",
"xml",
"zip"
],
"optional" => [],
],
],
]
);
$oMonitor->addCheck(
[
"name" => "config file",
......@@ -72,30 +127,34 @@ $oMonitor->addCheck(
"check" => [
"function" => "MysqlConnect",
"params" => [
"server" => $aDb['server'],
"user" => $aDb['username'],
"server" => $aDb['server'],
"user" => $aDb['username'],
"password" => $aDb['password'],
"db" => $aDb['database'],
"db" => $aDb['database'],
// "port" => $aDb['port'],
],
],
]
);
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']){
if (isset($aAppDefaults['df'])) {
$oMonitor->addCheck(
[
"name" => "Certificate check",
"description" => "Check if SSL cert is valid and does not expire soon",
"name" => "check disk space",
"description" => "The file storage must have some space left - warn: " . $aAppDefaults["df"]['warning'] . "/ critical: " . $aAppDefaults["df"]['critical'],
"check" => [
"function" => "Cert",
"function" => "Diskfree",
"params" => [
"directory" => "$sApproot",
"warning" => $aAppDefaults["df"]['warning'],
"critical" => $aAppDefaults["df"]['critical'],
],
],
]
);
}
// ----------------------------------------------------------------------
require 'inc_appcheck_end.php';
// ----------------------------------------------------------------------
......@@ -19,7 +19,7 @@
*
* 2021-10-26 <axel.hahn@iml.unibe.ch>
* 2024-07-23 <axel.hahn@unibe.ch> php 8 only: use typed variables
*
* 2025-01-02 <www.axel-hahn.de> update output
*/
class checkDiskfree extends appmonitorcheck
{
......@@ -58,7 +58,7 @@ class checkDiskfree extends appmonitorcheck
$iCritical = $this->_getSize($aParams["critical"]);
$iSpaceLeft = disk_free_space($sDirectory);
$sMessage = '[' . $sDirectory . '] has ' . $this->_getHrSize($iSpaceLeft) . ' left.';
$sMessage = $this->_getHrSize($iSpaceLeft) . ' left in [' . $sDirectory . '].';
if ($iWarn) {
if ($iWarn <= $iCritical) {
......@@ -68,7 +68,7 @@ class checkDiskfree extends appmonitorcheck
if ($iWarn < $iSpaceLeft) {
return [
RESULT_OK,
"$sMessage Warning level is not reached yet (still " . $this->_getHrSize($iSpaceLeft - $iWarn) . "over warning limit)."
"$sMessage Warning level is not reached yet (still " . $this->_getHrSize($iSpaceLeft - $iWarn) . " over warning limit)."
];
}
if ($iWarn > $iSpaceLeft && $iCritical < $iSpaceLeft) {
......
......@@ -21,7 +21,7 @@
* 2022-12-21 <axel.hahn@unibe.ch> add flag sslverify
* 2023-07-06 <axel.hahn@unibe.ch> add flag userpwd
* 2024-07-23 <axel.hahn@unibe.ch> php 8 only: use typed variables
*
* 2024-11-22 <axel.hahn@unibe.ch> Return unknown if curl module is not active
*/
class checkHttpContent extends appmonitorcheck
{
......@@ -67,8 +67,7 @@ class checkHttpContent extends appmonitorcheck
{
$this->_checkArrayKeys($aParams, "url");
if (!function_exists("curl_init")) {
header('HTTP/1.0 503 Service Unavailable');
die("ERROR: PHP CURL module is not installed.");
return [RESULT_UNKNOWN, "UNKNOWN: Unable to perform mysqli test. The php-curl module is not active."];
}
$bShowContent = (isset($aParams["content"]) && $aParams["content"]) ? true : false;
$ch = curl_init($aParams["url"]);
......
......@@ -19,7 +19,7 @@
*
* 2021-10-27 <axel.hahn@iml.unibe.ch>
* 2024-07-23 <axel.hahn@unibe.ch> php 8 only: use typed variables
*
* 2024-11-22 <axel.hahn@unibe.ch> detect installed mysqli function
*/
class checkMysqlConnect extends appmonitorcheck
{
......@@ -48,6 +48,9 @@ class checkMysqlConnect extends appmonitorcheck
public function run(array $aParams): array
{
$this->_checkArrayKeys($aParams, "server,user,password,db");
if (!function_exists("mysqli_init")) {
return [RESULT_UNKNOWN, "UNKNOWN: Unable to perform mysqli test. The php-mysqli module is not active."];
}
$mysqli = mysqli_init();
if (!$mysqli) {
return [RESULT_ERROR, 'ERROR: mysqli_init failed.'];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment