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_sessionid'), 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 CForm('get')) 68 ->cleanItems() 69 ->addItem((new CList()) 70 ->addItem((new CComboBox('config', $config, 'submit();', [ 71 QUEUE_OVERVIEW => _('Overview'), 72 QUEUE_OVERVIEW_BY_PROXY => _('Overview by proxy'), 73 QUEUE_DETAILS => _('Details') 74 ]))) 75 ) 76 ); 77 78$table = new CTableInfo(); 79 80$severityConfig = select_config(); 81 82// overview 83if ($config == QUEUE_OVERVIEW) { 84 $itemTypes = [ 85 ITEM_TYPE_ZABBIX, 86 ITEM_TYPE_ZABBIX_ACTIVE, 87 ITEM_TYPE_SIMPLE, 88 ITEM_TYPE_SNMPV1, 89 ITEM_TYPE_SNMPV2C, 90 ITEM_TYPE_SNMPV3, 91 ITEM_TYPE_INTERNAL, 92 ITEM_TYPE_AGGREGATE, 93 ITEM_TYPE_EXTERNAL, 94 ITEM_TYPE_DB_MONITOR, 95 ITEM_TYPE_IPMI, 96 ITEM_TYPE_SSH, 97 ITEM_TYPE_TELNET, 98 ITEM_TYPE_JMX, 99 ITEM_TYPE_CALCULATED 100 ]; 101 102 $table->setHeader([ 103 _('Items'), 104 _('5 seconds'), 105 _('10 seconds'), 106 _('30 seconds'), 107 _('1 minute'), 108 _('5 minutes'), 109 _('More than 10 minutes') 110 ]); 111 112 $queueData = zbx_toHash($queueData, 'itemtype'); 113 114 foreach ($itemTypes as $type) { 115 if (isset($queueData[$type])) { 116 $itemTypeData = $queueData[$type]; 117 } 118 else { 119 $itemTypeData = [ 120 'delay5' => 0, 121 'delay10' => 0, 122 'delay30' => 0, 123 'delay60' => 0, 124 'delay300' => 0, 125 'delay600' => 0 126 ]; 127 } 128 129 $table->addRow([ 130 item_type2str($type), 131 getSeverityCell(TRIGGER_SEVERITY_NOT_CLASSIFIED, $severityConfig, $itemTypeData['delay5'], 132 !$itemTypeData['delay5'] 133 ), 134 getSeverityCell(TRIGGER_SEVERITY_INFORMATION, $severityConfig, $itemTypeData['delay10'], 135 !$itemTypeData['delay10'] 136 ), 137 getSeverityCell(TRIGGER_SEVERITY_WARNING, $severityConfig, $itemTypeData['delay30'], 138 !$itemTypeData['delay30'] 139 ), 140 getSeverityCell(TRIGGER_SEVERITY_AVERAGE, $severityConfig, $itemTypeData['delay60'], 141 !$itemTypeData['delay60'] 142 ), 143 getSeverityCell(TRIGGER_SEVERITY_HIGH, $severityConfig, $itemTypeData['delay300'], 144 !$itemTypeData['delay300'] 145 ), 146 getSeverityCell(TRIGGER_SEVERITY_DISASTER, $severityConfig, $itemTypeData['delay600'], 147 !$itemTypeData['delay600'] 148 ) 149 ]); 150 } 151} 152 153// overview by proxy 154elseif ($config == QUEUE_OVERVIEW_BY_PROXY) { 155 $proxies = API::proxy()->get([ 156 'output' => ['hostid', 'host'], 157 'preservekeys' => true 158 ]); 159 order_result($proxies, 'host'); 160 161 $proxies[0] = ['host' => _('Server')]; 162 163 $table->setHeader([ 164 _('Proxy'), 165 _('5 seconds'), 166 _('10 seconds'), 167 _('30 seconds'), 168 _('1 minute'), 169 _('5 minutes'), 170 _('More than 10 minutes') 171 ]); 172 173 $queueData = zbx_toHash($queueData, 'proxyid'); 174 foreach ($proxies as $proxyId => $proxy) { 175 if (isset($queueData[$proxyId])) { 176 $proxyData = $queueData[$proxyId]; 177 } 178 else { 179 $proxyData = [ 180 'delay5' => 0, 181 'delay10' => 0, 182 'delay30' => 0, 183 'delay60' => 0, 184 'delay300' => 0, 185 'delay600' => 0 186 ]; 187 } 188 189 $table->addRow([ 190 $proxy['host'], 191 getSeverityCell(TRIGGER_SEVERITY_NOT_CLASSIFIED, $severityConfig, $proxyData['delay5'], 192 !$proxyData['delay5'] 193 ), 194 getSeverityCell(TRIGGER_SEVERITY_INFORMATION, $severityConfig, $proxyData['delay10'], 195 !$proxyData['delay10'] 196 ), 197 getSeverityCell(TRIGGER_SEVERITY_WARNING, $severityConfig, $proxyData['delay30'], !$proxyData['delay30']), 198 getSeverityCell(TRIGGER_SEVERITY_AVERAGE, $severityConfig, $proxyData['delay60'], !$proxyData['delay60']), 199 getSeverityCell(TRIGGER_SEVERITY_HIGH, $severityConfig, $proxyData['delay300'], !$proxyData['delay300']), 200 getSeverityCell(TRIGGER_SEVERITY_DISASTER, $severityConfig, $proxyData['delay600'], !$proxyData['delay600']) 201 ]); 202 } 203} 204 205// details 206elseif ($config == QUEUE_DETAILS) { 207 $queueData = zbx_toHash($queueData, 'itemid'); 208 209 $items = API::Item()->get([ 210 'output' => ['itemid', 'hostid', 'name', 'key_'], 211 'selectHosts' => ['name'], 212 'itemids' => array_keys($queueData), 213 'webitems' => true, 214 'preservekeys' => true 215 ]); 216 217 $items = CMacrosResolverHelper::resolveItemNames($items); 218 219 // get hosts for queue items 220 $hostIds = zbx_objectValues($items, 'hostid'); 221 $hostIds = array_keys(array_flip($hostIds)); 222 223 $hosts = API::Host()->get([ 224 'output' => ['hostid', 'proxy_hostid'], 225 'hostids' => $hostIds, 226 'preservekeys' => true 227 ]); 228 229 // get proxies for those hosts 230 $proxyHostIds = []; 231 foreach ($hosts as $host) { 232 if ($host['proxy_hostid']) { 233 $proxyHostIds[$host['proxy_hostid']] = $host['proxy_hostid']; 234 } 235 } 236 237 if ($proxyHostIds) { 238 $proxies = API::Proxy()->get([ 239 'proxyids' => $proxyHostIds, 240 'output' => ['proxyid', 'host'], 241 'preservekeys' => true 242 ]); 243 } 244 245 $table->setHeader([ 246 _('Scheduled check'), 247 _('Delayed by'), 248 _('Host'), 249 _('Name') 250 ]); 251 252 $i = 0; 253 foreach ($queueData as $itemData) { 254 if (!isset($items[$itemData['itemid']])) { 255 continue; 256 } 257 258 // display only the first QUEUE_DETAIL_ITEM_COUNT items (can only occur when using old server versions) 259 $i++; 260 if ($i > QUEUE_DETAIL_ITEM_COUNT) { 261 break; 262 } 263 264 $item = $items[$itemData['itemid']]; 265 $host = reset($item['hosts']); 266 267 $table->addRow([ 268 zbx_date2str(DATE_TIME_FORMAT_SECONDS, $itemData['nextcheck']), 269 zbx_date2age($itemData['nextcheck']), 270 (isset($proxies[$hosts[$item['hostid']]['proxy_hostid']])) 271 ? $proxies[$hosts[$item['hostid']]['proxy_hostid']]['host'].NAME_DELIMITER.$host['name'] 272 : $host['name'], 273 $item['name_expanded'] 274 ]); 275 } 276} 277 278// display the table footer 279if ($config == QUEUE_OVERVIEW_BY_PROXY) { 280 $total = _('Total').': '.$table->getNumRows(); 281} 282elseif ($config == QUEUE_DETAILS) { 283 if (null !== $zabbixServer->getTotalCount()) { 284 $total = _s('Displaying %1$s of %2$s found', $table->getNumRows(), $zabbixServer->getTotalCount()); 285 } 286 else { 287 // fallback to old solution 288 $total = _('Total').': '.$table->getNumRows(). 289 (count($queueData) > QUEUE_DETAIL_ITEM_COUNT ? ' ('._('Truncated').')' : ''); 290 } 291} 292else { 293 $total = null; 294} 295 296if ($total !== null) { 297 $total = (new CDiv()) 298 ->addClass(ZBX_STYLE_TABLE_PAGING) 299 ->addItem((new CDiv()) 300 ->addClass(ZBX_STYLE_PAGING_BTN_CONTAINER) 301 ->addItem((new CDiv()) 302 ->addClass(ZBX_STYLE_TABLE_STATS) 303 ->addItem($total) 304 ) 305 ); 306} 307 308$widget 309 ->addItem($table) 310 ->addItem($total) 311 ->show(); 312 313require_once dirname(__FILE__).'/include/page_footer.php'; 314