mirror of
https://github.com/Icinga/icingaweb2-module-graphite.git
synced 2026-05-28 04:34:57 -04:00
Merge branch 'master' into feature/restrictions-11
This commit is contained in:
commit
90278c3497
6 changed files with 262 additions and 131 deletions
117
application/controllers/GraphController.php
Normal file
117
application/controllers/GraphController.php
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Graphite\Controllers;
|
||||
|
||||
use Icinga\Exception\Http\HttpBadRequestException;
|
||||
use Icinga\Exception\Http\HttpNotFoundException;
|
||||
use Icinga\Module\Graphite\GraphiteQuery;
|
||||
use Icinga\Module\Graphite\GraphTemplate;
|
||||
use Icinga\Module\Graphite\Web\Widget\GraphsTrait;
|
||||
use Icinga\Web\Controller;
|
||||
use Icinga\Web\UrlParams;
|
||||
|
||||
class GraphController extends Controller
|
||||
{
|
||||
use GraphsTrait;
|
||||
|
||||
/**
|
||||
* The URL parameters for graph sizing
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $geometryParamsNames = ['start', 'end', 'width', 'height', 'legend'];
|
||||
|
||||
/**
|
||||
* Whether we supply a service's graph
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $service = true;
|
||||
|
||||
/**
|
||||
* The URL parameters for metrics filtering
|
||||
*
|
||||
* @var UrlParams
|
||||
*/
|
||||
protected $filterParams;
|
||||
|
||||
/**
|
||||
* The URL parameters for graph sizing
|
||||
*
|
||||
* @var string[string]
|
||||
*/
|
||||
protected $geometryParams = [];
|
||||
|
||||
public function hostAction()
|
||||
{
|
||||
$this->service = false;
|
||||
|
||||
$this->supplyImage();
|
||||
}
|
||||
|
||||
public function serviceAction()
|
||||
{
|
||||
$this->supplyImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do all monitored object type independend actions
|
||||
*/
|
||||
protected function supplyImage()
|
||||
{
|
||||
$this->filterParams = clone $this->getRequest()->getUrl()->getParams();
|
||||
|
||||
foreach ($this->geometryParamsNames as $paramName) {
|
||||
$this->geometryParams[$paramName] = $this->filterParams->shift($paramName);
|
||||
}
|
||||
|
||||
$this->collectTemplates();
|
||||
$this->collectGraphiteQueries();
|
||||
|
||||
$charts = [];
|
||||
foreach ($this->graphiteQueries as $templateName => $graphiteQuery) {
|
||||
/** @var GraphiteQuery $graphiteQuery */
|
||||
|
||||
$charts = array_merge($charts, $graphiteQuery->getImages($this->templates[$templateName]));
|
||||
if (count($charts) > 1) {
|
||||
throw new HttpBadRequestException('%s', $this->translate(
|
||||
'Graphite Web yields more than one metric for the given filter.'
|
||||
. ' Please specify a more precise filter.'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($charts)) {
|
||||
throw new HttpNotFoundException('%s', $this->translate('No such graph'));
|
||||
}
|
||||
|
||||
$image = $charts[0]
|
||||
->setStart($this->geometryParams['start'])
|
||||
->setUntil($this->geometryParams['end'])
|
||||
->setWidth($this->geometryParams['width'])
|
||||
->setHeight($this->geometryParams['height'])
|
||||
->showLegend((bool) $this->geometryParams['legend'])
|
||||
->fetchImage();
|
||||
|
||||
$this->_helper->layout()->disableLayout();
|
||||
|
||||
header('Content-Type: image/png');
|
||||
header('Content-Disposition: inline; filename="graph.png"');
|
||||
echo $image;
|
||||
exit;
|
||||
}
|
||||
|
||||
protected function includeTemplate(GraphTemplate $template)
|
||||
{
|
||||
return (strpos($template->getFilterString(), '$service') !== false) === $this->service;
|
||||
}
|
||||
|
||||
protected function filterGraphiteQuery(GraphiteQuery $query)
|
||||
{
|
||||
foreach ($this->filterParams->toArray() as list($key, $value)) {
|
||||
$query->where($key, $value);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
|
|
@ -40,39 +40,6 @@ class ShowController extends Controller
|
|||
$this->params->shift('r');
|
||||
}
|
||||
|
||||
public function graphAction()
|
||||
{
|
||||
$template = $this->loadTemplate();
|
||||
$title = $template->getTitle();
|
||||
if (false === strpos($title, '$')) {
|
||||
$template->setTitle('$hostname');
|
||||
} else {
|
||||
if (false === strpos($title, '$hostname')) {
|
||||
$template->setTitle('$hostname: ' . $template->getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
$query = $this->graphiteWeb
|
||||
->select()
|
||||
->from(
|
||||
$template->getFilterString()
|
||||
);
|
||||
|
||||
foreach ($this->params->toArray() as $val) {
|
||||
$query->where($val[0], urldecode($val[1]));
|
||||
}
|
||||
|
||||
$img = $this->applyGraphParams(current($query->getImages($template)))
|
||||
->showLegend(false);
|
||||
|
||||
$this->_helper->layout()->disableLayout();
|
||||
|
||||
$image = $img->fetchImage();
|
||||
header('Content-Type: image/png');
|
||||
echo $image;
|
||||
exit;
|
||||
}
|
||||
|
||||
protected function loadTemplate()
|
||||
{
|
||||
$this->handleTemplateParams();
|
||||
|
|
@ -160,7 +127,7 @@ class ShowController extends Controller
|
|||
$params->add('disabled', $key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->redirectNow($url);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,36 +5,20 @@ namespace Icinga\Module\Graphite\Web\Widget;
|
|||
use Icinga\Application\Icinga;
|
||||
use Icinga\Module\Graphite\Forms\TimeRangePicker\TimeRangePickerTrait;
|
||||
use Icinga\Module\Graphite\GraphiteQuery;
|
||||
use Icinga\Module\Graphite\GraphiteWeb;
|
||||
use Icinga\Module\Graphite\GraphiteWebClient;
|
||||
use Icinga\Module\Graphite\GraphTemplate;
|
||||
use Icinga\Module\Graphite\TemplateSet;
|
||||
use Icinga\Module\Graphite\TemplateStore;
|
||||
use Icinga\Module\Graphite\GraphiteUtil;
|
||||
use Icinga\Module\Graphite\Web\Widget\Graphs\Host as HostGraphs;
|
||||
use Icinga\Module\Graphite\Web\Widget\Graphs\Service as ServiceGraphs;
|
||||
use Icinga\Module\Monitoring\Object\Host;
|
||||
use Icinga\Module\Monitoring\Object\MonitoredObject;
|
||||
use Icinga\Module\Monitoring\Object\Service;
|
||||
use Icinga\Web\Request;
|
||||
use Icinga\Web\UrlParams;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Web\View;
|
||||
use Icinga\Web\Widget\AbstractWidget;
|
||||
|
||||
abstract class Graphs extends AbstractWidget
|
||||
{
|
||||
/**
|
||||
* [$setName => $set]
|
||||
*
|
||||
* @var TemplateSet[string]
|
||||
*/
|
||||
protected static $templateSets;
|
||||
|
||||
/**
|
||||
* [$setName => [$templateName => $template]]
|
||||
*
|
||||
* @var GraphTemplate[string][string]
|
||||
*/
|
||||
protected static $allTemplates = [];
|
||||
use GraphsTrait;
|
||||
|
||||
/**
|
||||
* Graph image width
|
||||
|
|
@ -78,12 +62,7 @@ abstract class Graphs extends AbstractWidget
|
|||
*
|
||||
* @var string[string][string]
|
||||
*/
|
||||
protected $images;
|
||||
|
||||
/**
|
||||
* @var GraphTemplate[string]
|
||||
*/
|
||||
protected $templates;
|
||||
protected $images = [];
|
||||
|
||||
/**
|
||||
* Factory, based on the given object
|
||||
|
|
@ -132,22 +111,20 @@ abstract class Graphs extends AbstractWidget
|
|||
$rendered = '';
|
||||
|
||||
foreach ($this->images as $type => $images) {
|
||||
if (count($images) > 0) {
|
||||
$rendered .= '<div class="images">';
|
||||
$rendered .= '<div class="images">';
|
||||
|
||||
if (! $this->compact) {
|
||||
$rendered .= "<h3>{$view->escape(ucfirst($type))}</h3>{$view->partial(
|
||||
'show/legend.phtml',
|
||||
['template' => $this->templates[$type]]
|
||||
)}";
|
||||
}
|
||||
|
||||
foreach ($images as $title => $url) {
|
||||
$rendered .= "<img src=\"$url\" class=\"graphiteImg\" alt=\"\" width=\"$this->width\" height=\"$this->height\" />";
|
||||
}
|
||||
|
||||
$rendered .= '</div>';
|
||||
if (! $this->compact) {
|
||||
$rendered .= "<h3>{$view->escape(ucfirst($type))}</h3>{$view->partial(
|
||||
'show/legend.phtml',
|
||||
['template' => $this->templates[$type]]
|
||||
)}";
|
||||
}
|
||||
|
||||
foreach ($images as $url) {
|
||||
$rendered .= "<img src=\"$url\" class=\"graphiteImg\" alt=\"\" width=\"$this->width\" height=\"$this->height\" />";
|
||||
}
|
||||
|
||||
$rendered .= '</div>';
|
||||
}
|
||||
|
||||
return $rendered ?: "<p>{$view->escape($view->translate('No graphs found'))}</p>";
|
||||
|
|
@ -186,75 +163,35 @@ abstract class Graphs extends AbstractWidget
|
|||
}
|
||||
|
||||
/**
|
||||
* Initialize {@link templates}
|
||||
* Initialize {@link images}
|
||||
*/
|
||||
protected function collectTemplates()
|
||||
protected function collectImages()
|
||||
{
|
||||
if (static::$templateSets === null) {
|
||||
static::$templateSets = (new TemplateStore())->loadTemplateSets();
|
||||
}
|
||||
$this->collectGraphiteQueries();
|
||||
$imageBaseUrl = $this->getImageBaseUrl();
|
||||
|
||||
foreach (static::$templateSets as $setname => $set) {
|
||||
/** @var TemplateSet $set */
|
||||
foreach ($this->graphiteQueries as $templateName => $graphiteQuery) {
|
||||
/** @var GraphiteQuery $graphiteQuery */
|
||||
|
||||
if (array_key_exists('icingaHost', $set->getBasePatterns())) {
|
||||
if (! isset(static::$allTemplates[$setname])) {
|
||||
static::$allTemplates[$setname] = $set->loadTemplates();
|
||||
}
|
||||
$searchPattern = $graphiteQuery->getSearchPattern();
|
||||
|
||||
foreach (static::$allTemplates[$setname] as $templateName => $template) {
|
||||
/** @var GraphTemplate $template */
|
||||
|
||||
if ($this->includeTemplate($template)) {
|
||||
$this->templates[$templateName] = $template;
|
||||
}
|
||||
}
|
||||
foreach ($graphiteQuery->listMetrics() as $metric) {
|
||||
$this->images[$templateName][] = $imageBaseUrl
|
||||
->with(GraphiteUtil::extractVars($metric, $searchPattern))
|
||||
->setParam('start', $this->start)
|
||||
->setParam('end', $this->end)
|
||||
->setParam('width', $this->width)
|
||||
->setParam('height', $this->height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize {@link images}
|
||||
* Get the base URL to a graph specifying just the monitored object kind
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
protected function collectImages()
|
||||
{
|
||||
$graphiteWeb = new GraphiteWeb(GraphiteWebClient::getInstance());
|
||||
foreach ($this->templates as $templateName => $template) {
|
||||
/** @var GraphTemplate $template */
|
||||
|
||||
$this->images[$templateName] = $this->filterGraphiteQuery(
|
||||
$graphiteWeb->select()->from($template->getFilterString())
|
||||
)
|
||||
->getWrappedImageLinks(
|
||||
$template,
|
||||
TimeRangePickerTrait::copyAllRangeParameters(
|
||||
(new UrlParams())
|
||||
->set('template', $templateName)
|
||||
->set('start', $this->start)
|
||||
->set('width', $this->width)
|
||||
->set('height', $this->height)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add filters to the given query so that only specific graphs are shown
|
||||
*
|
||||
* @param GraphiteQuery $query
|
||||
*
|
||||
* @return GraphiteQuery The given query
|
||||
*/
|
||||
abstract protected function filterGraphiteQuery(GraphiteQuery $query);
|
||||
|
||||
/**
|
||||
* Return whether to use the given template
|
||||
*
|
||||
* @param GraphTemplate $template
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function includeTemplate(GraphTemplate $template);
|
||||
abstract protected function getImageBaseUrl();
|
||||
|
||||
/**
|
||||
* Get {@link compact}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace Icinga\Module\Graphite\Web\Widget\Graphs;
|
|||
use Icinga\Module\Graphite\GraphiteQuery;
|
||||
use Icinga\Module\Graphite\GraphTemplate;
|
||||
use Icinga\Module\Graphite\Web\Widget\Graphs;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
class Host extends Graphs
|
||||
{
|
||||
|
|
@ -34,4 +35,9 @@ class Host extends Graphs
|
|||
{
|
||||
return strpos($template->getFilterString(), '$service') === false;
|
||||
}
|
||||
|
||||
protected function getImageBaseUrl()
|
||||
{
|
||||
return Url::fromPath('graphite/graph/host');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace Icinga\Module\Graphite\Web\Widget\Graphs;
|
|||
use Icinga\Module\Graphite\GraphiteQuery;
|
||||
use Icinga\Module\Graphite\GraphTemplate;
|
||||
use Icinga\Module\Graphite\Web\Widget\Graphs;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
class Service extends Graphs
|
||||
{
|
||||
|
|
@ -45,4 +46,9 @@ class Service extends Graphs
|
|||
{
|
||||
return strpos($template->getFilterString(), '$service') !== false;
|
||||
}
|
||||
|
||||
protected function getImageBaseUrl()
|
||||
{
|
||||
return Url::fromPath('graphite/graph/service');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
98
library/Graphite/Web/Widget/GraphsTrait.php
Normal file
98
library/Graphite/Web/Widget/GraphsTrait.php
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Graphite\Web\Widget;
|
||||
|
||||
use Icinga\Module\Graphite\GraphiteQuery;
|
||||
use Icinga\Module\Graphite\GraphiteWeb;
|
||||
use Icinga\Module\Graphite\GraphiteWebClient;
|
||||
use Icinga\Module\Graphite\GraphTemplate;
|
||||
use Icinga\Module\Graphite\TemplateSet;
|
||||
use Icinga\Module\Graphite\TemplateStore;
|
||||
|
||||
trait GraphsTrait
|
||||
{
|
||||
/**
|
||||
* [$setName => $set]
|
||||
*
|
||||
* @var TemplateSet[string]
|
||||
*/
|
||||
protected static $templateSets;
|
||||
|
||||
/**
|
||||
* [$setName => [$templateName => $template]]
|
||||
*
|
||||
* @var GraphTemplate[string][string]
|
||||
*/
|
||||
protected static $allTemplates = [];
|
||||
|
||||
/**
|
||||
* @var GraphTemplate[string]
|
||||
*/
|
||||
protected $templates;
|
||||
|
||||
/**
|
||||
* @var GraphiteQuery[string]
|
||||
*/
|
||||
protected $graphiteQueries;
|
||||
|
||||
/**
|
||||
* Initialize {@link templates}
|
||||
*/
|
||||
protected function collectTemplates()
|
||||
{
|
||||
if (static::$templateSets === null) {
|
||||
static::$templateSets = (new TemplateStore())->loadTemplateSets();
|
||||
}
|
||||
|
||||
foreach (static::$templateSets as $setname => $set) {
|
||||
/** @var TemplateSet $set */
|
||||
|
||||
if (array_key_exists('icingaHost', $set->getBasePatterns())) {
|
||||
if (! isset(static::$allTemplates[$setname])) {
|
||||
static::$allTemplates[$setname] = $set->loadTemplates();
|
||||
}
|
||||
|
||||
foreach (static::$allTemplates[$setname] as $templateName => $template) {
|
||||
/** @var GraphTemplate $template */
|
||||
|
||||
if ($this->includeTemplate($template)) {
|
||||
$this->templates[$templateName] = $template;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize {@link graphiteQueries}
|
||||
*/
|
||||
protected function collectGraphiteQueries()
|
||||
{
|
||||
$graphiteWeb = new GraphiteWeb(GraphiteWebClient::getInstance());
|
||||
foreach ($this->templates as $templateName => $template) {
|
||||
/** @var GraphTemplate $template */
|
||||
|
||||
$this->graphiteQueries[$templateName] = $this->filterGraphiteQuery(
|
||||
$graphiteWeb->select()->from($template->getFilterString())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to use the given template
|
||||
*
|
||||
* @param GraphTemplate $template
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function includeTemplate(GraphTemplate $template);
|
||||
|
||||
/**
|
||||
* Add filters to the given query so that only specific graphs are shown
|
||||
*
|
||||
* @param GraphiteQuery $query
|
||||
*
|
||||
* @return GraphiteQuery The given query
|
||||
*/
|
||||
abstract protected function filterGraphiteQuery(GraphiteQuery $query);
|
||||
}
|
||||
Loading…
Reference in a new issue