diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2dcc0504..338b2aa9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,11 +5,19 @@ Changelog Not yet released ---------------- -#626: Added redirect check. -b49659f: Added question to notification faq about not recieving notifications. -ef28908: Indentation fix. -#605: Added Norwegian language. -f6173d4: Added license to composer.json file. +* #626: Added redirect check. +* #627: Latest server output, error and output during a failure will be saved and are shown on the server page. +* #631: Added option to specify the request method. +* #628: Added the option to mark specific HTTP status codes as online. +* #640: Removed () after last offline value when the last offline duration is unknown. +* #637: Added php extensions to composer required list, spelling fixes in changelog and composer update. +* #635: Changed server order on ?&mod=user&action=edit&id=x. +* #634: Changed ' to " in sql query, both were used. +* #629: Fix bug that made it impossible to check rdp:// and fixed port update. +* b49659f: Added question to notification faq about not receiving notifications. +* ef28908: Indentation fix. +* #605: Added Norwegian language. +* f6173d4: Added license to composer.json file. v3.3.1 (released August 10, 2018) -------------------------------- @@ -40,7 +48,7 @@ v3.3.1 (released August 10, 2018) v3.3.0 (released May 30, 2018) -------------------------------- -* 57f4c36: Added support voor the following SMS gateways: Plivo, SolutionsInfini, Callr and GAtewayAPI. +* 57f4c36: Added support for the following SMS gateways: Plivo, SolutionsInfini, Callr and GatewayAPI. * c3751e7: Moved Clickatell api key to password field. * #590: Rollback Twig version update to work with PHP5. * #589: Enlarge select pattern_online width. @@ -66,7 +74,7 @@ v3.3.0 (released May 30, 2018) * #541: Fix method declaration error in PHP7.2. * #515: Run archive and cleanup per server to reduce memory use. * #516: Fixed #500 ping latency. -* 2471767: Fixed preinstalled server query. +* 2471767: Fixed pre installed server query. v3.2.2 (released March 27, 2018) -------------------------------- @@ -84,7 +92,7 @@ v3.2.2 (released March 27, 2018) v3.2.1 (released March 27, 2018) -------------------------------- -* #343: Added optinal header value check. +* #343: Added optional header value check. * #433: Changed baseurl repoforgeextras. * #432: Changed baseurl repoforge. * #437: Octopush.class.php updates to Octopush.php. diff --git a/composer.json b/composer.json index 68006ba1..9780cd02 100755 --- a/composer.json +++ b/composer.json @@ -2,9 +2,12 @@ "name": "phpservermon/phpservermon", "description": "PHP Server Monitor", "license": "GPL-3.0-or-later", - "homepage": "http://www.phpservermonitor.org", + "homepage": "https://www.phpservermonitor.org", "require": { "php": ">=5.5.9", + "ext-curl": "*", + "ext-pdo": "*", + "ext-xml": "*", "phpmailer/phpmailer": "~6.0", "symfony/config": "~3.4", "symfony/dependency-injection": "~3.4", diff --git a/composer.lock b/composer.lock index cd3184d8..9c3f01e3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "280e04b14bf6e80bca192b48a12bb342", + "content-hash": "b116489d45aab7506cedf3f94fb60ee4", "packages": [ { "name": "paragonie/random_compat", @@ -202,7 +202,7 @@ }, { "name": "symfony/config", - "version": "v3.4.14", + "version": "v3.4.15", "source": { "type": "git", "url": "https://github.com/symfony/config.git", @@ -266,16 +266,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v3.4.14", + "version": "v3.4.15", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "1c0e679e522591fd744fdf242fec41a43d62b2b1" + "reference": "09d7df7bf06c1393b6afc85875993cbdbdf897a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/1c0e679e522591fd744fdf242fec41a43d62b2b1", - "reference": "1c0e679e522591fd744fdf242fec41a43d62b2b1", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/09d7df7bf06c1393b6afc85875993cbdbdf897a0", + "reference": "09d7df7bf06c1393b6afc85875993cbdbdf897a0", "shasum": "" }, "require": { @@ -333,11 +333,11 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2018-07-29T15:19:31+00:00" + "time": "2018-08-08T11:42:34+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v3.4.14", + "version": "v3.4.15", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -400,16 +400,16 @@ }, { "name": "symfony/filesystem", - "version": "v4.1.3", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "2e30335e0aafeaa86645555959572fe7cea22b43" + "reference": "c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/2e30335e0aafeaa86645555959572fe7cea22b43", - "reference": "2e30335e0aafeaa86645555959572fe7cea22b43", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e", + "reference": "c0f5f62db218fa72195b8b8700e4b9b9cf52eb5e", "shasum": "" }, "require": { @@ -446,20 +446,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-07-26T11:24:31+00:00" + "time": "2018-08-18T16:52:46+00:00" }, { "name": "symfony/http-foundation", - "version": "v3.4.14", + "version": "v3.4.15", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "19a3267828046a2a4a05e3dc2954bbd2e0ad9fa6" + "reference": "2fb33cb6eefe6e790e4023f7c534a9e4214252fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/19a3267828046a2a4a05e3dc2954bbd2e0ad9fa6", - "reference": "19a3267828046a2a4a05e3dc2954bbd2e0ad9fa6", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/2fb33cb6eefe6e790e4023f7c534a9e4214252fc", + "reference": "2fb33cb6eefe6e790e4023f7c534a9e4214252fc", "shasum": "" }, "require": { @@ -500,29 +500,32 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2018-08-01T14:04:26+00:00" + "time": "2018-08-27T17:45:33+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.8.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", - "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "suggest": { + "ext-ctype": "For best performance" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8-dev" + "dev-master": "1.9-dev" } }, "autoload": { @@ -555,20 +558,20 @@ "polyfill", "portable" ], - "time": "2018-04-30T19:57:29+00:00" + "time": "2018-08-06T14:22:27+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.8.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "3296adf6a6454a050679cde90f95350ad604b171" + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171", - "reference": "3296adf6a6454a050679cde90f95350ad604b171", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", "shasum": "" }, "require": { @@ -580,7 +583,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8-dev" + "dev-master": "1.9-dev" } }, "autoload": { @@ -614,30 +617,30 @@ "portable", "shim" ], - "time": "2018-04-26T10:06:28+00:00" + "time": "2018-08-06T14:22:27+00:00" }, { "name": "symfony/polyfill-php70", - "version": "v1.8.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "77454693d8f10dd23bb24955cffd2d82db1007a6" + "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/77454693d8f10dd23bb24955cffd2d82db1007a6", - "reference": "77454693d8f10dd23bb24955cffd2d82db1007a6", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/1e24b0c4a56d55aaf368763a06c6d1c7d3194934", + "reference": "1e24b0c4a56d55aaf368763a06c6d1c7d3194934", "shasum": "" }, "require": { - "paragonie/random_compat": "~1.0|~2.0", + "paragonie/random_compat": "~1.0|~2.0|~9.99", "php": ">=5.3.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8-dev" + "dev-master": "1.9-dev" } }, "autoload": { @@ -673,7 +676,7 @@ "portable", "shim" ], - "time": "2018-04-26T10:06:28+00:00" + "time": "2018-08-06T14:22:27+00:00" }, { "name": "twig/twig", @@ -751,7 +754,10 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.5.9" + "php": ">=5.5.9", + "ext-curl": "*", + "ext-pdo": "*", + "ext-xml": "*" }, "platform-dev": [] } diff --git a/composer.phar b/composer.phar index 4055d874..96fa2df7 100755 Binary files a/composer.phar and b/composer.phar differ diff --git a/src/includes/functions.inc.php b/src/includes/functions.inc.php index 0b2ceba2..a0e3b32d 100644 --- a/src/includes/functions.inc.php +++ b/src/includes/functions.inc.php @@ -343,9 +343,10 @@ function psm_parse_msg($status, $type, $vars) { * @param boolean $add_agent add user agent? * @param string|bool $website_username Username website * @param string|bool $website_password Password website + * @param string|bool $request_method Request method like GET, POST etc. * @return string cURL result */ -function psm_curl_get($href, $header = false, $body = true, $timeout = null, $add_agent = true, $website_username = false, $website_password = false) { +function psm_curl_get($href, $header = false, $body = true, $timeout = null, $add_agent = true, $website_username = false, $website_password = false, $request_method = null) { $timeout = $timeout == null ? PSM_CURL_TIMEOUT : intval($timeout); $ch = curl_init(); @@ -358,6 +359,10 @@ function psm_curl_get($href, $header = false, $body = true, $timeout = null, $ad curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_ENCODING, ''); + + if (!empty($request_method)) { + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request_method); + } if ($website_username !== false && $website_password !== false && !empty($website_username) && !empty($website_password)) { curl_setopt($ch, CURLOPT_USERPWD, $website_username.":".$website_password); diff --git a/src/lang/en_US.lang.php b/src/lang/en_US.lang.php index 318b6732..d474ece3 100644 --- a/src/lang/en_US.lang.php +++ b/src/lang/en_US.lang.php @@ -49,7 +49,9 @@ $sm_lang = array( 'ok' => 'OK', 'bad' => 'bad', 'cancel' => 'Cancel', + 'none' => 'None', 'activate' => 'Activate', + 'advanced' => 'Advanced', // date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php 'short_day_format' => '%B %e', 'long_day_format' => '%B %e, %Y', @@ -161,6 +163,9 @@ $sm_lang = array( 'port' => 'Port', 'custom_port' => 'Custom Port', 'popular_ports' => 'Popular Ports', + 'request_method' => 'Request method', + 'custom_request_method' => 'Custom request method', + 'popular_request_methods' => 'Popular request methods', 'please_select' => 'Please select', 'type' => 'Type', 'type_website' => 'Website', @@ -172,12 +177,17 @@ $sm_lang = array( 'pattern_online_description' => 'Online: If this pattern is not found on the website, the server will be marked online. Offline: If this pattern is not found on the website, the server will be marked offline.', 'redirect_check' => 'Redirecting to another domain is', 'redirect_check_description' => 'Redirect to another domain is usually a bad sign.', + 'allow_http_status' => 'Allow HTTP status code', + 'allow_http_status_description' => 'Mark website as online. HTTP Status codes lower then 400 are marked as online by default. Seperate with |. Example: 401|403.', 'header' => 'Header', 'header_name_description' => 'Header name (case-sensitive)', 'header_value_description' => 'Header value. Regular expressions are allowed.', 'last_check' => 'Last check', 'last_online' => 'Last online', 'last_offline' => 'Last offline', + 'last_output' => 'Last positive output', + 'last_error' => 'Last error', + 'last_error_output' => 'Last error output', 'monitoring' => 'Monitoring', 'no_monitoring' => 'No monitoring', 'email' => 'Email', diff --git a/src/lang/nl_NL.lang.php b/src/lang/nl_NL.lang.php index e4b60416..b29493ec 100644 --- a/src/lang/nl_NL.lang.php +++ b/src/lang/nl_NL.lang.php @@ -148,6 +148,8 @@ $sm_lang = array( 'pattern_description' => 'Als dit patroon niet gevonden wordt op de website, zal de server als offline gemarkeerd worden. Regular expressions zijn toegestaan.', 'redirect_check' => 'Omleiden naar een ander domein is', 'redirect_check_description' => 'Een omleiding naar een ander domein is meestal een slecht teken.', + 'allow_http_status' => 'Sta HTTP status code toe', + 'allow_http_status_description' => 'Markeer website als online. HTTP status code lager dan 400 worden standaard als online gemarkeerd. Scheiden met |. Bijvoorbeeld: 401|403.', 'last_check' => 'Laatst gecontroleerd', 'last_online' => 'Laatst online', 'last_offline' => 'Laatst offline', diff --git a/src/psm/Module/Server/Controller/AbstractServerController.php b/src/psm/Module/Server/Controller/AbstractServerController.php index ab499f02..b5c7ee83 100644 --- a/src/psm/Module/Server/Controller/AbstractServerController.php +++ b/src/psm/Module/Server/Controller/AbstractServerController.php @@ -61,11 +61,13 @@ abstract class AbstractServerController extends AbstractController { `s`.`server_id`, `s`.`ip`, `s`.`port`, + `s`.`request_method`, `s`.`type`, `s`.`label`, `s`.`pattern`, `s`.`pattern_online`, `s`.`redirect_check`, + `s`.`allow_http_status`, `s`.`header_name`, `s`.`header_value`, `s`.`status`, @@ -84,7 +86,10 @@ abstract class AbstractServerController extends AbstractController { `s`.`warning_threshold_counter`, `s`.`timeout`, `s`.`website_username`, - `s`.`website_password` + `s`.`website_password`, + `s`.`last_error`, + `s`.`last_error_output`, + `s`.`last_output` FROM `".PSM_DB_PREFIX."servers` AS `s` {$sql_join} {$sql_where} @@ -108,7 +113,8 @@ abstract class AbstractServerController extends AbstractController { $server['last_online'] = psm_timespan($server['last_online']); $server['last_offline'] = psm_timespan($server['last_offline']); if ($server['last_offline'] != psm_get_lang('system', 'never')) { - $server['last_offline_duration'] = "(".$server['last_offline_duration'].")"; + $server['last_offline_duration'] = is_null($server['last_offline_duration']) ? + null : "(".$server['last_offline_duration'].")"; } $server['last_check'] = psm_timespan($server['last_check']); $server['active'] = psm_get_lang('system', $server['active']); @@ -125,6 +131,10 @@ abstract class AbstractServerController extends AbstractController { $server['type'] = psm_get_lang('servers', 'type_'.$server['type']); $server['timeout'] = ($server['timeout'] > 0) ? $server['timeout'] : PSM_CURL_TIMEOUT; + $server['last_error'] = htmlentities($server['last_error']); + $server['last_error_output'] = htmlentities($server['last_error_output']); + $server['last_output'] = htmlentities($server['last_output']); + $url_actions = array('delete', 'edit', 'view'); foreach ($url_actions as $action) { $server['url_'.$action] = psm_build_url(array( diff --git a/src/psm/Module/Server/Controller/ServerController.php b/src/psm/Module/Server/Controller/ServerController.php index a2df2703..5dc88438 100644 --- a/src/psm/Module/Server/Controller/ServerController.php +++ b/src/psm/Module/Server/Controller/ServerController.php @@ -196,11 +196,13 @@ class ServerController extends AbstractServerController { 'edit_value_label' => $edit_server['label'], 'edit_value_ip' => $edit_server['ip'], 'edit_value_port' => $edit_server['port'], + 'edit_value_request_method' => $edit_server['request_method'], 'edit_value_timeout' => $edit_server['timeout'], 'default_value_timeout' => PSM_CURL_TIMEOUT, 'edit_value_pattern' => $edit_server['pattern'], 'edit_pattern_selected_'.$edit_server['pattern_online'] => 'selected="selected"', 'edit_redirect_check_selected_'.$edit_server['redirect_check'] => 'selected="selected"', + 'edit_value_allow_http_status' => $edit_server['allow_http_status'], 'edit_value_header_name' => $edit_server['header_name'], 'edit_value_header_value' => $edit_server['header_value'], 'edit_value_warning_threshold' => $edit_server['warning_threshold'], @@ -265,10 +267,12 @@ class ServerController extends AbstractServerController { 'website_username' => psm_POST('website_username'), 'website_password' => $encrypted_password, 'port' => intval(psm_POST('port', 0)), + 'request_method' => empty(psm_POST('request_method')) ? null : psm_POST('request_method'), 'type' => psm_POST('type', ''), 'pattern' => psm_POST('pattern', ''), 'pattern_online' => in_array($_POST['pattern_online'], array('yes', 'no')) ? $_POST['pattern_online'] : 'yes', 'redirect_check' => in_array($_POST['redirect_check'], array('ok', 'bad')) ? $_POST['redirect_check'] : 'bad', + 'allow_http_status' => psm_POST('allow_http_status', ''), 'header_name' => psm_POST('header_name', ''), 'header_value' => psm_POST('header_value', ''), 'rtime' => psm_POST('rtime', '0.0000000'), @@ -280,15 +284,15 @@ class ServerController extends AbstractServerController { 'telegram' => in_array($_POST['telegram'], array('yes', 'no')) ? $_POST['telegram'] : 'no', ); // make sure websites start with http:// - if ($clean['type'] == 'website' && substr($clean['ip'], 0, 4) != 'http') { + if ($clean['type'] == 'website' && substr($clean['ip'], 0, 4) != 'http' && substr($clean['ip'], 0, 3) != 'rdp') { $clean['ip'] = 'http://'.$clean['ip']; } // validate the lot $server_validator = new \psm\Util\Server\ServerValidator($this->db); - // format port from http/s url - if ($clean['type'] == 'website' && empty($clean['port'])) { + // format port from http, https or rdp url + if ($clean['type'] == 'website') { $tmp = parse_url($clean["ip"]); if (isset($tmp["port"])) { $clean["port"] = $tmp["port"]; @@ -465,8 +469,12 @@ class ServerController extends AbstractServerController { 'label_fieldset_permissions' => psm_get_lang('servers', 'fieldset_permissions'), 'label_port' => psm_get_lang('servers', 'port'), 'label_custom_port' => psm_get_lang('servers', 'custom_port'), - 'label_please_select' => psm_get_lang('servers', 'please_select'), 'label_popular_ports' => psm_get_lang('servers', 'popular_ports'), + 'label_request_method' => psm_get_lang('servers', 'request_method'), + 'label_custom_request_method' => psm_get_lang('servers', 'custom_request_method'), + 'label_popular_request_methods' => psm_get_lang('servers', 'popular_request_methods'), + 'label_none' => psm_get_lang('system', 'none'), + 'label_please_select' => psm_get_lang('servers', 'please_select'), 'label_type' => psm_get_lang('servers', 'type'), 'label_website' => psm_get_lang('servers', 'type_website'), 'label_service' => psm_get_lang('servers', 'type_service'), @@ -477,6 +485,8 @@ class ServerController extends AbstractServerController { 'label_pattern_online_description' => psm_get_lang('servers', 'pattern_online_description'), 'label_redirect_check' => psm_get_lang('servers', 'redirect_check'), 'label_redirect_check_description' => psm_get_lang('servers', 'redirect_check_description'), + 'label_allow_http_status' => psm_get_lang('servers', 'allow_http_status'), + 'label_allow_http_status_description' => psm_get_lang('servers', 'allow_http_status_description'), 'label_header' => psm_get_lang('servers', 'header'), 'label_header_name_description' => psm_get_lang('servers', 'header_name_description'), 'label_header_value_description' => psm_get_lang('servers', 'header_value_description'), @@ -484,6 +494,9 @@ class ServerController extends AbstractServerController { 'label_rtime' => psm_get_lang('servers', 'latency'), 'label_last_online' => psm_get_lang('servers', 'last_online'), 'label_last_offline' => psm_get_lang('servers', 'last_offline'), + 'label_last_output' => psm_get_lang('servers', 'last_output'), + 'label_last_error' => psm_get_lang('servers', 'last_error'), + 'label_last_error_output' => psm_get_lang('servers', 'last_error_output'), 'label_monitoring' => psm_get_lang('servers', 'monitoring'), 'label_email' => psm_get_lang('servers', 'email'), 'label_send_email' => psm_get_lang('servers', 'send_email'), @@ -502,6 +515,7 @@ class ServerController extends AbstractServerController { 'label_yes' => psm_get_lang('system', 'yes'), 'label_no' => psm_get_lang('system', 'no'), 'label_add_new' => psm_get_lang('system', 'add_new'), + 'label_advanced' => psm_get_lang('system', 'advanced'), 'label_online' => psm_get_lang('system', 'online'), 'label_offline' => psm_get_lang('system', 'offline'), 'label_ok' => psm_get_lang('system', 'ok'), @@ -527,4 +541,3 @@ class ServerController extends AbstractServerController { return $result; } } - diff --git a/src/psm/Module/User/Controller/UserController.php b/src/psm/Module/User/Controller/UserController.php index 5c32cf5b..035c49d5 100644 --- a/src/psm/Module/User/Controller/UserController.php +++ b/src/psm/Module/User/Controller/UserController.php @@ -49,7 +49,7 @@ class UserController extends AbstractController { } public function run($action = NULL) { - $servers = $this->db->select(PSM_DB_PREFIX.'servers', null, array('server_id', 'label'), '', "ORDER BY `active` ASC, `status` DESC, `label` ASC"); + $servers = $this->db->select(PSM_DB_PREFIX.'servers', null, array('server_id', 'label'), '', "ORDER BY `label` ASC"); // change the indexes to reflect their server ids foreach ($servers as $server) { $this->servers[$server['server_id']] = $server; @@ -110,6 +110,7 @@ class UserController extends AbstractController { 'label' => $servers_labels[$server_id] ); } + sort($user['emp_servers']); $user['url_delete'] = psm_build_url(array( 'mod' => 'user', diff --git a/src/psm/Util/Install/Installer.php b/src/psm/Util/Install/Installer.php index 916d1fb1..ccb4a299 100644 --- a/src/psm/Util/Install/Installer.php +++ b/src/psm/Util/Install/Installer.php @@ -225,11 +225,13 @@ class Installer { `server_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `ip` varchar(500) NOT NULL, `port` int(5) unsigned NOT NULL, + `request_method` varchar(50) unsigned NULL, `label` varchar(255) NOT NULL, `type` enum('ping','service','website') NOT NULL default 'service', - `pattern` varchar(255) NOT NULL, + `pattern` varchar(255) NOT NULL default '', `pattern_online` enum('yes','no') NOT NULL default 'yes', `redirect_check` enum('ok','bad') NOT NULL default 'bad', + `allow_http_status` varchar(255) NOT NULL default '', `header_name` varchar(255) NOT NULL default '', `header_value` varchar(255) NOT NULL default '', `status` enum('on','off') NOT NULL default 'on', @@ -249,6 +251,9 @@ class Installer { `timeout` smallint(1) unsigned NULL DEFAULT NULL, `website_username` varchar(255) DEFAULT NULL, `website_password` varchar(255) DEFAULT NULL, + `last_error` varchar(255) DEFAULT NULL, + `last_error_output` varchar(255) DEFAULT NULL, + `last_output` varchar(255) DEFAULT NULL, PRIMARY KEY (`server_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;", PSM_DB_PREFIX.'servers_uptime' => "CREATE TABLE IF NOT EXISTS `".PSM_DB_PREFIX."servers_uptime` ( @@ -555,8 +560,13 @@ class Installer { * If you have a lot of server that are redirecting, * this will make sure you're servers stay online. */ - $queries[] = "ALTER TABLE `".PSM_DB_PREFIX."servers` ADD `redirect_check` ENUM( 'ok','bad' ) NOT NULL DEFAULT 'ok' AFTER `pattern_online`;"; + $queries[] = "ALTER TABLE `".PSM_DB_PREFIX."servers` ADD COLUMN `allow_http_status` VARCHAR(255) NOT NULL DEFAULT '' AFTER `pattern_online`;"; + $queries[] = "ALTER TABLE `".PSM_DB_PREFIX."servers` ADD `redirect_check` ENUM( 'ok','bad' ) NOT NULL DEFAULT 'ok' AFTER `allow_http_status`;"; $queries[] = "ALTER TABLE `".PSM_DB_PREFIX."servers` CHANGE `redirect_check` `redirect_check` ENUM('ok','bad') NOT NULL DEFAULT 'bad';"; + $queries[] = "ALTER TABLE `".PSM_DB_PREFIX."servers` ADD COLUMN `last_error` VARCHAR(255) NULL AFTER `website_password`;"; + $queries[] = "ALTER TABLE `".PSM_DB_PREFIX."servers` ADD COLUMN `last_error_output` TEXT NULL AFTER `last_error`;"; + $queries[] = "ALTER TABLE `".PSM_DB_PREFIX."servers` ADD COLUMN `last_output` TEXT NULL AFTER `last_error_output`;"; + $queries[] = "ALTER TABLE `".PSM_DB_PREFIX."servers` ADD COLUMN `request_method` varchar(50) NULL AFTER `port`;"; $this->execSQL($queries); } } diff --git a/src/psm/Util/Server/HistoryGraph.php b/src/psm/Util/Server/HistoryGraph.php index 605e4912..28e4f0c6 100644 --- a/src/psm/Util/Server/HistoryGraph.php +++ b/src/psm/Util/Server/HistoryGraph.php @@ -179,8 +179,8 @@ class HistoryGraph { } $records = $this->db->execute( - 'SELECT * - FROM `'.PSM_DB_PREFIX."servers_$type` + "SELECT * + FROM `".PSM_DB_PREFIX."servers_$type` WHERE `server_id` = :server_id AND `date` BETWEEN :start_time AND :end_time ORDER BY `date` ASC", array( 'server_id' => $server_id, diff --git a/src/psm/Util/Server/Updater/StatusUpdater.php b/src/psm/Util/Server/Updater/StatusUpdater.php index 38619d26..3e9fffab 100644 --- a/src/psm/Util/Server/Updater/StatusUpdater.php +++ b/src/psm/Util/Server/Updater/StatusUpdater.php @@ -37,6 +37,8 @@ use psm\Service\Database; class StatusUpdater { public $error = ''; + public $header = ''; + public $rtime = 0; public $status_new = false; @@ -69,6 +71,9 @@ class StatusUpdater { * * Please note: if the server is down but has not met the warning threshold, this will return true * to avoid any "we are down" events. + * + * @todo Get last_output when there is a HPPT 50x error. + * * @param int $server_id * @param int $max_runs how many times should the script recheck the server if unavailable. default is 2 * @return boolean TRUE if server is up, FALSE otherwise @@ -76,13 +81,14 @@ class StatusUpdater { public function update($server_id, $max_runs = 2) { $this->server_id = $server_id; $this->error = ''; + $this->header = ''; $this->rtime = ''; // get server info from db $this->server = $this->db->selectRow(PSM_DB_PREFIX.'servers', array( 'server_id' => $server_id, ), array( - 'server_id', 'ip', 'port', 'label', 'type', 'pattern', 'pattern_online', 'redirect_check', 'header_name', 'header_value', 'status', 'active', 'warning_threshold', + 'server_id', 'ip', 'port', 'request_method', 'label', 'type', 'pattern', 'pattern_online', 'allow_http_status', 'redirect_check', 'header_name', 'header_value', 'status', 'active', 'warning_threshold', 'warning_threshold_counter', 'timeout', 'website_username', 'website_password', 'last_offline' )); if (empty($this->server)) { @@ -105,8 +111,11 @@ class StatusUpdater { $save = array( 'last_check' => date('Y-m-d H:i:s'), 'error' => $this->error, - 'rtime' => $this->rtime, + '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. @@ -116,6 +125,7 @@ class StatusUpdater { // 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'] = $this->header; $save['warning_threshold_counter'] = 0; if ($this->server['status'] == 'off') { $online_date = new \DateTime($save['last_online']); @@ -124,8 +134,10 @@ class StatusUpdater { $save['last_offline_duration'] = trim(psm_format_interval($difference)); } } else { - // server is offline, increase the error counter + // server is offline, increase the error counter and set last offline $save['warning_threshold_counter'] = $this->server['warning_threshold_counter'] + 1; + $save['last_offline'] = date('Y-m-d H:i:s'); + $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. @@ -229,8 +241,10 @@ class StatusUpdater { $this->server['timeout'], true, $this->server['website_username'], - psm_password_decrypt($this->server['server_id'].psm_get_conf('password_encrypt_key'), $this->server['website_password']) + psm_password_decrypt($this->server['server_id'].psm_get_conf('password_encrypt_key'), $this->server['website_password']), + $this->server['request_method'] ); + $this->header = $curl_result; $this->rtime = (microtime(true) - $starttime); @@ -250,8 +264,9 @@ class StatusUpdater { $code = $code_matches[1][0]; $msg = $code_matches[2][0]; + $allow_http_status = explode("|", $this->server['allow_http_status']); // All status codes starting with a 4 or higher mean trouble! - if (substr($code, 0, 1) >= '4') { + if (substr($code, 0, 1) >= '4' && !in_array($code ,$allow_http_status)) { $this->error = "HTTP STATUS ERROR: ".$code.' '.$msg; $result = false; } else { diff --git a/src/templates/default/module/server/server/update.tpl.html b/src/templates/default/module/server/server/update.tpl.html index b3af2848..c0934dd9 100644 --- a/src/templates/default/module/server/server/update.tpl.html +++ b/src/templates/default/module/server/server/update.tpl.html @@ -59,6 +59,32 @@ +