From 442f9d115ef15bd62f40c32010a77fc2fcb05248 Mon Sep 17 00:00:00 2001 From: Petr Suchy Date: Tue, 4 Feb 2020 16:41:34 +0100 Subject: [PATCH] Added Separate check when server is down (#844) Future request - separate checks when down. Closes #755. --- cron/status.cron.php | 73 ++++++++++++++++++++++++--- docs/install.rst | 11 ++++ src/psm/Util/Install/Installer.php | 4 +- src/psm/Util/Server/UpdateManager.php | 9 +++- 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/cron/status.cron.php b/cron/status.cron.php index 92b70182..249e8743 100644 --- a/cron/status.cron.php +++ b/cron/status.cron.php @@ -28,6 +28,9 @@ namespace { // include main configuration and functionality + use psm\Router; + use psm\Util\Server\UpdateManager; + require_once __DIR__ . '/../src/bootstrap.php'; if (!psm_is_cli()) { @@ -81,21 +84,79 @@ namespace { // however if the cron has been running for X mins, we'll assume it died and run anyway // if you want to change PSM_CRON_TIMEOUT, have a look in src/includes/psmconfig.inc.php. // or you can provide the --timeout=x argument + + $status = null; + if (PHP_SAPI === 'cli') { + $shortOptions = 's:'; // status + + $longOptions = [ + 'status:' + ]; + + $options = getopt($shortOptions, $longOptions); + + $possibleValues = [ + 'on' => 'on', + '1' => 'on', + 'up' => 'on', + 'off' => 'off', + '0' => 'off', + 'down' => 'off' + ]; + + if ( + true === array_key_exists('status', $options) && + true === array_key_exists(strtolower($options['status']), $possibleValues) + ) { + $status = $possibleValues[$options['status']]; + } elseif ( + true === array_key_exists('s', $options) && + true === array_key_exists(strtolower($options['s']), $possibleValues) + ) { + $status = $possibleValues[$options['s']]; + } + } + + if ($status === 'off') { + $confPrefix = 'cron_off_'; + } else { + $confPrefix = 'cron_'; + } + $time = time(); if ( - psm_get_conf('cron_running') == 1 + psm_get_conf($confPrefix . 'running') == 1 && $cron_timeout > 0 - && ($time - psm_get_conf('cron_running_time') < $cron_timeout) + && ($time - psm_get_conf($confPrefix . 'running_time') < $cron_timeout) ) { die('Cron is already running. Exiting.'); } if (!defined('PSM_DEBUG') || !PSM_DEBUG) { - psm_update_conf('cron_running', 1); + psm_update_conf($confPrefix . 'running', 1); } - psm_update_conf('cron_running_time', $time); + psm_update_conf($confPrefix . 'running_time', $time); + /** @var Router $router */ + /** @var UpdateManager $autorun */ $autorun = $router->getService('util.server.updatemanager'); - $autorun->run(true); - psm_update_conf('cron_running', 0); + if ($status !== 'off') { + $autorun->run(true, $status); + } else { + set_time_limit(60); + if (false === defined('CRON_DOWN_INTERVAL')) { + define('CRON_DOWN_INTERVAL', 5); // every 5 second call update + } + $start = time(); + $i = 0; + while ($i < 59) { + $autorun->run(true, $status); + if ($i < (59 - CRON_DOWN_INTERVAL)) { + time_sleep_until($start + $i + CRON_DOWN_INTERVAL); + } + $i += CRON_DOWN_INTERVAL; + } + } + + psm_update_conf($confPrefix . 'running', 0); } diff --git a/docs/install.rst b/docs/install.rst index 93898e36..56126553 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -92,6 +92,16 @@ Please note that some distros have user-specific crontabs (e.g. Debian). If that */15 * * * * /usr/bin/php /var/www/html/phpservermon/cron/status.cron.php +If you want to check in different intervals online and offline servers you can use attribute `-s` (or `--status`) with value `on` or `off`. +So for example you want to check your servers which are online every 10 minutes and offline every 5 seconds. So configure two cron jobs:: + + */10 * * * * /usr/bin/php /var/www/html/phpservermon/cron/status.cron.php -s on + */1 * * * * /usr/bin/php /var/www/html/phpservermon/cron/status.cron.php -s off + +By default `off` servers are checked every 5 seconds. If you want to change it add into your config file this constant with required value in seconds:: + + define('CRON_DOWN_INTERVAL', 1); // every 1 second call update + The update script has been designed to prevent itself from running multiple times. It has a maximum timeout of 10 minutes. After that the script is assumed dead and the cronjob will run again. If you want to change the 10 minutes timeout, find the constant "PSM_CRON_TIMEOUT" in src/includes/psmconfig.inc.php. @@ -144,3 +154,4 @@ If you have problems setting up or accessing your monitor and do not know why, e To enable debug mode, add the following line to your config.php file:: define('PSM_DEBUG', true); + diff --git a/src/psm/Util/Install/Installer.php b/src/psm/Util/Install/Installer.php index 010b9fbf..eb307294 100644 --- a/src/psm/Util/Install/Installer.php +++ b/src/psm/Util/Install/Installer.php @@ -178,7 +178,9 @@ class Installer ('show_update', '1'), ('last_update_check', '0'), ('cron_running', '0'), - ('cron_running_time', '0');"; + ('cron_running_time', '0'), + ('cron_off_running', '0'), + ('cron_off_running_time', '0');"; $this->execSQL($queries); } diff --git a/src/psm/Util/Server/UpdateManager.php b/src/psm/Util/Server/UpdateManager.php index 29a397cd..92b37bad 100644 --- a/src/psm/Util/Server/UpdateManager.php +++ b/src/psm/Util/Server/UpdateManager.php @@ -49,9 +49,14 @@ class UpdateManager implements ContainerAwareInterface * Go :-) * * @param boolean $skip_perms if TRUE, no user permissions will be taken in account and all servers will be updated + * @param string|null $status If all servers (null), or just `on` or `off` should be checked. */ - public function run($skip_perms = false) + public function run($skip_perms = false, $status = null) { + if (false === in_array($status, ['on', 'off'], true)) { + $status = null; + } + // check if we need to restrict the servers to a certain user $sql_join = ''; @@ -67,7 +72,7 @@ class UpdateManager implements ContainerAwareInterface `s`.`header_value`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`,`s`.`telegram` FROM `" . PSM_DB_PREFIX . "servers` AS `s` {$sql_join} - WHERE `active`='yes' "; + WHERE `active`='yes' " . ($status !== null ? ' AND `status` = \'' . $status . '\'' : ''); $servers = $this->container->get('db')->query($sql);