From f978545801cbd1a67739af96606694571112f962 Mon Sep 17 00:00:00 2001 From: Germs2004 <5519340+Germs2004@users.noreply.github.com> Date: Mon, 7 Sep 2020 11:06:02 -0400 Subject: [PATCH 1/4] added field: connectivity_sanity_test connectivity_sanity_test holds an IP address which will be pinged before and after this server gets its uptime checked --- src/templates/default/module/server/server/update.tpl.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/templates/default/module/server/server/update.tpl.html b/src/templates/default/module/server/server/update.tpl.html index 286a05d3..60b72057 100644 --- a/src/templates/default/module/server/server/update.tpl.html +++ b/src/templates/default/module/server/server/update.tpl.html @@ -45,6 +45,8 @@ + + {{ macro.input_field("text", "connectivity_sanity_test", null, "connectivity_sanity_test", label_connectivity_sanity_test, edit_value_connectivity_sanity_test, null, null, null, label_connectivity_sanity_test_description, null, null, null) }} {{ macro.input_field("number", "port", "port types typeService", "port", label_custom_port, edit_value_port, null, "5") }} From 638a8ec4f4a9f46693e47ed4511f2806e1c6d3b2 Mon Sep 17 00:00:00 2001 From: Germs2004 <5519340+Germs2004@users.noreply.github.com> Date: Mon, 7 Sep 2020 11:07:15 -0400 Subject: [PATCH 2/4] added strings for connectivity_sanity_test --- src/lang/en_US.lang.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lang/en_US.lang.php b/src/lang/en_US.lang.php index e6c412e7..a3b4b3b6 100644 --- a/src/lang/en_US.lang.php +++ b/src/lang/en_US.lang.php @@ -255,6 +255,8 @@ $sm_lang = array( 'hour' => 'Hour', 'warning_threshold' => 'Warning threshold', 'warning_threshold_description' => 'Number of failed checks required before it is marked offline.', + 'connectivity_sanity_test' => 'phpservermon Connectivity Sanity Test', + 'connectivity_sanity_test_description' => 'Optional. The IP address entered here should be one that is trusted to be always online. It will be pinged before and after this server gets checked. If either sanity (ping) test fails, then it is assumed that phpservermon has a connectivity problem and the results will not be saved. If both sanity tests pass, the server results will be logged like normal. To disable this sanity test, leave this box blank.', 'ssl_cert_expiry_days' => 'SSL Certificate Validity', 'ssl_cert_expiry_days_description' => 'The minimum remaining days the SSL certificate is still valid. Use 0 to disable check.', 'ssl_cert_expired' => 'SSL certificate expired since', From 550b7ad4fc5bb004f65601cc3d589d830e106ce3 Mon Sep 17 00:00:00 2001 From: Germs2004 <5519340+Germs2004@users.noreply.github.com> Date: Mon, 7 Sep 2020 11:08:59 -0400 Subject: [PATCH 3/4] added links for connectivity_sanity_test --- src/psm/Module/Server/Controller/ServerController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/psm/Module/Server/Controller/ServerController.php b/src/psm/Module/Server/Controller/ServerController.php index cb08e5fc..b95085e2 100644 --- a/src/psm/Module/Server/Controller/ServerController.php +++ b/src/psm/Module/Server/Controller/ServerController.php @@ -611,6 +611,8 @@ class ServerController extends AbstractServerController 'label_users' => psm_get_lang('servers', 'users'), 'label_warning_threshold' => psm_get_lang('servers', 'warning_threshold'), 'label_warning_threshold_description' => psm_get_lang('servers', 'warning_threshold_description'), + 'label_connectivity_sanity_test' => psm_get_lang('servers', 'connectivity_sanity_test'), + 'label_connectivity_sanity_test_description' => psm_get_lang('servers', 'connectivity_sanity_test_description'), 'label_ssl_cert_expiry_days' => psm_get_lang('servers', 'ssl_cert_expiry_days'), 'label_ssl_cert_expiry_days_description' => psm_get_lang('servers', 'ssl_cert_expiry_days_description'), 'label_action' => psm_get_lang('system', 'action'), From cb75c8657489f235dff546c8bb97b90b2d7451b8 Mon Sep 17 00:00:00 2001 From: Germs2004 <5519340+Germs2004@users.noreply.github.com> Date: Mon, 7 Sep 2020 11:13:44 -0400 Subject: [PATCH 4/4] added support for connectivity_sanity_test If the user has entered an IP address for the connectivity_sanity_test field on the server edit page, that IP address will be pinged before and after that server gets checked. If either of those pings fails, the server uptime results will not be logged because it is assumed that the phpservermon system is experiencing a connectivity problem. If both sanity test pings succeed, the server uptime results will be logged as normal. --- src/psm/Util/Server/Updater/StatusUpdater.php | 146 +++++++++++------- 1 file changed, 87 insertions(+), 59 deletions(-) diff --git a/src/psm/Util/Server/Updater/StatusUpdater.php b/src/psm/Util/Server/Updater/StatusUpdater.php index 5cc42f1c..107306af 100644 --- a/src/psm/Util/Server/Updater/StatusUpdater.php +++ b/src/psm/Util/Server/Updater/StatusUpdater.php @@ -95,98 +95,126 @@ class StatusUpdater $this->server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array( 'server_id' => $server_id, ), array( - 'server_id', 'ip', 'port', 'request_method', 'label', + 'server_id', 'connectivity_sanity_test', + 'ip', 'port', 'request_method', 'label', 'type', 'pattern', 'pattern_online', 'post_field', 'allow_http_status', 'redirect_check', 'header_name', 'header_value', 'status', 'active', 'warning_threshold', - 'warning_threshold_counter', 'ssl_cert_expiry_days', 'ssl_cert_expired_time', 'timeout', 'website_username', + 'warning_threshold_counter', 'ssl_cert_expiry_days', + 'ssl_cert_expired_time', 'timeout', 'website_username', 'website_password', 'last_offline' )); if (empty($this->server)) { return false; } - - switch ($this->server['type']) { - case 'ping': - $this->status_new = $this->updatePing($max_runs); - break; - case 'service': - $this->status_new = $this->updateService($max_runs); - break; - case 'website': - $this->status_new = $this->updateWebsite($max_runs); - break; + + // do Sanity Test before checking the actual server + $sanity_result_before = true; + $sanity_result_after = true; + $connectivity_sanity_test_ip = escapeshellcmd($this->server['connectivity_sanity_test']); + if (!empty($connectivity_sanity_test_ip)) + { + $sanity_result_before = $this->updatePing($connectivity_sanity_test_ip, 1); } - - // update server status - $save = array( - 'last_check' => date('Y-m-d H:i:s'), - 'error' => $this->error, - 'rtime' => $this->rtime - ); - if (!empty($this->error)) { - $save['last_error'] = $this->error; - } - - // log the uptime before checking the warning threshold, - // so that the warnings can still be reviewed in the server history. - psm_log_uptime($this->server_id, (int) $this->status_new, $this->rtime); - - if ($this->status_new == true) { - // if the server is on, add the last_online value and reset the error threshold counter - $save['status'] = 'on'; - $save['last_online'] = date('Y-m-d H:i:s'); - $save['last_output'] = substr($this->header, 0, 5000); - $save['warning_threshold_counter'] = 0; - if ($this->server['status'] == 'off') { - $online_date = new \DateTime($save['last_online']); - $offline_date = new \DateTime($this->server['last_offline']); - $difference = $online_date->diff($offline_date); - $save['last_offline_duration'] = trim(psm_format_interval($difference)); + + if ($sanity_result_before) { + // check the actual server + switch ($this->server['type']) { + case 'ping': + $ip_to_ping = escapeshellcmd($this->server['ip']); + $this->status_new = $this->updatePing($ip_to_ping, $max_runs); + break; + case 'service': + $this->status_new = $this->updateService($max_runs); + break; + case 'website': + $this->status_new = $this->updateWebsite($max_runs); + break; + } + + // do Sanity Test again after checking the server + if (!empty($connectivity_sanity_test_ip)) + { + $sanity_result_after = $this->updatePing($connectivity_sanity_test_ip, 1); + } + } + + // Only log the results if both sanity tests pass (or if they were not requested) + if ($sanity_result_before && $sanity_result_after) { + + // update server status + $save = array( + 'last_check' => date('Y-m-d H:i:s'), + 'error' => $this->error, + 'rtime' => $this->rtime + ); + if (!empty($this->error)) { + $save['last_error'] = $this->error; } - } else { - // server is offline, increase the error counter and set last offline - $save['warning_threshold_counter'] = $this->server['warning_threshold_counter'] + 1; - $save['last_error_output'] = empty($this->header) ? - "Could not get headers. probably HTTP 50x error." : $this->header; - if ($save['warning_threshold_counter'] < $this->server['warning_threshold']) { - // the server is offline but the error threshold has not been met yet. - // so we are going to leave the status "on" for now while we are in a sort of warning state.. + // log the uptime before checking the warning threshold, + // so that the warnings can still be reviewed in the server history. + psm_log_uptime($this->server_id, (int) $this->status_new, $this->rtime); + + if ($this->status_new == true) { + // if the server is on, add the last_online value and reset the error threshold counter $save['status'] = 'on'; - $this->status_new = true; + $save['last_online'] = date('Y-m-d H:i:s'); + $save['last_output'] = substr($this->header, 0, 5000); + $save['warning_threshold_counter'] = 0; + if ($this->server['status'] == 'off') { + $online_date = new \DateTime($save['last_online']); + $offline_date = new \DateTime($this->server['last_offline']); + $difference = $online_date->diff($offline_date); + $save['last_offline_duration'] = trim(psm_format_interval($difference)); + } } else { - $save['status'] = 'off'; - if ($this->server['status'] == 'on') { - $save['last_offline'] = $save['last_check']; + // server is offline, increase the error counter and set last offline + $save['warning_threshold_counter'] = $this->server['warning_threshold_counter'] + 1; + $save['last_error_output'] = empty($this->header) ? + "Could not get headers. probably HTTP 50x error." : $this->header; + + if ($save['warning_threshold_counter'] < $this->server['warning_threshold']) { + // the server is offline but the error threshold has not been met yet. + // so we are going to leave the status "on" for now while we are in a sort of warning state.. + $save['status'] = 'on'; + $this->status_new = true; + } else { + $save['status'] = 'off'; + if ($this->server['status'] == 'on') { + $save['last_offline'] = $save['last_check']; + } } } - } - $this->db->save(PSM_DB_PREFIX . 'servers', $save, array('server_id' => $this->server_id)); + $this->db->save(PSM_DB_PREFIX . 'servers', $save, array('server_id' => $this->server_id)); - return $this->status_new; + return $this->status_new; + } else { + // if either Sanity Test failed, do not log the results from the server check + return false; + } } /** * Check the current servers ping status + * @param string $ip_to_ping * @param int $max_runs * @param int $run * @return boolean */ - protected function updatePing($max_runs, $run = 1) + protected function updatePing($ip_to_ping, $max_runs, $run = 1) { // Settings $max_runs = ($max_runs == null || $max_runs > 1) ? 1 : $max_runs; - $server_ip = escapeshellcmd($this->server['ip']); $os_is_windows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; $status = $os_is_windows ? - $this->pingFromWindowsMachine($server_ip, $max_runs) : - $this->pingFromNonWindowsMachine($server_ip, $max_runs); + $this->pingFromWindowsMachine($ip_to_ping, $max_runs) : + $this->pingFromNonWindowsMachine($ip_to_ping, $max_runs); // check if server is available and rerun if asked. if (!$status && $run < $max_runs) { - return $this->updatePing($max_runs, $run + 1); + return $this->updatePing($ip_to_ping, $max_runs, $run + 1); } return $status; }