adding server view mode; moving history to view page; changing archive

from 1 month to 1 week; adding history graphs (in addition to uptime)
This commit is contained in:
Pepijn Over 2014-03-30 03:48:48 +02:00
parent 6d5397bf61
commit b1f6879ce0
23 changed files with 567 additions and 251 deletions

View File

@ -61,7 +61,6 @@ $sm_lang = array(
'menu' => array(
'config' => 'Настройки',
'server' => 'Сървъри',
'server_history' => 'History',
'server_log' => 'Логове',
'server_status' => 'Статус',
'server_update' => 'Обнови данните',
@ -119,15 +118,21 @@ $sm_lang = array(
'send_sms' => 'SMS',
'updated' => 'Информацията за сървъра е обновена.',
'inserted' => 'Сървърът е добвен успешно.',
'rtime' => 'Пинг',
'latency' => 'Пинг',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (average)',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
'day' => 'Day',
'hour' => 'Hour',
'warning_threshold' => 'Warning threshold',
'warning_threshold_description' => 'Number of failed checks required before it is marked offline.',
'chart_last_week' => 'Last week',
'chart_history' => 'History',
// 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_long_date_format' => '%d.%m.%Y %H:%M:%S',
'chart_short_date_format' => '%d.%m %H:%M',
'chart_short_time_format' => '%H:%M',

View File

@ -61,7 +61,6 @@ $sm_lang = array(
'menu' => array(
'config' => 'Einstellungen',
'server' => 'Server',
'server_history' => 'History',
'server_log' => 'Log',
'server_status' => 'Status',
'server_update' => 'Updates',
@ -119,15 +118,21 @@ $sm_lang = array(
'send_sms' => 'SMS',
'updated' => 'Server aktualisiert.',
'inserted' => 'Server eingetragen.',
'rtime' => 'Antwortzeit',
'latency' => 'Antwortzeit',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (average)',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
'day' => 'Day',
'hour' => 'Hour',
'warning_threshold' => 'Warning threshold',
'warning_threshold_description' => 'Number of failed checks required before it is marked offline.',
'chart_last_week' => 'Last week',
'chart_history' => 'History',
// 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_long_date_format' => '%d.%m.%Y %H:%M:%S',
'chart_short_date_format' => '%d.%m %H:%M',
'chart_short_time_format' => '%H:%M',

View File

@ -61,7 +61,6 @@ $sm_lang = array(
'menu' => array(
'config' => 'Config',
'server' => 'Servers',
'server_history' => 'History',
'server_log' => 'Log',
'server_status' => 'Status',
'server_update' => 'Update',
@ -119,15 +118,21 @@ $sm_lang = array(
'send_sms' => 'Send SMS',
'updated' => 'Server updated.',
'inserted' => 'Server added.',
'rtime' => 'Response time',
'latency' => 'Latency',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (average)',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
'day' => 'Day',
'hour' => 'Hour',
'warning_threshold' => 'Warning threshold',
'warning_threshold_description' => 'Number of failed checks required before it is marked offline.',
'chart_last_week' => 'Last week',
'chart_history' => 'History',
// Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html
'chart_day_format' => '%Y-%m-%d',
'chart_long_date_format' => '%Y-%m-%d %H:%M:%S',
'chart_short_date_format' => '%m/%d %H:%M',
'chart_short_time_format' => '%H:%M',

View File

@ -61,7 +61,6 @@ $sm_lang = array(
'menu' => array(
'config' => 'Configuration',
'server' => 'Serveurs',
'server_history' => 'Historique',
'server_log' => 'Événements',
'server_status' => 'États',
'server_update' => 'Mise à jour',
@ -119,15 +118,21 @@ $sm_lang = array(
'send_sms' => 'Envoyer un SMS',
'updated' => 'Serveur mis à jour.',
'inserted' => 'Serveur ajouté.',
'rtime' => 'Temps de réponse',
'latency' => 'Temps de réponse',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (average)',
'year' => 'Year',
'month' => 'Mois',
'week' => 'Semaine',
'day' => 'Jour',
'hour' => 'Heure',
'warning_threshold' => 'Seuil d\'alerte',
'warning_threshold_description' => 'Nombre d\'échecs de connexion avant que le serveur soit marqué hors-service.',
'chart_last_week' => 'Last week',
'chart_history' => 'History',
// 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_long_date_format' => '%d/%m/%Y %H:%M:%S',
'chart_short_date_format' => '%d/%m %H:%M',
'chart_short_time_format' => '%H:%M',

View File

@ -61,7 +61,6 @@ $sm_lang = array(
'menu' => array(
'config' => '설정',
'server' => '서버목록',
'server_history' => 'History',
'server_log' => '로그',
'server_status' => 'Status',
'server_update' => '업데이트',
@ -119,15 +118,21 @@ $sm_lang = array(
'send_sms' => 'SMS 전송',
'updated' => '서버가 수정되었습니다.',
'inserted' => '서버가 추가되었습니다.',
'rtime' => '응답',
'latency' => '응답',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (average)',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
'day' => 'Day',
'hour' => 'Hour',
'warning_threshold' => 'Warning threshold',
'warning_threshold_description' => 'Number of failed checks required before it is marked offline.',
'chart_last_week' => 'Last week',
'chart_history' => 'History',
// Charts date format according jqPlot date format http://www.jqplot.com/docs/files/plugins/jqplot-dateAxisRenderer-js.html
'chart_day_format' => '%Y-%m-%d',
'chart_long_date_format' => '%Y-%m-%d %H:%M:%S',
'chart_short_date_format' => '%m/%d %H:%M',
'chart_short_time_format' => '%H:%M',

View File

@ -61,7 +61,6 @@ $sm_lang = array(
'menu' => array(
'config' => 'Config',
'server' => 'Servers',
'server_history' => 'Geschiedenis',
'server_log' => 'Log',
'server_status' => 'Status',
'server_update' => 'Update',
@ -119,15 +118,21 @@ $sm_lang = array(
'send_sms' => 'Stuur SMS',
'updated' => 'Server gewijzigd.',
'inserted' => 'Server toegevoegd.',
'rtime' => 'Response tijd',
'latency' => 'Response tijd',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (average)',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
'day' => 'Day',
'hour' => 'Hour',
'warning_threshold' => 'Warning threshold',
'warning_threshold_description' => 'Aantal mislukte pogingen voordat de server als offline gemarkeerd wordt.',
'chart_last_week' => 'Last week',
'chart_history' => 'History',
// 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_long_date_format' => '%d-%m-%Y %H:%M:%S',
'chart_short_date_format' => '%d-%m %H:%M',
'chart_short_time_format' => '%H:%M',

View File

@ -61,7 +61,6 @@ $sm_lang = array(
'menu' => array(
'config' => 'Configuração',
'server' => 'Servidores',
'server_history' => 'History',
'server_log' => 'Log',
'server_status' => 'Status',
'server_update' => 'Atualização',
@ -119,15 +118,21 @@ $sm_lang = array(
'send_sms' => 'Enviar SMS',
'updated' => 'Servidor atualizado.',
'inserted' => 'Servidor adicionar.',
'rtime' => 'Tempo de resposta',
'latency' => 'Tempo de resposta',
'latency_max' => 'Latency (maximum)',
'latency_min' => 'Latency (minimum)',
'latency_avg' => 'Latency (average)',
'year' => 'Year',
'month' => 'Month',
'week' => 'Week',
'day' => 'Day',
'hour' => 'Hour',
'warning_threshold' => 'Warning threshold',
'warning_threshold_description' => 'Number of failed checks required before it is marked offline.',
'chart_last_week' => 'Last week',
'chart_history' => 'History',
// 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_long_date_format' => '%d/%m/%Y %H:%M:%S',
'chart_short_date_format' => '%d/%m %H:%M',
'chart_short_time_format' => '%H:%M',

View File

@ -31,13 +31,6 @@ use psm\Service\Template;
abstract class AbstractController implements ControllerInterface {
/**
* Current mode. Can be used by modules to determine
* what to do
* @var string $mode
*/
public $mode;
/**
* Current action
* @var string $action
@ -234,10 +227,10 @@ abstract class AbstractController implements ControllerInterface {
switch($ulvl) {
case PSM_USER_ADMIN:
$items = array('server', 'server_status', 'server_history', 'server_log', 'user', 'config', 'server_update');
$items = array('server', 'server_status', 'server_log', 'user', 'config', 'server_update');
break;
case PSM_USER_USER:
$items = array('server', 'server_status', 'server_history', 'server_log', 'server_update');
$items = array('server', 'server_status', 'server_log', 'server_update');
break;
default:
$items = array();

View File

@ -77,8 +77,4 @@ abstract class AbstractServerController extends AbstractController {
return $servers;
}
public function getServerUptime($server_id) {
return $this->db->select(PSM_DB_PREFIX.'servers_uptime' , "server_id=$server_id", null, '', 'date');
}
}

View File

@ -1,134 +0,0 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Pepijn Over <pep@neanderthal-technology.com>
* History module : Jérôme Cabanis <http://lauraly.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
**/
namespace psm\Module\Server\Controller;
use psm\Service\Database;
use psm\Service\Template;
/**
* History module. Create the page to view server history
*/
class HistoryController extends AbstractServerController {
function __construct(Database $db, Template $tpl) {
parent::__construct($db, $tpl);
$this->setActions('index', 'index');
}
/**
* Prepare the template with a list of all log entries
*/
protected function executeIndex() {
$this->setTemplateId('history_list', 'history.tpl.html');
// get the active servers from database
$servers = $this->getServers();
$data = array();
foreach ($servers as $server) {
if($server['active'] == 'no') {
continue;
}
$server_id = $server['server_id'];
$uptimes = $this->getServerUptime($server_id);
$last_date = 0;
$last_status = 0;
// Create the list of points and server down zones
$line = array();
$lines = array();
$down = array();
foreach ($uptimes as $uptime) {
$time = strtotime($uptime['date']) * 1000;
if($uptime['status']) {
// The server is up
$line[] = '[' . $time . ',' . round((float)$uptime['latency'], 3) . ']';
if($last_date) {
// Was down before.
// Record the first and last date as a string in the down array
$down[] = '[' . $last_date . ',' . $time . ']';
$last_date = 0;
}
$last_status = 1;
}
else {
// The server is down
if($last_status) {
// If was up before, record la line as string in the lines array
$lines[] = '[' . implode(',', $line) . ']';
$line = array();
$last_status = 0;
}
if(!$last_date) {
$last_date = $time;
}
}
}
if($last_status) {
$lines[] = '[' . implode(',', $line) . ']';
}
if($last_date) {
$down[] = '[' . $last_date . ',0]';
}
$data[] = array(
'server_id' => $server_id,
'server_name' => $server['label'],
'server_lines' => sizeof($lines) ? '[' . implode(',', $lines) . ']' : '',
'server_down' => sizeof($down) ? '[' . implode(',', $down) . ']' : '',
'server_online' => psm_date($server['last_online']),
'server_rtime' => round((float)$server['rtime'], 3),
);
}
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'servers', $data);
}
// override parent::createHTMLLabels()
protected function createHTMLLabels() {
$this->tpl->addTemplateData(
$this->getTemplateId(),
array(
'subtitle' => psm_get_lang('menu', 'server_history'),
'label_server' => psm_get_lang('servers', 'server'),
'label_last_online' => psm_get_lang('servers', 'last_online'),
'label_rtime' => psm_get_lang('servers', 'rtime'),
'label_month' => psm_get_lang('servers', 'month'),
'label_week' => psm_get_lang('servers', 'week'),
'label_day' => psm_get_lang('servers', 'day'),
'label_hour' => psm_get_lang('servers', 'hour'),
'long_date_format' => psm_get_lang('servers', 'chart_long_date_format'),
'short_date_format' => psm_get_lang('servers', 'chart_short_date_format'),
'short_time_format' => psm_get_lang('servers', 'chart_short_time_format'),
)
);
return parent::createHTMLLabels();
}
}

View File

@ -38,7 +38,7 @@ class ServerController extends AbstractServerController {
parent::__construct($db, $tpl);
$this->setActions(array(
'index', 'edit', 'save', 'delete',
'index', 'edit', 'save', 'delete', 'view',
), 'index');
// make sure only admins are allowed to edit/delete servers:
@ -89,23 +89,12 @@ class ServerController extends AbstractServerController {
// will also be replaced in the html_actions template itself
$servers[$x] = $html_actions + $servers[$x];
$servers[$x]['class'] = ($x & 1) ? 'odd' : 'even';
$servers[$x]['rtime'] = round((float) $servers[$x]['rtime'], 4);
$servers[$x]['last_online'] = psm_date($servers[$x]['last_online']);
$servers[$x]['last_check'] = psm_date($servers[$x]['last_check']);
$servers[$x]['active'] = psm_get_lang('system', $servers[$x]['active']);
$servers[$x]['email'] = psm_get_lang('system', $servers[$x]['email']);
$servers[$x]['sms'] = psm_get_lang('system', $servers[$x]['sms']);
$servers[$x] = $this->formatServer($servers[$x]);
if($servers[$x]['type'] == 'website') {
// add link to label
$servers[$x]['ip'] = '<a href="'.$servers[$x]['ip'].'" target="_blank">'.$servers[$x]['ip'].'</a>';
}
if($servers[$x]['status'] == 'on' && $servers[$x]['warning_threshold_counter'] > 0) {
$servers[$x]['status'] = 'warning';
}
$servers[$x]['type'] = psm_get_lang('servers', 'type_' . $servers[$x]['type']);
}
// add servers to template
$this->tpl->addTemplateDataRepeat($this->getTemplateId(), 'servers', $servers);
@ -156,7 +145,7 @@ class ServerController extends AbstractServerController {
array('server_id' => $server_id)
);
if (empty($edit_server)) {
$this->addMessage('Invalid server id', 'error');
$this->addMessage('Invalid server', 'error');
return $this->initializeAction('index');
}
@ -242,6 +231,85 @@ class ServerController extends AbstractServerController {
$this->initializeAction('index');
}
/**
* Prepare the view template
*/
protected function executeView() {
$this->setTemplateId('server_view', 'server/view.tpl.html');
$server_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
// get server entry
$server = $this->db->selectRow(
PSM_DB_PREFIX.'servers',
array('server_id' => $server_id)
);
if (empty($server)) {
$this->addMessage('Invalid server', 'error');
return $this->initializeAction('index');
}
$sidebar = new \psm\Util\Module\Sidebar($this->tpl);
$this->setSidebar($sidebar);
$sidebar->setSubtitle($server['label']);
if($this->user->getUserLevel() == PSM_USER_ADMIN) {
$sidebar->addLink(
'edit',
psm_get_lang('system', 'edit'),
psm_build_url(array('mod' => 'server', 'action' => 'edit', 'id' => $server_id)),
'edit'
);
$sidebar->addLink(
'delete',
psm_get_lang('system', 'delete'),
"javascript:sm_delete('{$server_id}', 'server');",
'remove'
);
}
$sidebar->addLink(
'go_back',
psm_get_lang('system', 'go_back'),
psm_build_url(array('mod' => 'server')),
'th-list'
);
$tpl_data = $this->formatServer($server);
$history = new \psm\Util\Server\HistoryGraph($this->db, $this->tpl);
$tpl_data['html_history'] = $history->createHTML($server_id);
$this->tpl->addTemplateData(
$this->getTemplateId(),
$tpl_data
);
}
/**
* Format server data for display
* @param array $server
* @return array
*/
protected function formatServer($server) {
$server['rtime'] = round((float) $server['rtime'], 4);
$server['last_online'] = psm_timespan($server['last_online']);
$server['last_check'] = psm_timespan($server['last_check']);
$server['active'] = psm_get_lang('system', $server['active']);
$server['email'] = psm_get_lang('system', $server['email']);
$server['sms'] = psm_get_lang('system', $server['sms']);
$server['url_view'] = psm_build_url(array(
'mod' => 'server',
'action' => 'view',
'id' => $server['server_id'],
));
if($server['status'] == 'on' && $server['warning_threshold_counter'] > 0) {
$server['status'] = 'warning';
}
$server['type'] = psm_get_lang('servers', 'type_' . $server['type']);
return $server;
}
// override parent::createHTMLLabels()
protected function createHTMLLabels() {
$this->tpl->addTemplateData(
@ -258,7 +326,7 @@ class ServerController extends AbstractServerController {
'label_pattern' => psm_get_lang('servers', 'pattern'),
'label_pattern_description' => psm_get_lang('servers', 'pattern_description'),
'label_last_check' => psm_get_lang('servers', 'last_check'),
'label_rtime' => psm_get_lang('servers', 'rtime'),
'label_rtime' => psm_get_lang('servers', 'latency'),
'label_last_online' => psm_get_lang('servers', 'last_online'),
'label_monitoring' => psm_get_lang('servers', 'monitoring'),
'label_send_email' => psm_get_lang('servers', 'send_email'),

View File

@ -65,7 +65,7 @@ class StatusController extends AbstractServerController {
'warning_fg' => '#F3F3B1',
'label_last_check' => psm_get_lang('servers', 'last_check'),
'label_last_online' => psm_get_lang('servers', 'last_online'),
'label_rtime' => psm_get_lang('servers', 'rtime'),
'label_rtime' => psm_get_lang('servers', 'latency'),
);
$this->tpl->addTemplateData($this->getTemplateId(), $tpl_data);
@ -75,6 +75,7 @@ class StatusController extends AbstractServerController {
}
$server['last_checked_nice'] = psm_timespan($server['last_check']);
$server['last_online_nice'] = psm_timespan($server['last_online']);
$server['url_view'] = psm_build_url(array('mod' => 'server', 'action' => 'view', 'id' => $server['server_id']));
if ($server['status'] == "off") {
$offline[$server['server_id']] = $server;

View File

@ -33,7 +33,6 @@ class ServerModule implements ModuleInterface {
public function getControllers() {
return array(
'server' => __NAMESPACE__ . '\Controller\ServerController',
'history' => __NAMESPACE__ . '\Controller\HistoryController',
'log' => __NAMESPACE__ . '\Controller\LogController',
'status' => __NAMESPACE__ . '\Controller\StatusController',
'update' => __NAMESPACE__ . '\Controller\UpdateController',

View File

@ -114,54 +114,100 @@ class Template {
}
/**
* Add repeat rows to template
* Add repeat rows to template.
* It's possible to create a nested repeat tpl. All you need to do is to create a subarray
* For example:
* $data = array(
* 0 => array(
* 'name' => 'Test',
* 'subdata' => array(
* 0 => array(
* 'name' => 'Subtest 1',
* ),
* 1 => array(...)
* ),
* ),
* );
* In your template you would literally put the nested repeat inside the first repeat.
* If you have more than 1 nested array, the first subtemplate will be used for all others.
*
* @param string $id template id used by add_template()
* @param string $id template id used by add_template() or html code in case of repeat-repeat tpl
* @param string $repeat_id ID used in template file for the repeat template: <!--%tpl_repeat_ID-->html<!--%%tpl_repeat_ID-->
* @param array $data
* @param boolean $use_html can only be used from within this function for recursive repeat templating. in this case the $id is the html code
* @param int $level starts off with 0. if level=2, current repeat template will be used again for subs, so you can go all the way
* @param int $level_reuse_prev from what level should we start repeating the current template for more subrecords, so we can go all the way?
* @return mixed false if repeat template cannot be found, html code on success
*/
public function addTemplateDataRepeat($id, $repeat_id, $data) {
// does the template exist?
if (!isset($this->templates[$id])) {
// file does not exist
trigger_error('Template not found with id: '.$id);
return false;
public function addTemplateDataRepeat($tpl_id, $repeat_id, $data, $use_html = false, $level = 0, $level_reuse_prev = 2) {
if($use_html) {
$source = $tpl_id;
} else {
// does the template exist?
if (!isset($this->templates[$tpl_id])) {
// file does not exist
trigger_error("Template '{$tpl_id}' could not be found", E_USER_WARNING);
return false;
}
$source =& $this->templates[$tpl_id];
}
$use_tpl = null;
if($level < $level_reuse_prev) {
// find "tpl_repeat_{$repeat_id}_" in the current template
preg_match_all("{<!--%tpl_repeat_{$repeat_id}-->(.*?)<!--%%tpl_repeat_{$repeat_id}-->}is", $source, $matches);
// find "tpl_repeat_{$repeat_id}_" in the current template
//preg_match_all('{<!--%(.+?)-->(.*?)<!--%%\\1-->}is', $this->templates[$id], $matches);
preg_match_all("{<!--%tpl_repeat_{$repeat_id}-->(.*?)<!--%%tpl_repeat_{$repeat_id}-->}is", $this->templates[$id], $matches);
// check if the repeat_id is in one of the matches
if (isset($matches[1][0])) {
$use_tpl = $matches[1][0];
} else {
// if we didn't find a repeat template for the repeat_id supplied, skip the rest..
return false;
}
// no repeat tpl found? skip to next one
if (empty($matches)) return false;
// check if the row_id is in one of the matches (aka whether the supplied row id actually has a repeat template in this file)
if (isset($matches[1][0])) {
$use_tpl = $matches[1][0];
// remove repeat tpl code from original template so it won't be in the source
$source = preg_replace("{<!--%tpl_repeat_".$repeat_id."-->(.*?)<!--%%tpl_repeat_".$repeat_id."-->}is", "", $source);
} else {
$use_tpl = $source;
}
// if we didn't find a repeat template for the row_id supplied, skip the rest..
if ($use_tpl === null) return false;
// remove repeat tpl code from original template so it won't be in the source
$this->templates[$id] = preg_replace("{<!--%tpl_repeat_".$repeat_id."-->(.*?)<!--%%tpl_repeat_".$repeat_id."-->}is", "", $this->templates[$id]);
// now lets go through all the records supplied and put them in the HTML repeat code we just found
$result = '';
foreach($data as $record) {
$tmp_string = $use_tpl;
foreach($record as $k => $v) {
$tmp_string = str_replace('{'.$k.'}', $v, $tmp_string);
if(!is_array($record)) {
$record = array(
'value' => $record,
);
}
$result .= $tmp_string."\n";
// multi dim array
foreach($record as $k => $v) {
if(is_array($v)) {
// nested repeat
if(isset($v[0]) && is_array($v[0])) {
// repeat template in a repeat template
$repeat_html = $this->addTemplateDataRepeat($use_tpl, $k, $v, true, ($level + 1), $level_reuse_prev);
$tmp_string = str_replace('{'.$k.'}', $repeat_html, $tmp_string);
} else {
foreach($v as $vk => $vv) {
$tmp_string = str_replace('{'.$k.'_'.$vk.'}', $vv, $tmp_string);
}
}
} else {
$tmp_string = str_replace('{'.$k.'}', $v, $tmp_string);
}
}
$result .= $tmp_string.PHP_EOL;
}
// add to main template..
return $this->addTemplateData($id, array($repeat_id => $result));
if($use_html === false) {
// add to main template..
return $this->addTemplateData($tpl_id, array($repeat_id => $result));
} else {
return $result;
}
}
public function display($id) {

View File

@ -43,6 +43,13 @@ class Sidebar implements SidebarInterface {
*/
protected $items = array();
/**
* Custom subtitle
* @var string $subtitle
* @see setSubtitle()
*/
protected $subtitle;
/**
* Template service
* @var \psm\Service\Template $tpl
@ -63,6 +70,16 @@ class Sidebar implements SidebarInterface {
return $this;
}
/**
* Set a custom subtitle (default is module subitle)
* @param string $title
* @return \psm\Util\Moduke\Sidebar
*/
public function setSubtitle($title) {
$this->subtitle = $title;
return $this;
}
/**
* Add new link to sidebar
* @param string $id
@ -114,6 +131,11 @@ class Sidebar implements SidebarInterface {
if(!empty($items)) {
$this->tpl->addTemplateDataRepeat($tpl_id, 'items', $items);
}
if($this->subtitle !== null) {
$this->tpl->addTemplateData($tpl_id, array(
'subtitle' => $this->subtitle,
));
}
$html = $this->tpl->getTemplate($tpl_id);

View File

@ -0,0 +1,221 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Jérôme Cabanis <http://lauraly.com>
* Pepijn Over <pep@neanderthal-technology.com>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
**/
namespace psm\Util\Server;
use psm\Service\Database;
use psm\Service\Template;
/**
* History util, create HTML for server graphs
*/
class HistoryGraph {
/**
* Database service
* @var \psm\Service\Database $db;
*/
protected $db;
/**
* Template service
* @var \psm\Service\Template $tpl
*/
protected $tpl;
function __construct(Database $db, Template $tpl) {
$this->db = $db;
$this->tpl = $tpl;
}
/**
* Prepare the HTML for the graph
* @return string
*/
public function createHTML($server_id) {
$tpl_id = 'server_history';
$this->tpl->newTemplate($tpl_id, 'server/history.tpl.html');
$graphs = array(
0 => $this->generateGraphUptime($server_id),
1 => $this->generateGraphHistory($server_id),
);
$this->tpl->addTemplateDataRepeat($tpl_id, 'graphs', $graphs);
$this->tpl->addTemplateData(
$tpl_id,
array(
'label_server' => psm_get_lang('servers', 'server'),
'label_latency_avg' => psm_get_lang('servers', 'latency_avg'),
'day_format' => psm_get_lang('servers', 'chart_day_format'),
'long_date_format' => psm_get_lang('servers', 'chart_long_date_format'),
'short_date_format' => psm_get_lang('servers', 'chart_short_date_format'),
'short_time_format' => psm_get_lang('servers', 'chart_short_time_format'),
)
);
return $this->tpl->getTemplate($tpl_id);
}
/**
* Generate data for uptime graph
* @param int $server_id
* @return array
*/
protected function generateGraphUptime($server_id) {
$uptimes = $this->db->select(PSM_DB_PREFIX.'servers_uptime' , array('server_id' => $server_id), null, '', 'date');
$last_date = 0;
$latency_avg = 0;
// Create the list of points and server down zones
$line = array();
$lines = array();
$down = array();
foreach ($uptimes as $uptime) {
$latency_avg += (float) $uptime['latency'];
$time = strtotime($uptime['date']) * 1000;
if($uptime['status']) {
// The server is up
$line[] = '[' . $time . ',' . round((float)$uptime['latency'], 4) . ']';
if($last_date) {
// Was down before.
// Record the first and last date as a string in the down array
$down[] = '[' . $last_date . ',' . $time . ']';
$last_date = 0;
}
}
else {
if(!$last_date) {
$last_date = $time;
}
}
}
if(!empty($line)) {
$lines[] = '[' . implode(',', $line) . ']';
}
if($last_date) {
$down[] = '[' . $last_date . ',0]';
}
$buttons = array();
$buttons[] = array('mode' => 'hour', 'label' => psm_get_lang('servers', 'hour'), 'class_active' => 'btn-info');
$buttons[] = array('mode' => 'day', 'label' => psm_get_lang('servers', 'day'));
$buttons[] = array('mode' => 'week', 'label' => psm_get_lang('servers', 'week'));
$data = array(
'title' => psm_get_lang('servers', 'chart_last_week'),
'latency_avg' => count($uptimes) > 0 ? round(($latency_avg / count($uptimes)), 4) : 0,
'server_lines' => sizeof($lines) ? '[' . implode(',', $lines) . ']' : '',
'server_down' => sizeof($down) ? '[' . implode(',', $down) . ']' : '',
'series' => "[{label: '".psm_get_lang('servers', 'latency')."', lineWidth: 1}]",
'plotmode' => 'hour',
'buttons' => $buttons,
'chart_id' => $server_id . '_uptime',
);
return $data;
}
/**
* Generate data for history graph
* @param int $server_id
* @return array
*/
protected function generateGraphHistory($server_id) {
$uptimes = $this->db->select(PSM_DB_PREFIX.'servers_history' , array('server_id' => $server_id), null, '', 'date');
$last_date = 0;
// Create the list of points and server down zones
$lines = array(
'latency_avg' => array(),
'latency_max' => array(),
'latency_min' => array(),
);
$latency_avg = 0;
$series = array();
$time_end = 0;
$down = array();
foreach ($uptimes as $uptime) {
$time = strtotime($uptime['date']) * 1000;
// keep track of highest timestamp to use as end-date for graphs
if($time > $time_end) {
$time_end = $time;
}
$latency_avg += (float) $uptime['latency_avg'];
if($uptime['checks_failed'] == 0) {
// The server is up
foreach($lines as $key => &$value) {
// add the value for each of the different lines
if(isset($uptime[$key])) {
$value[] = '[' . $time . ',' . round((float)$uptime[$key], 4) . ']';
}
}
if($last_date) {
// Was down before.
// Record the first and last date as a string in the down array
$down[] = '[' . $last_date . ',' . $time . ']';
$last_date = 0;
}
} else {
// The server is down
if(!$last_date) {
$last_date = $time;
}
}
}
$lines_merged = array();
foreach($lines as $line_key => $line_value) {
if(empty($value)) {
continue;
}
$lines_merged[] = '[' . implode(',', $line_value) . ']';
$series[] = "{label: '".psm_get_lang('servers', $line_key)."', lineWidth: 1}";
}
if($last_date) {
$down[] = '[' . $last_date . ',0]';
}
$buttons = array();
$buttons[] = array('mode' => 'week', 'label' => psm_get_lang('servers', 'week'));
$buttons[] = array('mode' => 'month', 'label' => psm_get_lang('servers', 'month'), 'class_active' => 'btn-info');
$buttons[] = array('mode' => 'year', 'label' => psm_get_lang('servers', 'year'));
$data = array(
'title' => psm_get_lang('servers', 'chart_history'),
'latency_avg' => count($uptimes) > 0 ? round(($latency_avg / count($uptimes)), 4) : 0,
'server_lines' => sizeof($lines_merged) ? '[' . implode(',', $lines_merged) . ']' : '',
'server_down' => sizeof($down) ? '[' . implode(',', $down) . ']' : '',
'series' => sizeof($series) ? '[' . implode(',', $series) . ']' : '',
'plotmode' => 'month',
'end_timestamp' => $time_end,
'buttons' => $buttons,
// make sure to add chart id after buttons so its added to those tmeplates as well
'chart_id' => $server_id . '_history',
);
return $data;
}
}

View File

@ -81,7 +81,7 @@ class Autorun {
$archiver = new StatusArchiver($this->db);
$cleanup_date = new \DateTime();
$cleanup_date->modify('-1 month');
$cleanup_date->modify('-1 week');
foreach($servers as $server) {
$status_old = ($server['status'] == 'on') ? true : false;

View File

@ -1,4 +1,4 @@
<!--%tpl_history_list-->
<!--%tpl_server_history-->
<link href="static/plugin/jqplot/jquery.jqplot.min.css" rel="stylesheet" >
<!--[if lt IE 9]><script type="text/javascript" src="static/plugin/excanvas.js"></script><![endif]-->
<script type="text/javascript" src="static/plugin/jqplot/jquery.jqplot.min.js"></script>
@ -9,6 +9,7 @@
<link href="static/css/history.css" rel="stylesheet" >
<script type="text/javascript">
var day_format = '{day_format}';
var long_date_format = '{long_date_format}';
var short_date_format = '{short_date_format}';
var short_time_format = '{short_time_format}';
@ -16,11 +17,11 @@
<script type="text/javascript" src="static/js/history.js"></script>
<div id="history-panel">
<!--%tpl_repeat_servers-->
<!--%tpl_repeat_graphs-->
<div class="chart-row">
<div class="chart-container">
<div class="chart-content">
<div id="chart{server_id}" class="chart" data-title="{server_name}" data-lines="{server_lines}" data-down="{server_down}"></div>
<div id="chart{chart_id}" class="chart" data-title="{title}" data-plotMode="{plotmode}" data-endTime="{end_timestamp}" data-series="{series}" data-lines="{server_lines}" data-down="{server_down}"></div>
</div>
</div>
<div class="info-container">
@ -28,28 +29,25 @@
<div class="info-dropdown btn-group">
<button class="btn dropdown-toggle" data-toggle="dropdown"><i class="icon-info-sign"></i></span></button>
<ul class="dropdown-menu">
<li><span>{label_last_online}: {server_online}</span></li>
<li><span>{label_rtime}: {server_rtime}</span></li>
<li><span>{label_latency_avg}: {latency_avg}</span></li>
</ul>
</div>
<div class="server-info">
{label_last_online}: {server_online}<br/>
{label_rtime}: {server_rtime}<br/>
{label_latency_avg}: {latency_avg}<br/>
</div>
</div>
<div class="chart-selector">
<div class="btn-group">
<button class="btn" data-chartId="{server_id}" data-chartMode="month" >{label_month}</button>
<button class="btn" data-chartId="{server_id}" data-chartMode="week" >{label_week}</button>
<button class="btn" data-chartId="{server_id}" data-chartMode="day" >{label_day}</button>
<button class="btn btn-info" data-chartId="{server_id}" data-chartMode="hour" >{label_hour}</button>
</div>
<!--%tpl_repeat_buttons-->
<button class="btn {class_active}" data-chartId="{chart_id}" data-chartMode="{mode}" >{label}</button>
<!--%%tpl_repeat_buttons-->
{buttons}
</div>
</div>
</div>
</div>
<div style="clear: both;">&nbsp;</div>
<!--%%tpl_repeat_servers-->
{servers}
<!--%%tpl_repeat_graphs-->
{graphs}
</div>
<!--%%tpl_history_list-->
<!--%%tpl_server_history-->

View File

@ -0,0 +1,56 @@
<!--%tpl_server_view-->
<table class="table">
<colgroup>
<col class="oce-first" />
</colgroup>
<thead>
<tr class="head">
<th colspan="2">
<span class="label label-status-{status}">
<a href="#" title="{error}">{status}</a>
</span>&nbsp;
{label}
</th>
</tr>
</thead>
<tbody>
<tr>
<td>{label_type}:</td>
<td>{type}</td>
</tr>
<tr>
<td>{label_domain}:</td>
<td>{ip}</td>
</tr>
<tr>
<td>{label_port}:</td>
<td>{port}</td>
</tr>
<tr>
<td>{label_last_check}:</td>
<td>{last_check}</td>
</tr>
<tr>
<td>{label_last_online}:</td>
<td>{last_online}</td>
</tr>
<tr>
<td>{label_rtime}:</td>
<td>{rtime} s</td>
</tr>
<tr>
<td>{label_monitoring}:</td>
<td>{active}</td>
</tr>
<tr>
<td>{label_send_email}:</td>
<td>{email}</td>
</tr>
<tr>
<td>{label_send_sms}:</td>
<td>{sms}</td>
</tr>
</tbody>
</table>
{html_history}
<!--%%tpl_server_view-->

View File

@ -24,7 +24,7 @@
<a href="#" title="{error}">{status}</a>
</span>
</td>
<td>{label}</td>
<td><a href="{url_view}">{label}</a></td>
<td>{ip}</td>
<td>{port}</td>
<td>{type}</td>

View File

@ -24,6 +24,7 @@
border-radius: 3px;
margin-bottom: 20px;
width: 300px;
cursor: pointer;
}
.offline {
@ -54,7 +55,7 @@
</style>
<div class="offline">
<!--%tpl_repeat_servers_offline-->
<div class="entity {class_warning}">
<div class="entity {class_warning}" onclick="window.location.href='{url_view}'">
<h2>{label}</h2>
<p>{label_last_online}: {last_online_nice}</p>
<p>{label_last_check}: {last_checked_nice}</p>
@ -64,7 +65,7 @@
</div>
<div class="online">
<!--%tpl_repeat_servers_online-->
<div class="entity">
<div class="entity" onclick="window.location.href='{url_view}'">
<h2>{label}</h2>
<p>{label_last_online}: {last_checked_nice}</p>
<p>{label_rtime}: {rtime}s</p>

View File

@ -87,4 +87,8 @@ legend{
max-width: 350px;
margin: auto;
margin-bottom: 18px;
}
.oce-first{
background-color:#eee;
}

View File

@ -3,8 +3,8 @@ $().ready(function()
$('.chart').each(function() {
var $this = $(this);
create_plot($this);
});
});
$(window).resize(function(){
$('.chart').each(function() {
var plot = $(this).data('psm_plot');
@ -12,7 +12,7 @@ $().ready(function()
plot.replot( );
});
});
$('.chart-selector .btn').click(function(){
var $btn = $(this);
var chartID = $btn.attr('data-chartId');
@ -26,14 +26,18 @@ $().ready(function()
function create_plot($this, mode)
{
if(!$this) return;
var plot = $this.data('psm_plot');
if(plot) {
plot.destroy();
$this.removeData('psm_plot');
}
var d = new Date();
if($this.attr('data-endTime')) {
var d = new Date(parseInt($this.attr('data-endTime')));
} else {
var d = new Date();
}
var time = d.getTime();
var lines = $this.attr('data-lines');
@ -44,14 +48,18 @@ function create_plot($this, mode)
lines = eval(lines);
}
mode = mode || $this.data('psm_plotMode') || 'hour';
$this.data('psm_plotMode', mode);
mode = mode || $this.attr('data-plotMode') || 'hour';
$this.attr('data-plotMode', mode);
var timeStamp, tickFormat;
switch(mode)
{
case 'year':
timeStamp = 1000 * 60 * 60 * 24 * 365.25;
tickFormat = day_format;
break;
case 'month':
timeStamp = 1000 * 60 * 60 * 24 * 30;
tickFormat = short_date_format;
tickFormat = day_format;
break;
case 'week':
timeStamp = 1000 * 60 * 60 * 24 * 7;
@ -87,14 +95,19 @@ function create_plot($this, mode)
showTooltipPrecision: 1.0,
tooltipFormatString: "&darr; " + d.strftime(long_date_format)
}});
}
}
}
plot = $.jqplot($this.attr('id'), lines, {
title: $this.attr('data-title'),
series: eval($this.attr('data-series')),
legend: {
show: true,
placement: 'outsideGrid'
},
axes : {
xaxis:{
renderer:$.jqplot.DateAxisRenderer,
renderer:$.jqplot.DateAxisRenderer,
tickOptions : { formatString: tickFormat },
min: time - timeStamp,
max: time
@ -111,20 +124,17 @@ function create_plot($this, mode)
return "&uarr; " + d.strftime(long_date_format) + ' - ' + $.jqplot.sprintf('%.3fs', point[1]);
}
},
seriesDefaults: {
color: "#4bb2c5"
},
canvasOverlay: {
show: true,
objects: downArray
},
cursor:{
cursor:{
show: true,
zoom: true,
zoom: true,
showTooltip:false,
dblClickReset: true,
constrainZoomTo: 'x'
}
}
});
$this.data('psm_plot', plot);
}