s around the images
*
* @var string[]
*/
protected $classes = [];
/**
* The amount of graphs to show
*
* @var int
*/
protected $maxVisibleGraphs;
/**
* Whether to serve a transparent dummy image first and let the JS code load the actual graph
*
* @var bool
*/
protected $preloadDummy = false;
/**
* Whether to explicitly display that no graphs were found
*
* @var bool|null
*/
protected $showNoGraphsFound;
/**
* Cache for {@link getGraphsList()}
*
* @var string
*/
protected $graphsList;
/**
* Factory, based on the given object
*
* @param MonitoredObject $object
*
* @return static
*/
public static function forMonitoredObject(MonitoredObject $object)
{
switch ($object->getType()) {
case 'host':
/** @var Host $object */
return new HostGraphs(
$object->getName(),
$object->host_check_command,
$object->{'_host_' . Graphs::getObscuredCheckCommandCustomVar()}
);
case 'service':
/** @var Service $object */
return new ServiceGraphs(
$object->getHost()->getName(),
$object->getName(),
$object->service_check_command,
$object->{'_service_' . Graphs::getObscuredCheckCommandCustomVar()}
);
}
}
/**
* Get the Icinga custom variable with the "real" check command (if any) of monitored objects we display graphs for
*
* @return string
*/
public static function getObscuredCheckCommandCustomVar()
{
if (static::$obscuredCheckCommandCustomVar === null) {
static::$obscuredCheckCommandCustomVar = Config::module('graphite')
->get('icinga', 'customvar_obscured_check_command', 'check_command');
}
return static::$obscuredCheckCommandCustomVar;
}
/**
* Constructor
*
* @param string $checkCommand The check command of the monitored object we display graphs for
* @param string|null $obscuredCheckCommand The "real" check command (if any) of the monitored object
* we display graphs for
*/
public function __construct($checkCommand, $obscuredCheckCommand)
{
$this->checkCommand = $checkCommand;
$this->obscuredCheckCommand = $obscuredCheckCommand;
}
/**
* Process the given request using this widget
*
* @param Request $request The request to be processed
*
* @return $this
*/
public function handleRequest(Request $request = null)
{
if ($request === null) {
$request = Icinga::app()->getRequest();
}
$params = $request->getUrl()->getParams();
list($this->start, $this->end) = $this->getRangeFromTimeRangePicker($request);
$this->width = $params->shift('width', $this->width);
$this->height = $params->shift('height', $this->height);
return $this;
}
/**
* Render the graphs list
*
* @return string
*/
protected function getGraphsList()
{
if ($this->graphsList === null) {
$result = []; // kind of string builder
$filter = $this->getMonitoredObjectFilter();
$imageBaseUrl = $this->preloadDummy ? $this->getDummyImageBaseUrl() : $this->getImageBaseUrl();
$allTemplates = $this->getAllTemplates();
$concreteTemplates = $allTemplates->getTemplates(
$this->obscuredCheckCommand === null ? $this->checkCommand : $this->obscuredCheckCommand
);
$excludedMetrics = [];
foreach ($concreteTemplates as $concreteTemplate) {
foreach ($concreteTemplate->getCurves() as $curve) {
$excludedMetrics[] = $curve[0];
}
}
foreach ([
['template', $concreteTemplates, []],
['default_template', $allTemplates->getDefaultTemplates(), $excludedMetrics],
] as $templateSet) {
list($urlParam, $templates, $excludeMetrics) = $templateSet;
foreach ($templates as $templateName => $template) {
if ($this->designedForMyMonitoredObjectType($template)) {
$charts = $template->getCharts(
static::getMetricsDataSource(), $filter, $this->checkCommand, $excludeMetrics
);
if (! empty($charts)) {
$currentGraphs = [];
foreach ($charts as $chart) {
$metricVariables = $chart->getMetricVariables();
$imageUrl = $this->filterImageUrl($imageBaseUrl->with($metricVariables))
->setParam($urlParam, $templateName)
->setParam('start', $this->start)
->setParam('end', $this->end)
->setParam('width', $this->width)
->setParam('height', $this->height)
->setParam('cachebuster', time() * 65536 + mt_rand(0, 65535));
if (! $this->compact) {
$imageUrl->setParam('legend', 1);
}
$bestIntersect = -1;
$bestPos = count($result);
foreach ($result as $graphPos => & $graph) {
$currentIntersect = count(array_intersect_assoc($graph[1], $metricVariables));
if ($currentIntersect >= $bestIntersect) {
$bestIntersect = $currentIntersect;
$bestPos = $graphPos + 1;
}
}
unset($graph);
$currentGraphs[] = [
'width\" height=\"$this->height\">",
$metricVariables,
$bestPos
];
}
foreach (array_reverse($currentGraphs) as $graph) {
list($img, $metricVariables, $bestPos) = $graph;
array_splice($result, $bestPos, 0, [[$img, $metricVariables]]);
}
}
}
}
}
if (! empty($result)) {
foreach ($result as & $graph) {
$graph = $graph[0];
}
unset($graph);
if ($this->maxVisibleGraphs && count($result) > $this->maxVisibleGraphs) {
/** @var View $view */
$view = $this->view();
array_splice($result, $this->maxVisibleGraphs, 0, [sprintf(
''
. ''
. '
{$view->escape($view->translate('No graphs found'))}
"; } return $result; } /** * Get time range parameters for Graphite from the URL * * @param Request $request The request to be used * * @return string[] */ protected function getRangeFromTimeRangePicker(Request $request) { $params = $request->getUrl()->getParams(); $relative = $params->get(TimeRangePickerTrait::getRelativeRangeParameter()); if ($relative !== null) { return ["-$relative", null]; } $absolute = TimeRangePickerTrait::getAbsoluteRangeParameters(); $start = $params->get($absolute['start']); return [ $start === null ? -TimeRangePickerTrait::getDefaultRelativeTimeRange() : $start, $params->get($absolute['end']) ]; } /** * Return a identifier specifying the monitored object we display graphs for * * @return string */ abstract protected function getMonitoredObjectIdentifier(); /** * Return a filter specifying the monitored object we display graphs for * * @return string[] */ abstract protected function getMonitoredObjectFilter(); /** * Get the base URL to a graph specifying just the monitored object kind * * @return Url */ abstract protected function getImageBaseUrl(); /** * Get the base URL to a dummy image specifying just the monitored object kind * * @return Url */ abstract protected function getDummyImageBaseUrl(); /** * Extend the {@link getImageBaseUrl()}'s result's parameters with the concrete monitored object * * @param Url $url The URL to extend * * @return Url The given URL */ abstract protected function filterImageUrl(Url $url); /** * Return whether the given template is designed for the type of the monitored object we display graphs for * * @param Template $template * * @return bool */ abstract protected function designedForMyMonitoredObjectType(Template $template); /** * Get {@link compact} * * @return bool */ public function getCompact() { return $this->compact; } /** * Set {@link compact} * * @param bool $compact * * @return $this */ public function setCompact($compact = true) { $this->compact = $compact; return $this; } /** * Get the graph image width * * @return string */ public function getWidth() { return $this->width; } /** * Set the graph image width * * @param string $width * * @return $this */ public function setWidth($width) { $this->width = $width; return $this; } /** * Get the graph image height * * @return string */ public function getHeight() { return $this->height; } /** * Set the graph image height * * @param string $height * * @return $this */ public function setHeight($height) { $this->height = $height; return $this; } /** * Get additional CSS classes for the s around the images * * @return string[] */ public function getClasses() { return $this->classes; } /** * Set additional CSS classes for the s around the images * * @param string[] $classes * * @return $this */ public function setClasses($classes) { $this->classes = $classes; return $this; } /** * Get the amount of graphs to show * * @return int */ public function getMaxVisbileGraphs() { return $this->maxVisibleGraphs; } /** * Set the amount of graphs to show * * @param int $count * * @return $this */ public function setMaxVisibleGraphs($count) { $this->maxVisibleGraphs = (int) $count; return $this; } /** * Get whether to serve a transparent dummy image first and let the JS code load the actual graph * * @return bool */ public function getPreloadDummy() { return $this->preloadDummy; } /** * Set whether to serve a transparent dummy image first and let the JS code load the actual graph * * @param bool $preloadDummy * * @return $this */ public function setPreloadDummy($preloadDummy = true) { $this->preloadDummy = $preloadDummy; return $this; } /** * Get whether to explicitly display that no graphs were found * * @return bool */ public function getShowNoGraphsFound() { if ($this->showNoGraphsFound === null) { $this->showNoGraphsFound = ! Config::module('graphite')->get('ui', 'disable_no_graphs_found'); } return $this->showNoGraphsFound; } /** * Set whether to explicitly display that no graphs were found * * @param bool $showNoGraphsFound * * @return $this */ public function setShowNoGraphsFound($showNoGraphsFound = true) { $this->showNoGraphsFound = $showNoGraphsFound; return $this; } }