/** * Process screen. * * @return CDiv (screen inside container) */ public function get() { // if screen is defined in template, then 'real_resourceid' is defined and should be used if (!empty($this->screenitem['real_resourceid'])) { $this->screenitem['resourceid'] = $this->screenitem['real_resourceid']; } if ($this->screenitem['dynamic'] == SCREEN_DYNAMIC_ITEM && !empty($this->hostid)) { $newitemid = get_same_item_for_host($this->screenitem['resourceid'], $this->hostid); $this->screenitem['resourceid'] = !empty($newitemid) ? $newitemid : 0; } if ($this->screenitem['resourceid'] == 0) { $table = (new CTableInfo())->setHeader([_('Timestamp'), _('Item')]); return $this->getOutput($table); } $items = CMacrosResolverHelper::resolveItemNames([get_item_by_itemid($this->screenitem['resourceid'])]); $item = reset($items); switch ($item['value_type']) { case ITEM_VALUE_TYPE_TEXT: case ITEM_VALUE_TYPE_LOG: $orderField = 'id'; break; case ITEM_VALUE_TYPE_FLOAT: case ITEM_VALUE_TYPE_UINT64: default: $orderField = ['itemid', 'clock']; } $host = get_host_by_itemid($this->screenitem['resourceid']); $table = (new CTableInfo())->setHeader([_('Timestamp'), _('Value')]); $stime = zbxDateToTime($this->timeline['stime']); $histories = API::History()->get(['history' => $item['value_type'], 'itemids' => $this->screenitem['resourceid'], 'output' => API_OUTPUT_EXTEND, 'sortorder' => ZBX_SORT_DOWN, 'sortfield' => $orderField, 'limit' => $this->screenitem['elements'], 'time_from' => $stime, 'time_till' => $stime + $this->timeline['period']]); foreach ($histories as $history) { switch ($item['value_type']) { case ITEM_VALUE_TYPE_FLOAT: sscanf($history['value'], '%f', $value); break; case ITEM_VALUE_TYPE_TEXT: case ITEM_VALUE_TYPE_STR: case ITEM_VALUE_TYPE_LOG: $value = $this->screenitem['style'] ? new CJsScript($history['value']) : $history['value']; break; default: $value = $history['value']; break; } if ($item['valuemapid'] > 0) { $value = applyValueMap($value, $item['valuemapid']); } if ($this->screenitem['style'] == 0) { $value = new CPre($value); } $table->addRow([zbx_date2str(DATE_TIME_FORMAT_SECONDS, $history['clock']), $value]); } $footer = (new CList())->addItem(_s('Updated: %s', zbx_date2str(TIME_FORMAT_SECONDS)))->addClass(ZBX_STYLE_DASHBRD_WIDGET_FOOT); return $this->getOutput((new CUiWidget(uniqid(), [$table, $footer]))->setHeader($host['name'] . NAME_DELIMITER . $item['name_expanded'])); }
/** * Process screen. * * @return CDiv (screen inside container) */ public function get() { // if screen is defined in template, then 'real_resourceid' is defined and should be used if (!empty($this->screenitem['real_resourceid'])) { $this->screenitem['resourceid'] = $this->screenitem['real_resourceid']; } if ($this->screenitem['dynamic'] == SCREEN_DYNAMIC_ITEM && !empty($this->hostid)) { $newitemid = get_same_item_for_host($this->screenitem['resourceid'], $this->hostid); $this->screenitem['resourceid'] = !empty($newitemid) ? $newitemid : 0; } if ($this->screenitem['resourceid'] == 0) { $table = new CTableInfo(_('No values found.')); $table->setHeader(array(_('Timestamp'), _('Item'))); return $this->getOutput($table); } $items = CMacrosResolverHelper::resolveItemNames(array(get_item_by_itemid($this->screenitem['resourceid']))); $item = reset($items); switch ($item['value_type']) { case ITEM_VALUE_TYPE_TEXT: case ITEM_VALUE_TYPE_LOG: $orderField = 'id'; break; case ITEM_VALUE_TYPE_FLOAT: case ITEM_VALUE_TYPE_UINT64: default: $orderField = array('itemid', 'clock'); } $host = get_host_by_itemid($this->screenitem['resourceid']); $table = new CTableInfo(_('No values found.')); $table->setHeader(array(_('Timestamp'), $host['name'] . NAME_DELIMITER . $item['name_expanded'])); $stime = zbxDateToTime($this->timeline['stime']); $histories = API::History()->get(array('history' => $item['value_type'], 'itemids' => $this->screenitem['resourceid'], 'output' => API_OUTPUT_EXTEND, 'sortorder' => ZBX_SORT_DOWN, 'sortfield' => $orderField, 'limit' => $this->screenitem['elements'], 'time_from' => $stime, 'time_till' => $stime + $this->timeline['period'])); foreach ($histories as $history) { switch ($item['value_type']) { case ITEM_VALUE_TYPE_FLOAT: sscanf($history['value'], '%f', $value); break; case ITEM_VALUE_TYPE_TEXT: case ITEM_VALUE_TYPE_STR: case ITEM_VALUE_TYPE_LOG: $value = $this->screenitem['style'] ? new CJsScript($history['value']) : $history['value']; break; default: $value = $history['value']; break; } if ($item['valuemapid'] > 0) { $value = applyValueMap($value, $item['valuemapid']); } $class = $this->screenitem['style'] ? null : 'pre'; $table->addRow(array(zbx_date2str(DATE_TIME_FORMAT_SECONDS, $history['clock']), new CCol($value, $class))); } return $this->getOutput($table); }
/** * Format history value. * First format the value according to the configuration of the item. Then apply the value mapping to the formatted (!) * value. * * @param mixed $value * @param array $item * @param int $item['value_type'] type of the value: ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64, ... * @param string $item['units'] units of item * @param int $item['valuemapid'] id of mapping set of values * @param bool $trim * * @return string */ function formatHistoryValue($value, array $item, $trim = true) { $mapping = false; // format value if ($item['value_type'] == ITEM_VALUE_TYPE_FLOAT || $item['value_type'] == ITEM_VALUE_TYPE_UINT64) { $value = convert_units(array('value' => $value, 'units' => $item['units'])); } elseif ($item['value_type'] != ITEM_VALUE_TYPE_STR && $item['value_type'] != ITEM_VALUE_TYPE_TEXT && $item['value_type'] != ITEM_VALUE_TYPE_LOG) { $value = _('Unknown value type'); } // apply value mapping switch ($item['value_type']) { case ITEM_VALUE_TYPE_STR: $mapping = getMappedValue($value, $item['valuemapid']); // break; is not missing here // break; is not missing here case ITEM_VALUE_TYPE_TEXT: case ITEM_VALUE_TYPE_LOG: if ($trim && zbx_strlen($value) > 20) { $value = zbx_substr($value, 0, 20) . '...'; } if ($mapping !== false) { $value = $mapping . ' (' . $value . ')'; } break; default: $value = applyValueMap($value, $item['valuemapid']); } return $value; }
/** * Process screen. * * @return CDiv (screen inside container) */ public function get() { $output = array(); $stime = zbxDateToTime($this->timeline['stime']); $iv_string = array(ITEM_VALUE_TYPE_LOG => 1, ITEM_VALUE_TYPE_TEXT => 1); $iv_numeric = array(ITEM_VALUE_TYPE_FLOAT => 1, ITEM_VALUE_TYPE_UINT64 => 1); if ($this->action == 'showvalues' || $this->action == 'showlatest') { $options = array('history' => $this->item['value_type'], 'itemids' => array_keys($this->items), 'output' => API_OUTPUT_EXTEND, 'sortorder' => ZBX_SORT_DOWN); if ($this->action == 'showlatest') { $options['limit'] = 500; } elseif ($this->action == 'showvalues') { $config = select_config(); $options['time_from'] = $stime - 10; // some seconds to allow script to execute $options['time_till'] = $stime + $this->timeline['period']; $options['limit'] = $config['search_limit']; } // text log if (isset($iv_string[$this->item['value_type']])) { $isManyItems = count($this->items) > 1; $useLogItem = $this->item['value_type'] == ITEM_VALUE_TYPE_LOG; $useEventLogItem = strpos($this->item['key_'], 'eventlog[') === 0; if (empty($this->plaintext)) { $historyTable = new CTableInfo(_('No values found.')); $historyTable->setHeader(array(_('Timestamp'), $isManyItems ? _('Item') : null, $useLogItem ? _('Local time') : null, $useEventLogItem && $useLogItem ? _('Source') : null, $useEventLogItem && $useLogItem ? _('Severity') : null, $useEventLogItem && $useLogItem ? _('Event ID') : null, _('Value')), 'header'); } if (!zbx_empty($this->filter) && in_array($this->filterTask, array(FILTER_TASK_SHOW, FILTER_TASK_HIDE))) { $options['search'] = array('value' => $this->filter); if ($this->filterTask == FILTER_TASK_HIDE) { $options['excludeSearch'] = 1; } } $options['sortfield'] = 'id'; $historyData = API::History()->get($options); foreach ($historyData as $data) { $data['value'] = encode_log(trim($data['value'], "\r\n")); if (empty($this->plaintext)) { $item = $this->items[$data['itemid']]; $host = reset($item['hosts']); $color = null; if (isset($this->filter) && !zbx_empty($this->filter)) { $contain = zbx_stristr($data['value'], $this->filter); if ($contain && $this->filterTask == FILTER_TASK_MARK) { $color = $this->markColor; } if (!$contain && $this->filterTask == FILTER_TASK_INVERT_MARK) { $color = $this->markColor; } switch ($color) { case MARK_COLOR_RED: $color = 'red'; break; case MARK_COLOR_GREEN: $color = 'green'; break; case MARK_COLOR_BLUE: $color = 'blue'; break; } } $row = array(nbsp(zbx_date2str(_('Y.M.d H:i:s'), $data['clock']))); if ($isManyItems) { $row[] = $host['name'] . NAME_DELIMITER . $item['name_expanded']; } if ($useLogItem) { $row[] = $data['timestamp'] == 0 ? '-' : zbx_date2str(HISTORY_LOG_LOCALTIME_DATE_FORMAT, $data['timestamp']); // if this is a eventLog item, showing additional info if ($useEventLogItem) { $row[] = zbx_empty($data['source']) ? '-' : $data['source']; $row[] = $data['severity'] == 0 ? '-' : new CCol(get_item_logtype_description($data['severity']), get_item_logtype_style($data['severity'])); $row[] = $data['logeventid'] == 0 ? '-' : $data['logeventid']; } } $row[] = new CCol($data['value'], 'pre'); $newRow = new CRow($row); if (!is_null($color)) { $newRow->setAttribute('class', $color); } $historyTable->addRow($newRow); } else { $output[] = zbx_date2str(HISTORY_LOG_ITEM_PLAINTEXT, $data['clock']); $output[] = "\t" . $data['clock'] . "\t" . htmlspecialchars($data['value']) . "\n"; } } if (empty($this->plaintext)) { $output[] = $historyTable; } } else { if (empty($this->plaintext)) { $historyTable = new CTableInfo(_('No values found.')); $historyTable->setHeader(array(_('Timestamp'), _('Value'))); } $options['sortfield'] = array('itemid', 'clock'); $historyData = API::History()->get($options); foreach ($historyData as $data) { $item = $this->items[$data['itemid']]; $value = $data['value']; // format the value as float if ($item['value_type'] == ITEM_VALUE_TYPE_FLOAT) { sscanf($data['value'], '%f', $value); } // html table if (empty($this->plaintext)) { if ($item['valuemapid']) { $value = applyValueMap($value, $item['valuemapid']); } $historyTable->addRow(array(zbx_date2str(HISTORY_ITEM_DATE_FORMAT, $data['clock']), zbx_nl2br($value))); } else { $output[] = zbx_date2str(HISTORY_PLAINTEXT_DATE_FORMAT, $data['clock']); $output[] = "\t" . $data['clock'] . "\t" . htmlspecialchars($value) . "\n"; } } if (empty($this->plaintext)) { $output[] = $historyTable; } } } if ($this->action == 'showgraph' && !isset($iv_string[$this->item['value_type']])) { $this->dataId = 'historyGraph'; $containerId = 'graph_cont1'; $src = 'chart.php?itemid=' . $this->item['itemid'] . '&period=' . $this->timeline['period'] . '&stime=' . $this->timeline['stime'] . $this->getProfileUrlParams(); $output[] = new CDiv(null, 'center', $containerId); } // time control if (!$this->plaintext && str_in_array($this->action, array('showvalues', 'showgraph'))) { $graphDims = getGraphDims(); $this->timeline['starttime'] = date(TIMESTAMP_FORMAT, get_min_itemclock_by_itemid($this->item['itemid'])); $timeControlData = array('periodFixed' => CProfile::get('web.history.timelinefixed', 1), 'sliderMaximumTimePeriod' => ZBX_MAX_PERIOD); if (!empty($this->dataId)) { $timeControlData['id'] = $this->getDataId(); $timeControlData['containerid'] = $containerId; $timeControlData['src'] = $src; $timeControlData['objDims'] = $graphDims; $timeControlData['loadSBox'] = 1; $timeControlData['loadImage'] = 1; $timeControlData['dynamic'] = 1; } else { $this->dataId = 'historyGraph'; $timeControlData['id'] = $this->getDataId(); $timeControlData['mainObject'] = 1; } if ($this->mode == SCREEN_MODE_JS) { $timeControlData['dynamic'] = 0; return 'timeControl.addObject("' . $this->getDataId() . '", ' . zbx_jsvalue($this->timeline) . ', ' . zbx_jsvalue($timeControlData) . ');'; } else { zbx_add_post_js('timeControl.addObject("' . $this->getDataId() . '", ' . zbx_jsvalue($this->timeline) . ', ' . zbx_jsvalue($timeControlData) . ');'); } } if (!empty($this->plaintext)) { return $output; } else { if ($this->mode != SCREEN_MODE_JS) { $flickerfreeData = array('itemids' => $this->itemids, 'action' => $this->action, 'filter' => $this->filter, 'filterTask' => $this->filterTask, 'markColor' => $this->markColor); return $this->getOutput($output, true, $flickerfreeData); } } }
/** * Process screen. * * @return CDiv (screen inside container) */ public function get() { $output = []; $items = API::Item()->get(['output' => ['itemid', 'hostid', 'name', 'key_', 'value_type', 'valuemapid'], 'selectHosts' => ['name'], 'itemids' => $this->itemids, 'webitems' => true, 'preservekeys' => true]); $items = CMacrosResolverHelper::resolveItemNames($items); $stime = zbxDateToTime($this->timeline['stime']); $firstItem = reset($items); $iv_string = [ITEM_VALUE_TYPE_LOG => 1, ITEM_VALUE_TYPE_TEXT => 1]; $iv_numeric = [ITEM_VALUE_TYPE_FLOAT => 1, ITEM_VALUE_TYPE_UINT64 => 1]; if ($this->action == HISTORY_VALUES || $this->action == HISTORY_LATEST) { $options = ['history' => $firstItem['value_type'], 'itemids' => $this->itemids, 'output' => API_OUTPUT_EXTEND, 'sortorder' => ZBX_SORT_DOWN]; if ($this->action == HISTORY_LATEST) { $options['limit'] = 500; } elseif ($this->action == HISTORY_VALUES) { $config = select_config(); // interval start value is non-inclusive, hence the + 1 second $options['time_from'] = $stime + 1; $options['time_till'] = $stime + $this->timeline['period']; $options['limit'] = $config['search_limit']; } // text log if (isset($iv_string[$firstItem['value_type']])) { $isManyItems = count($items) > 1; $useLogItem = $firstItem['value_type'] == ITEM_VALUE_TYPE_LOG; $useEventLogItem = strpos($firstItem['key_'], 'eventlog[') === 0; if (empty($this->plaintext)) { $historyTable = (new CTableInfo())->setHeader([(new CColHeader(_('Timestamp')))->addClass(ZBX_STYLE_CELL_WIDTH), $isManyItems ? _('Item') : null, $useLogItem ? (new CColHeader(_('Local time')))->addClass(ZBX_STYLE_CELL_WIDTH) : null, $useEventLogItem && $useLogItem ? (new CColHeader(_('Source')))->addClass(ZBX_STYLE_CELL_WIDTH) : null, $useEventLogItem && $useLogItem ? (new CColHeader(_('Severity')))->addClass(ZBX_STYLE_CELL_WIDTH) : null, $useEventLogItem && $useLogItem ? (new CColHeader(_('Event ID')))->addClass(ZBX_STYLE_CELL_WIDTH) : null, _('Value')]); } if ($this->filter !== '' && in_array($this->filterTask, [FILTER_TASK_SHOW, FILTER_TASK_HIDE])) { $options['search'] = ['value' => $this->filter]; if ($this->filterTask == FILTER_TASK_HIDE) { $options['excludeSearch'] = 1; } } $options['sortfield'] = 'id'; $historyData = API::History()->get($options); foreach ($historyData as $data) { $data['value'] = rtrim($data['value'], " \t\r\n"); if (empty($this->plaintext)) { $item = $items[$data['itemid']]; $host = reset($item['hosts']); $color = null; if ($this->filter !== '') { $haystack = mb_strtolower($data['value']); $needle = mb_strtolower($this->filter); $pos = mb_strpos($haystack, $needle); if ($pos !== false && $this->filterTask == FILTER_TASK_MARK) { $color = $this->markColor; } elseif ($pos === false && $this->filterTask == FILTER_TASK_INVERT_MARK) { $color = $this->markColor; } switch ($color) { case MARK_COLOR_RED: $color = ZBX_STYLE_RED; break; case MARK_COLOR_GREEN: $color = ZBX_STYLE_GREEN; break; case MARK_COLOR_BLUE: $color = ZBX_STYLE_BLUE; break; } } $row = []; $row[] = (new CCol(zbx_date2str(DATE_TIME_FORMAT_SECONDS, $data['clock'])))->addClass(ZBX_STYLE_NOWRAP)->addClass($color); if ($isManyItems) { $row[] = (new CCol($host['name'] . NAME_DELIMITER . $item['name_expanded']))->addClass($color); } if ($useLogItem) { $row[] = $data['timestamp'] != 0 ? (new CCol(zbx_date2str(DATE_TIME_FORMAT_SECONDS, $data['timestamp'])))->addClass(ZBX_STYLE_NOWRAP)->addClass($color) : ''; // if this is a eventLog item, showing additional info if ($useEventLogItem) { $row[] = (new CCol($data['source']))->addClass(ZBX_STYLE_NOWRAP)->addClass($color); $row[] = $data['severity'] != 0 ? (new CCol(get_item_logtype_description($data['severity'])))->addClass(ZBX_STYLE_NOWRAP)->addClass(get_item_logtype_style($data['severity'])) : ''; $row[] = $data['logeventid'] != 0 ? (new CCol($data['logeventid']))->addClass(ZBX_STYLE_NOWRAP)->addClass($color) : ''; } } $row[] = (new CCol(new CPre(zbx_nl2br($data['value']))))->addClass($color); $historyTable->addRow($row); } else { $output[] = zbx_date2str(DATE_TIME_FORMAT_SECONDS, $data['clock']) . ' ' . $data['clock'] . ' ' . htmlspecialchars($data['value']); } } if (empty($this->plaintext)) { $output[] = $historyTable; } } else { if (empty($this->plaintext)) { $historyTable = (new CTableInfo())->setHeader([(new CColHeader(_('Timestamp')))->addClass(ZBX_STYLE_CELL_WIDTH), _('Value')]); } $options['sortfield'] = ['itemid', 'clock']; $historyData = API::History()->get($options); foreach ($historyData as $data) { $item = $items[$data['itemid']]; $value = rtrim($data['value'], " \t\r\n"); // format the value as float if ($item['value_type'] == ITEM_VALUE_TYPE_FLOAT) { sscanf($data['value'], '%f', $value); } // html table if (empty($this->plaintext)) { if ($item['valuemapid']) { $value = applyValueMap($value, $item['valuemapid']); } $historyTable->addRow([(new CCol(zbx_date2str(DATE_TIME_FORMAT_SECONDS, $data['clock'])))->addClass(ZBX_STYLE_NOWRAP), new CPre(zbx_nl2br($value))]); } else { $output[] = zbx_date2str(DATE_TIME_FORMAT_SECONDS, $data['clock']) . ' ' . $data['clock'] . ' ' . htmlspecialchars($value); } } if (empty($this->plaintext)) { $output[] = $historyTable; } } } // time control if (!$this->plaintext && str_in_array($this->action, [HISTORY_VALUES, HISTORY_GRAPH, HISTORY_BATCH_GRAPH])) { $graphDims = getGraphDims(); $this->timeline['starttime'] = date(TIMESTAMP_FORMAT, get_min_itemclock_by_itemid($firstItem['itemid'])); $this->dataId = 'historyGraph'; $timeControlData = ['periodFixed' => CProfile::get('web.history.timelinefixed', 1), 'sliderMaximumTimePeriod' => ZBX_MAX_PERIOD]; if (($this->action == HISTORY_GRAPH || $this->action == HISTORY_BATCH_GRAPH) && !isset($iv_string[$firstItem['value_type']])) { $containerId = 'graph_cont1'; $output[] = (new CDiv())->addClass('center')->setId($containerId); $timeControlData['id'] = $this->getDataId(); $timeControlData['containerid'] = $containerId; $timeControlData['src'] = $this->getGraphUrl($this->itemids); $timeControlData['objDims'] = $graphDims; $timeControlData['loadSBox'] = 1; $timeControlData['loadImage'] = 1; $timeControlData['dynamic'] = 1; } else { $timeControlData['id'] = $this->getDataId(); $timeControlData['mainObject'] = 1; } if ($this->mode == SCREEN_MODE_JS) { $timeControlData['dynamic'] = 0; return 'timeControl.addObject("' . $this->getDataId() . '", ' . CJs::encodeJson($this->timeline) . ', ' . CJs::encodeJson($timeControlData) . ');'; } else { zbx_add_post_js('timeControl.addObject("' . $this->getDataId() . '", ' . CJs::encodeJson($this->timeline) . ', ' . CJs::encodeJson($timeControlData) . ');'); } } if (!empty($this->plaintext)) { return $output; } else { if ($this->mode != SCREEN_MODE_JS) { $flickerfreeData = ['itemids' => $this->itemids, 'action' => $this->action == HISTORY_BATCH_GRAPH ? HISTORY_GRAPH : $this->action, 'filter' => $this->filter, 'filterTask' => $this->filterTask, 'markColor' => $this->markColor]; return $this->getOutput($output, true, $flickerfreeData); } } }
/** * Format item lastvalue. * First format the value according to the configuration of the item. Then apply the value mapping to the formatted (!) * value. * * @param array $item * @param string $unknownString the text to be used if the item has no data * * @return string */ function formatItemValue(array $item, $unknownString = '-') { if (!isset($item['lastvalue']) || $item['lastclock'] == 0) { return $unknownString; } $value = formatItemValueType($item); if ($item['valuemapid'] > 0) { $value = applyValueMap($value, $item['valuemapid']); } return $value; }
/** * Expand functional macros in given map label. * * @param string $label label to expand * @param array $replaceHosts list of hosts in order which they appear in trigger expression if trigger label is given, * or single host when host label is given * * @return string expanded label */ function resolveMapLabelMacros($label, $replaceHosts = null) { // find functional macro pattern $pattern = null === $replaceHosts ? '/{' . ZBX_PREG_HOST_FORMAT . ":.+\\.(last|max|min|avg)\\([0-9]+[smhdwKMGT]?\\)}/Uu" : '/{(' . ZBX_PREG_HOST_FORMAT . "|{HOSTNAME[0-9]?}|{HOST.HOST[0-9]?}):.+\\.(last|max|min|avg)\\([0-9]+[smhdwKMGT]?\\)}/Uu"; preg_match_all($pattern, $label, $matches); // for each functional macro foreach ($matches[0] as $expr) { $macro = $expr; if ($replaceHosts !== null) { // search for macros with all possible indecies foreach ($replaceHosts as $i => $host) { $macroTmp = $macro; // repalce only macro in first position $macro = preg_replace('/{({HOSTNAME' . $i . '}|{HOST.HOST' . $i . '}):(.*)}/U', '{' . $host['host'] . ':$2}', $macro); // only one simple macro possible inside functional macro if ($macro != $macroTmp) { break; } } } // try to create valid expression $expressionData = new CTriggerExpression(); if (!$expressionData->parse($macro) || !isset($expressionData->expressions[0])) { continue; } // look in DB for coressponding item $itemHost = $expressionData->expressions[0]['host']; $key = $expressionData->expressions[0]['item']; $function = $expressionData->expressions[0]['functionName']; $parameter = convertFunctionValue($expressionData->expressions[0]['functionParamList'][0]); $item = API::Item()->get(array('webitems' => true, 'filter' => array('host' => $itemHost, 'key_' => $key), 'output' => array('lastclock', 'value_type', 'lastvalue', 'units', 'valuemapid'))); $item = reset($item); // if no corresponding item found with functional macro key and host if (!$item) { $label = str_replace($expr, '???', $label); continue; } // do function type (last, min, max, avg) related actions if (0 == strcmp($function, 'last')) { if ($item['lastclock'] == 0) { $label = str_replace($expr, '(' . _('no data') . ')', $label); } else { $mapping = false; $value = formatItemValueType($item); switch ($item['value_type']) { case ITEM_VALUE_TYPE_STR: $mapping = getMappedValue($value, $item['valuemapid']); // break; is not missing here // break; is not missing here case ITEM_VALUE_TYPE_TEXT: case ITEM_VALUE_TYPE_LOG: if ($mapping !== false) { $value = $mapping . ' (' . $value . ')'; } break; default: $value = applyValueMap($value, $item['valuemapid']); } } if (isset($value)) { $label = str_replace($expr, $value, $label); } } elseif (0 == strcmp($function, 'min') || 0 == strcmp($function, 'max') || 0 == strcmp($function, 'avg')) { // allowed item types for min, max and avg function $history_table = array(ITEM_VALUE_TYPE_FLOAT => 'history', ITEM_VALUE_TYPE_UINT64 => 'history_uint'); if (!isset($history_table[$item['value_type']])) { $label = str_replace($expr, '???', $label); continue; } // search for item function data in DB corresponding history tables $result = DBselect('SELECT ' . $function . '(value) AS value' . ' FROM ' . $history_table[$item['value_type']] . ' WHERE clock>' . (time() - $parameter) . ' AND itemid=' . zbx_dbstr($item['itemid'])); if (null === ($row = DBfetch($result))) { $label = str_replace($expr, '(' . _('no data') . ')', $label); } else { $label = str_replace($expr, convert_units($row['value'], $item['units']), $label); } } } return $label; }