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/items.inc.php'; 24 25$page['title'] = _('Queue'); 26$page['file'] = 'queue.php'; 27 28define('ZBX_PAGE_DO_REFRESH', 1); 29 30require_once dirname(__FILE__).'/include/page_header.php'; 31 32$queueModes = [ 33 QUEUE_OVERVIEW, 34 QUEUE_OVERVIEW_BY_PROXY, 35 QUEUE_DETAILS 36]; 37 38// VAR TYPE OPTIONAL FLAGS VALIDATION EXCEPTION 39$fields = [ 40 'config' => [T_ZBX_INT, O_OPT, P_SYS, IN($queueModes), null] 41]; 42 43check_fields($fields); 44 45$config = getRequest('config', CProfile::get('web.queue.config', 0)); 46CProfile::update('web.queue.config', $config, PROFILE_TYPE_INT); 47 48// fetch data 49$zabbixServer = new CZabbixServer($ZBX_SERVER, $ZBX_SERVER_PORT, ZBX_SOCKET_TIMEOUT, ZBX_SOCKET_BYTES_LIMIT); 50$queueRequests = [ 51 QUEUE_OVERVIEW => CZabbixServer::QUEUE_OVERVIEW, 52 QUEUE_OVERVIEW_BY_PROXY => CZabbixServer::QUEUE_OVERVIEW_BY_PROXY, 53 QUEUE_DETAILS => CZabbixServer::QUEUE_DETAILS 54]; 55$queueData = $zabbixServer->getQueue($queueRequests[$config], get_cookie(ZBX_SESSION_NAME), QUEUE_DETAIL_ITEM_COUNT); 56 57// check for errors error 58if ($zabbixServer->getError()) { 59 error($zabbixServer->getError()); 60 show_error_message(_('Cannot display item queue.')); 61 62 require_once dirname(__FILE__).'/include/page_footer.php'; 63} 64 65$widget = (new CWidget()) 66 ->setTitle(_('Queue of items to be updated')) 67 ->setControls((new CTag('nav', true, [ 68 (new CForm('get')) 69 ->cleanItems() 70 ->addItem((new CList()) 71 ->addItem( 72 (new CComboBox('config', $config, 'submit();', [ 73 QUEUE_OVERVIEW => _('Overview'), 74 QUEUE_OVERVIEW_BY_PROXY => _('Overview by proxy'), 75 QUEUE_DETAILS => _('Details') 76 ]))->removeId() 77 ) 78 ) 79 ])) 80 ->setAttribute('aria-label', _('Content controls')) 81 ); 82 83$table = new CTableInfo(); 84 85$severityConfig = select_config(); 86 87// overview 88if ($config == QUEUE_OVERVIEW) { 89 $itemTypes = [ 90 ITEM_TYPE_ZABBIX, 91 ITEM_TYPE_ZABBIX_ACTIVE, 92 ITEM_TYPE_SIMPLE, 93 ITEM_TYPE_SNMPV1, 94 ITEM_TYPE_SNMPV2C, 95 ITEM_TYPE_SNMPV3, 96 ITEM_TYPE_INTERNAL, 97 ITEM_TYPE_AGGREGATE, 98 ITEM_TYPE_EXTERNAL, 99 ITEM_TYPE_DB_MONITOR, 100 ITEM_TYPE_HTTPAGENT, 101 ITEM_TYPE_IPMI, 102 ITEM_TYPE_SSH, 103 ITEM_TYPE_TELNET, 104 ITEM_TYPE_JMX, 105 ITEM_TYPE_CALCULATED 106 ]; 107 108 $table->setHeader([ 109 _('Items'), 110 _('5 seconds'), 111 _('10 seconds'), 112 _('30 seconds'), 113 _('1 minute'), 114 _('5 minutes'), 115 _('More than 10 minutes') 116 ]); 117 118 $queueData = zbx_toHash($queueData, 'itemtype'); 119 120 foreach ($itemTypes as $type) { 121 if (isset($queueData[$type])) { 122 $itemTypeData = $queueData[$type]; 123 } 124 else { 125 $itemTypeData = [ 126 'delay5' => 0, 127 'delay10' => 0, 128 'delay30' => 0, 129 'delay60' => 0, 130 'delay300' => 0, 131 'delay600' => 0 132 ]; 133 } 134 135 $table->addRow([ 136 item_type2str($type), 137 getSeverityCell(TRIGGER_SEVERITY_NOT_CLASSIFIED, $severityConfig, $itemTypeData['delay5'], 138 !$itemTypeData['delay5'] 139 ), 140 getSeverityCell(TRIGGER_SEVERITY_INFORMATION, $severityConfig, $itemTypeData['delay10'], 141 !$itemTypeData['delay10'] 142 ), 143 getSeverityCell(TRIGGER_SEVERITY_WARNING, $severityConfig, $itemTypeData['delay30'], 144 !$itemTypeData['delay30'] 145 ), 146 getSeverityCell(TRIGGER_SEVERITY_AVERAGE, $severityConfig, $itemTypeData['delay60'], 147 !$itemTypeData['delay60'] 148 ), 149 getSeverityCell(TRIGGER_SEVERITY_HIGH, $severityConfig, $itemTypeData['delay300'], 150 !$itemTypeData['delay300'] 151 ), 152 getSeverityCell(TRIGGER_SEVERITY_DISASTER, $severityConfig, $itemTypeData['delay600'], 153 !$itemTypeData['delay600'] 154 ) 155 ]); 156 } 157} 158 159// overview by proxy 160elseif ($config == QUEUE_OVERVIEW_BY_PROXY) { 161 $proxies = API::proxy()->get([ 162 'output' => ['hostid', 'host'], 163 'preservekeys' => true 164 ]); 165 order_result($proxies, 'host'); 166 167 $proxies[0] = ['host' => _('Server')]; 168 169 $table->setHeader([ 170 _('Proxy'), 171 _('5 seconds'), 172 _('10 seconds'), 173 _('30 seconds'), 174 _('1 minute'), 175 _('5 minutes'), 176 _('More than 10 minutes') 177 ]); 178 179 $queueData = zbx_toHash($queueData, 'proxyid'); 180 foreach ($proxies as $proxyId => $proxy) { 181 if (isset($queueData[$proxyId])) { 182 $proxyData = $queueData[$proxyId]; 183 } 184 else { 185 $proxyData = [ 186 'delay5' => 0, 187 'delay10' => 0, 188 'delay30' => 0, 189 'delay60' => 0, 190 'delay300' => 0, 191 'delay600' => 0 192 ]; 193 } 194 195 $table->addRow([ 196 $proxy['host'], 197 getSeverityCell(TRIGGER_SEVERITY_NOT_CLASSIFIED, $severityConfig, $proxyData['delay5'], 198 !$proxyData['delay5'] 199 ), 200 getSeverityCell(TRIGGER_SEVERITY_INFORMATION, $severityConfig, $proxyData['delay10'], 201 !$proxyData['delay10'] 202 ), 203 getSeverityCell(TRIGGER_SEVERITY_WARNING, $severityConfig, $proxyData['delay30'], !$proxyData['delay30']), 204 getSeverityCell(TRIGGER_SEVERITY_AVERAGE, $severityConfig, $proxyData['delay60'], !$proxyData['delay60']), 205 getSeverityCell(TRIGGER_SEVERITY_HIGH, $severityConfig, $proxyData['delay300'], !$proxyData['delay300']), 206 getSeverityCell(TRIGGER_SEVERITY_DISASTER, $severityConfig, $proxyData['delay600'], !$proxyData['delay600']) 207 ]); 208 } 209} 210 211// details 212elseif ($config == QUEUE_DETAILS) { 213 $queueData = zbx_toHash($queueData, 'itemid'); 214 215 $items = API::Item()->get([ 216 'output' => ['itemid', 'hostid', 'name', 'key_'], 217 'selectHosts' => ['name'], 218 'itemids' => array_keys($queueData), 219 'webitems' => true, 220 'preservekeys' => true 221 ]); 222 223 if (count($queueData) != count($items)) { 224 $items += API::DiscoveryRule()->get([ 225 'output' => ['itemid', 'hostid', 'name', 'key_'], 226 'selectHosts' => ['name'], 227 'itemids' => array_diff(array_keys($queueData), array_keys($items)), 228 'preservekeys' => true 229 ]); 230 } 231 232 $items = CMacrosResolverHelper::resolveItemNames($items); 233 234 // get hosts for queue items 235 $hostIds = zbx_objectValues($items, 'hostid'); 236 $hostIds = array_keys(array_flip($hostIds)); 237 238 $hosts = API::Host()->get([ 239 'output' => ['hostid', 'proxy_hostid'], 240 'hostids' => $hostIds, 241 'preservekeys' => true 242 ]); 243 244 // get proxies for those hosts 245 $proxyHostIds = []; 246 foreach ($hosts as $host) { 247 if ($host['proxy_hostid']) { 248 $proxyHostIds[$host['proxy_hostid']] = $host['proxy_hostid']; 249 } 250 } 251 252 if ($proxyHostIds) { 253 $proxies = API::Proxy()->get([ 254 'proxyids' => $proxyHostIds, 255 'output' => ['proxyid', 'host'], 256 'preservekeys' => true 257 ]); 258 } 259 260 $table->setHeader([ 261 _('Scheduled check'), 262 _('Delayed by'), 263 _('Host'), 264 _('Name') 265 ]); 266 267 $i = 0; 268 foreach ($queueData as $itemData) { 269 if (!isset($items[$itemData['itemid']])) { 270 continue; 271 } 272 273 // display only the first QUEUE_DETAIL_ITEM_COUNT items (can only occur when using old server versions) 274 $i++; 275 if ($i > QUEUE_DETAIL_ITEM_COUNT) { 276 break; 277 } 278 279 $item = $items[$itemData['itemid']]; 280 $host = reset($item['hosts']); 281 282 $table->addRow([ 283 zbx_date2str(DATE_TIME_FORMAT_SECONDS, $itemData['nextcheck']), 284 zbx_date2age($itemData['nextcheck']), 285 isset($proxies[$hosts[$item['hostid']]['proxy_hostid']]) 286 ? $proxies[$hosts[$item['hostid']]['proxy_hostid']]['host'].NAME_DELIMITER.$host['name'] 287 : $host['name'], 288 $item['name_expanded'] 289 ]); 290 } 291} 292 293// display the table footer 294if ($config == QUEUE_OVERVIEW_BY_PROXY) { 295 $total = _('Total').': '.$table->getNumRows(); 296} 297elseif ($config == QUEUE_DETAILS) { 298 $total = _s('Displaying %1$s of %2$s found', $table->getNumRows(), $zabbixServer->getTotalCount()); 299} 300else { 301 $total = null; 302} 303 304if ($total !== null) { 305 $total = (new CDiv()) 306 ->addClass(ZBX_STYLE_TABLE_PAGING) 307 ->addItem((new CDiv()) 308 ->addClass(ZBX_STYLE_PAGING_BTN_CONTAINER) 309 ->addItem((new CDiv()) 310 ->addClass(ZBX_STYLE_TABLE_STATS) 311 ->addItem($total) 312 ) 313 ); 314} 315 316$widget 317 ->addItem($table) 318 ->addItem($total) 319 ->show(); 320 321require_once dirname(__FILE__).'/include/page_footer.php'; 322