dataSource = $dataSource; } public function from($target, array $fields = null) { if ($fields !== null) { throw new InvalidArgumentException('Fields are not applicable to this kind of query'); } try { $this->base = $target instanceof MacroTemplate ? $target : new MacroTemplate((string) $target); } catch (InvalidArgumentException $e) { throw new InvalidArgumentException('Bad target', $e); } return $this; } public function applyFilter(Filter $filter) { throw new NotImplementedError(__METHOD__); } public function setFilter(Filter $filter) { throw new NotImplementedError(__METHOD__); } public function getFilter() { throw new NotImplementedError(__METHOD__); } public function addFilter(Filter $filter) { throw new NotImplementedError(__METHOD__); } public function where($condition, $value = null) { $this->filter[$condition] = $this->escapeMetricStep($value); return $this; } public function fetchAll() { $result = []; foreach ($this->fetchColumn() as $metric) { $result[] = (object) ['metric' => $metric]; } return $result; } public function fetchRow() { $result = $this->fetchColumn(); return empty($result) ? false : (object) ['metric' => $result[0]]; } public function fetchColumn() { $filter = []; foreach ($this->base->getMacros() as $macro) { if (isset($this->filter[$macro])) { $filter[$macro] = $this->filter[$macro]; continue; } if (strpos($macro, '.') === false) { continue; } $workaroundMacro = str_replace('.', '_', $macro); if ($this->object instanceof Model) { // icingadb macro $tranformFilter = UrlMigrator::transformFilter( IplFilter::equal($workaroundMacro, ''), $this->object instanceof Host ? 'hosts' : 'services' ); if ($tranformFilter === false) { continue; } $migratedMacro = $tranformFilter->getColumn(); if ($migratedMacro === $workaroundMacro) { $workaroundMacro = $macro; } else { $workaroundMacro = $migratedMacro; } $icingadbMacros = IcingadbUtils::getInstance(); $result = $icingadbMacros->resolveMacro($workaroundMacro, $this->object); } else { if ($workaroundMacro === 'service_name') { $workaroundMacro = 'service_description'; } $result = Macro::resolveMacro($workaroundMacro, $this->object); } if ($result !== $workaroundMacro) { $filter[$macro] = $this->escapeMetricStep($result); } } $client = $this->dataSource->getClient(); $url = Url::fromPath('metrics/expand', [ 'query' => $this->base->resolve($filter, '*') ]); $res = Json::decode($client->request($url)); natsort($res->results); IPT::recordf('Fetched %s metric(s) from %s', count($res->results), (string) $client->completeUrl($url)); return array_values($res->results); } public function fetchOne() { $result = $this->fetchColumn(); return empty($result) ? false : $result[0]; } public function fetchPairs() { throw new NotImplementedError(__METHOD__); } /** * Set the object to render the graphs for * * @param MonitoredObject|Model $object * * @return $this */ public function setObject($object) { $this->object = $object; return $this; } /** * Escapes a string for usage in a Graphite metric path between two dots * * @param string $step * * @return string */ protected function escapeMetricStep($step) { return preg_replace('/[^a-zA-Z0-9\*\-:^[\]$#%\']/', '_', $step); } }