Merge branch 'develop' into feature/270

pull/639/head
Tim 2018-09-05 23:01:29 +02:00 committed by GitHub
commit 53ec3882fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 241 additions and 73 deletions

View File

@ -6,6 +6,11 @@ Not yet released
---------------- ----------------
* #639: Added combined notifications. * #639: Added combined notifications.
* #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. * #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. * #635: Changed server order on ?&mod=user&action=edit&id=x.
* #634: Changed ' to " in sql query, both were used. * #634: Changed ' to " in sql query, both were used.

View File

@ -349,9 +349,10 @@ function psm_parse_msg($status, $type, $vars, $combi = false) {
* @param boolean $add_agent add user agent? * @param boolean $add_agent add user agent?
* @param string|bool $website_username Username website * @param string|bool $website_username Username website
* @param string|bool $website_password Password website * @param string|bool $website_password Password website
* @param string|bool $request_method Request method like GET, POST etc.
* @return string cURL result * @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); $timeout = $timeout == null ? PSM_CURL_TIMEOUT : intval($timeout);
$ch = curl_init(); $ch = curl_init();
@ -365,6 +366,10 @@ function psm_curl_get($href, $header = false, $body = true, $timeout = null, $ad
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_ENCODING, ''); 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)) { if ($website_username !== false && $website_password !== false && !empty($website_username) && !empty($website_password)) {
curl_setopt($ch, CURLOPT_USERPWD, $website_username.":".$website_password); curl_setopt($ch, CURLOPT_USERPWD, $website_username.":".$website_password);
} }

View File

@ -47,9 +47,11 @@ $sm_lang = array(
'back_to_top' => 'Back to top', 'back_to_top' => 'Back to top',
'go_back' => 'Go back', 'go_back' => 'Go back',
'ok' => 'OK', 'ok' => 'OK',
'bad' => 'bad',
'cancel' => 'Cancel', 'cancel' => 'Cancel',
'none' => 'None', 'none' => 'None',
'activate' => 'Activate', 'activate' => 'Activate',
'advanced' => 'Advanced',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php // date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e', 'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y', 'long_day_format' => '%B %e, %Y',
@ -161,6 +163,9 @@ $sm_lang = array(
'port' => 'Port', 'port' => 'Port',
'custom_port' => 'Custom Port', 'custom_port' => 'Custom Port',
'popular_ports' => 'Popular Ports', 'popular_ports' => 'Popular Ports',
'request_method' => 'Request method',
'custom_request_method' => 'Custom request method',
'popular_request_methods' => 'Popular request methods',
'please_select' => 'Please select', 'please_select' => 'Please select',
'type' => 'Type', 'type' => 'Type',
'type_website' => 'Website', 'type_website' => 'Website',
@ -170,12 +175,19 @@ $sm_lang = array(
'pattern_description' => 'If this pattern is not found on the website, the server will be marked online/offline. Regular expressions are allowed.', 'pattern_description' => 'If this pattern is not found on the website, the server will be marked online/offline. Regular expressions are allowed.',
'pattern_online' => 'Pattern indicates website is', 'pattern_online' => 'Pattern indicates website is',
'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.', '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' => 'Header',
'header_name_description' => 'Header name (case-sensitive)', 'header_name_description' => 'Header name (case-sensitive)',
'header_value_description' => 'Header value. Regular expressions are allowed.', 'header_value_description' => 'Header value. Regular expressions are allowed.',
'last_check' => 'Last check', 'last_check' => 'Last check',
'last_online' => 'Last online', 'last_online' => 'Last online',
'last_offline' => 'Last offline', 'last_offline' => 'Last offline',
'last_output' => 'Last positive output',
'last_error' => 'Last error',
'last_error_output' => 'Last error output',
'monitoring' => 'Monitoring', 'monitoring' => 'Monitoring',
'no_monitoring' => 'No monitoring', 'no_monitoring' => 'No monitoring',
'email' => 'Email', 'email' => 'Email',

View File

@ -27,7 +27,11 @@
$sm_lang = array( $sm_lang = array(
'name' => 'Nederlands - Dutch', 'name' => 'Nederlands - Dutch',
'locale' => array('nl_NL.UTF-8', 'nl_NL', 'dutch'), 'locale' => array(
'0' => 'nl_NL.UTF-8',
'1' => 'nl_NL',
'2' => 'dutch',
),
'locale_tag' => 'nl', 'locale_tag' => 'nl',
'locale_dir' => 'ltr', 'locale_dir' => 'ltr',
'system' => array( 'system' => array(
@ -47,8 +51,8 @@ $sm_lang = array(
'back_to_top' => 'Terug naar boven', 'back_to_top' => 'Terug naar boven',
'go_back' => 'Terug', 'go_back' => 'Terug',
'ok' => 'OK', 'ok' => 'OK',
'bad' => 'niet goed',
'cancel' => 'Cancel', 'cancel' => 'Cancel',
// date/time format according the strftime php function format parameter http://php.net/manual/function.strftime.php
'short_day_format' => '%B %e', 'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y', 'long_day_format' => '%B %e, %Y',
'yesterday_format' => 'Gisteren om %k:%M', 'yesterday_format' => 'Gisteren om %k:%M',
@ -142,6 +146,10 @@ $sm_lang = array(
'type_service' => 'Service', 'type_service' => 'Service',
'pattern' => 'Zoek voor tekst/regex', 'pattern' => 'Zoek voor tekst/regex',
'pattern_description' => 'Als dit patroon niet gevonden wordt op de website, zal de server als offline gemarkeerd worden. Regular expressions zijn toegestaan.', '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_check' => 'Laatst gecontroleerd',
'last_online' => 'Laatst online', 'last_online' => 'Laatst online',
'last_offline' => 'Laatst offline', 'last_offline' => 'Laatst offline',
@ -172,7 +180,6 @@ $sm_lang = array(
'warning_threshold_description' => 'Aantal mislukte pogingen voordat de server als offline gemarkeerd wordt.', 'warning_threshold_description' => 'Aantal mislukte pogingen voordat de server als offline gemarkeerd wordt.',
'chart_last_week' => 'Afgelopen week', 'chart_last_week' => 'Afgelopen week',
'chart_history' => 'Geschiedenis', 'chart_history' => 'Geschiedenis',
// Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html
'chart_day_format' => '%d-%m-%Y', 'chart_day_format' => '%d-%m-%Y',
'chart_long_date_format' => '%d-%m-%Y %H:%M:%S', 'chart_long_date_format' => '%d-%m-%Y %H:%M:%S',
'chart_short_date_format' => '%d-%m %H:%M', 'chart_short_date_format' => '%d-%m %H:%M',
@ -214,14 +221,7 @@ $sm_lang = array(
'pushover_api_token' => 'Pushover App API Token', 'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Voordat je Pushover kunt gebruiken moet je een <a href="%1$s" target="_blank">App registreren</a> via hun website, en daarvan de App API Token hier invullen.', 'pushover_api_token_description' => 'Voordat je Pushover kunt gebruiken moet je een <a href="%1$s" target="_blank">App registreren</a> via hun website, en daarvan de App API Token hier invullen.',
'alert_type' => 'Selecteer wanneer je een notificatie wilt', 'alert_type' => 'Selecteer wanneer je een notificatie wilt',
'alert_type_description' => '<b>Status verandert:</b> '. 'alert_type_description' => '<b>Status verandert:</b> Je ontvangt alleen bericht wanneer een server van status verandert. Dus van online -> offline of offline -> online.<br/><br /><b>Offline:</b> Je ontvangt bericht wanneer een server offline gaat voor de *EERSTE KEER*. Bijvoorbeeld, je cronjob draait iedere 15 min en je server gaat down om 01:00 en blijft offline tot 06:00. Je krijgt 1 bericht om 01:00 en dat is het.<br/><br/><b>Altijd:</b> Je krijgt een bericht elke keer dat het script draait en een website is down, ook al is de site al een paar uur offline.',
'Je ontvangt alleen bericht wanneer een server van status verandert. Dus van online -> offline of offline -> online.<br/>'.
'<br /><b>Offline:</b> '.
'Je ontvangt bericht wanneer een server offline gaat voor de *EERSTE KEER*. Bijvoorbeeld, '.
'je cronjob draait iedere 15 min en je server gaat down om 01:00 en blijft offline tot 06:00. '.
'Je krijgt 1 bericht om 01:00 en dat is het.<br/>'.
'<br/><b>Altijd:</b> '.
'Je krijgt een bericht elke keer dat het script draait en een website is down, ook al is de site al een paar uur offline.',
'alert_type_status' => 'Status verandering', 'alert_type_status' => 'Status verandering',
'alert_type_offline' => 'Offline', 'alert_type_offline' => 'Offline',
'alert_type_always' => 'Altijd', 'alert_type_always' => 'Altijd',
@ -240,11 +240,7 @@ $sm_lang = array(
'settings_notification' => 'Notificatie instellingen', 'settings_notification' => 'Notificatie instellingen',
'settings_log' => 'Log instellingen', 'settings_log' => 'Log instellingen',
'auto_refresh' => 'Auto-refresh', 'auto_refresh' => 'Auto-refresh',
'auto_refresh_servers' => 'auto_refresh_servers' => 'Auto-herladen servers pagina.<br/><span class="small">Tijd in seconden, als de tijd 0 is wordt de pagina niet ververst.</span>',
'Auto-herladen servers pagina.<br/>'.
'<span class="small">'.
'Tijd in seconden, als de tijd 0 is wordt de pagina niet ververst.'.
'</span>',
'seconds' => 'seconden', 'seconds' => 'seconden',
'test' => 'Test', 'test' => 'Test',
'test_email' => 'Er zal een email verstuurd worden naar het email adres in je profiel.', 'test_email' => 'Er zal een email verstuurd worden naar het email adres in je profiel.',
@ -266,18 +262,17 @@ $sm_lang = array(
'log_retention_period_description' => 'Aantal dagen dat logs van notificaties en archieven van server uptime worden bewaard. Vul 0 in om log opruiming uit te zetten.', 'log_retention_period_description' => 'Aantal dagen dat logs van notificaties en archieven van server uptime worden bewaard. Vul 0 in om log opruiming uit te zetten.',
'log_retention_days' => 'dagen', 'log_retention_days' => 'dagen',
), ),
// for newlines in the email messages use <br/>
'notifications' => array( 'notifications' => array(
'off_sms' => 'Server %LABEL% is DOWN: ip=%IP%, poort=%PORT%. Fout=%ERROR%', 'off_sms' => 'Server %LABEL% is DOWN: ip=%IP%, poort=%PORT%. Fout=%ERROR%',
'off_email_subject' => 'BELANGRIJK: Server %LABEL% is DOWN', 'off_email_subject' => 'BELANGRIJK: Server %LABEL% is DOWN',
'off_email_body' => "De server kon niet worden bereikt:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Fout: %ERROR%<br/>Datum: %DATE%", 'off_email_body' => 'De server kon niet worden bereikt:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Fout: %ERROR%<br/>Datum: %DATE%',
'off_pushover_title' => 'Server %LABEL% is DOWN', 'off_pushover_title' => 'Server %LABEL% is DOWN',
'off_pushover_message' => "De server kon niet worden bereikt:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Fout: %ERROR%<br/>Datum: %DATE%", 'off_pushover_message' => 'De server kon niet worden bereikt:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Fout: %ERROR%<br/>Datum: %DATE%',
'on_sms' => 'Server %LABEL% is RUNNING: ip=%IP%, poort=%PORT%, tijd offline=%LAST_OFFLINE_DURATION%', 'on_sms' => 'Server %LABEL% is RUNNING: ip=%IP%, poort=%PORT%, tijd offline=%LAST_OFFLINE_DURATION%',
'on_email_subject' => 'BELANGRIJK: Server %LABEL% is RUNNING', 'on_email_subject' => 'BELANGRIJK: Server %LABEL% is RUNNING',
'on_email_body' => "Server %LABEL% is na %LAST_OFFLINE_DURATION% weer online:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Datum: %DATE%", 'on_email_body' => 'Server %LABEL% is na %LAST_OFFLINE_DURATION% weer online:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Datum: %DATE%',
'on_pushover_title' => 'Server %LABEL% is RUNNING', 'on_pushover_title' => 'Server %LABEL% is RUNNING',
'on_pushover_message' => "Server %LABEL% is na %LAST_OFFLINE_DURATION% weer online:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Datum: %DATE%", 'on_pushover_message' => 'Server %LABEL% is na %LAST_OFFLINE_DURATION% weer online:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Poort: %PORT%<br/>Datum: %DATE%',
), ),
'login' => array( 'login' => array(
'welcome_usermenu' => 'Welkom, %user_name%', 'welcome_usermenu' => 'Welkom, %user_name%',

View File

@ -61,10 +61,13 @@ abstract class AbstractServerController extends AbstractController {
`s`.`server_id`, `s`.`server_id`,
`s`.`ip`, `s`.`ip`,
`s`.`port`, `s`.`port`,
`s`.`request_method`,
`s`.`type`, `s`.`type`,
`s`.`label`, `s`.`label`,
`s`.`pattern`, `s`.`pattern`,
`s`.`pattern_online`, `s`.`pattern_online`,
`s`.`redirect_check`,
`s`.`allow_http_status`,
`s`.`header_name`, `s`.`header_name`,
`s`.`header_value`, `s`.`header_value`,
`s`.`status`, `s`.`status`,
@ -83,7 +86,10 @@ abstract class AbstractServerController extends AbstractController {
`s`.`warning_threshold_counter`, `s`.`warning_threshold_counter`,
`s`.`timeout`, `s`.`timeout`,
`s`.`website_username`, `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` FROM `".PSM_DB_PREFIX."servers` AS `s`
{$sql_join} {$sql_join}
{$sql_where} {$sql_where}
@ -107,7 +113,8 @@ abstract class AbstractServerController extends AbstractController {
$server['last_online'] = psm_timespan($server['last_online']); $server['last_online'] = psm_timespan($server['last_online']);
$server['last_offline'] = psm_timespan($server['last_offline']); $server['last_offline'] = psm_timespan($server['last_offline']);
if ($server['last_offline'] != psm_get_lang('system', 'never')) { 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['last_check'] = psm_timespan($server['last_check']);
$server['active'] = psm_get_lang('system', $server['active']); $server['active'] = psm_get_lang('system', $server['active']);
@ -124,6 +131,10 @@ abstract class AbstractServerController extends AbstractController {
$server['type'] = psm_get_lang('servers', 'type_'.$server['type']); $server['type'] = psm_get_lang('servers', 'type_'.$server['type']);
$server['timeout'] = ($server['timeout'] > 0) ? $server['timeout'] : PSM_CURL_TIMEOUT; $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'); $url_actions = array('delete', 'edit', 'view');
foreach ($url_actions as $action) { foreach ($url_actions as $action) {
$server['url_'.$action] = psm_build_url(array( $server['url_'.$action] = psm_build_url(array(

View File

@ -196,10 +196,13 @@ class ServerController extends AbstractServerController {
'edit_value_label' => $edit_server['label'], 'edit_value_label' => $edit_server['label'],
'edit_value_ip' => $edit_server['ip'], 'edit_value_ip' => $edit_server['ip'],
'edit_value_port' => $edit_server['port'], 'edit_value_port' => $edit_server['port'],
'edit_value_request_method' => $edit_server['request_method'],
'edit_value_timeout' => $edit_server['timeout'], 'edit_value_timeout' => $edit_server['timeout'],
'default_value_timeout' => PSM_CURL_TIMEOUT, 'default_value_timeout' => PSM_CURL_TIMEOUT,
'edit_value_pattern' => $edit_server['pattern'], 'edit_value_pattern' => $edit_server['pattern'],
'edit_pattern_selected_'.$edit_server['pattern_online'] => 'selected="selected"', '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_name' => $edit_server['header_name'],
'edit_value_header_value' => $edit_server['header_value'], 'edit_value_header_value' => $edit_server['header_value'],
'edit_value_warning_threshold' => $edit_server['warning_threshold'], 'edit_value_warning_threshold' => $edit_server['warning_threshold'],
@ -264,9 +267,12 @@ class ServerController extends AbstractServerController {
'website_username' => psm_POST('website_username'), 'website_username' => psm_POST('website_username'),
'website_password' => $encrypted_password, 'website_password' => $encrypted_password,
'port' => intval(psm_POST('port', 0)), 'port' => intval(psm_POST('port', 0)),
'request_method' => empty(psm_POST('request_method')) ? null : psm_POST('request_method'),
'type' => psm_POST('type', ''), 'type' => psm_POST('type', ''),
'pattern' => psm_POST('pattern', ''), 'pattern' => psm_POST('pattern', ''),
'pattern_online' => in_array($_POST['pattern_online'], array('yes', 'no')) ? $_POST['pattern_online'] : 'yes', '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_name' => psm_POST('header_name', ''),
'header_value' => psm_POST('header_value', ''), 'header_value' => psm_POST('header_value', ''),
'rtime' => psm_POST('rtime', '0.0000000'), 'rtime' => psm_POST('rtime', '0.0000000'),
@ -463,8 +469,12 @@ class ServerController extends AbstractServerController {
'label_fieldset_permissions' => psm_get_lang('servers', 'fieldset_permissions'), 'label_fieldset_permissions' => psm_get_lang('servers', 'fieldset_permissions'),
'label_port' => psm_get_lang('servers', 'port'), 'label_port' => psm_get_lang('servers', 'port'),
'label_custom_port' => psm_get_lang('servers', 'custom_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_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_type' => psm_get_lang('servers', 'type'),
'label_website' => psm_get_lang('servers', 'type_website'), 'label_website' => psm_get_lang('servers', 'type_website'),
'label_service' => psm_get_lang('servers', 'type_service'), 'label_service' => psm_get_lang('servers', 'type_service'),
@ -473,6 +483,10 @@ class ServerController extends AbstractServerController {
'label_pattern_description' => psm_get_lang('servers', 'pattern_description'), 'label_pattern_description' => psm_get_lang('servers', 'pattern_description'),
'label_pattern_online' => psm_get_lang('servers', 'pattern_online'), 'label_pattern_online' => psm_get_lang('servers', 'pattern_online'),
'label_pattern_online_description' => psm_get_lang('servers', 'pattern_online_description'), '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' => psm_get_lang('servers', 'header'),
'label_header_name_description' => psm_get_lang('servers', 'header_name_description'), 'label_header_name_description' => psm_get_lang('servers', 'header_name_description'),
'label_header_value_description' => psm_get_lang('servers', 'header_value_description'), 'label_header_value_description' => psm_get_lang('servers', 'header_value_description'),
@ -480,6 +494,9 @@ class ServerController extends AbstractServerController {
'label_rtime' => psm_get_lang('servers', 'latency'), 'label_rtime' => psm_get_lang('servers', 'latency'),
'label_last_online' => psm_get_lang('servers', 'last_online'), 'label_last_online' => psm_get_lang('servers', 'last_online'),
'label_last_offline' => psm_get_lang('servers', 'last_offline'), '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_monitoring' => psm_get_lang('servers', 'monitoring'),
'label_email' => psm_get_lang('servers', 'email'), 'label_email' => psm_get_lang('servers', 'email'),
'label_send_email' => psm_get_lang('servers', 'send_email'), 'label_send_email' => psm_get_lang('servers', 'send_email'),
@ -498,8 +515,11 @@ class ServerController extends AbstractServerController {
'label_yes' => psm_get_lang('system', 'yes'), 'label_yes' => psm_get_lang('system', 'yes'),
'label_no' => psm_get_lang('system', 'no'), 'label_no' => psm_get_lang('system', 'no'),
'label_add_new' => psm_get_lang('system', 'add_new'), 'label_add_new' => psm_get_lang('system', 'add_new'),
'label_advanced' => psm_get_lang('system', 'advanced'),
'label_online' => psm_get_lang('system', 'online'), 'label_online' => psm_get_lang('system', 'online'),
'label_offline' => psm_get_lang('system', 'offline'), 'label_offline' => psm_get_lang('system', 'offline'),
'label_ok' => psm_get_lang('system', 'ok'),
'label_bad' => psm_get_lang('system', 'bad'),
); );
} }
@ -521,4 +541,3 @@ class ServerController extends AbstractServerController {
return $result; return $result;
} }
} }

View File

@ -126,7 +126,7 @@ class Installer {
$this->log('Populating database...'); $this->log('Populating database...');
$queries = array(); $queries = array();
$queries[] = "INSERT INTO `".PSM_DB_PREFIX."servers` (`ip`, `port`, `label`, `type`, `pattern`, `pattern_online`, `status`, `rtime`, `active`, `email`, `sms`, `pushover`, `telegram`) VALUES ('http://sourceforge.net/index.php', 80, 'SourceForge', 'website', '', 'yes','on', '0.0000000', 'yes', 'yes', 'yes', 'yes', 'yes'), ('smtp.gmail.com', 465, 'Gmail SMTP', 'service', '', 'yes', 'on', '0.0000000', 'yes', 'yes', 'yes', 'yes', 'yes')"; $queries[] = "INSERT INTO `".PSM_DB_PREFIX."servers` (`ip`, `port`, `label`, `type`, `pattern`, `pattern_online`, `redirect_check`, `status`, `rtime`, `active`, `email`, `sms`, `pushover`, `telegram`) VALUES ('http://sourceforge.net/index.php', 80, 'SourceForge', 'website', '', 'yes', 'bad', 'on', '0.0000000', 'yes', 'yes', 'yes', 'yes', 'yes'), ('smtp.gmail.com', 465, 'Gmail SMTP', 'service', '', 'yes', 'bad','on', '0.0000000', 'yes', 'yes', 'yes', 'yes', 'yes')";
$queries[] = "INSERT INTO `".PSM_DB_PREFIX."users_servers` (`user_id`,`server_id`) VALUES (1, 1), (1, 2);"; $queries[] = "INSERT INTO `".PSM_DB_PREFIX."users_servers` (`user_id`,`server_id`) VALUES (1, 1), (1, 2);";
$queries[] = "INSERT INTO `".PSM_DB_PREFIX."config` (`key`, `value`) VALUE $queries[] = "INSERT INTO `".PSM_DB_PREFIX."config` (`key`, `value`) VALUE
('language', 'en_US'), ('language', 'en_US'),
@ -225,10 +225,13 @@ class Installer {
`server_id` int(11) unsigned NOT NULL AUTO_INCREMENT, `server_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ip` varchar(500) NOT NULL, `ip` varchar(500) NOT NULL,
`port` int(5) unsigned NOT NULL, `port` int(5) unsigned NOT NULL,
`request_method` varchar(50) unsigned NULL,
`label` varchar(255) NOT NULL, `label` varchar(255) NOT NULL,
`type` enum('ping','service','website') NOT NULL default 'service', `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', `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_name` varchar(255) NOT NULL default '',
`header_value` varchar(255) NOT NULL default '', `header_value` varchar(255) NOT NULL default '',
`status` enum('on','off') NOT NULL default 'on', `status` enum('on','off') NOT NULL default 'on',
@ -248,6 +251,9 @@ class Installer {
`timeout` smallint(1) unsigned NULL DEFAULT NULL, `timeout` smallint(1) unsigned NULL DEFAULT NULL,
`website_username` varchar(255) DEFAULT NULL, `website_username` varchar(255) DEFAULT NULL,
`website_password` 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`) PRIMARY KEY (`server_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;", ) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX.'servers_uptime' => "CREATE TABLE IF NOT EXISTS `".PSM_DB_PREFIX."servers_uptime` ( PSM_DB_PREFIX.'servers_uptime' => "CREATE TABLE IF NOT EXISTS `".PSM_DB_PREFIX."servers_uptime` (
@ -549,9 +555,20 @@ class Installer {
*/ */
protected function upgrade340() { protected function upgrade340() {
$queries = array(); $queries = array();
/**
* Redirect_check is first set to default ok.
* 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 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`;";
$queries[] = "INSERT INTO `".PSM_DB_PREFIX."config` (`key`, `value`) VALUES ('combine_notifications', '1');"; $queries[] = "INSERT INTO `".PSM_DB_PREFIX."config` (`key`, `value`) VALUES ('combine_notifications', '1');";
$this->execSQL($queries); $this->execSQL($queries);
$this->log('Combined notifications enabled. Check out the config page for more info.'); $this->log('Combined notifications enabled. Check out the config page for more info.');
} }
} }

View File

@ -37,6 +37,8 @@ use psm\Service\Database;
class StatusUpdater { class StatusUpdater {
public $error = ''; public $error = '';
public $header = '';
public $rtime = 0; public $rtime = 0;
public $status_new = false; 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 * 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. * to avoid any "we are down" events.
*
* @todo Get last_output when there is a HPPT 50x error.
*
* @param int $server_id * @param int $server_id
* @param int $max_runs how many times should the script recheck the server if unavailable. default is 2 * @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 * @return boolean TRUE if server is up, FALSE otherwise
@ -76,13 +81,14 @@ class StatusUpdater {
public function update($server_id, $max_runs = 2) { public function update($server_id, $max_runs = 2) {
$this->server_id = $server_id; $this->server_id = $server_id;
$this->error = ''; $this->error = '';
$this->header = '';
$this->rtime = ''; $this->rtime = '';
// get server info from db // get server info from db
$this->server = $this->db->selectRow(PSM_DB_PREFIX.'servers', array( $this->server = $this->db->selectRow(PSM_DB_PREFIX.'servers', array(
'server_id' => $server_id, 'server_id' => $server_id,
), array( ), array(
'server_id', 'ip', 'port', 'label', 'type', 'pattern', 'pattern_online', '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' 'warning_threshold_counter', 'timeout', 'website_username', 'website_password', 'last_offline'
)); ));
if (empty($this->server)) { if (empty($this->server)) {
@ -105,8 +111,11 @@ class StatusUpdater {
$save = array( $save = array(
'last_check' => date('Y-m-d H:i:s'), 'last_check' => date('Y-m-d H:i:s'),
'error' => $this->error, '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, // log the uptime before checking the warning threshold,
// so that the warnings can still be reviewed in the server history. // 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 // if the server is on, add the last_online value and reset the error threshold counter
$save['status'] = 'on'; $save['status'] = 'on';
$save['last_online'] = date('Y-m-d H:i:s'); $save['last_online'] = date('Y-m-d H:i:s');
$save['last_output'] = $this->header;
$save['warning_threshold_counter'] = 0; $save['warning_threshold_counter'] = 0;
if ($this->server['status'] == 'off') { if ($this->server['status'] == 'off') {
$online_date = new \DateTime($save['last_online']); $online_date = new \DateTime($save['last_online']);
@ -124,8 +134,10 @@ class StatusUpdater {
$save['last_offline_duration'] = trim(psm_format_interval($difference)); $save['last_offline_duration'] = trim(psm_format_interval($difference));
} }
} else { } 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['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']) { if ($save['warning_threshold_counter'] < $this->server['warning_threshold']) {
// the server is offline but the error threshold has not been met yet. // the server is offline but the error threshold has not been met yet.
@ -229,8 +241,10 @@ class StatusUpdater {
$this->server['timeout'], $this->server['timeout'],
true, true,
$this->server['website_username'], $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); $this->rtime = (microtime(true) - $starttime);
@ -250,8 +264,9 @@ class StatusUpdater {
$code = $code_matches[1][0]; $code = $code_matches[1][0];
$msg = $code_matches[2][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! // 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; $this->error = "HTTP STATUS ERROR: ".$code.' '.$msg;
$result = false; $result = false;
} else { } else {
@ -269,6 +284,18 @@ class StatusUpdater {
} }
} }
// Check if the website redirects to another domain
if ($this->server['redirect_check'] == 'bad'){
$location_matches = array();
preg_match('/(Location: )(https*:\/\/)([a-zA-Z.:0-9]*)([\/][[:alnum:][:punct:]]*)/', $curl_result, $location_matches);
$ip_matches = array();
preg_match('/(https*:\/\/)([a-zA-Z.:0-9]*)([\/][[:alnum:][:punct:]]*)/', $this->server['ip'], $ip_matches);
if($location_matches[3] !== $ip_matches[2]){
$this->error = "The IP/URL redirects to another domain.";
$result = false;
}
}
// Should we check a header ? // Should we check a header ?
if ($this->server['header_name'] != '' && $this->server['header_value'] != '') { if ($this->server['header_name'] != '' && $this->server['header_value'] != '') {
$header_flag = false; $header_flag = false;

View File

@ -59,6 +59,32 @@
<input class="input-mini" type="text" id="port" name="port" value="{{ edit_value_port }}" maxlength="5" /> <input class="input-mini" type="text" id="port" name="port" value="{{ edit_value_port }}" maxlength="5" />
</div> </div>
</div> </div>
<div class="control-group popularRequestMethodsGroup types typeWebsite">
<label class="control-label" for="popularRequestMethods">{{ label_request_method }}</label>
<div class="controls">
<select id="popularRequestMethods" name="popularRequestMethods">
<option value="">{{ label_none }}</option>
<optgroup label="{{ label_popular_request_methods }}">
<option value="GET">GET</option>
<option value="HEAD">HEAD</option>
<option value="POST">POST</option>
<option value="PUT">PUT</option>
<option value="DELETE">DELETE</option>
<option value="CONNECT">CONNECT</option>
<option value="OPTIONS">OPTIONS</option>
<option value="TRACE">TRACE</option>
<option value="PATCH">PATCH</option>
</optgroup>
<option value="custom">{{ label_custom_request_method }}</option>
</select>
</div>
</div>
<div class="control-group requestMethodGroup types typeWebsite">
<label class="control-label" for="requestMethod">{{ label_custom_request_method }}</label>
<div class="controls">
<input class="input" type="text" id="requestMethod" name="request_method" value="{{ edit_value_request_method }}" maxlength="50" />
</div>
</div>
<div class="control-group types typeWebsite"> <div class="control-group types typeWebsite">
<label class="control-label" for="pattern">{{ label_pattern }}</label> <label class="control-label" for="pattern">{{ label_pattern }}</label>
<div class="controls"> <div class="controls">
@ -74,6 +100,21 @@
</select> </select>
</div> </div>
</div> </div>
<div class="control-group types typeWebsite">
<label class="control-label" for="redirect_check">{{ label_redirect_check }}</label>
<div class="controls">
<select id="redirect_check" name="redirect_check" data-toggle="tooltip" title="{{ label_redirect_check_description}}">
<option value="ok" {{ edit_redirect_check_selected_ok|raw }}>{{ label_ok }}</option>
<option value="bad" {{ edit_redirect_check_selected_bad|raw }}>{{ label_bad }}</option>
</select>
</div>
</div>
<div class="control-group types typeWebsite">
<label class="control-label" for="allow_http_status">{{ label_allow_http_status }}</label>
<div class="controls">
<input type="text" id="allow_http_status" name="allow_http_status" value="{{ edit_value_allow_http_status }}" maxlength="255" data-toggle="tooltip" title="{{ label_allow_http_status_description }}" />
</div>
</div>
<div class="control-group types typeWebsite"> <div class="control-group types typeWebsite">
<label class="control-label" for="header_name">{{ label_header }}</label> <label class="control-label" for="header_name">{{ label_header }}</label>
<div class="controls"> <div class="controls">

View File

@ -93,6 +93,22 @@
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
<tr>
<td id="advanced">{{ label_advanced }}&nbsp;<i class="icon-expand-arrow"></i></td>
<td>&nbsp;</td>
</tr>
<tr class="advanced">
<td>{{ label_last_error }}:</td>
<td>{{ last_error }}</td>
</tr>
<tr class="advanced">
<td>{{ label_last_output }}:</td>
<td>{{ last_output }}</td>
</tr>
<tr class="advanced">
<td>{{ label_last_error_output }}:</td>
<td>{{ last_error_output }}</td>
</tr>
{% if has_admin_actions %} {% if has_admin_actions %}
<tr> <tr>
<td class="hidden-small">&nbsp;</td> <td class="hidden-small">&nbsp;</td>

View File

@ -676,3 +676,6 @@ legend{
.icon-telegram { .icon-telegram {
background-position: -96px -168px; background-position: -96px -168px;
} }
.icon-expand-arrow {
background-position: -312px -120px;
}

View File

@ -65,16 +65,33 @@ $().ready(function() {
} }
$('#popularPorts').change(function () { $('#popularPorts').change(function () {
changePopularPorts($(this).val(), false, $('#type').val()); changePopular($(this).val(), $('#type').val());
}); });
// popularRequestMethods
// initial
$('.requestMethodGroup').hide();
var requestMethodInput = $('#requestMethod').val();
if (requestMethodInput != '') {
var findPopularRequestMethods = $('#popularRequestMethods').find('option[value=' + requestMethodInput + ']');
if (findPopularRequestMethods.length) {
$(findPopularRequestMethods).attr("selected", "selected");
} else {
$('#popularRequestMethods').find('option[value=custom]').attr("selected", "selected");
$('.requestMethodGroup').slideDown();
}
}
$('#popularRequestMethods').change(function () {
changePopular($(this).val(), $('#type').val());
});
// server type // server type
$('.types').hide(); $('.types').hide();
changeTypeSwitch($('#type').val()); changeTypeSwitch($('#type').val());
$('#type').change(function () { $('#type').change(function () {
changeTypeSwitch($('#type').val()); changeTypeSwitch($('#type').val());
changePopularPorts($('#popularPorts').val(), true, $('#type').val());
}); });
}); });
@ -83,34 +100,34 @@ function changeTypeSwitch(typeInput) {
case 'service': case 'service':
$('.types').slideUp(); $('.types').slideUp();
$('.typeService').slideDown(); $('.typeService').slideDown();
changePopular($('#popularPorts').val(), typeInput, true);
break; break;
case 'website': case 'website':
$('.types').slideUp(); $('.types').slideUp();
$('.typeWebsite').slideDown(); $('.typeWebsite').slideDown();
changePopular($('#popularRequestMethods').val(), typeInput, true);
break; break;
default: default:
$('.types').hide(); $('.types').slideUp();
} }
} }
function changePopularPorts(popularPorts, changeType, typeInput) { function changePopular(inputValue, typeInput, changedType = false) {
if (changeType === true) { if (typeInput == 'website') {
if (typeInput == 'service') { htmlClass = '.requestMethodGroup';
if (popularPorts == 'custom') { htmlID = '#requestMethod';
$('.portGroup').slideDown(); } else if (typeInput == 'service') {
} else { htmlClass = '.portGroup';
$('.portGroup').hide(); htmlID = '#port';
}
} }
if (inputValue == 'custom') {
$(htmlClass).slideDown();
} else { } else {
if (popularPorts == 'custom') { changedType ? $(htmlClass).hide() : $(htmlClass).slideUp();
$('.portGroup').slideDown(); $(htmlID).val(inputValue);
} else {
$('#port').val(popularPorts);
$('.portGroup').slideUp();
}
} }
} }