Merge branch 'feature/statusdat-revisited-3801'
This commit is contained in:
commit
235ab3f5f1
|
@ -222,15 +222,6 @@ abstract class BaseQuery implements Filterable
|
|||
$this->filter = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a backend specific filter expression and return a Query\Node object
|
||||
*
|
||||
* @param $expression The expression to parse
|
||||
* @param $parameters Optional parameters for the expression
|
||||
* @return Node A query node or null if it's an invalid expression
|
||||
*/
|
||||
abstract protected function parseFilterExpression($expression, $parameters = null);
|
||||
|
||||
/**
|
||||
* Return all default columns
|
||||
*
|
||||
|
@ -422,6 +413,33 @@ abstract class BaseQuery implements Filterable
|
|||
return $paginator;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a backend specific filter expression and return a Query\Node object
|
||||
*
|
||||
* @param $expression The expression to parse
|
||||
* @param $parameters Optional parameters for the expression
|
||||
*
|
||||
* @return Node A query node or null if it's an invalid expression
|
||||
*/
|
||||
protected function parseFilterExpression($expression, $parameter = null)
|
||||
{
|
||||
$splitted = explode(' ', $expression, 3);
|
||||
if (count($splitted) === 1 && $parameter) {
|
||||
return Node::createOperatorNode(Node::OPERATOR_EQUALS, $splitted[0], $parameter);
|
||||
} elseif (count($splitted) === 2 && $parameter) {
|
||||
Node::createOperatorNode($splitted[0], $splitted[1], is_string($parameter));
|
||||
return Node::createOperatorNode(Node::OPERATOR_EQUALS, $splitted[0], $parameter);
|
||||
} elseif (count($splitted) === 3) {
|
||||
if (trim($splitted[2]) === '?' && is_string($parameter)) {
|
||||
return Node::createOperatorNode($splitted[1], $splitted[0], $parameter);
|
||||
} else {
|
||||
return Node::createOperatorNode($splitted[1], $splitted[0], $splitted[2]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Total result size regardless of limit and offset
|
||||
*
|
||||
|
|
|
@ -287,32 +287,6 @@ class Query extends BaseQuery
|
|||
return strval($this->getSelectQuery());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a backend specific filter expression and return a Query\Node object
|
||||
*
|
||||
* @param $expression The expression to parse
|
||||
* @param $parameters Optional parameters for the expression
|
||||
*
|
||||
* @return Node A query node or null if it's an invalid expression
|
||||
*/
|
||||
protected function parseFilterExpression($expression, $parameter = null)
|
||||
{
|
||||
$splitted = explode(' ', $expression, 3);
|
||||
if (count($splitted) === 1 && $parameter) {
|
||||
return Node::createOperatorNode(Node::OPERATOR_EQUALS, $splitted[0], $parameter);
|
||||
} elseif (count($splitted) === 2 && $parameter) {
|
||||
Node::createOperatorNode($splitted[0], $splitted[1], is_string($parameter));
|
||||
return Node::createOperatorNode(Node::OPERATOR_EQUALS, $splitted[0], $parameter);
|
||||
} elseif (count($splitted) === 3) {
|
||||
if (trim($splitted[2]) === '?' && is_string($parameter)) {
|
||||
return Node::createOperatorNode($splitted[1], $splitted[0], $parameter);
|
||||
} else {
|
||||
return Node::createOperatorNode($splitted[1], $splitted[0], $splitted[2]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function applyFilter()
|
||||
{
|
||||
$parser = new TreeToSqlParser($this);
|
||||
|
|
|
@ -25,7 +25,7 @@ class ResourceFactory implements ConfigAwareFactory
|
|||
public static function getResourceConfig($resourceName)
|
||||
{
|
||||
if (($resourceConfig = self::$resources->get($resourceName)) === null) {
|
||||
throw new ConfigurationError('BLUBB?!');
|
||||
throw new ConfigurationError('Resource "' . $resourceName . '" couldn\'t be retrieved');
|
||||
}
|
||||
return $resourceConfig;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ class ResourceFactory implements ConfigAwareFactory
|
|||
$resource = new StatusdatReader($config);
|
||||
break;
|
||||
default:
|
||||
throw new ConfigurationError('BLUBB2?!');
|
||||
throw new ConfigurationError('Unsupported Backend "' + $config->type + '"');
|
||||
|
||||
}
|
||||
return $resource;
|
||||
|
|
|
@ -142,7 +142,7 @@ class CommandPipe
|
|||
* @param Command $command
|
||||
* @param array $objects
|
||||
*/
|
||||
public function sendCommand(Command $command, array $objects)
|
||||
public function sendCommand(Command $command, array $objects = array())
|
||||
{
|
||||
if ($command->provideGlobalCommand() === true) {
|
||||
$this->transport->send($command->getGlobalCommand());
|
||||
|
|
|
@ -35,11 +35,6 @@ interface IReader
|
|||
*/
|
||||
public function getState();
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getObjects();
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $name
|
||||
|
|
|
@ -48,7 +48,7 @@ class ObjectContainer extends \stdClass
|
|||
* @param \stdClass $obj
|
||||
* @param IReader $reader
|
||||
*/
|
||||
public function __construct(\stdClass &$obj, IReader &$reader)
|
||||
public function __construct(&$obj, IReader &$reader)
|
||||
{
|
||||
$this->ref = & $obj;
|
||||
$this->reader = & $reader;
|
||||
|
@ -62,10 +62,13 @@ class ObjectContainer extends \stdClass
|
|||
{
|
||||
$exploded = explode(".", $attribute);
|
||||
$result = $this->ref;
|
||||
foreach ($exploded as $elem) {
|
||||
|
||||
$result = $result->$elem;
|
||||
foreach ($exploded as $elem) {
|
||||
if (isset($result->$elem)) {
|
||||
$result = $result->$elem;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,45 +34,59 @@ use Icinga\Exception\ProgrammingError;
|
|||
use Icinga\Protocol\Statusdat\Exception\ParsingException as ParsingException;
|
||||
|
||||
/**
|
||||
* Class Parser
|
||||
* @package Icinga\Protocol\Statusdat
|
||||
* Status.dat and object.cache parser implementation
|
||||
*/
|
||||
class Parser
|
||||
{
|
||||
/**
|
||||
* An array of objects that couldn't be resolved yet due to missing dependencies
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $deferred = array();
|
||||
|
||||
/**
|
||||
* @var null|resource
|
||||
* The resource pointing to the currently read file
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
private $filehandle = null;
|
||||
private $filehandle;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
* String representation of the currently parsed object type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $currentObjectType = null;
|
||||
private $currentObjectType;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
* The current state type (host, service)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $currentStateType = null;
|
||||
private $currentStateType;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
* The internal representation of the icinga statue
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $icingaState = null;
|
||||
private $icingaState;
|
||||
|
||||
/**
|
||||
* The current line being read
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $lineCtr = 0;
|
||||
|
||||
/**
|
||||
* @param null $filehandle
|
||||
* @param null $baseState
|
||||
* @throws \Icinga\Exception\ConfigurationError
|
||||
* Create a new parser using the given file
|
||||
*
|
||||
* @param resource $filehandle The file handle to usefor parsing
|
||||
* @param array $baseState The state using for the base
|
||||
*
|
||||
* @throws ConfigurationError When the file can't be used
|
||||
*/
|
||||
public function __construct($filehandle = null, $baseState = null)
|
||||
{
|
||||
|
@ -85,11 +99,10 @@ class Parser
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Parse the given file handle as an objects file and read object information
|
||||
*/
|
||||
public function parseObjectsFile()
|
||||
{
|
||||
Logger::debug("Reading new objects file");
|
||||
$DEFINE = strlen("define ");
|
||||
$filehandle = $this->filehandle;
|
||||
$this->icingaState = array();
|
||||
|
@ -111,8 +124,7 @@ class Parser
|
|||
}
|
||||
|
||||
/**
|
||||
* @param null $filehandle
|
||||
* @throws ProgrammingError
|
||||
* Parse the given file handle as an status.dat file and read runtime information
|
||||
*/
|
||||
public function parseRuntimeState($filehandle = null)
|
||||
{
|
||||
|
@ -127,27 +139,25 @@ class Parser
|
|||
}
|
||||
$this->overwrites = array();
|
||||
while (!feof($filehandle)) {
|
||||
|
||||
$line = trim(fgets($filehandle));
|
||||
|
||||
$this->lineCtr++;
|
||||
if ($line === "" || $line[0] === "#") {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->currentStateType = trim(substr($line, 0, -1));
|
||||
$this->readCurrentState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception\ParsingException
|
||||
* Read the next object from the object.cache file handle
|
||||
*
|
||||
* @throws ParsingException
|
||||
*/
|
||||
private function readCurrentObject()
|
||||
{
|
||||
$filehandle = $this->filehandle;
|
||||
$monitoringObject = new \stdClass();
|
||||
$monitoringObject = new PrintableObject();
|
||||
while (!feof($filehandle)) {
|
||||
$line = explode("\t", trim(fgets($filehandle)), 2);
|
||||
$this->lineCtr++;
|
||||
|
@ -169,7 +179,8 @@ class Parser
|
|||
}
|
||||
|
||||
/**
|
||||
* TODO: Discard old runtime data
|
||||
* Read the next state from the status.dat file handler
|
||||
*
|
||||
* @throws Exception\ParsingException
|
||||
*/
|
||||
private function readCurrentState()
|
||||
|
@ -204,6 +215,7 @@ class Parser
|
|||
$type = substr($this->currentStateType, strlen($objectType));
|
||||
|
||||
if ($type == "status") {
|
||||
// directly set the status to the status field of the given object
|
||||
$base[$name]->status = & $statusdatObject;
|
||||
} else {
|
||||
if (!isset($base[$name]->$type) || !in_array($base[$name]->$type, $this->overwrites)) {
|
||||
|
@ -211,13 +223,25 @@ class Parser
|
|||
$this->overwrites[] = & $base[$name]->$type;
|
||||
}
|
||||
array_push($base[$name]->$type, $statusdatObject);
|
||||
$this->currentObjectType = $type;
|
||||
if (!isset($this->icingaState[$type])) {
|
||||
$this->icingaState[$type] = array();
|
||||
}
|
||||
$this->icingaState[$type][] = &$statusdatObject;
|
||||
$id = $this->getObjectIdentifier($statusdatObject);
|
||||
if ($id !== false && isset($this->icingaState[$objectType][$id])) {
|
||||
$statusdatObject->$objectType = $this->icingaState[$objectType][$id];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
* Get the corresponding object type name for the given state
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getObjectTypeForState()
|
||||
{
|
||||
|
@ -241,8 +265,10 @@ class Parser
|
|||
}
|
||||
|
||||
/**
|
||||
* @param bool $returnString
|
||||
* @return string
|
||||
* Skip the current object definition
|
||||
*
|
||||
* @param bool $returnString If true, the object string will be returned
|
||||
* @return string The skipped object if $returnString is true
|
||||
*/
|
||||
protected function skipObject($returnString = false)
|
||||
{
|
||||
|
@ -260,42 +286,54 @@ class Parser
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* Register the given object in the icinga state
|
||||
*
|
||||
* @param object $object The monitoring object to register
|
||||
*/
|
||||
protected function registerObject(&$object)
|
||||
{
|
||||
|
||||
$name = $this->getObjectIdentifier($object);
|
||||
|
||||
if ($name !== false) {
|
||||
$this->icingaState[$this->currentObjectType][$name] = & $object;
|
||||
$this->icingaState[$this->currentObjectType][$name] = &$object;
|
||||
}
|
||||
$this->registerObjectAsProperty($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* Register the given object as a property in related objects
|
||||
*
|
||||
* This registers for example hosts underneath their hostgroup and vice cersa
|
||||
*
|
||||
* @param object $object The object to register as a property
|
||||
*/
|
||||
protected function registerObjectAsProperty(&$object)
|
||||
{
|
||||
if ($this->currentObjectType == "service" || $this->currentObjectType == "host") {
|
||||
if ($this->currentObjectType == 'service'
|
||||
|| $this->currentObjectType == 'host'
|
||||
|| $this->currentObjectType == 'contact') {
|
||||
return null;
|
||||
}
|
||||
$isService = strpos($this->currentObjectType, "service") !== false;
|
||||
$isHost = strpos($this->currentObjectType, "host") !== false;
|
||||
|
||||
$isContact = strpos($this->currentObjectType, "contact") !== false;
|
||||
$name = $this->getObjectIdentifier($object);
|
||||
if ($isService === false && $isHost === false) { // this would be error in the parser implementation
|
||||
|
||||
if ($isService === false && $isHost === false && $isContact === false) { // this would be error in the parser implementation
|
||||
return null;
|
||||
}
|
||||
$property = $this->currentObjectType;
|
||||
if ($isService) {
|
||||
$this->currentObjectType = "service";
|
||||
$property = substr($property, strlen("service"));
|
||||
} else {
|
||||
} elseif ($isHost) {
|
||||
$this->currentObjectType = "host";
|
||||
$property = substr($property, strlen("host"));
|
||||
} elseif ($isContact) {
|
||||
$this->currentObjectType = "contact";
|
||||
$property = substr($property, strlen("contact"));
|
||||
}
|
||||
|
||||
if (!isset($this->icingaState[$this->currentObjectType])) {
|
||||
return $this->deferRegistration($object, $this->currentObjectType . $property);
|
||||
}
|
||||
|
@ -308,6 +346,13 @@ class Parser
|
|||
if (!isset($source->$property)) {
|
||||
$source->$property = array();
|
||||
}
|
||||
$type = $this->currentObjectType;
|
||||
if (!isset($object->$type)) {
|
||||
$object->$type = array();
|
||||
}
|
||||
// add the member to the group object
|
||||
array_push($object->$type, $source);
|
||||
// add the group to the member object
|
||||
array_push($source->$property, $name);
|
||||
}
|
||||
} else {
|
||||
|
@ -315,6 +360,7 @@ class Parser
|
|||
if (!isset($source->$property)) {
|
||||
$source->$property = array();
|
||||
}
|
||||
|
||||
array_push($source->$property, $object);
|
||||
}
|
||||
|
||||
|
@ -322,8 +368,10 @@ class Parser
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* @param $objType
|
||||
* Defer registration of the given object
|
||||
*
|
||||
* @param object $object The object to defer
|
||||
* @param String $objType The name of the object type
|
||||
*/
|
||||
protected function deferRegistration($object, $objType)
|
||||
{
|
||||
|
@ -331,7 +379,7 @@ class Parser
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Process deferred objects
|
||||
*/
|
||||
protected function processDeferred()
|
||||
{
|
||||
|
@ -342,8 +390,10 @@ class Parser
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* @return array
|
||||
* Return the resolved members directive of an object
|
||||
*
|
||||
* @param object $object The object to get the members from
|
||||
* @return array An array of member names
|
||||
*/
|
||||
protected function getMembers(&$object)
|
||||
{
|
||||
|
@ -366,11 +416,17 @@ class Parser
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* @return bool|string
|
||||
* Return the unique name of the given object
|
||||
*
|
||||
* @param object $object The object to retrieve the name from
|
||||
* @return string The name of the object or null if no name can be retrieved
|
||||
*/
|
||||
protected function getObjectIdentifier(&$object)
|
||||
{
|
||||
if ($this->currentObjectType == 'contact') {
|
||||
return $object->contact_name;
|
||||
}
|
||||
|
||||
if ($this->currentObjectType == "service") {
|
||||
return $object->host_name . ";" . $object->service_description;
|
||||
}
|
||||
|
@ -378,11 +434,18 @@ class Parser
|
|||
if (isset($object->{$name})) {
|
||||
return $object->{$name};
|
||||
}
|
||||
return false;
|
||||
if (isset($object->service_description)) {
|
||||
return $object->host_name . ";" . $object->service_description;
|
||||
} elseif (isset($object->host_name)) {
|
||||
return $object->host_name;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the internal state of the parser
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function getRuntimeState()
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
class PrintableObject
|
||||
{
|
||||
public function __toString()
|
||||
{
|
||||
if (isset($this->contact_name)) {
|
||||
return $this->contact_name;
|
||||
} else if (isset($this->service_description)) {
|
||||
return $this->service_description;
|
||||
} else if (isset($this->host_name)) {
|
||||
return $this->host_name;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
|
@ -28,93 +28,85 @@
|
|||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
use Icinga\Data\Optional;
|
||||
use Icinga\Data\The;
|
||||
use Exception;
|
||||
use Icinga\Filter\Query\Node;
|
||||
use Icinga\Protocol;
|
||||
use Icinga\Data\BaseQuery;
|
||||
use Icinga\Protocol\Statusdat\View\MonitoringObjectList;
|
||||
use Icinga\Protocol\Statusdat\Query\IQueryPart;
|
||||
|
||||
/**
|
||||
* Class Query
|
||||
* @package Icinga\Protocol\Statusdat
|
||||
* Base implementation for Statusdat queries.
|
||||
*
|
||||
*/
|
||||
class Query extends BaseQuery
|
||||
{
|
||||
/**
|
||||
* An array denoting valid targets by mapping the query target to
|
||||
* the 'define' directives found in the status.dat/objects.cache files
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $VALID_TARGETS = array(
|
||||
"hosts" => array("host"),
|
||||
"services" => array("service"),
|
||||
"downtimes" => array("hostdowntime", "servicedowntime"),
|
||||
"hostdowntimes" => array("hostdowntime"),
|
||||
"servicedowntimes" => array("servicedowntime"),
|
||||
"hostgroups" => array("hostgroup"),
|
||||
"servicegroups" => array("servicegroup"),
|
||||
"comments" => array("servicecomment", "hostcomment"),
|
||||
"hostcomments" => array("hostcomment"),
|
||||
"servicecomments" => array("servicecomment")
|
||||
'hosts' => array('host'),
|
||||
'services' => array('service'),
|
||||
'downtimes' => array('downtime'),
|
||||
'groups' => array('hostgroup', 'servicegroup'),
|
||||
'hostgroups' => array('hostgroup'),
|
||||
'servicegroups' => array('servicegroup'),
|
||||
'comments' => array('comment'),
|
||||
'contacts' => array('contact'),
|
||||
'contactgroups' => array('contactgroup')
|
||||
);
|
||||
|
||||
/**
|
||||
* @var IReader|null
|
||||
* The current StatusDat query that will be applied upon calling fetchAll
|
||||
*
|
||||
* @var IQueryPart
|
||||
*/
|
||||
private $reader = null;
|
||||
private $queryFilter = null;
|
||||
|
||||
/**
|
||||
* The current query source being used
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $source = "";
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $limit = null;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $offset = 0;
|
||||
private $source = '';
|
||||
|
||||
/**
|
||||
* An array containing all columns used for sorting
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $orderColumns = array();
|
||||
|
||||
/**
|
||||
* An array containig all columns used for (simple) grouping
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $groupColumns = array();
|
||||
|
||||
/**
|
||||
* @var null
|
||||
* An optional function callback to use for more specific grouping
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $groupByFn = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $filter = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* The scope index for the callback function
|
||||
*/
|
||||
const FN_SCOPE = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
* The name index for the callback function
|
||||
*/
|
||||
const FN_NAME = 1;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOrder()
|
||||
{
|
||||
return !empty($this->orderColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if columns are set for this query
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasColumns()
|
||||
|
@ -123,59 +115,27 @@ class Query extends BaseQuery
|
|||
return !empty($columns);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* Set the status.dat specific IQueryPart filter to use
|
||||
*
|
||||
* @param IQueryPart $filter
|
||||
*/
|
||||
public function hasLimit()
|
||||
public function setQueryFilter($filter)
|
||||
{
|
||||
return $this->limit !== false;
|
||||
$this->queryFilter = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* Order the query result by the given columns
|
||||
*
|
||||
* @param String|array $columns An array of columns to order by
|
||||
* @param String $dir The direction (asc or desc) in string form
|
||||
*
|
||||
* @return $this Fluent interface
|
||||
*/
|
||||
public function hasOffset()
|
||||
public function order($columns, $dir = null, $isFunction = false)
|
||||
{
|
||||
return $this->offset !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function getLimit()
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function getOffset()
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param null $val
|
||||
* @return $this
|
||||
*/
|
||||
public function where($key, $val = null)
|
||||
{
|
||||
$this->filter[] = array($key, $val);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $columns
|
||||
* @param null $dir
|
||||
* @return $this
|
||||
*/
|
||||
public function order($columns, $dir = null)
|
||||
{
|
||||
if ($dir && strtolower($dir) == "desc") {
|
||||
if ($dir && strtolower($dir) == 'desc') {
|
||||
$dir = self::SORT_DESC;
|
||||
} else {
|
||||
$dir = self::SORT_ASC;
|
||||
|
@ -183,8 +143,8 @@ class Query extends BaseQuery
|
|||
if (!is_array($columns)) {
|
||||
$columns = array($columns);
|
||||
}
|
||||
foreach ($columns as $col) {
|
||||
|
||||
foreach ($columns as $col) {
|
||||
if (($pos = strpos($col, ' ')) !== false) {
|
||||
$dir = strtoupper(substr($col, $pos + 1));
|
||||
if ($dir === 'DESC') {
|
||||
|
@ -203,60 +163,68 @@ class Query extends BaseQuery
|
|||
}
|
||||
|
||||
/**
|
||||
* @param null $count
|
||||
* @param int $offset
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
* Order the query result using the callback to retrieve values for items
|
||||
*
|
||||
* @param array $columns A scope, function array to use for retrieving the values when ordering
|
||||
* @param String $dir The direction (asc or desc) in string form
|
||||
*
|
||||
* @return $this Fluent interface
|
||||
*/
|
||||
public function limit($count = null, $offset = 0)
|
||||
public function orderByFn(array $callBack, $dir = null)
|
||||
{
|
||||
if ((is_null($count) || is_integer($count)) && (is_null($offset) || is_integer($offset))) {
|
||||
$this->offset = $offset;
|
||||
$this->limit = $count;
|
||||
if ($dir && strtolower($dir) == 'desc') {
|
||||
$dir = self::SORT_DESC;
|
||||
} else {
|
||||
throw new Exception("Got invalid limit $count, $offset");
|
||||
$dir = self::SORT_ASC;
|
||||
}
|
||||
return $this;
|
||||
$this->orderColumns[] = array($callBack, $dir);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param $table
|
||||
* @param null $columns
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
* Set the query target
|
||||
*
|
||||
* @param String $table The table/target to select the query from
|
||||
* @param array $columns An array of attributes to use (required for fetchPairs())
|
||||
*
|
||||
* @return $this Fluent interface
|
||||
* @throws \Exception If the target is unknonw
|
||||
*/
|
||||
public function from($table, array $attributes = null)
|
||||
{
|
||||
if (!$this->getColumns() && $attributes) {
|
||||
$this->setColumns($attributes);
|
||||
}
|
||||
if (isset(self::$VALID_TARGETS[$table])) {
|
||||
$this->source = $table;
|
||||
} else {
|
||||
throw new \Exception("Unknown from target for status.dat :" . $table);
|
||||
throw new \Exception('Unknown from target for status.dat :' . $table);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an index of all objects matching the filter of this query
|
||||
*
|
||||
* @throws Exception
|
||||
* This index will be used for ordering, grouping and limiting
|
||||
*/
|
||||
private function getFilteredIndices($classType = "\Icinga\Protocol\Statusdat\Query\Group")
|
||||
private function getFilteredIndices($classType = '\Icinga\Protocol\Statusdat\Query\Group')
|
||||
{
|
||||
$baseGroup = null;
|
||||
if (!empty($this->filter)) {
|
||||
$baseGroup = new $classType();
|
||||
|
||||
foreach ($this->filter as $values) {
|
||||
$baseGroup->addItem(new $classType($values[0], $values[1]));
|
||||
}
|
||||
}
|
||||
|
||||
$state = $this->ds->getObjects();
|
||||
$baseGroup = $this->queryFilter;
|
||||
$state = $this->ds->getState();
|
||||
$result = array();
|
||||
$source = self::$VALID_TARGETS[$this->source];
|
||||
|
||||
foreach ($source as $target) {
|
||||
|
||||
if (! isset($state[$target])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$indexes = array_keys($state[$target]);
|
||||
if ($baseGroup) {
|
||||
$baseGroup->setQuery($this);
|
||||
$indexes = $baseGroup->filter($state[$target]);
|
||||
}
|
||||
if (!isset($result[$target])) {
|
||||
|
@ -269,54 +237,78 @@ class Query extends BaseQuery
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $indices
|
||||
* Order the given result set
|
||||
*
|
||||
* @param array $indices The result set of the query that should be ordered
|
||||
*/
|
||||
private function orderIndices(array &$indices)
|
||||
{
|
||||
if (!empty($this->orderColumns)) {
|
||||
foreach ($indices as $type => &$subindices) {
|
||||
$this->currentType = $type; // we're singlethreaded, so let's do it a bit dirty
|
||||
usort($subindices, array($this, "orderResult"));
|
||||
$this->currentType = $type;
|
||||
usort($subindices, array($this, 'orderResult'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $a
|
||||
* @param $b
|
||||
* @return int
|
||||
* Start a query
|
||||
*
|
||||
* This is just a dummy function to allow a more convenient syntax
|
||||
*
|
||||
* @return self Fluent interface
|
||||
*/
|
||||
public function select()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order implementation called by usort
|
||||
*
|
||||
* @param String $a The left object index
|
||||
* @param Strinv $b The right object index
|
||||
* @return int 0, 1 or -1, see usort for detail
|
||||
*/
|
||||
private function orderResult($a, $b)
|
||||
{
|
||||
$o1 = $this->ds->getObjectByName($this->currentType, $a);
|
||||
$o2 = $this->ds->getObjectByName($this->currentType, $b);
|
||||
$result = 0;
|
||||
foreach ($this->orderColumns as $col) {
|
||||
$result += $col[1] * strnatcasecmp($o1->{$col[0]}, $o2->{$col[0]});
|
||||
|
||||
foreach ($this->orderColumns as &$col) {
|
||||
if (is_array($col[0])) {
|
||||
// sort by function
|
||||
$result += $col[1] * strnatcasecmp(
|
||||
$col[0][0]->$col[0][1]($o1),
|
||||
$col[0][0]->$col[0][1]($o2)
|
||||
);
|
||||
} else {
|
||||
$result += $col[1] * strnatcasecmp($o1->{$col[0]}, $o2->{$col[0]});
|
||||
}
|
||||
}
|
||||
if ($result > 0) {
|
||||
return 1;
|
||||
}
|
||||
if ($result < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $indices
|
||||
* Limit the given resultset
|
||||
*
|
||||
* @param array $indices The filtered, ordered indices
|
||||
*/
|
||||
private function limitIndices(array &$indices)
|
||||
{
|
||||
foreach ($indices as $type => $subindices) {
|
||||
$indices[$type] = array_slice($subindices, $this->offset, $this->limit);
|
||||
$indices[$type] = array_slice($subindices, $this->getOffset(), $this->getLimit());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fn
|
||||
* @param null $scope
|
||||
* @return $this
|
||||
* Register the given function for grouping the result
|
||||
*
|
||||
* @param String $fn The function to use for grouping
|
||||
* @param Object $scope An optional scope to use instead of $this
|
||||
*
|
||||
* @return self Fluent interface
|
||||
*/
|
||||
public function groupByFunction($fn, $scope = null)
|
||||
{
|
||||
|
@ -325,8 +317,11 @@ class Query extends BaseQuery
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $columns
|
||||
* @return $this
|
||||
* Group by the given column
|
||||
*
|
||||
* @param array|string $columns The columns to use for grouping
|
||||
* @return self Fluent interface
|
||||
* @see Query::columnGroupFn() The implementation used for grouping
|
||||
*/
|
||||
public function groupByColumns($columns)
|
||||
{
|
||||
|
@ -334,13 +329,15 @@ class Query extends BaseQuery
|
|||
$columns = array($columns);
|
||||
}
|
||||
$this->groupColumns = $columns;
|
||||
$this->groupByFn = array($this, "columnGroupFn");
|
||||
$this->groupByFn = array($this, 'columnGroupFn');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $indices
|
||||
* @return array
|
||||
* The internal handler function used by the group function
|
||||
*
|
||||
* @param array $indices The indices to group
|
||||
* @return array The grouped result set
|
||||
*/
|
||||
private function columnGroupFn(array &$indices)
|
||||
{
|
||||
|
@ -349,7 +346,7 @@ class Query extends BaseQuery
|
|||
foreach ($indices as $type => $subindices) {
|
||||
foreach ($subindices as $objectIndex) {
|
||||
$r = $this->ds->getObjectByName($type, $objectIndex);
|
||||
$hash = "";
|
||||
$hash = '';
|
||||
$cols = array();
|
||||
foreach ($this->groupColumns as $col) {
|
||||
$hash = md5($hash . $r->$col);
|
||||
|
@ -357,8 +354,8 @@ class Query extends BaseQuery
|
|||
}
|
||||
if (!isset($result[$hash])) {
|
||||
$result[$hash] = (object)array(
|
||||
"columns" => (object)$cols,
|
||||
"count" => 0
|
||||
'columns' => (object)$cols,
|
||||
'count' => 0
|
||||
);
|
||||
}
|
||||
$result[$hash]->count++;
|
||||
|
@ -368,11 +365,12 @@ class Query extends BaseQuery
|
|||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* Query Filter, Order, Group, Limit and return the result set
|
||||
*
|
||||
* @return array The resultset matching this query
|
||||
*/
|
||||
public function getResult()
|
||||
{
|
||||
|
||||
$indices = $this->getFilteredIndices();
|
||||
$this->orderIndices($indices);
|
||||
if ($this->groupByFn) {
|
||||
|
@ -385,9 +383,9 @@ class Query extends BaseQuery
|
|||
$this->limitIndices($indices);
|
||||
|
||||
$result = array();
|
||||
$state = $this->ds->getObjects();
|
||||
foreach ($indices as $type => $subindices) {
|
||||
$state = $this->ds->getState();
|
||||
|
||||
foreach ($indices as $type => $subindices) {
|
||||
foreach ($subindices as $index) {
|
||||
$result[] = & $state[$type][$index];
|
||||
}
|
||||
|
@ -395,21 +393,92 @@ class Query extends BaseQuery
|
|||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a backend specific filter expression and return a Query\Node object
|
||||
*
|
||||
* @param $expression The expression to parse
|
||||
* @param $parameters Optional parameters for the expression
|
||||
* @return Node A query node or null if it's an invalid expression
|
||||
* Apply all filters of this filterable on the datasource
|
||||
*/
|
||||
protected function parseFilterExpression($expression, $parameters = null)
|
||||
{
|
||||
// TODO: Implement parseFilterExpression() method.
|
||||
}
|
||||
|
||||
public function applyFilter()
|
||||
{
|
||||
// TODO: Implement applyFilter() method.
|
||||
$parser = new TreeToStatusdatQueryParser();
|
||||
if ($this->getFilter()) {
|
||||
$query = $parser->treeToQuery($this->getFilter(), $this);
|
||||
$this->setQueryFilter($query);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the first result row
|
||||
*
|
||||
* @return MonitoringObjectList The monitoring object matching this query
|
||||
*/
|
||||
public function fetchRow()
|
||||
{
|
||||
$result = $this->fetchAll();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the result as an associative array using the first column as the key and the second as the value
|
||||
*
|
||||
* @return array An associative array with the result
|
||||
* @throws \Exception If no attributes are defined
|
||||
*/
|
||||
public function fetchPairs()
|
||||
{
|
||||
$result = array();
|
||||
if (count($this->getColumns()) < 2) {
|
||||
throw new Exception(
|
||||
'Status.dat "fetchPairs()" query expects at least' .
|
||||
' columns to be set in the query expression'
|
||||
);
|
||||
}
|
||||
$attributes = $this->getColumns();
|
||||
|
||||
$param1 = $attributes[0];
|
||||
$param2 = $attributes[1];
|
||||
foreach ($this->fetchAll() as $resultList) {
|
||||
$result[$resultList->$param1] = $resultList->$param2;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all results
|
||||
*
|
||||
* @return MonitoringObjectList An MonitoringObjectList wrapping the given resultset
|
||||
*/
|
||||
public function fetchAll()
|
||||
{
|
||||
$this->applyFilter();
|
||||
if (!isset($this->cursor)) {
|
||||
$result = $this->getResult();
|
||||
$this->cursor = new MonitoringObjectList($result, $this);
|
||||
}
|
||||
return $this->cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch one result
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
return next($this->fetchAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of results
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$q = clone $this;
|
||||
$q->limit(null, null);
|
||||
return count($q->fetchAll());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -75,6 +75,13 @@ class Expression implements IQueryPart
|
|||
*/
|
||||
private $operator = null;
|
||||
|
||||
/**
|
||||
* Optional query information
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private $query = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
|
@ -154,6 +161,7 @@ class Expression implements IQueryPart
|
|||
|
||||
$this->fields = explode(".", trim($tokenized[0]));
|
||||
$this->field = $this->fields[count($this->fields) - 1];
|
||||
|
||||
$this->getOperatorType(trim($tokenized[1]));
|
||||
$tokenized[2] = trim($tokenized[2]);
|
||||
|
||||
|
@ -189,6 +197,9 @@ class Expression implements IQueryPart
|
|||
public function __construct($expression = null, &$values = array())
|
||||
{
|
||||
if ($expression) {
|
||||
if (!is_array($values)) {
|
||||
$values = array($values);
|
||||
}
|
||||
$this->fromString($expression, $values);
|
||||
}
|
||||
|
||||
|
@ -205,6 +216,7 @@ class Expression implements IQueryPart
|
|||
$idx = array_keys($base);
|
||||
}
|
||||
$this->basedata = $base;
|
||||
|
||||
return array_filter($idx, array($this, "filterFn"));
|
||||
}
|
||||
|
||||
|
@ -249,11 +261,20 @@ class Expression implements IQueryPart
|
|||
}
|
||||
}
|
||||
foreach ($values as $val) {
|
||||
|
||||
if (!is_string($val) && !is_numeric($val) && is_object($val)) {
|
||||
if (isset($val->service_description)) {
|
||||
$val = $val->service_description;
|
||||
} elseif(isset($val->host_name)) {
|
||||
$val = $val->host_name;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($this->{$this->CB}($val)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -264,8 +285,14 @@ class Expression implements IQueryPart
|
|||
private function getFieldValues($idx)
|
||||
{
|
||||
$res = $this->basedata[$idx];
|
||||
|
||||
foreach ($this->fields as $field) {
|
||||
if (!is_array($res)) {
|
||||
if ($this->query) {
|
||||
$res = $this->query->get($res, $field);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($res->$field)) {
|
||||
$res = array();
|
||||
break;
|
||||
|
@ -279,6 +306,10 @@ class Expression implements IQueryPart
|
|||
// array that contains the values/objects we're searching
|
||||
$swap = array();
|
||||
foreach ($res as $sub) {
|
||||
if ($this->query) {
|
||||
$swap[] = $this->query->get($sub, $field);
|
||||
continue;
|
||||
}
|
||||
if (!isset($sub->$field)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -293,6 +324,7 @@ class Expression implements IQueryPart
|
|||
if (!is_array($res)) {
|
||||
return array($res);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
@ -361,4 +393,17 @@ class Expression implements IQueryPart
|
|||
{
|
||||
return $value <= $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add additional information about the query this filter belongs to
|
||||
*
|
||||
* @param $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function setQuery($query)
|
||||
{
|
||||
$this->query = $query;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -109,6 +109,13 @@ class Group implements IQueryPart
|
|||
*/
|
||||
private $subExpressionLength = 0;
|
||||
|
||||
/**
|
||||
* Optional query to use
|
||||
*
|
||||
* @var Query
|
||||
*/
|
||||
private $query = null;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
|
@ -380,6 +387,7 @@ class Group implements IQueryPart
|
|||
$idx = array();
|
||||
foreach ($this->items as &$subFilter) {
|
||||
$baseKeys = array_keys($base);
|
||||
$subFilter->setQuery($this->query);
|
||||
$idx += $subFilter->filter($base, $baseKeys);
|
||||
}
|
||||
} else {
|
||||
|
@ -387,10 +395,24 @@ class Group implements IQueryPart
|
|||
$idx = array_keys($base);
|
||||
}
|
||||
foreach ($this->items as $subFilter) {
|
||||
$subFilter->setQuery($this->query);
|
||||
$idx = array_intersect($idx, $subFilter->filter($base, $idx));
|
||||
}
|
||||
}
|
||||
|
||||
return $idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add additional information about the query this filter belongs to
|
||||
*
|
||||
* @param $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function setQuery($query)
|
||||
{
|
||||
$this->query = $query;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -35,15 +35,27 @@ namespace Icinga\Protocol\Statusdat\Query;
|
|||
interface IQueryPart
|
||||
{
|
||||
/**
|
||||
* @param null $expression
|
||||
* @param array $value
|
||||
* Create a new query part with an optional expression to be parse
|
||||
*
|
||||
* @param string $expression An optional expression string to use
|
||||
* @param array $value The values fot the optional expression
|
||||
*/
|
||||
public function __construct($expression = null, &$value = array());
|
||||
|
||||
/**
|
||||
* @param array $base
|
||||
* @param null $idx
|
||||
* @return mixed
|
||||
* Filter the given resultset
|
||||
*
|
||||
* @param array $base The resultset to use for filtering
|
||||
* @param array $idx An optional array containing prefiltered indices
|
||||
*/
|
||||
public function filter(array &$base, &$idx = null);
|
||||
|
||||
/**
|
||||
* Add additional information about the query this filter belongs to
|
||||
*
|
||||
* @param $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function setQuery($query);
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
use Icinga\Data\DatasourceInterface;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Exception;
|
||||
use Icinga\Benchmark;
|
||||
use Icinga\Protocol\Statusdat\View\MonitoringObjectList;
|
||||
|
@ -40,54 +41,70 @@ use Icinga\Protocol\Statusdat\View\MonitoringObjectList;
|
|||
class Reader implements IReader, DatasourceInterface
|
||||
{
|
||||
/**
|
||||
*
|
||||
* The default lifetime of the cache in milliseconds
|
||||
*/
|
||||
const DEFAULT_CACHE_LIFETIME = 300;
|
||||
const DEFAULT_CACHE_LIFETIME = 30;
|
||||
|
||||
/**
|
||||
* The folder for the statusdat cache
|
||||
*
|
||||
*/
|
||||
const STATUSDAT_DEFAULT_CACHE_PATH = "/cache";
|
||||
|
||||
/**
|
||||
* @var null
|
||||
* The last state from the cache
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $lastState = null;
|
||||
private $lastState;
|
||||
|
||||
/**
|
||||
* True when this reader has already acquired the current runtime state (i.e. Status.dat)
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $hasRuntimeState = false;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
* The representation of the object.cache file
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $objectCache = null;
|
||||
private $objectCache ;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
* The representation of the status.dat file
|
||||
* @var array
|
||||
*/
|
||||
private $statusCache = null;
|
||||
private $statusCache;
|
||||
|
||||
/**
|
||||
* True when the icinga state differs from the cache
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $newState = false;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
* The Parser object to use for parsing
|
||||
*
|
||||
* @var Parser
|
||||
*/
|
||||
private $parser = null;
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* Whether to disable the cache
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $noCache = false;
|
||||
private $noCache;
|
||||
|
||||
/**
|
||||
* @param $config
|
||||
* @param null $parser
|
||||
* @param bool $noCache
|
||||
* Create a new Reader from the given configuraion
|
||||
*
|
||||
* @param Zend_Config $config The configuration to read the status.dat information from
|
||||
* @param Parser $parser The parser to use (for testing)
|
||||
* @param bool $noCache Whether to disable the cache
|
||||
*/
|
||||
public function __construct($config = \Zend_Config, $parser = null, $noCache = false)
|
||||
{
|
||||
|
@ -97,6 +114,7 @@ class Reader implements IReader, DatasourceInterface
|
|||
}
|
||||
$this->config = $config;
|
||||
$this->parser = $parser;
|
||||
|
||||
if (!$this->noCache) {
|
||||
$this->cache = $this->initializeCaches($config);
|
||||
if ($this->fromCache()) {
|
||||
|
@ -104,6 +122,7 @@ class Reader implements IReader, DatasourceInterface
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->lastState) {
|
||||
$this->parseObjectsCacheFile();
|
||||
}
|
||||
|
@ -112,14 +131,16 @@ class Reader implements IReader, DatasourceInterface
|
|||
}
|
||||
$this->parseStatusDatFile();
|
||||
if (!$noCache && $this->newState) {
|
||||
$this->statusCache->save($this->parser->getRuntimeState(), 'objects' . md5($this->config->objects_file));
|
||||
$this->statusCache->save($this->parser->getRuntimeState(), 'object' . md5($this->config->object_file));
|
||||
}
|
||||
$this->createHostServiceConnections();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception\ConfigurationError
|
||||
* Initialize the internal caches if enabled
|
||||
*
|
||||
* @throws ConfigurationError
|
||||
*/
|
||||
private function initializeCaches()
|
||||
{
|
||||
|
@ -128,7 +149,7 @@ class Reader implements IReader, DatasourceInterface
|
|||
$cachePath = $this->config->get('cache_path', $defaultCachePath);
|
||||
$maxCacheLifetime = intval($this->config->get('cache_path', self::DEFAULT_CACHE_LIFETIME));
|
||||
if (!is_writeable($cachePath)) {
|
||||
throw new Exception\ConfigurationError(
|
||||
throw new ConfigurationError(
|
||||
"Cache path $cachePath is not writable, check your configuration"
|
||||
);
|
||||
}
|
||||
|
@ -136,16 +157,19 @@ class Reader implements IReader, DatasourceInterface
|
|||
$backendOptions = array(
|
||||
'cache_dir' => $cachePath
|
||||
);
|
||||
// the objects cache might exist for months and is still valid
|
||||
$this->objectCache = $this->initCache($this->config->objects_file, $backendOptions, null);
|
||||
// the object cache might exist for months and is still valid
|
||||
$this->objectCache = $this->initCache($this->config->object_file, $backendOptions, null);
|
||||
$this->statusCache = $this->initCache($this->config->status_file, $backendOptions, $maxCacheLifetime);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $file
|
||||
* @param $backend
|
||||
* @param $lifetime
|
||||
* Init the Cache backend in Zend
|
||||
*
|
||||
* @param String $file The file to use as the cache master file
|
||||
* @param Zend_Config $backend The backend configuration to use
|
||||
* @param integer $lifetime The lifetime of the cache
|
||||
*
|
||||
* @return \Zend_Cache_Core|\Zend_Cache_Frontend
|
||||
*/
|
||||
private function initCache($file, $backend, $lifetime)
|
||||
|
@ -159,7 +183,9 @@ class Reader implements IReader, DatasourceInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* Read the current cache state
|
||||
*
|
||||
* @return bool True if the state is the same as the icinga state
|
||||
*/
|
||||
private function fromCache()
|
||||
{
|
||||
|
@ -171,16 +197,17 @@ class Reader implements IReader, DatasourceInterface
|
|||
$this->newState = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* Read the object.cache file from the Zend_Cache backend
|
||||
*
|
||||
* @return bool True if the file could be loaded from cache
|
||||
*/
|
||||
private function readObjectsCache()
|
||||
{
|
||||
$this->lastState = $this->objectCache->load('objects' . md5($this->config->objects_file));
|
||||
$this->lastState = $this->objectCache->load('object' . md5($this->config->object_file));
|
||||
if ($this->lastState == false) {
|
||||
return false;
|
||||
}
|
||||
|
@ -189,16 +216,16 @@ class Reader implements IReader, DatasourceInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* Read the status.dat file from the Zend_Cache backend
|
||||
*
|
||||
* @return bool True if the file could be loaded from cache
|
||||
*/
|
||||
private function readStatusCache()
|
||||
{
|
||||
if (!isset($this->stateCache)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$statusInfo = $this->stateCache->load('state' . md5($this->config->status_file));
|
||||
|
||||
if ($statusInfo == false) {
|
||||
return false;
|
||||
}
|
||||
|
@ -208,6 +235,7 @@ class Reader implements IReader, DatasourceInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Take the status.dat and objects.cache and connect all services to hosts
|
||||
*
|
||||
*/
|
||||
private function createHostServiceConnections()
|
||||
|
@ -215,9 +243,12 @@ class Reader implements IReader, DatasourceInterface
|
|||
if (!isset($this->lastState["service"])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->lastState["host"] as &$host) {
|
||||
$host->host = $host;
|
||||
}
|
||||
foreach ($this->lastState["service"] as &$service) {
|
||||
$host = & $this->lastState["host"][$service->host_name];
|
||||
$service->service = &$service; // allow easier querying
|
||||
$host = &$this->lastState["host"][$service->host_name];
|
||||
if (!isset($host->services)) {
|
||||
$host->services = array();
|
||||
}
|
||||
|
@ -227,29 +258,33 @@ class Reader implements IReader, DatasourceInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @throws Exception\ConfigurationError
|
||||
* Parse the object.cache file and update the current state
|
||||
*
|
||||
* @throws ConfigurationError If the object.cache couldn't be read
|
||||
*/
|
||||
private function parseObjectsCacheFile()
|
||||
{
|
||||
if (!is_readable($this->config->objects_file)) {
|
||||
throw new Exception\ConfigurationError(
|
||||
"Can't read objects-file {$this->config->objects_file}, check your configuration"
|
||||
if (!is_readable($this->config->object_file)) {
|
||||
throw new ConfigurationError(
|
||||
'Can\'t read object-file "' . $this->config->object_file . '", check your configuration'
|
||||
);
|
||||
}
|
||||
if (!$this->parser) {
|
||||
$this->parser = new Parser(fopen($this->config->objects_file, "r"));
|
||||
$this->parser = new Parser(fopen($this->config->object_file, "r"));
|
||||
}
|
||||
$this->parser->parseObjectsFile();
|
||||
$this->lastState = $this->parser->getRuntimeState();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception\ConfigurationError
|
||||
* Parse the status.dat file and update the current state
|
||||
*
|
||||
* @throws ConfigurationError If the status.dat couldn't be read
|
||||
*/
|
||||
private function parseStatusDatFile()
|
||||
{
|
||||
if (!is_readable($this->config->status_file)) {
|
||||
throw new Exception\ConfigurationError(
|
||||
throw new ConfigurationError(
|
||||
"Can't read status-file {$this->config->status_file}, check your configuration"
|
||||
);
|
||||
}
|
||||
|
@ -259,12 +294,14 @@ class Reader implements IReader, DatasourceInterface
|
|||
$this->parser->parseRuntimeState(fopen($this->config->status_file, "r"));
|
||||
$this->lastState = $this->parser->getRuntimeState();
|
||||
if (!$this->noCache) {
|
||||
$this->statusCache->save(array("true" => true), "state" . md5($this->config->objects_file));
|
||||
$this->statusCache->save(array("true" => true), "state" . md5($this->config->object_file));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
* Create a new Query
|
||||
*
|
||||
* @return Query The query to operate on
|
||||
*/
|
||||
public function select()
|
||||
{
|
||||
|
@ -272,34 +309,23 @@ class Reader implements IReader, DatasourceInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Query $query
|
||||
* @return MonitoringObjectList
|
||||
*/
|
||||
public function fetchAll(Query $query)
|
||||
{
|
||||
return $query->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
* Return the internal state of the status.dat
|
||||
*
|
||||
* @return mixed The internal status.dat representation
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
return $this->lastState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getObjects()
|
||||
{
|
||||
return $this->lastState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $name
|
||||
* @return ObjectContainer|mixed|null
|
||||
* Return the object with the given name and type
|
||||
*
|
||||
* @param String $type The type of the object to return (service, host, servicegroup...)
|
||||
* @param String $name The name of the object
|
||||
*
|
||||
* @return ObjectContainer An object container wrapping the result or null if the object doesn't exist
|
||||
*/
|
||||
public function getObjectByName($type, $name)
|
||||
{
|
||||
|
@ -310,8 +336,10 @@ class Reader implements IReader, DatasourceInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @return array|null
|
||||
* Get an array containing all names of monitoring objects with the given type
|
||||
*
|
||||
* @param String $type The type of object to get the names for
|
||||
* @return array An array of names or null if the type does not exist
|
||||
*/
|
||||
public function getObjectNames($type)
|
||||
{
|
||||
|
|
|
@ -29,17 +29,25 @@
|
|||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
/**
|
||||
* Class RuntimeStateContainer
|
||||
* @package Icinga\Protocol\Statusdat
|
||||
* Container class containing the runtime state of an object
|
||||
*
|
||||
* This class contains the state of the object as a string and parses it
|
||||
* on the fly as soon as values should be retrieved. This reduces memory usage,
|
||||
* as most runtime information is never received and only lives for a very short time.
|
||||
*
|
||||
*/
|
||||
class RuntimeStateContainer extends \stdClass
|
||||
{
|
||||
/**
|
||||
* The state string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $runtimeState = "";
|
||||
|
||||
/**
|
||||
* Create a new runtime state container from the givven string
|
||||
*
|
||||
* @param string $str
|
||||
*/
|
||||
public function __construct($str = "")
|
||||
|
@ -48,8 +56,10 @@ class RuntimeStateContainer extends \stdClass
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $attr
|
||||
* @return bool
|
||||
* Return true if the argument exists
|
||||
*
|
||||
* @param String $attr The argument to retrieve
|
||||
* @return bool True if it exists, otherwise false
|
||||
*/
|
||||
public function __isset($attr)
|
||||
{
|
||||
|
@ -62,9 +72,13 @@ class RuntimeStateContainer extends \stdClass
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $attr
|
||||
* @return mixed
|
||||
* @throws \InvalidArgumentException
|
||||
* Return the given attribute
|
||||
*
|
||||
* If the container string is not yet parsed, this will happen here
|
||||
*
|
||||
* @param String $attr The attribute to retrieve
|
||||
* @return mixed The value of the attribute
|
||||
* @throws \InvalidArgumentException When the attribute does not exist
|
||||
*/
|
||||
public function __get($attr)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
|
||||
use Icinga\Filter\Filterable;
|
||||
use Icinga\Filter\Query\Node;
|
||||
use Icinga\Filter\Query\Tree;
|
||||
use Icinga\Protocol\Statusdat\Query\Expression;
|
||||
use Icinga\Protocol\Statusdat\Query\Group;
|
||||
|
||||
class TreeToStatusdatQueryParser
|
||||
{
|
||||
|
||||
private function nodeToQuery(Node $node, Filterable $source)
|
||||
{
|
||||
if ($node->type === Node::TYPE_OPERATOR) {
|
||||
$op = $node->operator;
|
||||
$value = $node->right;
|
||||
$node->left = $source->getMappedField($node->left);
|
||||
if (stripos($node->right, '*') !== false) {
|
||||
$op = 'LIKE';
|
||||
$value = str_replace('*', '%', $value);
|
||||
}
|
||||
return new Expression($node->left . ' ' . $op . ' ?', $value);
|
||||
} else {
|
||||
$group = new Group();
|
||||
$group->setType(($node->type === Node::TYPE_OR) ? Group::TYPE_OR : Group::TYPE_AND);
|
||||
$group->addItem($this->nodeToQuery($node->left, $source));
|
||||
$group->addItem($this->nodeToQuery($node->right, $source));
|
||||
return $group;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function treeToQuery(Tree $tree, Filterable $source)
|
||||
{
|
||||
|
||||
$tree = $tree->getCopyForFilterable($source);
|
||||
if ($tree->root !== null) {
|
||||
$tree->root = $tree->normalizeTree($tree->root);
|
||||
return $this->nodeToQuery($tree->root, $source);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -55,13 +55,6 @@ interface AccessorStrategy
|
|||
*/
|
||||
public function get(&$item, $field);
|
||||
|
||||
/**
|
||||
* Returns the name that the field has in the specific backend. Might not be available for every field/view
|
||||
* @param $field The field name that should be translated
|
||||
* @return string The real name of this field
|
||||
*/
|
||||
public function getNormalizedFieldName($field);
|
||||
|
||||
/**
|
||||
* Returns true if the field exists on the specific item, otherwise false
|
||||
*
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\View;
|
||||
|
||||
use \Iterator;
|
||||
use \Countable;
|
||||
use \ArrayAccess;
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* Wrapper around an array of monitoring objects that can be enhanced with an optional
|
||||
* object that extends AccessorStrategy. This will act as a dataview and provide
|
||||
|
@ -11,14 +18,6 @@
|
|||
* If the dataset contains arrays instead of objects, they will be cast to objects.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\View;
|
||||
|
||||
use \Iterator;
|
||||
use \Countable;
|
||||
use \ArrayAccess;
|
||||
use \Exception;
|
||||
|
||||
class MonitoringObjectList implements Iterator, Countable, ArrayAccess
|
||||
{
|
||||
private $dataSet = array();
|
||||
|
@ -53,6 +52,7 @@ class MonitoringObjectList implements Iterator, Countable, ArrayAccess
|
|||
if ($this->dataView) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->dataSet[$this->position];
|
||||
}
|
||||
|
||||
|
|
|
@ -189,15 +189,20 @@ class Monitoring_CommandController extends ActionController
|
|||
|
||||
$query = Backend::createBackend($this->_getParam('backend'))->select()->from("status", $fields);
|
||||
$data = $query->fetchAll();
|
||||
|
||||
$out = array();
|
||||
|
||||
foreach ($data as $o) {
|
||||
$test = (array)$o;
|
||||
if ($test['host_name'] === $hostname) {
|
||||
if ($o->host_name === $hostname) {
|
||||
if (!$servicename) {
|
||||
$out[] = (object) $o;
|
||||
} elseif ($servicename && strtolower($test['service_description']) === strtolower($servicename)) {
|
||||
$out[] = (object) $o;
|
||||
$out[] = (object) array(
|
||||
"host_name" => $o->host_name
|
||||
);
|
||||
} elseif ($servicename && strtolower($o->service_description) === strtolower($servicename)) {
|
||||
$out[] = (object) array(
|
||||
"host_name" => $o->host_name,
|
||||
"service_description" => $o->service_description
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +213,7 @@ class Monitoring_CommandController extends ActionController
|
|||
"CommandController: SQL Query '%s' failed (message %s) ",
|
||||
$query ? (string) $query->getQuery()->dump() : '--', $e->getMessage()
|
||||
);
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ class Monitoring_MultiController extends ActionController
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getUniqueValues(array $values, $key)
|
||||
private function getUniqueValues($values, $key)
|
||||
{
|
||||
$unique = array();
|
||||
foreach ($values as $value)
|
||||
|
@ -144,7 +144,7 @@ class Monitoring_MultiController extends ActionController
|
|||
*
|
||||
* @param $object array The hosts or services
|
||||
*/
|
||||
private function getProblems(array $objects)
|
||||
private function getProblems($objects)
|
||||
{
|
||||
$problems = 0;
|
||||
foreach ($objects as $object) {
|
||||
|
|
|
@ -58,9 +58,9 @@ class Monitoring_ShowController extends MonitoringController
|
|||
|
||||
if ($this->getRequest()->getActionName() === 'host') {
|
||||
$this->view->object = new Host($this->getRequest());
|
||||
} elseif ($this->getRequest()->getActionName() === 'service') {
|
||||
} elseif ($this->getRequest()->getActionName() === 'service'
|
||||
|| $this->getRequest()->getActionName() === 'services' ) {
|
||||
$this->view->object = new Service($this->getRequest());
|
||||
|
||||
} else {
|
||||
$this->view->object = AbstractObject::fromRequest($this->getRequest());
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class Zend_View_Helper_CommandForm extends Zend_View_Helper_Abstract
|
|||
*
|
||||
* @return Form Form to modify
|
||||
*/
|
||||
private function simpleForm($commandName, array $arguments = array())
|
||||
public function simpleForm($commandName, array $arguments = array())
|
||||
{
|
||||
$form = new Form();
|
||||
$form->setIgnoreChangeDiscarding(true);
|
||||
|
|
|
@ -25,6 +25,11 @@ class Zend_View_Helper_ContactFlags extends Zend_View_Helper_Abstract
|
|||
*/
|
||||
public function contactFlags($contact, $type, $glue = ', ')
|
||||
{
|
||||
|
||||
$optionName = 'contact_' . $type . '_notification_options';
|
||||
if (isset($contact->$optionName)) {
|
||||
return $contact->$optionName;
|
||||
}
|
||||
$out = array();
|
||||
foreach ($contact as $key => $value) {
|
||||
if (preg_match('/^contact_notify_' . $type . '_.*/', $key) && $value == True) {
|
||||
|
|
|
@ -18,8 +18,8 @@ $knownGroups = array()
|
|||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php foreach($contactgroups as $contact): ?>
|
||||
|
||||
<?php foreach($contactgroups as $contact): ?>
|
||||
<?php $periodLink = $this->href('monitoring/show/contacts', array('contact' => $contact->contact_name)); ?>
|
||||
<tr>
|
||||
<?php
|
||||
|
|
|
@ -23,14 +23,14 @@ $commandHelper = $this->getHelper('CommandForm');
|
|||
<td>
|
||||
<?php if (isset($downtime->service)): ?>
|
||||
<a href="<?= $this->href('monitoring/show/service', array(
|
||||
'host' => $downtime->host,
|
||||
'service' => $downtime->service
|
||||
'host' => $downtime->host_name,
|
||||
'service' => $downtime->service_description
|
||||
)); ?>"><?= $downtime->service ?></a>
|
||||
<small>on <?= $downtime->host ?></small>
|
||||
<?php else: ?>
|
||||
<a href="<?= $this->href('monitoring/show/host', array(
|
||||
'host' => $downtime->host
|
||||
)); ?>"><?= $downtime->host ?></a>
|
||||
'host' => $downtime->host_name
|
||||
)); ?>"><?= $downtime->host ?> </a>
|
||||
<?php endif; ?>
|
||||
<br />
|
||||
<?= $downtime->downtime_author ?>: <?= $downtime->downtime_comment ?>
|
||||
|
|
|
@ -106,7 +106,7 @@ $viewHelper = $this->getHelper('MonitoringState');
|
|||
<?php if ($service->service_state): ?>
|
||||
<br />
|
||||
<strong>Attempt:</strong>
|
||||
<?= $service->current_check_attempt; ?>/<?= $service->max_check_attempts; ?>
|
||||
<?= $service->service_attempt; ?>
|
||||
(<?= ($service->service_state_type === '1') ? 'Hard' : 'Soft'; ?>)
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<span class="panel-header-status">
|
||||
- <?= $this->util()->getServiceStateName($object->service_state); ?>
|
||||
since <?= $this->timeSince($object->service_last_state_change); ?>
|
||||
since <?= $this->timeSince($object->service_slast_state_change); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/** @var boolean $showService */
|
||||
$showService = false;
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring;
|
||||
|
||||
use Icinga\Module\Monitoring\Exception\UnsupportedBackendException;
|
||||
use Zend_Config;
|
||||
use Icinga\Application\Config as IcingaConfig;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
|
@ -80,6 +81,13 @@ class Backend implements ConfigAwareFactory, DatasourceInterface
|
|||
. '\\Query\\'
|
||||
. ucfirst($table)
|
||||
. 'Query';
|
||||
if (!class_exists($queryClass)) {
|
||||
throw new UnsupportedBackendException('Query '
|
||||
. ucfirst($table)
|
||||
. ' Is Not Available For Backend '
|
||||
. ucfirst($this->config->type)
|
||||
);
|
||||
}
|
||||
return new $queryClass($this->resource, $columns);
|
||||
}
|
||||
|
||||
|
@ -142,6 +150,7 @@ class Backend implements ConfigAwareFactory, DatasourceInterface
|
|||
}
|
||||
|
||||
$config = self::$backendConfigs[$name];
|
||||
|
||||
self::$backendInstances[$name] = $backend = new self($config, ResourceFactory::getResourceConfig($config->resource));
|
||||
switch (strtolower($config->type)) {
|
||||
case 'ido':
|
||||
|
|
|
@ -1,341 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
class HoststatusQuery extends IdoQuery
|
||||
{
|
||||
protected $allowCustomVars = true;
|
||||
protected $columnMap = array(
|
||||
'hosts' => array(
|
||||
'host' => 'ho.name1 COLLATE latin1_general_ci',
|
||||
'host_name' => 'ho.name1 COLLATE latin1_general_ci',
|
||||
'host_display_name' => 'h.display_name',
|
||||
'host_alias' => 'h.alias',
|
||||
'host_address' => 'h.address',
|
||||
'host_ipv4' => 'INET_ATON(h.address)',
|
||||
'host_icon_image' => 'h.icon_image',
|
||||
),
|
||||
'hoststatus' => array(
|
||||
'problems' => 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END',
|
||||
'handled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END',
|
||||
'unhandled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) = 0 THEN 1 ELSE 0 END',
|
||||
'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END',
|
||||
'host_output' => 'hs.output',
|
||||
'host_long_output' => 'hs.long_output',
|
||||
'host_perfdata' => 'hs.perfdata',
|
||||
'host_problem' => 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END',
|
||||
'host_acknowledged' => 'hs.problem_has_been_acknowledged',
|
||||
'host_in_downtime' => 'CASE WHEN (hs.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END',
|
||||
'host_handled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END',
|
||||
'host_does_active_checks' => 'hs.active_checks_enabled',
|
||||
'host_accepts_passive_checks' => 'hs.passive_checks_enabled',
|
||||
'host_last_state_change' => 'UNIX_TIMESTAMP(hs.last_state_change)',
|
||||
'host_last_hard_state' => 'hs.last_hard_state',
|
||||
'host_check_command' => 'hs.check_command',
|
||||
'host_last_check' => 'UNIX_TIMESTAMP(hs.last_check)',
|
||||
'host_next_check' => 'CASE WHEN hs.should_be_scheduled THEN UNIX_TIMESTAMP(hs.next_check) ELSE NULL END',
|
||||
'host_check_execution_time' => 'hs.execution_time',
|
||||
'host_check_latency' => 'hs.latency',
|
||||
'host_notifications_enabled' => 'hs.notifications_enabled',
|
||||
'host_last_time_up' => 'hs.last_time_up',
|
||||
'host_last_time_down' => 'hs.last_time_down',
|
||||
'host_last_time_unreachable' => 'hs.last_time_unreachable',
|
||||
'host_current_check_attempt' => 'hs.current_check_attempt',
|
||||
'host_max_check_attempts' => 'hs.max_check_attempts',
|
||||
'host_severity' => 'CASE WHEN hs.current_state = 0
|
||||
THEN
|
||||
CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL
|
||||
THEN 16
|
||||
ELSE 0
|
||||
END
|
||||
+
|
||||
CASE WHEN hs.problem_has_been_acknowledged = 1
|
||||
THEN 2
|
||||
ELSE
|
||||
CASE WHEN hs.scheduled_downtime_depth > 0
|
||||
THEN 1
|
||||
ELSE 4
|
||||
END
|
||||
END
|
||||
ELSE
|
||||
CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 16
|
||||
WHEN hs.current_state = 1 THEN 32
|
||||
WHEN hs.current_state = 2 THEN 64
|
||||
ELSE 256
|
||||
END
|
||||
+
|
||||
CASE WHEN hs.problem_has_been_acknowledged = 1
|
||||
THEN 2
|
||||
ELSE
|
||||
CASE WHEN hs.scheduled_downtime_depth > 0
|
||||
THEN 1
|
||||
ELSE 4
|
||||
END
|
||||
END
|
||||
END',
|
||||
),
|
||||
'hostgroups' => array(
|
||||
'hostgroup' => 'hgo.name1 COLLATE latin1_general_ci',
|
||||
),
|
||||
'contactgroups' => array(
|
||||
'contactgroup' => 'contactgroup',
|
||||
),
|
||||
'contacts' => array(
|
||||
'contact' => 'hco.name1 COLLATE latin1_general_ci',
|
||||
),
|
||||
'services' => array(
|
||||
'services_cnt' => 'SUM(1)',
|
||||
'services_ok' => 'SUM(CASE WHEN ss.current_state = 0 THEN 1 ELSE 0 END)',
|
||||
'services_warning' => 'SUM(CASE WHEN ss.current_state = 1 THEN 1 ELSE 0 END)',
|
||||
'services_critical' => 'SUM(CASE WHEN ss.current_state = 2 THEN 1 ELSE 0 END)',
|
||||
'services_unknown' => 'SUM(CASE WHEN ss.current_state = 3 THEN 1 ELSE 0 END)',
|
||||
'services_pending' => 'SUM(CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 1 ELSE 0 END)',
|
||||
'services_problem' => 'SUM(CASE WHEN ss.current_state > 0 THEN 1 ELSE 0 END)',
|
||||
'services_problem_handled' => 'SUM(CASE WHEN ss.current_state > 0 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
|
||||
'services_problem_unhandled' => 'SUM(CASE WHEN ss.current_state > 0 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
|
||||
'services_warning_handled' => 'SUM(CASE WHEN ss.current_state = 1 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
|
||||
'services_critical_handled' => 'SUM(CASE WHEN ss.current_state = 2 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
|
||||
'services_unknown_handled' => 'SUM(CASE WHEN ss.current_state = 3 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
|
||||
'services_warning_unhandled' => 'SUM(CASE WHEN ss.current_state = 1 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
|
||||
'services_critical_unhandled' => 'SUM(CASE WHEN ss.current_state = 2 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
|
||||
'services_unknown_unhandled' => 'SUM(CASE WHEN ss.current_state = 3 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
|
||||
),
|
||||
);
|
||||
protected $aggregateColumnIdx = array(
|
||||
'services_cnt' => true,
|
||||
'services_problem' => true,
|
||||
'services_problem_handled' => true,
|
||||
'services_problem_unhandled' => true,
|
||||
);
|
||||
protected $hcgSub;
|
||||
|
||||
public function getDefaultColumns()
|
||||
{
|
||||
return $this->columnMap['hosts'] + $this->columnMap['hoststatus'];
|
||||
}
|
||||
|
||||
protected function joinBaseTables()
|
||||
{
|
||||
// TODO: Shall we always add hostobject?
|
||||
$this->baseQuery = $this->db->select()->from(
|
||||
array('ho' => $this->prefix . 'objects'),
|
||||
array()
|
||||
)->join(
|
||||
array('hs' => $this->prefix . 'hoststatus'),
|
||||
'ho.' . $this->object_id . ' = hs.host_object_id AND ho.is_active = 1 AND ho.objecttype_id = 1',
|
||||
array()
|
||||
)->join(
|
||||
array('h' => $this->prefix . 'hosts'),
|
||||
'hs.host_object_id = h.host_object_id',
|
||||
array()
|
||||
);
|
||||
$this->joinedVirtualTables = array(
|
||||
'hosts' => true,
|
||||
'hoststatus' => true,
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinStatus()
|
||||
{
|
||||
$this->requireVirtualTable('services');
|
||||
}
|
||||
|
||||
protected function joinServiceStatus()
|
||||
{
|
||||
$this->requireVirtualTable('services');
|
||||
}
|
||||
|
||||
protected function joinServices()
|
||||
{
|
||||
$this->baseQuery->join(
|
||||
array('s' => $this->prefix . 'services'),
|
||||
's.host_object_id = h.host_object_id',
|
||||
array()
|
||||
)->join(
|
||||
array('so' => $this->prefix . 'objects'),
|
||||
"so.$this->object_id = s.service_object_id AND so.is_active = 1",
|
||||
array()
|
||||
)->joinLeft(
|
||||
array('ss' => $this->prefix . 'servicestatus'),
|
||||
"so.$this->object_id = ss.service_object_id",
|
||||
array()
|
||||
);
|
||||
foreach ($this->getColumns() as $col) {
|
||||
$real = $this->aliasToColumnName($col);
|
||||
if (substr($real, 0, 4) === 'SUM(') {
|
||||
continue;
|
||||
}
|
||||
$this->baseQuery->group($real);
|
||||
}
|
||||
$this->useSubqueryCount = true;
|
||||
}
|
||||
|
||||
protected function joinHostgroups()
|
||||
{
|
||||
if ($this->hasJoinedVirtualTable('services')) {
|
||||
return $this->joinServiceHostgroups();
|
||||
} else {
|
||||
return $this->joinHostHostgroups();
|
||||
}
|
||||
}
|
||||
|
||||
protected function joinServiceHostgroups()
|
||||
{
|
||||
$this->baseQuery->join(
|
||||
array('hgm' => $this->prefix . 'hostgroup_members'),
|
||||
'hgm.host_object_id = s.host_object_id',
|
||||
array()
|
||||
)->join(
|
||||
array('hg' => $this->prefix . 'hostgroups'),
|
||||
'hgm.hostgroup_id = hg.' . $this->hostgroup_id,
|
||||
array()
|
||||
)->join(
|
||||
array('hgo' => $this->prefix . 'objects'),
|
||||
'hgo.' . $this->object_id . ' = hg.hostgroup_object_id'
|
||||
. ' AND hgo.is_active = 1',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function joinHostHostgroups()
|
||||
{
|
||||
$this->baseQuery->join(
|
||||
array('hgm' => $this->prefix . 'hostgroup_members'),
|
||||
'hgm.host_object_id = h.host_object_id',
|
||||
array()
|
||||
)->join(
|
||||
array('hg' => $this->prefix . 'hostgroups'),
|
||||
"hgm.hostgroup_id = hg.$this->hostgroup_id",
|
||||
array()
|
||||
)->join(
|
||||
array('hgo' => $this->prefix . 'objects'),
|
||||
'hgo.' . $this->object_id . ' = hg.hostgroup_object_id'
|
||||
. ' AND hgo.is_active = 1',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function joinContacts()
|
||||
{
|
||||
$this->hcgcSub = $this->db->select()->distinct()->from(
|
||||
array('hcgc' => $this->prefix . 'host_contactgroups'),
|
||||
array('host_name' => 'ho.name1')
|
||||
)->join(
|
||||
array('cgo' => $this->prefix . 'objects'),
|
||||
'hcg.contactgroup_object_id = cgo.' . $this->object_id
|
||||
. ' AND cgo.is_active = 1',
|
||||
array()
|
||||
)->join(
|
||||
array('h' => $this->prefix . 'hosts'),
|
||||
'hcg.host_id = h.host_id',
|
||||
array()
|
||||
)->join(
|
||||
array('ho' => $this->prefix . 'objects'),
|
||||
'h.host_object_id = ho.' . $this->object_id . ' AND ho.is_active = 1',
|
||||
array()
|
||||
);
|
||||
$this->baseQuery->join(
|
||||
array('hcg' => $this->hcgSub),
|
||||
'hcg.host_name = ho.name1',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function filterContactgroup($value)
|
||||
{
|
||||
$this->hcgSub->where(
|
||||
$this->prepareFilterStringForColumn(
|
||||
'cgo.name1 COLLATE latin1_general_ci',
|
||||
$value
|
||||
)
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function joinContactgroups()
|
||||
{
|
||||
$this->hcgSub = $this->createContactgroupFilterSubselect();
|
||||
$this->baseQuery->join(
|
||||
array('hcg' => $this->hcgSub),
|
||||
'hcg.object_id = ho.object_id',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function createContactgroupFilterSubselect()
|
||||
{
|
||||
die((string)$this->db->select()->distinct()->from(
|
||||
array('hcg' => $this->prefix . 'host_contactgroups'),
|
||||
array('object_id' => 'ho.object_id')
|
||||
)->join(
|
||||
array('cgo' => $this->prefix . 'objects'),
|
||||
'hcg.contactgroup_object_id = cgo.' . $this->object_id
|
||||
. ' AND cgo.is_active = 1',
|
||||
array()
|
||||
)->join(
|
||||
array('h' => $this->prefix . 'hosts'),
|
||||
'hcg.host_id = h.host_id',
|
||||
array()
|
||||
)->join(
|
||||
array('ho' => $this->prefix . 'objects'),
|
||||
'h.host_object_id = ho.' . $this->object_id . ' AND ho.is_active = 1',
|
||||
array()
|
||||
));
|
||||
}
|
||||
|
||||
protected function joinServicegroups()
|
||||
{
|
||||
// TODO: Only hosts with services having such servicegroups
|
||||
$this->requireVirtualTable('services');
|
||||
$this->baseQuery->join(
|
||||
array('sgm' => $this->prefix . 'servicegroup_members'),
|
||||
'sgm.service_object_id = s.service_object_id',
|
||||
array()
|
||||
)->join(
|
||||
array('sg' => $this->prefix . 'servicegroups'),
|
||||
'sgm.servicegroup_id = sg.' . $this->servicegroup_id,
|
||||
array()
|
||||
)->join(
|
||||
array('sgo' => $this->prefix . 'objects'),
|
||||
'sgo.' . $this->object_id . ' = sg.servicegroup_object_id'
|
||||
. ' AND sgo.is_active = 1',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -1,167 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
class ServicestatusQuery extends IdoQuery
|
||||
{
|
||||
protected $allowCustomVars = true;
|
||||
|
||||
protected $columnMap = array(
|
||||
'services' => array(
|
||||
'service_host_name' => 'so.name1 COLLATE latin1_general_ci',
|
||||
'service' => 'so.name2 COLLATE latin1_general_ci',
|
||||
'service_description' => 'so.name2 COLLATE latin1_general_ci',
|
||||
'service_display_name' => 's.display_name',
|
||||
'service_icon_image' => 's.icon_image',
|
||||
),
|
||||
'servicestatus' => array(
|
||||
'current_state' => 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE ss.current_state END',
|
||||
'service_state' => 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE ss.current_state END',
|
||||
'service_hard_state' => 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE CASE WHEN ss.state_type = 1 THEN ss.current_state ELSE ss.last_hard_state END END',
|
||||
'service_state_type' => 'ss.state_type',
|
||||
'service_output' => 'ss.output',
|
||||
'service_long_output' => 'ss.long_output',
|
||||
'service_perfdata' => 'ss.perfdata',
|
||||
'service_acknowledged' => 'ss.problem_has_been_acknowledged',
|
||||
'service_in_downtime' => 'CASE WHEN (ss.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END',
|
||||
'service_handled' => 'CASE WHEN (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) > 0 THEN 1 ELSE 0 END',
|
||||
'service_does_active_checks' => 'ss.active_checks_enabled',
|
||||
'service_accepts_passive_checks' => 'ss.passive_checks_enabled',
|
||||
'service_last_state_change' => 'UNIX_TIMESTAMP(ss.last_state_change)',
|
||||
'service_last_hard_state' => 'ss.last_hard_state',
|
||||
'service_last_hard_state_change' => 'UNIX_TIMESTAMP(ss.last_hard_state_change)',
|
||||
'service_check_command' => 'ss.check_command',
|
||||
'service_last_check' => 'UNIX_TIMESTAMP(ss.last_check)',
|
||||
'service_next_check' => 'CASE WHEN ss.should_be_scheduled THEN UNIX_TIMESTAMP(ss.next_check) ELSE NULL END',
|
||||
'service_check_execution_time' => 'ss.execution_time',
|
||||
'service_check_latency' => 'ss.latency',
|
||||
'service_notifications_enabled' => 'ss.notifications_enabled',
|
||||
'service_last_time_ok' => 'ss.last_time_ok',
|
||||
'service_last_time_warning' => 'ss.last_time_warning',
|
||||
'service_last_time_critical' => 'ss.last_time_critical',
|
||||
'service_last_time_unknown' => 'ss.last_time_unknown',
|
||||
),
|
||||
'servicegroups' => array(
|
||||
'servicegroups' => 'sgo.name1',
|
||||
)
|
||||
);
|
||||
|
||||
public function getDefaultColumns()
|
||||
{
|
||||
return $this->columnMap['services']
|
||||
+ $this->columnMap['servicestatus'];
|
||||
}
|
||||
|
||||
protected function joinBaseTables()
|
||||
{
|
||||
// TODO: Shall we always add hostobject?
|
||||
$this->baseQuery = $this->db->select()->from(
|
||||
array('so' => $this->prefix . 'objects'),
|
||||
array()
|
||||
)->join(
|
||||
array('ss' => $this->prefix . 'servicestatus'),
|
||||
'so.object_id = ss.service_object_id AND so.is_active = 1 AND so.objecttype_id = 2',
|
||||
array()
|
||||
)->join(
|
||||
array('s' => $this->prefix . 'services'),
|
||||
'ss.service_object_id = s.service_object_id',
|
||||
array()
|
||||
);
|
||||
$this->joinedVirtualTables = array(
|
||||
'services' => true,
|
||||
'servicestatus' => true,
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinStatus()
|
||||
{
|
||||
$this->requireVirtualTable('services');
|
||||
}
|
||||
|
||||
protected function joinServiceStatus()
|
||||
{
|
||||
$this->requireVirtualTable('services');
|
||||
}
|
||||
|
||||
protected function joinServices()
|
||||
{
|
||||
$this->baseQuery->join(
|
||||
array('s' => $this->prefix . 'services'),
|
||||
's.host_object_id = h.host_object_id',
|
||||
array()
|
||||
)->join(
|
||||
array('so' => $this->prefix . 'objects'),
|
||||
"so.$this->object_id = s.service_object_id AND so.is_active = 1",
|
||||
array()
|
||||
)->joinLeft(
|
||||
array('ss' => $this->prefix . 'servicestatus'),
|
||||
"so.$this->object_id = ss.service_object_id",
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinHostgroups()
|
||||
{
|
||||
if ($this->hasJoinedVirtualTable('services')) {
|
||||
return $this->joinServiceHostgroups();
|
||||
} else {
|
||||
return $this->joinHostHostgroups();
|
||||
}
|
||||
}
|
||||
|
||||
protected function joinHostHostgroups()
|
||||
{
|
||||
$this->baseQuery->join(
|
||||
array('hgm' => $this->prefix . 'hostgroup_members'),
|
||||
'hgm.host_object_id = h.host_object_id',
|
||||
array()
|
||||
)->join(
|
||||
array('hg' => $this->prefix . 'hostgroups'),
|
||||
"hgm.hostgroup_id = hg.$this->hostgroup_id",
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function joinServiceHostgroups()
|
||||
{
|
||||
$this->baseQuery->join(
|
||||
array('hgm' => $this->prefix . 'hostgroup_members'),
|
||||
'hgm.host_object_id = s.host_object_id',
|
||||
array()
|
||||
)->join(
|
||||
array('hg' => $this->prefix . 'hostgroups'),
|
||||
'hgm.hostgroup_id = hg.' . $this->hostgroup_id,
|
||||
array()
|
||||
)->join(
|
||||
array('hgo' => $this->prefix . 'objects'),
|
||||
'hgo.' . $this->object_id. ' = hg.hostgroup_object_id'
|
||||
. ' AND hgo.is_active = 1',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function joinServicegroups()
|
||||
{
|
||||
$this->requireVirtualTable('services');
|
||||
$this->baseQuery->join(
|
||||
array('sgm' => $this->prefix . 'servicegroup_members'),
|
||||
'sgm.service_object_id = s.service_object_id',
|
||||
array()
|
||||
)->join(
|
||||
array('sg' => $this->prefix . 'servicegroups'),
|
||||
'sgm.servicegroup_id = sg.' . $this->servicegroup_id,
|
||||
array()
|
||||
)->join(
|
||||
array('sgo' => $this->prefix . 'objects'),
|
||||
'sgo.' . $this->object_id. ' = sg.servicegroup_object_id'
|
||||
. ' AND sgo.is_active = 1',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ class StatusQuery extends IdoQuery
|
|||
),
|
||||
'hoststatus' => array(
|
||||
'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END',
|
||||
'host_hard_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE CASE WHEN hs.state_type = 1 THEN hs.current_state ELSE hs.last_hard_state END END',
|
||||
'host_output' => 'hs.output',
|
||||
'host_long_output' => 'hs.long_output',
|
||||
'host_perfdata' => 'hs.perfdata',
|
||||
|
@ -220,7 +221,40 @@ class StatusQuery extends IdoQuery
|
|||
'service_normal_check_interval' => 'ss.normal_check_interval',
|
||||
'service_retry_check_interval' => 'ss.retry_check_interval',
|
||||
'service_check_timeperiod_object_id' => 'ss.check_timeperiod_object_id',
|
||||
'service_status_update_time' => 'ss.status_update_time'
|
||||
'service_status_update_time' => 'ss.status_update_time',
|
||||
'service_problem' => 'CASE WHEN ss.current_state = 0 THEN 0 ELSE 1 END',
|
||||
'service_severity' => 'CASE WHEN ss.current_state = 0
|
||||
THEN
|
||||
CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL
|
||||
THEN 16
|
||||
ELSE 0
|
||||
END
|
||||
+
|
||||
CASE WHEN ss.problem_has_been_acknowledged = 1
|
||||
THEN 2
|
||||
ELSE
|
||||
CASE WHEN ss.scheduled_downtime_depth > 0
|
||||
THEN 1
|
||||
ELSE 4
|
||||
END
|
||||
END
|
||||
ELSE
|
||||
CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 16
|
||||
WHEN ss.current_state = 1 THEN 32
|
||||
WHEN ss.current_state = 2 THEN 128
|
||||
WHEN ss.current_state = 3 THEN 64
|
||||
ELSE 256
|
||||
END
|
||||
+
|
||||
CASE WHEN ss.problem_has_been_acknowledged = 1
|
||||
THEN 2
|
||||
ELSE
|
||||
CASE WHEN ss.scheduled_downtime_depth > 0
|
||||
THEN 1
|
||||
ELSE 4
|
||||
END
|
||||
END
|
||||
END'
|
||||
),
|
||||
'serviceproblemsummary' => array(
|
||||
'host_unhandled_service_count' => 'sps.unhandled_service_count'
|
||||
|
@ -230,44 +264,7 @@ class StatusQuery extends IdoQuery
|
|||
),
|
||||
'lastservicecomment' => array(
|
||||
'service_last_comment' => 'slc.comment_id'
|
||||
),
|
||||
'status' => array(
|
||||
'service_problems' => 'CASE WHEN ss.current_state = 0 THEN 0 ELSE 1 END',
|
||||
'service_handled' => 'CASE WHEN ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0 THEN 1 ELSE 0 END',
|
||||
'service_unhandled' => 'CASE WHEN ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0 THEN 1 ELSE 0 END',
|
||||
'service_severity' => 'CASE WHEN ss.current_state = 0
|
||||
THEN
|
||||
CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL
|
||||
THEN 16
|
||||
ELSE 0
|
||||
END
|
||||
+
|
||||
CASE WHEN ss.problem_has_been_acknowledged = 1
|
||||
THEN 2
|
||||
ELSE
|
||||
CASE WHEN ss.scheduled_downtime_depth > 0
|
||||
THEN 1
|
||||
ELSE 4
|
||||
END
|
||||
END
|
||||
ELSE
|
||||
CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 16
|
||||
WHEN ss.current_state = 1 THEN 32
|
||||
WHEN ss.current_state = 2 THEN 128
|
||||
WHEN ss.current_state = 3 THEN 64
|
||||
ELSE 256
|
||||
END
|
||||
+
|
||||
CASE WHEN ss.problem_has_been_acknowledged = 1
|
||||
THEN 2
|
||||
ELSE
|
||||
CASE WHEN ss.scheduled_downtime_depth > 0
|
||||
THEN 1
|
||||
ELSE 4
|
||||
END
|
||||
END
|
||||
END',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
protected function joinBaseTables()
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Criteria;
|
||||
|
||||
/**
|
||||
* Constants for filter definitions.
|
||||
* These only describe logical filter operations without going into storage specific
|
||||
* details, like which fields are used for querying. It's completely up to the query to determine what to do with these
|
||||
* constants (although the result should be consistent among the different storage apis).
|
||||
*
|
||||
*/
|
||||
class Filter
|
||||
{
|
||||
/**
|
||||
* Whether to remove or keep handled objects
|
||||
* This means objects that are currently in a downtime or problems that have been acknowledged
|
||||
*/
|
||||
const HANDLED = "handled";
|
||||
|
||||
/**
|
||||
* Whether to display problems
|
||||
* This means objects with a state higher than 0
|
||||
*/
|
||||
const PROBLEMS = "problems";
|
||||
|
||||
/**
|
||||
* Whether to limit the result to a specific hostgroup.
|
||||
* Filters usually accept an array of hostgroup names
|
||||
*/
|
||||
const HOSTGROUPS = "hostgroups";
|
||||
|
||||
/**
|
||||
* Whether to limit the result to a specific servicegroup.
|
||||
* Filters usually accept an array of servicegroup names
|
||||
*/
|
||||
const SERVICEGROUPS = "servicegroups";
|
||||
|
||||
/**
|
||||
* Defines a string based search.
|
||||
* Which objects and criterias are used have to be decided in the backend
|
||||
*/
|
||||
const SEARCH = "search";
|
||||
|
||||
const STATE = "state";
|
||||
const HOSTSTATE = "hoststate";
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Criteria;
|
||||
|
||||
/**
|
||||
* Class Order
|
||||
*
|
||||
* Constants for order definitions.
|
||||
* These only describe logical orders without going into storage specific
|
||||
* details, like which fields are used for ordering. It's completely up to the query to determine what to do with these
|
||||
* constants (although the result should be consistent among the different storage apis).
|
||||
*
|
||||
* @package Icinga\Backend\Criteria
|
||||
*/
|
||||
class Order
|
||||
{
|
||||
/**
|
||||
* Order by the newest events. What this means has to be determined in the context.
|
||||
* Mostly this affects last_state_change
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const STATE_CHANGE = "state_change";
|
||||
|
||||
/**
|
||||
* Order by the state of service objects. Mostly this is critical->unknown->warning->ok,
|
||||
* but also might take acknowledgments and downtimes in account
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SERVICE_STATE = "service_state";
|
||||
|
||||
/**
|
||||
* Order by the state of host objects. Mostly this is critical->unknown->warning->ok,
|
||||
* but also might take acknowledgments and downtimes in account
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const HOST_STATE = "host_state";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const HOST_NAME = "host_name";
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SERVICE_NAME = "service_description";
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\DataView;
|
||||
|
||||
use Icinga\Protocol\Statusdat\View\ObjectRemappingView;
|
||||
use Icinga\Protocol\Statusdat\IReader;
|
||||
|
||||
/**
|
||||
* Class StatusdatHostView
|
||||
* @package Icinga\Backend\Statusdat\DataView
|
||||
*/
|
||||
class HostStatusView extends ObjectRemappingView
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $handlerParameters = array(
|
||||
"host" => "getHost",
|
||||
"host_unhandled_service_count" => "getNrOfUnhandledServices",
|
||||
"host_last_comment" => "getLastComment",
|
||||
'host_handled' => "checkIfHandled",
|
||||
|
||||
);
|
||||
|
||||
public function checkIfHandled(&$host)
|
||||
{
|
||||
return $host->status->current_state == 0 ||
|
||||
$host->status->problem_has_been_acknowledged ||
|
||||
$host->status->scheduled_downtime_depth;
|
||||
}
|
||||
|
||||
public function getNrOfUnhandledServices(&$host)
|
||||
{
|
||||
$ct = 0;
|
||||
foreach ($host->services as &$service) {
|
||||
if ($service->status->current_state > 0
|
||||
&& $service->status->problem_has_been_acknowledged == 0
|
||||
&& $service->status->scheduled_downtime_depth == 0) {
|
||||
$ct++;
|
||||
}
|
||||
}
|
||||
return $ct;
|
||||
}
|
||||
|
||||
public function getLastComment(&$host)
|
||||
{
|
||||
if (!isset($host->comment) || empty($host->comment)) {
|
||||
return null;
|
||||
}
|
||||
$comment = end($host->comment);
|
||||
return $comment->comment_id;
|
||||
}
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $mappedParameters = array(
|
||||
"host_address" => "address",
|
||||
"host_name" => "host_name",
|
||||
"host" => "host_name",
|
||||
"host_state" => "status.current_state",
|
||||
"host_output" => "status.plugin_output",
|
||||
"host_long_output" => "status.long_plugin_output",
|
||||
"host_perfdata" => "status.performance_data",
|
||||
"host_last_state_change" => "status.last_state_change",
|
||||
"host_check_command" => "check_command",
|
||||
"host_last_check" => "TO_DATE(status.last_check)",
|
||||
"host_next_check" => "status.next_check",
|
||||
"host_check_latency" => "status.check_latency",
|
||||
"host_check_execution_time" => "status.check_execution_time",
|
||||
"host_active_checks_enabled" => "status.active_checks_enabled",
|
||||
"host_in_downtime" => "status.scheduled_downtime_depth",
|
||||
"host_is_flapping" => "status.is_flapping",
|
||||
"host_notifications_enabled"=> "status.notifications_enabled",
|
||||
"host_state_type" => "status.state_type",
|
||||
"host_icon_image" => "icon_image",
|
||||
"host_action_url" => "action_url",
|
||||
"host_notes_url" => "notes_url",
|
||||
"host_acknowledged" => "status.problem_has_been_acknowledged"
|
||||
// "state" => "current_state"
|
||||
);
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
* @return null
|
||||
*/
|
||||
public function getHost(&$item)
|
||||
{
|
||||
if (!isset($this->state["service"][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
if (!isset($this->state["host"][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
return $this->state["host"][$item->host_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IReader $reader
|
||||
*/
|
||||
public function __construct(IReader $reader)
|
||||
{
|
||||
$this->state = $reader->getState();
|
||||
}
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\DataView;
|
||||
|
||||
use Icinga\Protocol\Statusdat\View\ObjectRemappingView;
|
||||
use Icinga\Protocol\Statusdat\IReader;
|
||||
|
||||
/**
|
||||
* Class StatusdatHostView
|
||||
* @package Icinga\Backend\Statusdat\DataView
|
||||
*/
|
||||
class ServiceStatusView extends ObjectRemappingView
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $handlerParameters = array(
|
||||
"host" => "getHost",
|
||||
"host_last_comment" => "getLastHostComment",
|
||||
'host_handled' => "checkIfHostHandled",
|
||||
'service_handled' => "checkIfHandled",
|
||||
"service_last_comment" => "getLastComment"
|
||||
);
|
||||
|
||||
public function checkIfHostHandled(&$service)
|
||||
{
|
||||
return $service->host->status->current_state == 0 ||
|
||||
$service->host->status->problem_has_been_acknowledged ||
|
||||
$service->host->status->scheduled_downtime_depth;
|
||||
}
|
||||
|
||||
public function checkIfHandled(&$service)
|
||||
{
|
||||
return $service->status->current_state == 0 ||
|
||||
$service->status->problem_has_been_acknowledged ||
|
||||
$service->status->scheduled_downtime_depth;
|
||||
}
|
||||
|
||||
public function getLastComment(&$service)
|
||||
{
|
||||
if (!isset($service->comment) || empty($service->comment)) {
|
||||
return null;
|
||||
}
|
||||
$comment = end($service->comment);
|
||||
return $comment->comment_id;
|
||||
}
|
||||
|
||||
public function getLastHostComment(&$service)
|
||||
{
|
||||
if (!isset($service->host->comment) || empty($service->host->comment)) {
|
||||
return null;
|
||||
}
|
||||
$comment = end($service->host->comment);
|
||||
return $comment->comment_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $mappedParameters = array(
|
||||
"host_address" => "host.address",
|
||||
"host_name" => "host.host_name",
|
||||
"host" => "host.host_name",
|
||||
"host_state" => "host.status.current_state",
|
||||
"host_output" => "host.status.plugin_output",
|
||||
"host_long_output" => "host.status.long_plugin_output",
|
||||
"host_perfdata" => "host.status.performance_data",
|
||||
"host_last_state_change" => "host.status.last_state_change",
|
||||
"host_check_command" => "host.check_command",
|
||||
"host_last_check" => "TO_DATE(host.status.last_check)",
|
||||
"host_next_check" => "host.status.next_check",
|
||||
"host_check_latency" => "host.status.check_latency",
|
||||
"host_check_execution_time" => "host.status.check_execution_time",
|
||||
"host_active_checks_enabled" => "host.status.active_checks_enabled",
|
||||
"host_in_downtime" => "host.status.scheduled_downtime_depth",
|
||||
"host_is_flapping" => "host.status.is_flapping",
|
||||
"host_notifications_enabled" => "host.status.notifications_enabled",
|
||||
"host_state_type" => "host.status.state_type",
|
||||
"host_icon_image" => "host.icon_image",
|
||||
"host_action_url" => "host.action_url",
|
||||
"host_notes_url" => "host.notes_url",
|
||||
"host_acknowledged" => "host.status.problem_has_been_acknowledged",
|
||||
"service" => "service_description",
|
||||
"service_display_name" => "service_description",
|
||||
"service_description" => "service_description",
|
||||
"service_state" => "status.current_state",
|
||||
"service_icon_image" => "icon_image",
|
||||
"service_output" => "status.plugin_output",
|
||||
"service_long_output" => "status.long_plugin_output",
|
||||
"service_perfdata" => "status.performance_data",
|
||||
"service_last_state_change" => "status.last_state_change",
|
||||
"service_check_command" => "check_command",
|
||||
"service_last_check" => "TO_DATE(status.last_check)",
|
||||
"service_next_check" => "status.next_check",
|
||||
"service_check_latency" => "status.check_latency",
|
||||
"service_check_execution_time" => "status.check_execution_time",
|
||||
"service_active_checks_enabled" => "status.active_checks_enabled",
|
||||
"service_in_downtime" => "status.scheduled_downtime_depth",
|
||||
"service_is_flapping" => "status.is_flapping",
|
||||
"service_notifications_enabled" => "status.notifications_enabled",
|
||||
"service_state_type" => "status.state_type",
|
||||
"service_icon_image" => "icon_image",
|
||||
"service_action_url" => "action_url",
|
||||
"service_notes_url" => "notes_url",
|
||||
"service_acknowledged" => "status.problem_has_been_acknowledged",
|
||||
// "state" => "current_state"
|
||||
);
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
* @return null
|
||||
*/
|
||||
public function getHost(&$item)
|
||||
{
|
||||
if (!isset($this->state["service"][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
if (!isset($this->state["host"][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
return $this->state["host"][$item->host_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IReader $reader
|
||||
*/
|
||||
public function __construct(IReader $reader)
|
||||
{
|
||||
$this->state = $reader->getState();
|
||||
}
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\DataView;
|
||||
|
||||
use Icinga\Protocol\Statusdat\View\ObjectRemappingView;
|
||||
use \Icinga\Protocol\Statusdat\IReader;
|
||||
|
||||
class StatusdatServiceView extends ObjectRemappingView
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $handlerParameters = array(
|
||||
"host" => "getHost",
|
||||
"downtimes_with_info" => "getDowntimes"
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $mappedParameters = array(
|
||||
"host_address" => "parenthost.address",
|
||||
"host_name" => "host_name",
|
||||
"active_checks_enabled" => "status.active_checks_enabled",
|
||||
"passive_checks_enabled" => "status.passive_checks_enabled",
|
||||
"service_state" => "status.current_state",
|
||||
"service_perfdata" => "status.performance_data",
|
||||
"service_last_state_change" => "status.last_state_change",
|
||||
"service_output" => "status.plugin_output",
|
||||
"service_long_output" => "status.long_plugin_output",
|
||||
"service_check_command" => "check_command",
|
||||
"service_last_check" => "status.last_check",
|
||||
"service_next_check" => "status.next_check",
|
||||
"service_check_latency" => "status.check_latency",
|
||||
"service_check_execution_time" => "status.check_execution_time",
|
||||
"service_acknowledged" => "status.problem_has_been_acknowledged",
|
||||
"service_comments" => "comment"
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* @param \Icinga\Backend\DataView\The $item
|
||||
* @param \Icinga\Backend\DataView\The $field
|
||||
* @return \Icinga\Backend\DataView\The|string
|
||||
*/
|
||||
public function get(&$item, $field)
|
||||
{
|
||||
if (!isset($item->parenthost) && isset($this->state["host"])) {
|
||||
$item->parenthost = $this->state["host"];
|
||||
}
|
||||
|
||||
return parent::get($item, $field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Icinga\Backend\DataView\The $item
|
||||
* @param \Icinga\Backend\DataView\The $field
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(&$item, $field)
|
||||
{
|
||||
if (!isset($item->parenthost)) {
|
||||
$item->parenthost = $this->state["host"];
|
||||
}
|
||||
|
||||
return parent::exists($item, $field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
* @return null
|
||||
*/
|
||||
public function getHost(&$item)
|
||||
{
|
||||
if (!isset($this->state["host"][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
if (!isset($this->state["host"][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
return $this->state["host"][$item->host_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IReader $reader
|
||||
*/
|
||||
public function __construct(IReader $reader)
|
||||
{
|
||||
$this->state = & $reader->getState();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
*
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* Query map for comments
|
||||
*/
|
||||
class CommentQuery extends StatusdatQuery
|
||||
{
|
||||
public static $mappedParameters = array(
|
||||
'comment_id' => 'comment_id',
|
||||
'comment_internal_id' => 'comment_id',
|
||||
'comment_data' => 'comment_data',
|
||||
'comment_author' => 'author',
|
||||
'comment_timestamp' => 'entry_time',
|
||||
'comment_is_persistent' => 'persistent',
|
||||
'host_name' => 'host_name',
|
||||
'host' => 'host_name',
|
||||
);
|
||||
|
||||
public static $handlerParameters = array(
|
||||
'comment_objecttype_id' => 'getCommentObjectType',
|
||||
'comment_type' => 'getCommentType',
|
||||
'comment_expiration_timestamp' => 'getExpirationTime',
|
||||
'service' => 'getServiceDescription',
|
||||
'service_name' => 'getServiceDescription',
|
||||
'service_description' => 'getServiceDescription'
|
||||
);
|
||||
|
||||
public function getServiceDescription(&$obj)
|
||||
{
|
||||
if (isset($obj->service_description)) {
|
||||
return $obj->service_description;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getExpirationTime(&$obj)
|
||||
{
|
||||
if ($obj->expires) {
|
||||
return $obj->expire_time;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function getCommentObjectType(&$obj)
|
||||
{
|
||||
if (isset($obj->service_description)) {
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public function getCommentType(&$obj)
|
||||
{
|
||||
switch ($obj->entry_type) {
|
||||
case 1:
|
||||
return 'comment';
|
||||
case 2:
|
||||
return 'downtime';
|
||||
case 3:
|
||||
return 'flapping';
|
||||
case 4:
|
||||
return 'ack';
|
||||
}
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
public function getObjectType(&$obj)
|
||||
{
|
||||
return isset($obj->service_description) ? 'service ': 'host';
|
||||
}
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from("comments", array());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
class ContactQuery extends StatusdatQuery
|
||||
{
|
||||
public static $mappedParameters = array(
|
||||
'contact_name' => 'contact_name',
|
||||
'contact_alias' => 'alias',
|
||||
'contact_email' => 'email',
|
||||
'contact_pager' => 'pager',
|
||||
'contact_has_host_notfications' => 'host_notifications_enabled',
|
||||
'contact_has_service_notfications' => 'service_notifications_enabled',
|
||||
'contact_can_submit_commands' => 'can_submit_commands',
|
||||
'contact_notify_host_timeperiod' => 'host_notification_period',
|
||||
'contact_notify_service_timeperiod'=> 'service_notification_period',
|
||||
'contact_service_notification_options' => 'service_notification_options',
|
||||
'contact_host_notification_options' => 'host_notification_options',
|
||||
'contactgroup_name' => 'group.contactgroup_name',
|
||||
'contactgroup_alias' => 'group.alias'
|
||||
);
|
||||
|
||||
public static $handlerParameters = array(
|
||||
'contact_notify_service_recovery' => 'getServiceRecoveryFlag',
|
||||
'contact_notify_service_warning' => 'getServiceWarningFlag',
|
||||
'contact_notify_service_critical' => 'getServiceCriticalFlag',
|
||||
'contact_notify_service_unknown' => 'getServiceUnknownFlag',
|
||||
'contact_notify_service_flapping' => 'getServiceFlappingFlag',
|
||||
'contact_notify_service_downtime' => 'getServiceDowntimeFlag',
|
||||
'contact_notify_host_recovery' => 'getHostRecoveryFlag',
|
||||
'contact_notify_host_down' => 'getHostDownFlag',
|
||||
'contact_notify_host_unreachable' => 'getHostUnreachableFlag',
|
||||
'contact_notify_host_flapping' => 'getHostFlappingFlag',
|
||||
'contact_notify_host_downtime' => 'getHostDowntimeFlag',
|
||||
'host_name' => 'getHost',
|
||||
'host' => 'getHost',
|
||||
'service_host_name' => 'getHost',
|
||||
'service' => 'getService',
|
||||
'service_description' => 'getService'
|
||||
);
|
||||
|
||||
|
||||
public function getHost(&$obj)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->state['host'] as $values) {
|
||||
if (!isset($values->contacts)) {
|
||||
continue;
|
||||
}
|
||||
if (stripos($values->contacts, $obj->contacts) !== false) {
|
||||
$result[] = $values;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getService(&$obj)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->state['service'] as $values) {
|
||||
if (!isset($values->contacts)) {
|
||||
continue;
|
||||
}
|
||||
if (stripos($values->contact_groups, $obj->contacts) !== false) {
|
||||
$result[] = $values;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getServiceRecoveryFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 'r') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getServiceWarningFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 'w') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getServiceCriticalFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 'c') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getServiceUnknownFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 'u') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getServiceFlappingFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 'f') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getServiceDowntimeFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 's') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getHostRecoveryFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->host_notification_options, 'r') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getHostDownFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->host_notification_options, 'd') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getHostUnreachableFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->host_notification_options, 'u') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getHostFlappingFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->host_notification_options, 'f') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getHostDowntimeFlag(&$obj)
|
||||
{
|
||||
return strpos($obj->host_notification_options, 's') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->state = $this->ds->getState();
|
||||
$this->select()->from("contacts", array());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
class ContactgroupQuery extends StatusdatQuery
|
||||
{
|
||||
public static $mappedParameters = array(
|
||||
'contactgroup_name' => 'contactgroup_name',
|
||||
'contactgroup_alias' => 'alias',
|
||||
'contact_name' => 'contact.contact_name',
|
||||
'contact_alias' => 'contact.alias',
|
||||
'contact_email' => 'contact.email',
|
||||
'contact_pager' => 'contact.pager',
|
||||
'contact_has_host_notfications' => 'contact.host_notifications_enabled',
|
||||
'contact_has_service_notfications' => 'contact.service_notifications_enabled',
|
||||
'contact_can_submit_commands' => 'contact.can_submit_commands',
|
||||
'contact_notify_host_timeperiod' => 'contact.host_notification_period',
|
||||
'contact_notify_service_timeperiod' => 'contact.service_notification_period',
|
||||
'contact_service_notification_options' => 'contact.service_notification_options',
|
||||
'contact_host_notification_options' => 'contact.host_notification_options',
|
||||
);
|
||||
|
||||
public static $handlerParameters = array(
|
||||
'host_name' => 'getHosts',
|
||||
'host' => 'getHosts',
|
||||
'service_host_name' => 'getHosts',
|
||||
'service' => 'getService',
|
||||
'service_description' => 'getService'
|
||||
);
|
||||
|
||||
public function getHosts(&$obj)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->state['host'] as $values) {
|
||||
if (stripos($values->contact_groups, $obj->contactgroup_name) !== false) {
|
||||
$result[] = $values;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getService(&$obj)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->state['service'] as $values) {
|
||||
if (stripos($values->contact_groups, $obj->contactgroup_name) !== false) {
|
||||
$result[] = $values;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->state = $this->ds->getState();
|
||||
return $this->select()->from("contactgroups", array());
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* Icinga 2 Web - Head for multiple monitoring frontends
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* Handling downtime queries
|
||||
*/
|
||||
class DowntimeQuery extends StatusdatQuery
|
||||
{
|
||||
/**
|
||||
* Column map
|
||||
* @var array
|
||||
*/
|
||||
public static $mappedParameters = array(
|
||||
'downtime_author' => 'author',
|
||||
'downtime_comment' => 'comment',
|
||||
'downtime_duration' => 'duration',
|
||||
'downtime_end' => 'end_time',
|
||||
'downtime_was_started' => 'was_started',
|
||||
'downtime_is_fixed' => 'fixed',
|
||||
'downtime_is_in_effect' => 'is_in_effect',
|
||||
'downtime_trigger_time' => 'trigger_time',
|
||||
'downtime_triggered_by_id' => 'triggered_by_id',
|
||||
'downtime_internal_downtime_id' => 'internal_downtime_id',
|
||||
'host' => 'host_name',
|
||||
'host_name' => 'host_name',
|
||||
'service_host_name' => 'host_name',
|
||||
'service_description' => 'service_description',
|
||||
);
|
||||
|
||||
public static $handlerParameters = array(
|
||||
'object_type' => 'getObjectType',
|
||||
'downtime_start' => 'getDowntimeStart',
|
||||
'downtime_is_flexible' => 'getFlexibleFlag'
|
||||
);
|
||||
|
||||
public static $fieldTypes = array(
|
||||
'downtime_end' => self::TIMESTAMP,
|
||||
'downtime_trigger_time' => self::TIMESTAMP,
|
||||
'downtime_start' => self::TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
public function getDowntimeStart(&$obj)
|
||||
{
|
||||
if ($obj->trigger_time != '0') {
|
||||
return $obj->trigger_time;
|
||||
} else {
|
||||
return $obj->start_time;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function getFlexibleFlag(&$obj)
|
||||
{
|
||||
return $obj->fixed ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getObjectType(&$obj)
|
||||
{
|
||||
return isset($obj->service_description) ? 'service ': 'host';
|
||||
}
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from("downtimes", array());
|
||||
}
|
||||
}
|
395
modules/monitoring/library/Monitoring/Backend/Statusdat/Query/GroupsummaryQuery.php
Executable file → Normal file
395
modules/monitoring/library/Monitoring/Backend/Statusdat/Query/GroupsummaryQuery.php
Executable file → Normal file
|
@ -1,203 +1,246 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
abstract class GroupsummaryQuery extends Query
|
||||
class GroupsummaryQuery extends StatusdatQuery
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $reader;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $groupType = "servicegroup";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $base = "services";
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $available_columns = array(
|
||||
'ok' => 'SUM(CASE WHEN state = 0 THEN 1 ELSE 0 END)',
|
||||
'critical' => 'SUM(CASE WHEN state = 2 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'critical_dt' => 'SUM(CASE WHEN state = 2 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'critical_ack' => 'SUM(CASE WHEN state = 2 AND downtime = 0 AND ack = 1 THEN 1 ELSE 0 END)',
|
||||
'unknown' => 'SUM(CASE WHEN state = 3 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'unknown_dt' => 'SUM(CASE WHEN state = 3 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'unknown_ack' => 'SUM(CASE WHEN state = 3 AND downtime = 0 AND ack = 1 THEN 1 ELSE 0 END)',
|
||||
'warning' => 'SUM(CASE WHEN state = 1 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'warning_dt' => 'SUM(CASE WHEN state = 1 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'warning_ack' => 'SUM(CASE WHEN state = 1 AND downtime = 0 AND ack = 1 THEN 1 ELSE 0 END)',
|
||||
public static $mappedParameters = array(
|
||||
'hostgroup_name' => 'hostgroup_name',
|
||||
'servicegroup_name' => 'servicegroup_name'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $orderColumns = array(
|
||||
'state' => array(
|
||||
'ASC' => array(
|
||||
'ok ASC',
|
||||
'warning_dt ASC',
|
||||
'warning_ack ASC',
|
||||
'warning ASC',
|
||||
'unknown_dt ASC',
|
||||
'unknown_ack ASC',
|
||||
'unknown ASC',
|
||||
'critical_dt ASC',
|
||||
'critical_ack ASC',
|
||||
'critical ASC',
|
||||
),
|
||||
'DESC' => array(
|
||||
'critical DESC',
|
||||
'critical_ack DESC',
|
||||
'critical_dt DESC',
|
||||
'unknown DESC',
|
||||
'unknown_ack DESC',
|
||||
'unknown_dt DESC',
|
||||
'warning DESC',
|
||||
'warning_ack DESC',
|
||||
'warning_dt DESC',
|
||||
'ok DESC',
|
||||
),
|
||||
'default' => 'DESC'
|
||||
)
|
||||
public static $handlerParameters = array(
|
||||
'cnt_hosts_up' => 'getHostUpSum',
|
||||
'cnt_hosts_unreachable' => 'getHostUnreachableSum',
|
||||
'cnt_hosts_unreachable_unhandled' => 'getHostUnreachableUnhandledSum',
|
||||
'cnt_hosts_down' => 'getHostDownSum',
|
||||
'cnt_hosts_down_unhandled' => 'getHostDownUnhandledSum',
|
||||
'cnt_hosts_pending' => 'getHostPendingSum',
|
||||
'cnt_services_ok' => 'getServiceOkSum',
|
||||
'cnt_services_unknown' => 'getServiceUnknownSum',
|
||||
'cnt_services_unknown_unhandled' => 'getServiceUnknownUnhandledSum',
|
||||
'cnt_services_critical' => 'getServiceCriticalSum',
|
||||
'cnt_services_critical_unhandled' => 'getServiceCriticalUnhandledSum',
|
||||
'cnt_services_warning' => 'getServiceWarningSum',
|
||||
'cnt_services_warning_unhandled' => 'getServiceWarningUnhandledSum',
|
||||
'cnt_services_pending' => 'getServicePendingSum',
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* @param $obj
|
||||
* @return string
|
||||
*/
|
||||
private function getStateType(&$obj)
|
||||
private function getMembers(&$obj, $hint = null)
|
||||
{
|
||||
if ($obj->status->current_state == 0) {
|
||||
return "ok";
|
||||
if (!isset($obj->service) && !isset($obj->host)) {
|
||||
return null;
|
||||
}
|
||||
$typeBase = "";
|
||||
if ($obj->status->current_state == 1) {
|
||||
$typeBase = 'warning';
|
||||
} else {
|
||||
if ($obj->status->current_state == 2) {
|
||||
$typeBase = 'critical';
|
||||
$memberList = isset($obj->service) ? $obj->service : $obj->host;
|
||||
|
||||
if (isset($obj->host) && $hint == 'service') {
|
||||
$result = array();
|
||||
foreach ($memberList as &$member) {
|
||||
if (isset($member->services)) {
|
||||
$result = $result + $member->services;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
return $memberList;
|
||||
}
|
||||
|
||||
private function getMembersByCriteria(&$obj, $type, $namefield, $criteriaFn)
|
||||
{
|
||||
$memberList = $this->getMembers($obj, $type);
|
||||
if ($memberList === null) {
|
||||
return 0;
|
||||
}
|
||||
$ids = array();
|
||||
foreach ($memberList as $member) {
|
||||
$name = $member->$type->$namefield;
|
||||
if ($namefield === 'service_description') {
|
||||
$name .= ';' . $member->$type->host_name;
|
||||
}
|
||||
|
||||
if (isset($ids[$name])) {
|
||||
continue;
|
||||
} else {
|
||||
if ($obj->status->current_state == 3) {
|
||||
$typeBase = 'unknown';
|
||||
if ($criteriaFn($member->$type)) {
|
||||
$ids[$name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($obj->status->problem_has_been_acknowledged) {
|
||||
return $typeBase . "_ack";
|
||||
|
||||
} else {
|
||||
if (isset($obj->status->downtime)) {
|
||||
return $typeBase . "_dt";
|
||||
}
|
||||
}
|
||||
return $typeBase;
|
||||
return count(array_keys($ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $indices
|
||||
* @return array
|
||||
*/
|
||||
public function groupByProblemType(&$indices)
|
||||
public function getHostUpSum(&$obj)
|
||||
{
|
||||
$typename = $this->groupType . "_name";
|
||||
$result = array();
|
||||
foreach ($indices as $type => $subIndices) {
|
||||
|
||||
foreach ($subIndices as $objName) {
|
||||
|
||||
$obj = $this->reader->getObjectByName($type, $objName);
|
||||
$statetype = $this->getStateType($obj);
|
||||
foreach ($obj->group as $group) {
|
||||
if (!isset($result[$group])) {
|
||||
$result[$group] = (object)array(
|
||||
$typename => $group,
|
||||
'ok' => 0,
|
||||
'critical' => 0,
|
||||
'critical_dt' => 0,
|
||||
'critical_ack' => 0,
|
||||
'unknown' => 0,
|
||||
'unknown_dt' => 0,
|
||||
'unknown_ack' => 0,
|
||||
'warning' => 0,
|
||||
'warning_dt' => 0,
|
||||
'warning_ack' => 0
|
||||
);
|
||||
}
|
||||
$result[$group]->$statetype++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($result);
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return ($member->status->current_state == 0
|
||||
&& $member->status->has_been_checked);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @var \Icinga\Protocol\Statusdat\Query
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function init()
|
||||
public function getHostUnreachableSum(&$obj)
|
||||
{
|
||||
$this->reader = $this->ds->getReader();
|
||||
$this->query = $this->reader->select()->from($this->base, array())->groupByFunction(
|
||||
"groupByProblemType",
|
||||
$this
|
||||
)->where("COUNT{group} > 0");
|
||||
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return ($member->status->current_state == 2
|
||||
&& $member->status->has_been_checked
|
||||
&& (
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param The $column
|
||||
* @param null $value
|
||||
* @return $this|Query
|
||||
*/
|
||||
public function where($column, $value = null)
|
||||
public function getHostUnreachableUnhandledSum(&$obj)
|
||||
{
|
||||
if ($column === 'problems') {
|
||||
if ($value === 'true') {
|
||||
//$this->where(
|
||||
// "COUNT{downtime} == 0 AND status.problem_has_been_acknowledged == 0 AND status.current_state > 0"
|
||||
// );
|
||||
}
|
||||
} elseif ($column === 'search') {
|
||||
if ($value) {
|
||||
$this->where($this->name_alias . ' LIKE ?', '%' . $value . '%');
|
||||
}
|
||||
} else {
|
||||
parent::where($column, $value);
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return ($member->status->current_state == 2
|
||||
&& $member->status->has_been_checked
|
||||
&& !(
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getHostDownSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return ($member->status->current_state == 1
|
||||
&& $member->status->has_been_checked
|
||||
&& (
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getHostDownUnhandledSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return ($member->status->current_state == 1
|
||||
&& $member->status->has_been_checked
|
||||
&& !(
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getHostPendingSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return (!$member->status->has_been_checked);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceOkSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 0
|
||||
&& $member->status->has_been_checked);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceUnknownSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
|
||||
return ($member->status->current_state == 3
|
||||
&& $member->status->has_been_checked
|
||||
&& (
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceUnknownUnhandledSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 3
|
||||
&& $member->status->has_been_checked
|
||||
&& !(
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceCriticalSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 2
|
||||
&& $member->status->has_been_checked
|
||||
&& (
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceCriticalUnhandledSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 2
|
||||
&& $member->status->has_been_checked
|
||||
&& !(
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceWarningSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 1
|
||||
&& $member->status->has_been_checked
|
||||
&& !(
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceWarningUnhandledSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 1
|
||||
&& $member->status->has_been_checked
|
||||
&& (
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServicePendingSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return (!$member->status->has_been_checked);
|
||||
});
|
||||
}
|
||||
|
||||
private function getTarget()
|
||||
{
|
||||
if (in_array('servicegroup_name', $this->getColumns())) {
|
||||
return 'servicegroups';
|
||||
}
|
||||
return $this;
|
||||
return "hostgroups";
|
||||
}
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from($this->getTarget(), array());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* Class HostgroupsummaryQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class HostgroupQuery extends StatusdatQuery
|
||||
{
|
||||
public static $mappedParameters = array(
|
||||
'hostgroups' => 'hostgroup_name',
|
||||
'hostgroup_name' => 'hostgroup_name',
|
||||
'hostgroup_alias' => 'alias',
|
||||
'host' => 'host.host_name',
|
||||
'host_name' => 'host.host_name'
|
||||
);
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from("hostgroups", array());
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ use Icinga\Exception;
|
|||
* Class HostListQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class HostListQuery extends Query
|
||||
class HostListQuery extends StatusdatQuery
|
||||
{
|
||||
/**
|
||||
* @var \Icinga\Protocol\Statusdat\Query
|
||||
|
@ -50,9 +50,8 @@ class HostListQuery extends Query
|
|||
/**
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function init()
|
||||
public function selectBase()
|
||||
{
|
||||
$this->reader = $this->backend->getReader();
|
||||
$this->query = $this->reader->select()->from("hosts", array());
|
||||
$this->select()->from("hosts", array());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,327 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
use Icinga\Data\Optional;
|
||||
use Icinga\Data\The;
|
||||
use Icinga\Filter\Query\Node;
|
||||
use Icinga\Filter\Query\Tree;
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Exception;
|
||||
use Icinga\Data\BaseQuery;
|
||||
use Icinga\Protocol\Statusdat\View\MonitoringObjectList as MList;
|
||||
use Icinga\Protocol\Statusdat\Query as StatusdatQuery;
|
||||
use Icinga\Filter\Filterable;
|
||||
|
||||
/**
|
||||
* Class Query
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
abstract class Query extends BaseQuery implements Filterable
|
||||
{
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $cursor = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $viewClass = '\Icinga\Module\Monitoring\Backend\Statusdat\DataView\StatusdatServiceView';
|
||||
private $baseQuery = null;
|
||||
|
||||
public function setBaseQuery(StatusdatQuery $query)
|
||||
{
|
||||
$this->baseQuery = $query;
|
||||
}
|
||||
|
||||
public function setResultViewClass($viewClass)
|
||||
{
|
||||
$this->viewClass = '\Icinga\Module\Monitoring\Backend\Statusdat\DataView\\'.$viewClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the apply%Filtername%Filter() method for the given filter, or simply calls
|
||||
* where(), if the method is not available.
|
||||
*
|
||||
* @see \Icinga\Backend\Query For the parent definition
|
||||
*
|
||||
* @param array $filters An array of "filtername"=>"value" definitions
|
||||
*
|
||||
* @return Query Returns the query object to allow fluent calls
|
||||
*/
|
||||
public function applyFilters(array $filters = array())
|
||||
{
|
||||
foreach ($filters as $filter => $value) {
|
||||
$filter[0] = strtoupper($filter[0]);
|
||||
$filterMethod = "apply" . $filter . "Filter";
|
||||
if (method_exists($this, $filterMethod)) {
|
||||
$this->$filterMethod($filter, $value);
|
||||
} else {
|
||||
$this->where($filter, $value);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a filter to only show open problems, or non problems, depending whether value is true or false
|
||||
*
|
||||
* @param $type ignored
|
||||
* @param $value Whether problems should be shown (1) or non problems (0)
|
||||
*/
|
||||
public function applyProblemsFilter($type, $value)
|
||||
{
|
||||
if ($value) { // Status.dat only contains active downtimes
|
||||
$value = array(1, 0);
|
||||
$this->where("(status.current_state >= ? and COUNT{status.downtime} = ? )", $value);
|
||||
} else {
|
||||
$value = array(0, 1);
|
||||
$this->where("(status.current_state < 1 or COUNT{status.downtime} > ? )", $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic object search by host name, service description and plugin output
|
||||
*
|
||||
* @param $type ignored
|
||||
* @param $value The string to search for
|
||||
*/
|
||||
public function applySearchFilter($type, $value)
|
||||
{
|
||||
$text = "%$value%";
|
||||
$val = array($text, $text, $text);
|
||||
|
||||
$this->baseQuery->where("(host_name LIKE ? OR service_description LIKE ? OR status.plugin_output LIKE ?)", $val);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a hostgroup filter on this object
|
||||
*
|
||||
* @param $type ignored
|
||||
* @param $value The hostgroup to filter for
|
||||
*/
|
||||
public function applyHostgroupsFilter($type, $value)
|
||||
{
|
||||
$filter = array($value);
|
||||
$this->baseQuery->where("host.group IN ?", $filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a servicegroup filter on this object
|
||||
*
|
||||
* @param $type ignored
|
||||
* @param $value The servicegroup to filter for
|
||||
*/
|
||||
public function applyServicegroupsFilter($type, $value)
|
||||
{
|
||||
$filter = array($value);
|
||||
$this->baseQuery->where("group IN ?", $filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters by handled problems or unhandled
|
||||
*
|
||||
* @todo: Add downtime
|
||||
* @param $type
|
||||
* @param $value Whether to search for unhandled (0) or handled (1)
|
||||
*/
|
||||
public function applyHandledFilter($type, $value)
|
||||
{
|
||||
$val = array($value, $value);
|
||||
$this->baseQuery->where("(status.problem_has_been_acknowledged = ? )", $val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $value
|
||||
*/
|
||||
public function applyHostnameFilter($type, $value)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
$value = array($value);
|
||||
}
|
||||
$this->baseQuery->where("host_name LIKE ?", $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $value
|
||||
*/
|
||||
public function applyStateFilter($type, $value)
|
||||
{
|
||||
$this->baseQuery->where("status.current_state = $value");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $value
|
||||
*/
|
||||
public function applyHoststateFilter($type, $value)
|
||||
{
|
||||
$this->baseQuery->where("host.status.current_state = $value");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $value
|
||||
*/
|
||||
public function applyServiceDescriptionFilter($type, $value)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
$value = array($value);
|
||||
}
|
||||
$this->baseQuery->where("service_description LIKE ?", $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits this query and offsets it
|
||||
* @param null|integer $count The maximum element count to display
|
||||
* @param null|integer $offset The offset to start counting
|
||||
* @return Query This object, for fluent interface
|
||||
*/
|
||||
public function limit($count = null, $offset = null)
|
||||
{
|
||||
$this->baseQuery->limit($count, $offset);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orders the resultset
|
||||
*
|
||||
* @param string $column Either a string in the 'FIELD ASC/DESC format or only the field
|
||||
* @param null $dir 'asc' or 'desc'
|
||||
* @return Query Returns this query,for fluent interface
|
||||
*/
|
||||
public function order($column = '', $dir = null)
|
||||
{
|
||||
|
||||
if ($column) {
|
||||
$class = $this->viewClass;
|
||||
$this->baseQuery->order($class::$mappedParameters[$column], strtolower($dir));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a filter on this query by calling the statusdat where() function
|
||||
*
|
||||
* @param $column The (statusdat!) column to filter in "field operator ?"
|
||||
* format. (@example status.current_state > ?)
|
||||
* @param mixed $value The value to filter for
|
||||
* @return Query Returns this query,for fluent interface
|
||||
*/
|
||||
public function where($column, $value = null)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
$value = array($value);
|
||||
}
|
||||
$this->baseQuery->where($column, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MList|mixed|null
|
||||
*/
|
||||
public function fetchAll()
|
||||
{
|
||||
$view = $this->viewClass;
|
||||
if (!$this->cursor) {
|
||||
$result = $this->baseQuery->getResult();
|
||||
$this->cursor = new MList($result, new $view($this->reader));
|
||||
}
|
||||
return $this->cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchRow()
|
||||
{
|
||||
return next($this->fetchAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function fetchPairs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
return next($this->fetchAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|mixed
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->baseQuery->getResult());
|
||||
}
|
||||
|
||||
public function isValidFilterTarget($field)
|
||||
{
|
||||
// TODO: Implement isValidFilterTarget() method.
|
||||
}
|
||||
|
||||
public function getMappedField($field)
|
||||
{
|
||||
// TODO: Implement getMappedField() method.
|
||||
}
|
||||
|
||||
public function applyFilter()
|
||||
{
|
||||
// TODO: Implement applyFilter() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a backend specific filter expression and return a Query\Node object
|
||||
*
|
||||
* @param $expression The expression to parse
|
||||
* @param $parameters Optional parameters for the expression
|
||||
* @return Node A query node or null if it's an invalid expression
|
||||
*/
|
||||
protected function parseFilterExpression($expression, $parameters = null)
|
||||
{
|
||||
// TODO: Implement parseFilterExpression() method.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* Class HostgroupsummaryQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class ServicegroupQuery extends StatusdatQuery
|
||||
{
|
||||
public static $mappedParameters = array(
|
||||
'servicegroups' => 'servicegroup_name',
|
||||
'servicegroup_name' => 'servicegroup_name',
|
||||
'servicegroup_alias' => 'alias',
|
||||
'host' => 'service.host_name',
|
||||
'host_name' => 'service.host_name',
|
||||
'service' => 'service.service_description',
|
||||
'service_description'=> 'service.service_description'
|
||||
|
||||
);
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from("servicegroups", array());
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ use Icinga\Exception;
|
|||
* Class ServicelistQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class ServicelistQuery extends Query
|
||||
class ServicelistQuery extends StatusdatQuery
|
||||
{
|
||||
/**
|
||||
* @var \Icinga\Protocol\Statusdat\Query
|
||||
|
@ -47,9 +47,8 @@ class ServicelistQuery extends Query
|
|||
*/
|
||||
protected $view = 'Icinga\Backend\Statusdat\DataView\StatusdatServiceView';
|
||||
|
||||
public function init()
|
||||
public function selectBase()
|
||||
{
|
||||
$this->reader = $this->backend->getReader();
|
||||
$this->query = $this->reader->select()->from("services", array());
|
||||
$this->select()->from("services", array());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,27 +10,344 @@
|
|||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Protocol\Statusdat\IReader;
|
||||
use Icinga\Exception;
|
||||
|
||||
class StatusQuery extends Query
|
||||
class StatusQuery extends StatusdatQuery
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $mappedParameters = array(
|
||||
'host' => 'host.host_name',
|
||||
'host_name' => 'host.host_name',
|
||||
'host_display_name' => 'host.host_name',
|
||||
'host_alias' => 'host.alias',
|
||||
'host_address' => 'host.address',
|
||||
'host_icon_image' => 'host.icon_image',
|
||||
'host_action_url' => 'host.action_url',
|
||||
'host_notes_url' => 'host.notes_url',
|
||||
'host_output' => 'host.status.plugin_output',
|
||||
'host_long_output' => 'host.status.long_plugin_output',
|
||||
'host_perfdata' => 'host.status.performance_data',
|
||||
'host_acknowledged' => 'host.status.problem_has_been_acknowledged',
|
||||
'host_last_state_change' => 'host.status.last_state_change',
|
||||
'host_last_hard_state' => 'host.status.last_hard_state',
|
||||
'host_last_hard_state_change' => 'host.status.last_hard_state_change',
|
||||
'host_check_command' => 'host.status.check_command',
|
||||
'host_last_check' => 'host.status.last_check',
|
||||
'host_next_check' => 'host.status.next_check',
|
||||
'host_check_execution_time' => 'host.status.check_execution_time',
|
||||
'host_check_latency' => 'host.status.check_latency',
|
||||
'host_notifications_enabled' => 'host.status.notifications_enabled',
|
||||
'host_last_time_up' => 'host.status.last_time_up',
|
||||
'host_last_time_down' => 'host.status.last_time_down',
|
||||
'host_last_time_unreachable' => 'host.status.last_time_unreachable',
|
||||
'host_current_check_attempt' => 'host.status.current_attempt',
|
||||
'host_max_check_attempts' => 'host.status.max_attempts',
|
||||
'host_check_type' => 'host.status.check_type',
|
||||
'host_state_type' => 'host.status.state_type',
|
||||
'host_last_notification' => 'host.status.last_notification',
|
||||
'host_next_notification' => 'host.status.next_notification',
|
||||
'host_no_more_notifications' => 'host.status.no_more_notifications',
|
||||
'host_problem_has_been_acknowledged' => 'host.status.problem_has_been_acknowledged',
|
||||
'host_acknowledgement_type' => 'host.status.acknowledgement_type',
|
||||
'host_current_notification_number' => 'host.status.current_notification_number',
|
||||
'host_passive_checks_enabled' => 'host.status.passive_checks_enabled',
|
||||
'host_active_checks_enabled' => 'host.status.active_checks_enabled',
|
||||
'host_event_handler_enabled' => 'host.status.event_handler_enabled',
|
||||
'host_flap_detection_enabled' => 'host.status.flap_detection_enabled',
|
||||
'host_is_flapping' => 'host.status.is_flapping',
|
||||
'host_percent_state_change' => 'host.status.percent_state_change',
|
||||
'host_scheduled_downtime_depth' => 'host.status.scheduled_downtime_depth',
|
||||
'host_failure_prediction_enabled' => 'host.status.failure_prediction_enabled',
|
||||
'host_process_performance_data' => 'host.status.process_performance_data',
|
||||
'host_obsessing' => 'host.status.obsess_over_host',
|
||||
'host_modified_host_attributes' => 'host.status.modified_host_attributes',
|
||||
'host_event_handler' => 'host.status.event_handler',
|
||||
'host_check_command' => 'host.status.check_command',
|
||||
'host_normal_check_interval' => 'host.status.normal_check_interval',
|
||||
'host_retry_check_interval' => 'host.status.retry_check_interval',
|
||||
'host_check_timeperiod_object_id' => 'host.status.check_timeperiod_object_id',
|
||||
'host_status_update_time' => 'host.status.status_update_time',
|
||||
|
||||
'service_host_name' => 'service.host_name',
|
||||
'service' => 'service.service_description',
|
||||
'service_description' => 'service.service_description',
|
||||
'service_display_name' => 'service.service_description',
|
||||
'service_icon_image' => 'service.icon_image',
|
||||
'service_action_url' => 'service.action_url',
|
||||
'service_notes_url' => 'service.notes_url',
|
||||
'service_state_type' => 'service.status.state_type',
|
||||
'service_output' => 'service.status.output',
|
||||
'service_long_output' => 'service.status.long_output',
|
||||
'service_perfdata' => 'service.status.perfdata',
|
||||
'service_acknowledged' => 'service.status.problem_has_been_acknowledged',
|
||||
'service_last_state_change' => 'service.status.last_state_change',
|
||||
'service_check_command' => 'service.status.check_command',
|
||||
'service_last_time_ok' => 'service.status.last_time_ok',
|
||||
'service_last_time_warning' => 'service.status.last_time_warning',
|
||||
'service_last_time_critical' => 'service.status.last_time_critical',
|
||||
'service_last_time_unknown' => 'service.status.last_time_unknown',
|
||||
'service_current_check_attempt' => 'service.status.current_check_attempt',
|
||||
'service_max_check_attempts' => 'service.status.max_check_attempts',
|
||||
'service_last_check' => 'service.status.last_check',
|
||||
'service_next_check' => 'service.status.next_check',
|
||||
'service_check_type' => 'service.status.check_type',
|
||||
'service_last_hard_state_change' => 'service.status.last_hard_state_change',
|
||||
'service_last_hard_state' => 'service.status.last_hard_state',
|
||||
'service_last_notification' => 'service.status.last_notification',
|
||||
'service_next_notification' => 'service.status.next_notification',
|
||||
'service_no_more_notifications' => 'service.status.no_more_notifications',
|
||||
'service_notifications_enabled' => 'service.status.notifications_enabled',
|
||||
'service_problem_has_been_acknowledged' => 'service.status.problem_has_been_acknowledged',
|
||||
'service_acknowledgement_type' => 'service.status.acknowledgement_type',
|
||||
'service_current_notification_number' => 'service.status.current_notification_number',
|
||||
'service_passive_checks_enabled' => 'service.status.passive_checks_enabled',
|
||||
'service_active_checks_enabled' => 'service.status.active_checks_enabled',
|
||||
'service_event_handler_enabled' => 'service.status.event_handler_enabled',
|
||||
'service_flap_detection_enabled' => 'service.status.flap_detection_enabled',
|
||||
'service_is_flapping' => 'service.status.is_flapping',
|
||||
'service_percent_state_change' => 'service.status.percent_state_change',
|
||||
'service_check_latency' => 'service.status.latency',
|
||||
'service_check_execution_time' => 'service.status.execution_time',
|
||||
'service_scheduled_downtime_depth' => 'service.status.scheduled_downtime_depth',
|
||||
'service_failure_prediction_enabled' => 'service.status.failure_prediction_enabled',
|
||||
'service_process_performance_data' => 'service.status.process_performance_data',
|
||||
'service_obsessing' => 'service.status.obsess_over_service',
|
||||
'service_modified_service_attributes' => 'service.status.modified_service_attributes',
|
||||
'service_event_handler' => 'service.status.event_handler',
|
||||
'service_check_command' => 'service.status.check_command',
|
||||
'service_normal_check_interval' => 'service.status.normal_check_interval',
|
||||
'service_retry_check_interval' => 'service.status.retry_check_interval',
|
||||
'service_check_timeperiod_object_id' => 'service.status.check_timeperiod_object_id',
|
||||
'service_status_update_time' => 'service.status.status_update_time',
|
||||
'hostgroups' => 'host.group',
|
||||
'servicegroups' => 'service.group'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $handlerParameters = array(
|
||||
'host_ipv4' => 'getAddress',
|
||||
'host_unhandled_service_count' => 'getNrOfUnhandledServices',
|
||||
'host_last_comment' => 'getLastComment',
|
||||
'service_last_comment' => 'getLastComment',
|
||||
'host_state' => 'getStateForHost',
|
||||
'host_hard_state' => 'getHardStateForHost',
|
||||
'host_handled' => 'isHandledForHost',
|
||||
'host_severity' => 'getSeverityForHost',
|
||||
'host_in_downtime' => 'isInDowntimeForHost',
|
||||
'host_problem' => 'isProblemForHost',
|
||||
'host_attempt' => 'getAttemptStringForHost',
|
||||
'service_state' => 'getState',
|
||||
'service_hard_state' => 'getHardState',
|
||||
'service_handled' => 'isHandled',
|
||||
'service_severity' => 'getSeverity',
|
||||
'service_in_downtime' => 'isInDowntime',
|
||||
'service_problem' => 'isProblem',
|
||||
'service_attempt' => 'getAttemptString'
|
||||
);
|
||||
|
||||
public static $fieldTypes = array(
|
||||
'host_last_state_change' => self::TIMESTAMP,
|
||||
'host_last_hard_state_change' => self::TIMESTAMP,
|
||||
'host_last_check' => self::TIMESTAMP,
|
||||
'host_next_check' => self::TIMESTAMP,
|
||||
'host_last_time_up' => self::TIMESTAMP,
|
||||
'host_last_time_down' => self::TIMESTAMP,
|
||||
'host_last_time_unreachable' => self::TIMESTAMP,
|
||||
'host_status_update_time' => self::TIMESTAMP,
|
||||
'service_last_state_change' => self::TIMESTAMP,
|
||||
'service_last_hard_state_change' => self::TIMESTAMP,
|
||||
'service_last_check' => self::TIMESTAMP,
|
||||
'service_next_check' => self::TIMESTAMP,
|
||||
'service_last_time_ok' => self::TIMESTAMP,
|
||||
'service_last_time_warning' => self::TIMESTAMP,
|
||||
'service_last_time_critical' => self::TIMESTAMP,
|
||||
'service_last_time_unknown' => self::TIMESTAMP,
|
||||
'service_status_update_time' => self::TIMESTAMP
|
||||
);
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$target = $this->getTarget();
|
||||
$this->select()->from($target."s", array());
|
||||
}
|
||||
|
||||
public function getAttemptString(&$obj)
|
||||
{
|
||||
return $obj->status->current_attempt . '/' . $obj->status->max_attempts;
|
||||
}
|
||||
|
||||
public function isProblem(&$obj)
|
||||
{
|
||||
return $obj->status->current_state > 0;
|
||||
}
|
||||
|
||||
public function isInDowntime(&$obj)
|
||||
{
|
||||
return $obj->status->scheduled_downtime_depth > 0;
|
||||
}
|
||||
|
||||
public function getAddress(&$obj)
|
||||
{
|
||||
return inet_pton($obj->host->address);
|
||||
}
|
||||
|
||||
public function getState(&$obj)
|
||||
{
|
||||
if (!$obj->status->has_been_checked) {
|
||||
return 99;
|
||||
}
|
||||
return $obj->status->current_state;
|
||||
}
|
||||
|
||||
public function getHardState(&$obj)
|
||||
{
|
||||
if (!$obj->status->has_been_checked) {
|
||||
return 99;
|
||||
} else {
|
||||
if ($obj->status->state_type == 1) {
|
||||
return $this->status->current_state;
|
||||
} else {
|
||||
return $this->status->last_hard_state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function getSeverity(&$host)
|
||||
{
|
||||
$status = $host->status;
|
||||
$severity = 0;
|
||||
|
||||
if (!$status->has_been_checked) {
|
||||
$severity += 16;
|
||||
} elseif($status->current_state == 0) {
|
||||
return $severity;
|
||||
} elseif ($status->current_state == 1) {
|
||||
$severity += 32;
|
||||
} elseif ($status->current_state == 2) {
|
||||
$severity += 64;
|
||||
} else {
|
||||
$severity += 256;
|
||||
}
|
||||
|
||||
if ($status->problem_has_been_acknowledged == 1) {
|
||||
$severity += 2;
|
||||
} elseif ($status->scheduled_downtime_depth > 0) {
|
||||
$severity += 1;
|
||||
} else {
|
||||
$severity += 4;
|
||||
}
|
||||
|
||||
return $severity;
|
||||
}
|
||||
|
||||
public function isHandled(&$host)
|
||||
{
|
||||
|
||||
return $host->status->current_state == 0 ||
|
||||
$host->status->problem_has_been_acknowledged ||
|
||||
$host->status->scheduled_downtime_depth;
|
||||
}
|
||||
|
||||
public function getNrOfUnhandledServices(&$obj)
|
||||
{
|
||||
$host = &$obj->host;
|
||||
$ct = 0;
|
||||
if (!isset($host->services)) {
|
||||
return $ct;
|
||||
}
|
||||
foreach ($host->services as &$service) {
|
||||
if ($service->status->current_state > 0
|
||||
&& $service->status->problem_has_been_acknowledged == 0
|
||||
&& $service->status->scheduled_downtime_depth == 0) {
|
||||
$ct++;
|
||||
}
|
||||
}
|
||||
return $ct;
|
||||
}
|
||||
|
||||
public function getLastComment(&$host)
|
||||
{
|
||||
if (!isset($host->comment) || empty($host->comment)) {
|
||||
return null;
|
||||
}
|
||||
$comment = end($host->comment);
|
||||
return $comment->comment_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
* @return null
|
||||
*/
|
||||
public function getHost(&$item)
|
||||
{
|
||||
if (!isset($this->state['service'][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
if (!isset($this->state['host'][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
return $this->state['host'][$item->host_name];
|
||||
}
|
||||
|
||||
|
||||
private function getTarget()
|
||||
{
|
||||
foreach($this->getColumns() as $column) {
|
||||
if(preg_match("/^service/",$column))
|
||||
foreach ($this->getColumns() as $column) {
|
||||
if (preg_match("/^service/",$column)) {
|
||||
return "service";
|
||||
}
|
||||
}
|
||||
|
||||
return "host";
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$target = $this->getTarget();
|
||||
$this->reader = $this->ds;
|
||||
$this->setResultViewClass(ucfirst($target)."StatusView");
|
||||
$this->setBaseQuery($this->reader->select()->from($target."s", array()));
|
||||
|
||||
public function getStateForHost(&$obj)
|
||||
{
|
||||
return $this->getState($obj->host);
|
||||
}
|
||||
|
||||
public function getHardStateForHost(&$obj)
|
||||
{
|
||||
return $this->getHardState($obj->host);
|
||||
}
|
||||
|
||||
public function isHandledForHost(&$obj)
|
||||
{
|
||||
return $this->isHandled($obj->host);
|
||||
}
|
||||
|
||||
public function getSeverityForHost(&$obj)
|
||||
{
|
||||
return $this->getSeverity($obj->host);
|
||||
}
|
||||
|
||||
public function isInDowntimeForHost(&$obj)
|
||||
{
|
||||
return $this->isInDowntime($obj->host);
|
||||
}
|
||||
|
||||
public function isProblemForHost(&$obj)
|
||||
{
|
||||
return $this->isProblem($obj->host);
|
||||
}
|
||||
|
||||
public function getAttemptStringForHost(&$obj)
|
||||
{
|
||||
return $this->getAttemptStringForHost($obj->host);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -26,49 +26,95 @@
|
|||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\View;
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
use Icinga\Application\Logger;
|
||||
use Icinga\Data\Optional;
|
||||
use Icinga\Data\The;
|
||||
use Icinga\Filter\Query\Node;
|
||||
use Icinga\Filter\Query\Tree;
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Exception;
|
||||
use Icinga\Data\BaseQuery;
|
||||
use Icinga\Protocol\Statusdat\Query as Query;
|
||||
use Icinga\Protocol\Statusdat\View\AccessorStrategy;
|
||||
use Icinga\Filter\Filterable;
|
||||
|
||||
/**
|
||||
* Class ObjectRemappingView
|
||||
*
|
||||
* Dataview that maps generic field names to storage specific fields or requests them via handlers.
|
||||
*
|
||||
* When accessing objects, every storage api returns them with other names. You can't simply say
|
||||
* $object->service_state, because this field is, e.g. under status.current_state in the status.dat
|
||||
* view, while IDO uses servicestate->current_state.
|
||||
*
|
||||
* This view is intended for normalizing these changes, so a request of service_state returns the
|
||||
* right field for the backend. When implementing it, you have to fill the mappedParameters and/or
|
||||
* the handlerParameters array. While mappedParameters simply translate logic field names to
|
||||
* storage specific ones, handlerParameters determins functions that handle data retrieval for
|
||||
* the specific fields.
|
||||
*
|
||||
* Class Query
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
|
||||
class ObjectRemappingView implements AccessorStrategy
|
||||
abstract class StatusdatQuery extends Query implements Filterable, AccessorStrategy
|
||||
{
|
||||
const TIMESTAMP = 'timestamp';
|
||||
|
||||
/**
|
||||
* When implementing your own Mapper, this contains the static mapping rules.
|
||||
* @see Icinga\Module\Monitoring\Backend\Statusdat\DataView\StatusdatServiceView for an example
|
||||
* An array containing the mappi
|
||||
*
|
||||
* When implementing your own Mapper, this contains the static mapping rules.
|
||||
*
|
||||
* @see Icinga\Module\Monitoring\Backend\Statusdat\DataView\StatusdatServiceView for an example
|
||||
* @var array
|
||||
*/
|
||||
public static $mappedParameters = array();
|
||||
|
||||
/**
|
||||
* An array containing all properties that are retrieved by a function
|
||||
*
|
||||
* When implementing your own Mapper, this contains the handler for specific fields and allows you to lazy load
|
||||
* different fields if necessary. The methods are strings that will be mapped to methods of this class
|
||||
*
|
||||
* @var array
|
||||
* @see Icinga\Backend\Statusdat\DataView\StatusdatServiceView for an example
|
||||
*/
|
||||
public static $handlerParameters = array();
|
||||
|
||||
public static $fieldTypes = array();
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $cursor = null;
|
||||
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
$this->selectBase();
|
||||
}
|
||||
|
||||
abstract public function selectBase();
|
||||
|
||||
/**
|
||||
* Orders the resultset
|
||||
*
|
||||
* @param string $column Either a string in the 'FIELD ASC/DESC format or only the field
|
||||
* @param null $dir 'asc' or 'desc'
|
||||
* @return Query Returns this query,for fluent interface
|
||||
*/
|
||||
public function order($column, $dir = null, $isFunction = false)
|
||||
{
|
||||
|
||||
if ($column) {
|
||||
$column = strval($column);
|
||||
if (isset(static::$mappedParameters[$column])) {
|
||||
parent::order(static::$mappedParameters[$column], strtolower($dir));
|
||||
} elseif (isset(static::$handlerParameters[$column])) {
|
||||
parent::orderByFn(array($this, static::$handlerParameters[$column]), strtolower($dir));
|
||||
} else {
|
||||
Logger::info("Tried to sort by unknown column %s", $column);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private $functionMap = array(
|
||||
"TO_DATE" => "toDateFormat"
|
||||
);
|
||||
|
||||
/**
|
||||
* When implementing your own Mapper, this contains the handler for specific fields and allows you to lazy load
|
||||
* different fields if necessary. The methods are strings that will be mapped to methods of this class
|
||||
*
|
||||
* @see Icinga\Backend\Statusdat\DataView\StatusdatServiceView for an example
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $handlerParameters = array();
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -81,19 +127,17 @@ class ObjectRemappingView implements AccessorStrategy
|
|||
*/
|
||||
public function get(&$item, $field)
|
||||
{
|
||||
|
||||
$result = null;
|
||||
if (isset($item->$field)) {
|
||||
return $item->$field;
|
||||
}
|
||||
if (isset(static::$mappedParameters[$field])) {
|
||||
return $this->getMappedParameter($item, $field);
|
||||
$result = $item->$field;
|
||||
} elseif (isset(static::$mappedParameters[$field])) {
|
||||
$result = $this->getMappedParameter($item, $field);
|
||||
} elseif (isset(static::$handlerParameters[$field])) {
|
||||
$hdl = static::$handlerParameters[$field];
|
||||
$result = $this->$hdl($item);
|
||||
}
|
||||
|
||||
if (isset($this->handlerParameters[$field])) {
|
||||
$hdl = $this->handlerParameters[$field];
|
||||
return $this->$hdl($item);
|
||||
}
|
||||
throw new \InvalidArgumentException("Field $field does not exist for status.dat services");
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function applyPropertyFunction($function, $value)
|
||||
|
@ -119,6 +163,7 @@ class ObjectRemappingView implements AccessorStrategy
|
|||
{
|
||||
$matches = array();
|
||||
$fieldDef = static::$mappedParameters[$field];
|
||||
|
||||
$function = false;
|
||||
if (preg_match_all('/(?P<FUNCTION>\w+)\((?P<PARAMETER>.*)\)/', $fieldDef, $matches)) {
|
||||
$function = $matches["FUNCTION"][0];
|
||||
|
@ -128,11 +173,23 @@ class ObjectRemappingView implements AccessorStrategy
|
|||
$res = $item;
|
||||
|
||||
foreach ($mapped as $map) {
|
||||
if (!isset($res->$map)) {
|
||||
return "";
|
||||
if (is_array($res)) {
|
||||
$subResult = array();
|
||||
foreach ($res as $subitem) {
|
||||
if (!isset($subitem->$map)) {
|
||||
continue;
|
||||
}
|
||||
$subResult[] = $subitem->$map;
|
||||
}
|
||||
$res = join(',', $subResult);
|
||||
} else {
|
||||
if (!isset($res->$map)) {
|
||||
return "";
|
||||
}
|
||||
$res = $res->$map;
|
||||
}
|
||||
$res = $res->$map;
|
||||
}
|
||||
|
||||
if ($function) {
|
||||
return $this->applyPropertyFunction($function, $res);
|
||||
}
|
||||
|
@ -146,7 +203,7 @@ class ObjectRemappingView implements AccessorStrategy
|
|||
* @param The $field
|
||||
* @return The|string
|
||||
*/
|
||||
public function getNormalizedFieldName($field)
|
||||
public function getMappedField($field)
|
||||
{
|
||||
if (isset(static::$mappedParameters[$field])) {
|
||||
return static::$mappedParameters[$field];
|
||||
|
@ -166,7 +223,20 @@ class ObjectRemappingView implements AccessorStrategy
|
|||
{
|
||||
return (isset($item->$field)
|
||||
|| isset(static::$mappedParameters[$field])
|
||||
|| isset($this->handlerParameters[$field])
|
||||
|| isset(static::$handlerParameters[$field])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function isValidFilterTarget($field)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isTimestamp($field)
|
||||
{
|
||||
return isset(static::$fieldTypes[$field]) && static::$fieldTypes[$field] === self::TIMESTAMP;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@ class Controller extends ActionController
|
|||
'service_acknowledged',
|
||||
'service_handled',
|
||||
'service_output',
|
||||
'service_attempt',
|
||||
'service_last_state_change',
|
||||
'service_icon_image',
|
||||
'service_long_output',
|
||||
|
|
|
@ -71,7 +71,6 @@ abstract class DataView implements Filterable
|
|||
*/
|
||||
public static function fromRequest($request, array $columns = null)
|
||||
{
|
||||
|
||||
$view = new static(Backend::createBackend($request->getParam('backend')), $columns);
|
||||
$parser = new UrlViewFilter($view);
|
||||
$view->getQuery()->setFilter($parser->fromRequest($request));
|
||||
|
@ -108,6 +107,7 @@ abstract class DataView implements Filterable
|
|||
$view->getQuery()->where($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$order = isset($params['order']) ? $params['order'] : null;
|
||||
if ($order !== null) {
|
||||
if (strtolower($order) === 'desc') {
|
||||
|
@ -154,6 +154,7 @@ abstract class DataView implements Filterable
|
|||
public function sort($column = null, $order = null)
|
||||
{
|
||||
$sortRules = $this->getSortRules();
|
||||
|
||||
if ($column === null) {
|
||||
$sortColumns = reset($sortRules);
|
||||
if (!isset($sortColumns['columns'])) {
|
||||
|
|
|
@ -85,8 +85,7 @@ class HostStatus extends DataView
|
|||
),
|
||||
'host_address' => array(
|
||||
'columns' => array(
|
||||
'host_ipv4',
|
||||
'service_description'
|
||||
'host_ipv4'
|
||||
),
|
||||
'order' => self::SORT_ASC
|
||||
),
|
||||
|
|
|
@ -41,6 +41,7 @@ class ServiceStatus extends DataView
|
|||
'service_last_comment',
|
||||
'service_last_check',
|
||||
'service_next_check',
|
||||
'service_attempt',
|
||||
'service_last_notification',
|
||||
'service_check_command',
|
||||
'host_icon_image',
|
||||
|
|
|
@ -26,21 +26,10 @@
|
|||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* Class HostgroupsummaryQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class HostgroupsummaryQuery extends GroupsummaryQuery
|
||||
namespace Icinga\Module\Monitoring\Exception;
|
||||
use \Exception;
|
||||
|
||||
class UnsupportedBackendException extends Exception
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $groupType = "hostgroup";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $base = "hosts";
|
||||
}
|
||||
}
|
|
@ -32,17 +32,13 @@ abstract class AbstractObject
|
|||
public $customvars = array();
|
||||
public $events = array();
|
||||
|
||||
private $properties = array();
|
||||
private $request = null;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
$properties = $this->getProperties();
|
||||
if ($properties) {
|
||||
foreach ($properties as $key => $value) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
$this->properties = $this->getProperties();
|
||||
}
|
||||
|
||||
abstract protected function getProperties();
|
||||
|
@ -81,6 +77,7 @@ abstract class AbstractObject
|
|||
'hostgroup_alias'
|
||||
)
|
||||
)->getQuery()->fetchPairs();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -147,6 +144,12 @@ abstract class AbstractObject
|
|||
|
||||
public function __get($param)
|
||||
{
|
||||
|
||||
if (isset($this->properties->$param)) {
|
||||
return $this->properties->$param;
|
||||
} elseif (isset($this->$param)) {
|
||||
return $this->$param;
|
||||
}
|
||||
if (substr($param, 0, strlen($this->prefix)) === $this->prefix) {
|
||||
return false;
|
||||
}
|
||||
|
@ -159,8 +162,6 @@ abstract class AbstractObject
|
|||
return $this->request;
|
||||
}
|
||||
|
||||
abstract public function populate();
|
||||
|
||||
public static function fromRequest(Request $request)
|
||||
{
|
||||
if ($request->has('service') && $request->has('host')) {
|
||||
|
@ -169,4 +170,6 @@ abstract class AbstractObject
|
|||
return new Host($request);
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function populate();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ class Host extends AbstractObject
|
|||
|
||||
public $type = self::TYPE_HOST;
|
||||
public $prefix = 'host_';
|
||||
private $view = null;
|
||||
private $view = null;
|
||||
|
||||
|
||||
public function populate()
|
||||
|
|
|
@ -44,12 +44,14 @@ class ListControllerHostMySQLTest extends MonitoringControllerTest
|
|||
$firstHostFlags = ObjectFlags::PASSIVE_ONLY();
|
||||
$firstHostFlags->acknowledged = 1;
|
||||
$firstHostFlags->in_downtime = 1;
|
||||
$firstHostFlags->has_been_checked = 1;
|
||||
$firstHostFlags->notifications = 0;
|
||||
$firstHostFlags->flapping = 1;
|
||||
$firstHostFlags->time = $checkTime;
|
||||
|
||||
$fixture->addHost('host1', 1, $firstHostFlags, array(
|
||||
"address" => "10.92.1.5",
|
||||
"has_been_checked" => 1,
|
||||
"icon_image" => "myIcon.png",
|
||||
"notes_url" => "note1.html",
|
||||
"action_url" => "action.html"))->
|
||||
|
@ -90,7 +92,6 @@ class ListControllerHostMySQLTest extends MonitoringControllerTest
|
|||
$persistedLastCheck = explode("+", $hostToTest->host_last_check);
|
||||
$persistedLastCheck = $persistedLastCheck[0];
|
||||
$this->assertEquals("10.92.1.5", $hostToTest->host_address, "Testing for correct host address field (backend ".$backend.")");
|
||||
$this->assertEquals(1, $hostToTest->host_state, "Testing for status being DOWN (backend ".$backend.")");
|
||||
// commented out due to failing tests when delay is too long
|
||||
// $this->assertEquals(date("Y-m-d H:i:s", intval($checkTime)), $persistedLastCheck, "Testing for correct last check time format (backend ".$backend.")");
|
||||
//$this->assertEquals($checkTime, $hostToTest->host_last_state_change, "Testing for correct last state change (backend ".$backend.")");
|
||||
|
|
|
@ -1,178 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Monitoring\Backend\Statusdat;
|
||||
|
||||
use Icinga\Data\DatasourceInterface;
|
||||
use Zend_Config;
|
||||
use Tests\Icinga\Protocol\Statusdat\ReaderMock as ReaderMock;
|
||||
use \Icinga\Module\Monitoring\Backend\Statusdat\Query\ServicegroupsummaryQuery;
|
||||
use Tests\Icinga\Protocol\Statusdat\StatusdatTestLoader;
|
||||
|
||||
$base = dirname(__FILE__)."/../../../../..";
|
||||
|
||||
require_once($base."/../../test/php/library/Icinga/Protocol/Statusdat/StatusdatTestLoader.php");
|
||||
StatusdatTestLoader::requireLibrary();
|
||||
require_once(realpath($base."/library/Monitoring/Backend/Statusdat/Query/GroupsummaryQuery.php"));
|
||||
require_once(realpath($base."/library/Monitoring/Backend/Statusdat/Query/ServicegroupsummaryQuery.php"));
|
||||
|
||||
class BackendMock implements DatasourceInterface
|
||||
{
|
||||
public $reader;
|
||||
|
||||
public function select() {
|
||||
return $this;
|
||||
}
|
||||
public function setReader($reader) {
|
||||
$this->reader = $reader;
|
||||
}
|
||||
|
||||
public function getReader() {
|
||||
return $this->reader;
|
||||
}
|
||||
}
|
||||
|
||||
class ServicegroupsummaryqueryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGroupByProblemType()
|
||||
{
|
||||
$backendConfig = new Zend_Config(
|
||||
array()
|
||||
);
|
||||
$backend = new BackendMock();
|
||||
$backend->setReader($this->getTestDataset());
|
||||
$q = new ServicegroupsummaryQuery($backend);
|
||||
$indices = array(
|
||||
"service" => array(
|
||||
"hosta;service1", "hosta;service2", "hosta;service3",
|
||||
"hostb;service1", "hostb;service2", "hostb;service3", "hostb;service4"
|
||||
)
|
||||
);
|
||||
$this->assertEquals(array(
|
||||
(object) array(
|
||||
"servicegroup_name" => "sv1",
|
||||
'ok' => 1,
|
||||
'critical' => 1,
|
||||
'critical_dt' => 0,
|
||||
'critical_ack' => 1,
|
||||
'unknown' => 0,
|
||||
'unknown_dt' => 0,
|
||||
'unknown_ack' => 0,
|
||||
'warning' => 0,
|
||||
'warning_dt' => 1,
|
||||
'warning_ack' => 2
|
||||
),
|
||||
(object) array(
|
||||
"servicegroup_name" => "sv2",
|
||||
'ok' => 0,
|
||||
'critical' => 0,
|
||||
'critical_dt' => 0,
|
||||
'critical_ack' => 1,
|
||||
'unknown' => 0,
|
||||
'unknown_dt' => 0,
|
||||
'unknown_ack' => 0,
|
||||
'warning' => 1,
|
||||
'warning_dt' => 0,
|
||||
'warning_ack' => 2
|
||||
)
|
||||
),$q->groupByProblemType($indices));
|
||||
}
|
||||
|
||||
private function getTestDataset()
|
||||
{
|
||||
return new ReaderMock(array(
|
||||
"host" => array(
|
||||
"hosta" => (object) array(
|
||||
"host_name" => "hosta",
|
||||
"numeric_val" => 0,
|
||||
"services" => array(0, 1, 2)
|
||||
),
|
||||
"hostb" => (object) array(
|
||||
"host_name" => "hostb",
|
||||
"numeric_val" => 0,
|
||||
"services" => array(3, 4, 5)
|
||||
)
|
||||
),
|
||||
"service" => array(
|
||||
"hosta;service1" => (object) array(
|
||||
"host_name" => "hosta",
|
||||
"service_description" => "service1",
|
||||
"group" => array(
|
||||
"sv1"
|
||||
),
|
||||
"status" => (object) array(
|
||||
"current_state" => 0,
|
||||
"problem_has_been_acknowledged" => 0
|
||||
|
||||
)
|
||||
),
|
||||
"hosta;service2" => (object) array(
|
||||
"host_name" => "hosta",
|
||||
"service_description" => "service2",
|
||||
"group" => array(
|
||||
"sv1"
|
||||
),
|
||||
"status" => (object) array(
|
||||
"current_state" => 1,
|
||||
"downtime" => array("..."),
|
||||
"problem_has_been_acknowledged" => 0
|
||||
)
|
||||
),
|
||||
"hosta;service3" => (object) array(
|
||||
"host_name" => "hosta",
|
||||
"service_description" => "service3",
|
||||
"group" => array(
|
||||
"sv1"
|
||||
),
|
||||
"status" => (object) array(
|
||||
"current_state" => 2,
|
||||
"problem_has_been_acknowledged" => 0
|
||||
)
|
||||
),
|
||||
"hostb;service1" => (object) array(
|
||||
"host_name" => "hostb",
|
||||
"service_description" => "service1",
|
||||
"group" => array(
|
||||
"sv2"
|
||||
),
|
||||
"status" => (object) array(
|
||||
"current_state" => 1,
|
||||
"problem_has_been_acknowledged" => 0
|
||||
)
|
||||
),
|
||||
"hostb;service2" => (object) array(
|
||||
"host_name" => "hostb",
|
||||
"service_description" => "service2",
|
||||
"group" => array(
|
||||
"sv2","sv1"
|
||||
),
|
||||
"status" => (object) array(
|
||||
"current_state" => 2,
|
||||
"problem_has_been_acknowledged" => 1
|
||||
)
|
||||
),
|
||||
"hostb;service3" => (object) array(
|
||||
"host_name" => "hostb",
|
||||
"service_description" => "service3",
|
||||
"group" => array(
|
||||
"sv2","sv1"
|
||||
),
|
||||
"status" => (object) array(
|
||||
"current_state" => 1,
|
||||
"problem_has_been_acknowledged" => 1
|
||||
)
|
||||
),
|
||||
"hostb;service4" => (object) array(
|
||||
"host_name" => "hostb",
|
||||
"service_description" => "service4",
|
||||
"group" => array(
|
||||
"sv2","sv1"
|
||||
),
|
||||
"status" => (object) array(
|
||||
"current_state" => 1,
|
||||
"problem_has_been_acknowledged" => 1
|
||||
)
|
||||
)
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
|
@ -110,7 +110,7 @@ abstract class MonitoringControllerTest extends Zend_Test_PHPUnit_ControllerTest
|
|||
'statusdat-unittest' => array(
|
||||
'type' => 'statusdat',
|
||||
'status_file' => '/tmp/teststatus.dat',
|
||||
'objects_file' => '/tmp/testobjects.cache',
|
||||
'object_file' => '/tmp/testobjects.cache',
|
||||
'no_cache' => true
|
||||
),
|
||||
'ido-mysql-unittest' => array(
|
||||
|
@ -203,11 +203,9 @@ abstract class MonitoringControllerTest extends Zend_Test_PHPUnit_ControllerTest
|
|||
*/
|
||||
private function requireStatusDatQueries()
|
||||
{
|
||||
require_once(realpath($this->moduleDir.'/library/Monitoring/Backend/Statusdat/Query/Query.php'));
|
||||
require_once(realpath($this->moduleDir.'/library/Monitoring/Backend/Statusdat/Query/StatusdatQuery.php'));
|
||||
$this->requireFolder('library/Monitoring/Backend/Statusdat');
|
||||
$this->requireFolder('library/Monitoring/Backend/Statusdat/Criteria');
|
||||
$this->requireFolder('library/Monitoring/Backend/Statusdat/Query');
|
||||
$this->requireFolder('library/Monitoring/Backend/Statusdat/DataView');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -300,7 +298,7 @@ abstract class MonitoringControllerTest extends Zend_Test_PHPUnit_ControllerTest
|
|||
array(
|
||||
'type' => 'statusdat',
|
||||
'status_file' => '/tmp/teststatus.dat',
|
||||
'objects_file' => '/tmp/testobjects.cache',
|
||||
'object_file' => '/tmp/testobjects.cache',
|
||||
'no_cache' => true
|
||||
)
|
||||
);
|
||||
|
|
|
@ -65,7 +65,7 @@ class StatusdatInsertionStrategy implements InsertionStrategy {
|
|||
public function setConnection($ressource)
|
||||
{
|
||||
$this->statusDatFile = $ressource['status_file'];
|
||||
$this->objectsCacheFile = $ressource['objects_file'];
|
||||
$this->objectsCacheFile = $ressource['object_file'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -65,13 +65,13 @@ class StatusdatSetupStrategy implements SetupStrategy {
|
|||
if ($resource == null) {
|
||||
$resource = array(
|
||||
"status_file" => "/tmp/teststatus.dat",
|
||||
"objects_file" => "/tmp/testobjects.cache"
|
||||
"object_file" => "/tmp/testobjects.cache"
|
||||
);
|
||||
}
|
||||
$this->requireStatusDat();
|
||||
$this->teardown($resource);
|
||||
touch($resource["status_file"]);
|
||||
touch($resource["objects_file"]);
|
||||
touch($resource["object_file"]);
|
||||
return $resource;
|
||||
}
|
||||
|
||||
|
@ -88,14 +88,14 @@ class StatusdatSetupStrategy implements SetupStrategy {
|
|||
if ($resource == null) {
|
||||
$resource = array(
|
||||
"status_file" => "/tmp/teststatus.dat",
|
||||
"objects_file" => "/tmp/testobjects.cache"
|
||||
"object_file" => "/tmp/testobjects.cache"
|
||||
);
|
||||
}
|
||||
if (file_exists($resource["status_file"])) {
|
||||
unlink($resource["status_file"]);
|
||||
}
|
||||
if (file_exists($resource["objects_file"])) {
|
||||
unlink($resource["objects_file"]);
|
||||
if (file_exists($resource["object_file"])) {
|
||||
unlink($resource["object_file"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -309,8 +309,6 @@ function(Container, $, logger, URI, tpl, urlMgr, Selectable, TableMultiSelection
|
|||
contentNode = determineContentTable();
|
||||
this.initRowSelection();
|
||||
this.registerControls();
|
||||
this.registerHistoryChanges();
|
||||
|
||||
};
|
||||
|
||||
this.construct(gridDomNode);
|
||||
|
|
|
@ -17,7 +17,7 @@ class StatusdatComponentTest extends \PHPUnit_Framework_TestCase
|
|||
StatusdatTestLoader::requireLibrary();
|
||||
$reader = new SD\Reader(new \Zend_Config(array(
|
||||
"status_file" => dirname(__FILE__)."/status.dat",
|
||||
"objects_file" => dirname(__FILE__)."/objects.cache"
|
||||
"object_file" => dirname(__FILE__)."/objects.cache"
|
||||
)),null,true);
|
||||
return $reader;
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ class StatusdatComponentTest extends \PHPUnit_Framework_TestCase
|
|||
$r = $this->getReader();
|
||||
$group = array(array('a1','b2'));
|
||||
$result = $r->select()->from("services")->where("group IN ?",$group)->getResult();
|
||||
$this->assertCount(2,$result);
|
||||
|
||||
$this->assertCount(9, $result, 'Assert items to be returned in a servicegroup filter');
|
||||
foreach($result as $obj) {
|
||||
$this->assertTrue(is_object($obj));
|
||||
}
|
||||
|
@ -36,7 +37,7 @@ class StatusdatComponentTest extends \PHPUnit_Framework_TestCase
|
|||
$r = $this->getReader();
|
||||
$group = array(array('a1','b2'));
|
||||
$result = $r->select()->from("hosts")->where("services.group IN ?",$group)->getResult();
|
||||
$this->assertCount(2,$result);
|
||||
$this->assertCount(3, $result);
|
||||
foreach($result as $obj) {
|
||||
$this->assertTrue(is_object($obj));
|
||||
}
|
||||
|
@ -46,7 +47,7 @@ class StatusdatComponentTest extends \PHPUnit_Framework_TestCase
|
|||
$r = $this->getReader();
|
||||
$group = array(array('exc-hostb'));
|
||||
$result = $r->select()->from("hosts")->where("group IN ?",$group)->getResult();
|
||||
$this->assertCount(2,$result);
|
||||
$this->assertCount(3, $result);
|
||||
foreach($result as $obj) {
|
||||
$this->assertTrue(is_object($obj));
|
||||
}
|
||||
|
@ -57,7 +58,7 @@ class StatusdatComponentTest extends \PHPUnit_Framework_TestCase
|
|||
$group = array(array('exc-hostb'));
|
||||
$result = $r->select()->from("services")->where("host.group IN ?",$group)->getResult();
|
||||
|
||||
$this->assertCount(6,$result);
|
||||
$this->assertCount(9, $result);
|
||||
foreach($result as $obj) {
|
||||
$this->assertTrue(is_object($obj));
|
||||
}
|
||||
|
|
|
@ -29,6 +29,19 @@ class QueryExpressionMock implements Statusdat\Query\IQueryPart
|
|||
{
|
||||
return array_intersect(array_values($idx), array_values($this->filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add additional information about the query this filter belongs to
|
||||
*
|
||||
* @param $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function setQuery($query)
|
||||
{
|
||||
// TODO: Implement setQuery() method.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class GroupTest extends \PHPUnit_Framework_TestCase
|
||||
|
|
|
@ -21,20 +21,19 @@ class QueryTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
$readerMock = $this->getServiceTestReader();
|
||||
$query = new Statusdat\Query($readerMock);
|
||||
|
||||
$result = $query->from("services")->getResult();
|
||||
$objects = $readerMock->getObjects();
|
||||
$this->assertCount(count($objects["service"]), $result);
|
||||
|
||||
$result = $query->select()->from("services")->getResult();
|
||||
$this->assertCount(count($objects["service"]), $result);
|
||||
}
|
||||
|
||||
public function testSimpleHostSelect()
|
||||
{
|
||||
$readerMock = $this->getServiceTestReader();
|
||||
$query = new Statusdat\Query($readerMock);
|
||||
$objects = $readerMock->getObjects();
|
||||
|
||||
$result = $query->from("hosts")->getResult();
|
||||
$objects = $readerMock->getObjects();
|
||||
$this->assertCount(count($objects["host"]), $result);
|
||||
|
||||
}
|
||||
|
@ -83,69 +82,15 @@ class QueryTest extends \PHPUnit_Framework_TestCase
|
|||
$query = new Statusdat\Query($readerMock);
|
||||
$result = $query->from("services")->order('numeric_val ASC')->groupByColumns("numeric_val")->getResult();
|
||||
$this->assertCount(3,$result);
|
||||
$lastIdx = ~PHP_INT_MAX;
|
||||
foreach($result as $sstatus) {
|
||||
$this->assertTrue(isset($sstatus->count));
|
||||
$this->assertTrue(isset($sstatus->columns));
|
||||
$this->assertEquals(2,$sstatus->count);
|
||||
$this->assertGreaterThanOrEqual($lastIdx,$sstatus->columns->numeric_val);
|
||||
$lastIdx = $sstatus->columns->numeric_val;
|
||||
$this->assertEquals(2, $sstatus->count);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function testOrderSingleColumnASC()
|
||||
{
|
||||
$readerMock = $this->getServiceTestReader();
|
||||
$objects = $readerMock->getObjects();
|
||||
$query = new Statusdat\Query($readerMock);
|
||||
$result = $query->from("services")->order('numeric_val ASC')->getResult();
|
||||
$lastIdx = ~PHP_INT_MAX;
|
||||
foreach($result as $sstatus) {
|
||||
$this->assertGreaterThanOrEqual($lastIdx,$sstatus->numeric_val);
|
||||
$lastIdx = $sstatus->numeric_val;
|
||||
}
|
||||
}
|
||||
|
||||
public function testOrderSingleColumnDESC()
|
||||
{
|
||||
$readerMock = $this->getServiceTestReader();
|
||||
$objects = $readerMock->getObjects();
|
||||
$query = new Statusdat\Query($readerMock);
|
||||
$result = $query->from("services")->order('numeric_val DESC')->getResult();
|
||||
$lastIdx = PHP_INT_MAX;
|
||||
foreach($result as $sstatus) {
|
||||
$this->assertLessThanOrEqual($lastIdx,$sstatus->numeric_val);
|
||||
$lastIdx = $sstatus->numeric_val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Integration test for query and Expression/Group objects.
|
||||
* This is not a unit test, but checks if the 'where' filter really works
|
||||
*/
|
||||
public function testQueryIntegration() {
|
||||
|
||||
$readerMock = $this->getServiceTestReader();
|
||||
$objects = $readerMock->getObjects();
|
||||
$query = new Statusdat\Query($readerMock);
|
||||
$result = $query->from("services")->where('numeric_val = ?',array(1))->getResult();
|
||||
foreach($result as $testresult) {
|
||||
$this->assertEquals($testresult->numeric_val,1);
|
||||
}
|
||||
$query = new Statusdat\Query($readerMock);
|
||||
$result = $query->from("services")->where('numeric_val < ? OR numeric_val = ?',array(2,3))->getResult();
|
||||
foreach($result as $testresult) {
|
||||
$this->assertNotEquals($testresult->numeric_val,2);
|
||||
}
|
||||
$query = new Statusdat\Query($readerMock);
|
||||
$result = $query->from("services")->where('numeric_val < ? OR numeric_val = ?',array(2,3))->where("numeric_val = ?",array(1))->getResult();
|
||||
foreach($result as $testresult) {
|
||||
$this->assertEquals($testresult->numeric_val,1);
|
||||
}
|
||||
}
|
||||
|
||||
private function getServiceTestReader()
|
||||
{
|
||||
$readerMock = new ReaderMock(array(
|
||||
|
|
|
@ -17,6 +17,12 @@ class ReaderMock implements IReader, DatasourceInterface
|
|||
|
||||
public function getState()
|
||||
{
|
||||
return $this->objects;
|
||||
}
|
||||
|
||||
public function getInternalState()
|
||||
{
|
||||
|
||||
return array(
|
||||
"objects" => $this->objects,
|
||||
"indices" => $this->indices
|
||||
|
|
|
@ -9,36 +9,47 @@ use Icinga\Protocol\Statusdat\Reader as Reader;
|
|||
StatusdatTestLoader::requireLibrary();
|
||||
|
||||
if (!defined('APPLICATION_PATH')) {
|
||||
define("APPLICATION_PATH","./"); // TODO: test boostrap
|
||||
define("APPLICATION_PATH", "./"); // TODO: test boostrap
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Test class for Reader
|
||||
* Created Wed, 16 Jan 2013 15:15:16 +0000
|
||||
*
|
||||
**/
|
||||
class ConfigMock {
|
||||
function __construct($data) {
|
||||
foreach($data as $key=>$val)
|
||||
*
|
||||
* Test class for Reader
|
||||
* Created Wed, 16 Jan 2013 15:15:16 +0000
|
||||
*
|
||||
**/
|
||||
class ConfigMock
|
||||
{
|
||||
function __construct($data)
|
||||
{
|
||||
foreach ($data as $key => $val) {
|
||||
$this->$key = $val;
|
||||
}
|
||||
}
|
||||
function get($attr) {
|
||||
|
||||
function get($attr)
|
||||
{
|
||||
return $this->$attr;
|
||||
}
|
||||
}
|
||||
|
||||
class ParserMock {
|
||||
class ParserMock
|
||||
{
|
||||
|
||||
public $runtime = array();
|
||||
public $objects = array();
|
||||
public function parseObjectsFile() {
|
||||
|
||||
public function parseObjectsFile()
|
||||
{
|
||||
return $this->objects;
|
||||
}
|
||||
public function parseRuntimeState() {
|
||||
|
||||
public function parseRuntimeState()
|
||||
{
|
||||
return $this->runtime;
|
||||
}
|
||||
|
||||
public function getRuntimeState() {
|
||||
public function getRuntimeState()
|
||||
{
|
||||
return $this->runtime;
|
||||
}
|
||||
}
|
||||
|
@ -52,37 +63,42 @@ class ReaderTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
}
|
||||
|
||||
public function testFileCaching() {
|
||||
public function testFileCaching()
|
||||
{
|
||||
if (!file_exists('./tmp')) {
|
||||
mkdir('./tmp');
|
||||
}
|
||||
$parser = new ParserMock();
|
||||
$parser->runtime = array("host"=>array(
|
||||
"test" => (object) array(
|
||||
"host_name" => "test"
|
||||
$parser->runtime = array(
|
||||
"host" => array(
|
||||
"test" => (object)array(
|
||||
"host_name" => "test"
|
||||
)
|
||||
)
|
||||
));
|
||||
$object_file = tempnam("./dir","object");
|
||||
$status_file = tempnam("./dir","status");
|
||||
);
|
||||
$object_file = tempnam("./dir", "object");
|
||||
$status_file = tempnam("./dir", "status");
|
||||
$reader = new Reader(new ConfigMock(array(
|
||||
"cache_path" => "/tmp",
|
||||
"objects_file" => $object_file,
|
||||
"object_file" => $object_file,
|
||||
"status_file" => $status_file
|
||||
)),$parser);
|
||||
)), $parser);
|
||||
unlink($object_file);
|
||||
unlink($status_file);
|
||||
$this->assertTrue(file_exists("/tmp/zend_cache---objects".md5($object_file)));
|
||||
$this->assertTrue(file_exists("/tmp/zend_cache---state".md5($object_file)));
|
||||
$this->assertTrue(file_exists("/tmp/zend_cache---object" . md5($object_file)));
|
||||
$this->assertTrue(file_exists("/tmp/zend_cache---state" . md5($object_file)));
|
||||
system("rm /tmp/zend_cache*");
|
||||
}
|
||||
public function testEmptyFileException() {
|
||||
|
||||
public function testEmptyFileException()
|
||||
{
|
||||
|
||||
$this->setExpectedException("Icinga\Exception\ConfigurationError");
|
||||
$parser = new ParserMock();
|
||||
$reader = new Reader(new ConfigMock(array(
|
||||
"cache_path" => "/tmp",
|
||||
"objects_file" => "",
|
||||
"object_file" => "",
|
||||
"status_file" => "",
|
||||
)),$parser);
|
||||
)), $parser);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Icinga\Protocol\Statusdat;
|
||||
|
||||
use Test\Icinga\LibraryLoader;
|
||||
|
||||
require_once(realpath(dirname(__FILE__)."/../../LibraryLoader.php"));
|
||||
require_once(realpath(dirname(__FILE__) . '/../../LibraryLoader.php'));
|
||||
|
||||
class StatusdatTestLoader extends LibraryLoader
|
||||
{
|
||||
public static function requireLibrary()
|
||||
|
@ -12,23 +14,24 @@ class StatusdatTestLoader extends LibraryLoader
|
|||
require_once 'Zend/Config.php';
|
||||
require_once 'Zend/Cache.php';
|
||||
require_once 'Zend/Log.php';
|
||||
require_once($libPath."/Data/BaseQuery.php");
|
||||
require_once($libPath."/Application/Logger.php");
|
||||
require_once($libPath."/Filter/Filterable.php");
|
||||
require_once($libPath."/Data/DatasourceInterface.php");
|
||||
$statusdat = realpath($libPath."/Protocol/Statusdat/");
|
||||
require_once($statusdat."/View/AccessorStrategy.php");
|
||||
require_once($statusdat."/View/MonitoringObjectList.php");
|
||||
require_once($statusdat."/View/ObjectRemappingView.php");
|
||||
require_once($statusdat."/ObjectContainer.php");
|
||||
require_once($statusdat."/IReader.php");
|
||||
require_once($statusdat."/RuntimeStateContainer.php");
|
||||
require_once($statusdat."/Query.php");
|
||||
require_once($statusdat."/Parser.php");
|
||||
require_once($statusdat."/Reader.php");
|
||||
require_once($statusdat."/Exception/ParsingException.php");
|
||||
require_once($statusdat."/Query/IQueryPart.php");
|
||||
require_once($statusdat."/Query/Expression.php");
|
||||
require_once($statusdat."/Query/Group.php");
|
||||
require_once($libPath . '/Data/BaseQuery.php');
|
||||
require_once($libPath . '/Application/Logger.php');
|
||||
require_once($libPath . '/Filter/Filterable.php');
|
||||
require_once($libPath . '/Data/DatasourceInterface.php');
|
||||
$statusdat = realpath($libPath . '/Protocol/Statusdat/');
|
||||
require_once($statusdat . '/View/AccessorStrategy.php');
|
||||
require_once($statusdat . '/PrintableObject.php');
|
||||
require_once($statusdat . '/View/MonitoringObjectList.php');
|
||||
require_once($statusdat . '/ObjectContainer.php');
|
||||
require_once($statusdat . '/IReader.php');
|
||||
require_once($statusdat . '/RuntimeStateContainer.php');
|
||||
require_once($statusdat . '/Query.php');
|
||||
require_once($statusdat . '/Parser.php');
|
||||
require_once($statusdat . '/Reader.php');
|
||||
require_once($statusdat . '/TreeToStatusdatQueryParser.php');
|
||||
require_once($statusdat . '/Exception/ParsingException.php');
|
||||
require_once($statusdat . '/Query/IQueryPart.php');
|
||||
require_once($statusdat . '/Query/Expression.php');
|
||||
require_once($statusdat . '/Query/Group.php');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,14 +12,11 @@ use Tests\Icinga\Protocol\Statusdat\StatusdatTestLoader;
|
|||
require_once 'Zend/Paginator/Adapter/Interface.php';
|
||||
|
||||
require_once '../../library/Icinga/Web/Paginator/Adapter/QueryAdapter.php';
|
||||
|
||||
require_once 'library/Icinga/Protocol/Statusdat/StatusdatTestLoader.php';
|
||||
StatusdatTestLoader::requireLibrary();
|
||||
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Criteria/Order.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Query/Query.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Query/StatusdatQuery.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Query/StatusQuery.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/DataView/HostStatusView.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend.php';
|
||||
|
||||
require_once '../../library/Icinga/Data/BaseQuery.php';
|
||||
|
@ -52,7 +49,7 @@ class QueryAdapterTest extends PHPUnit_Framework_TestCase
|
|||
$this->resourceConfig = new Zend_Config(
|
||||
array(
|
||||
'status_file' => $statusdatFile,
|
||||
'objects_file' => $cacheFile,
|
||||
'object_file' => $cacheFile,
|
||||
'type' => 'statusdat'
|
||||
)
|
||||
);
|
||||
|
|
|
@ -21,11 +21,9 @@ require_once 'library/Icinga/Protocol/Statusdat/StatusdatTestLoader.php';
|
|||
|
||||
StatusdatTestLoader::requireLibrary();
|
||||
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Criteria/Order.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Query/Query.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Query/StatusdatQuery.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Query/StatusQuery.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/DataView/HostStatusView.php';
|
||||
require_once '../../library/Icinga/Web/Paginator/ScrollingStyle/SlidingWithBorder.php';
|
||||
|
||||
class TestPaginatorAdapter implements Zend_Paginator_Adapter_Interface
|
||||
|
@ -103,7 +101,7 @@ class SlidingwithborderTest extends \PHPUnit_Framework_TestCase
|
|||
$this->resourceConfig = new Zend_Config(
|
||||
array(
|
||||
'status_file' => $statusdatFile,
|
||||
'objects_file' => $cacheFile,
|
||||
'object_file' => $cacheFile,
|
||||
'type' => 'statusdat'
|
||||
)
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue