1<?php
2/*
3** Zabbix
4** Copyright (C) 2001-2021 Zabbix SIA
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19**/
20
21
22require_once dirname(__FILE__).'/include/config.inc.php';
23require_once dirname(__FILE__).'/include/triggers.inc.php';
24require_once dirname(__FILE__).'/include/services.inc.php';
25
26$page['title'] = _('Services');
27$page['file'] = 'srv_status.php';
28$page['scripts'] = ['layout.mode.js'];
29
30define('ZBX_PAGE_DO_REFRESH', 1);
31
32if (!getRequest('serviceid') || !getRequest('showgraph')) {
33	CView::$has_web_layout_mode = true;
34	$page['web_layout_mode'] = CView::getLayoutMode();
35}
36require_once dirname(__FILE__).'/include/page_header.php';
37
38$periods = [
39	'today' => _('Today'),
40	'week' => _('This week'),
41	'month' => _('This month'),
42	'year' => _('This year'),
43	24 => _('Last 24 hours'),
44	24 * 7 => _('Last 7 days'),
45	24 * 30 => _('Last 30 days'),
46	24 * DAY_IN_YEAR => _('Last 365 days')
47];
48
49// VAR	TYPE	OPTIONAL	FLAGS	VALIDATION	EXCEPTION
50$fields = [
51	'serviceid' =>	[T_ZBX_INT, O_OPT, P_SYS|P_NZERO, DB_ID,	null],
52	'showgraph' =>	[T_ZBX_INT, O_OPT, P_SYS,	IN('1'),		'isset({serviceid})'],
53	'period' =>		[T_ZBX_STR, O_OPT, P_SYS,	IN('"'.implode('","', array_keys($periods)).'"'),	null]
54];
55check_fields($fields);
56
57if (isset($_REQUEST['serviceid']) && isset($_REQUEST['showgraph'])) {
58	$service = API::Service()->get([
59		'output' => ['serviceid'],
60		'serviceids' => getRequest('serviceid')
61	]);
62	$service = reset($service);
63
64	if ($service) {
65		$table = (new CDiv())
66			->addClass(ZBX_STYLE_TABLE_FORMS_CONTAINER)
67			->addClass(ZBX_STYLE_CENTER)
68			->addItem(new CImg('chart5.php?serviceid='.$service['serviceid'].url_param('path')))
69			->show();
70	}
71	else {
72		access_deny();
73	}
74}
75else {
76	$period = getRequest('period', 7 * 24);
77	$period_end = time();
78
79	switch ($period) {
80		case 'today':
81			$period_start = mktime(0, 0, 0, date('n'), date('j'), date('Y'));
82			break;
83		case 'week':
84			$period_start = strtotime('last sunday');
85			break;
86		case 'month':
87			$period_start = mktime(0, 0, 0, date('n'), 1, date('Y'));
88			break;
89		case 'year':
90			$period_start = mktime(0, 0, 0, 1, 1, date('Y'));
91			break;
92		case 24:
93		case 24 * 7:
94		case 24 * 30:
95		case 24 * DAY_IN_YEAR:
96			$period_start = $period_end - ($period * 3600);
97			break;
98	}
99
100	// fetch services
101	$services = API::Service()->get([
102		'output' => ['name', 'serviceid', 'showsla', 'goodsla', 'algorithm', 'sortorder'],
103		'selectParent' => ['serviceid'],
104		'selectDependencies' => ['servicedownid', 'soft', 'linkid'],
105		'selectTrigger' => ['description', 'triggerid', 'expression'],
106		'preservekeys' => true
107	]);
108
109	sortServices($services);
110
111	// expand trigger descriptions
112	$triggers = zbx_objectValues(
113		array_filter($services, function($service) { return (bool) $service['trigger']; }), 'trigger'
114	);
115	$triggers = CMacrosResolverHelper::resolveTriggerNames(zbx_toHash($triggers, 'triggerid'));
116
117	foreach ($services as &$service) {
118		if ($service['trigger']) {
119			$service['trigger'] = $triggers[$service['trigger']['triggerid']];
120		}
121	}
122	unset($service);
123
124	// fetch sla
125	$slaData = API::Service()->getSla([
126		'intervals' => [[
127			'from' => $period_start,
128			'to' => $period_end
129		]]
130	]);
131	// expand problem trigger descriptions
132	foreach ($slaData as &$serviceSla) {
133		foreach ($serviceSla['problems'] as &$problemTrigger) {
134			$problemTrigger['description'] = $triggers[$problemTrigger['triggerid']]['description'];
135		}
136		unset($problemTrigger);
137	}
138	unset($serviceSla);
139
140	$treeData = [];
141	createServiceMonitoringTree($services, $slaData, $period, $treeData);
142	$tree = new CServiceTree('service_status_tree',
143		$treeData,
144		[
145			'caption' => _('Service'),
146			'status' => _('Status'),
147			'reason' => _('Reason'),
148			'sla' => (new CColHeader(_('Problem time')))->setColSpan(2),
149			'sla2' => null,
150			'sla3' => _('SLA').' / '._('Acceptable SLA')
151		]
152	);
153
154	if ($tree) {
155		// creates form for choosing a preset interval
156		$period_combo = new CComboBox('period', $period, 'javascript: submit();');
157		foreach ($periods as $key => $val) {
158			$period_combo->addItem($key, $val);
159		}
160
161		(new CWidget())
162			->setTitle(_('Services'))
163			->setWebLayoutMode($page['web_layout_mode'])
164			->setControls(new CList([
165				(new CForm('get'))
166					->cleanItems()
167					->setAttribute('aria-label', _('Main filter'))
168					->addItem((new CList())
169						->addItem([
170							new CLabel(_('Period'), 'period'),
171							(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
172							$period_combo
173						])
174					),
175				(new CTag('nav', true, get_icon('fullscreen')))->setAttribute('aria-label', _('Content controls'))
176			]))
177			->addItem($tree->getHTML())
178			->show();
179	}
180	else {
181		error(_('Cannot format Tree. Check logic structure in service links.'));
182	}
183}
184
185require_once dirname(__FILE__).'/include/page_footer.php';
186