Refactored Ido\EventHistoryQuery, now it's fully based on other subqueries.
* Added hostgroup filters * Added aggregation columns
This commit is contained in:
parent
c9ce7c53b0
commit
c6db0067ec
|
@ -10,195 +10,73 @@ class EventHistoryQuery extends AbstractQuery
|
|||
|
||||
protected $columnMap = array(
|
||||
'eventhistory' => array(
|
||||
'cnt_notification' => "SUM(CASE eh.type WHEN 'notify' THEN 1 ELSE 0 END)",
|
||||
'cnt_hard_state' => "SUM(CASE eh.type WHEN 'hard_state' THEN 1 ELSE 0 END)",
|
||||
'cnt_soft_state' => "SUM(CASE eh.type WHEN 'hard_state' THEN 1 ELSE 0 END)",
|
||||
'cnt_downtime_start' => "SUM(CASE eh.type WHEN 'dt_start' THEN 1 ELSE 0 END)",
|
||||
'cnt_downtime_end' => "SUM(CASE eh.type WHEN 'dt_end' THEN 1 ELSE 0 END)",
|
||||
'host' => 'eho.name1 COLLATE latin1_general_ci',
|
||||
'service' => 'eho.name2 COLLATE latin1_general_ci',
|
||||
'host_name' => 'eho.name1 COLLATE latin1_general_ci',
|
||||
'service_description' => 'eho.name2 COLLATE latin1_general_ci',
|
||||
'object_type' => "CASE WHEN eho.objecttype_id = 1 THEN 'host' ELSE 'service' END",
|
||||
'timestamp' => 'UNIX_TIMESTAMP(eh.state_time)',
|
||||
'raw_timestamp' => 'eh.state_time',
|
||||
'timestamp' => 'eh.timestamp',
|
||||
'raw_timestamp' => 'eh.raw_timestamp',
|
||||
'state' => 'eh.state',
|
||||
// 'last_state' => 'eh.last_state',
|
||||
// 'last_hard_state' => 'eh.last_hard_state',
|
||||
'attempt' => 'eh.attempt',
|
||||
'max_attempts' => 'eh.max_attempts',
|
||||
'output' => 'eh.output', // we do not want long_output
|
||||
'problems' => 'CASE WHEN eh.state = 0 OR eh.state IS NULL THEN 0 ELSE 1 END',
|
||||
//'problems' => 'CASE WHEN eh.state = 0 OR eh.state IS NULL THEN 0 ELSE 1 END',
|
||||
'type' => 'eh.type',
|
||||
)
|
||||
),
|
||||
'hostgroups' => array(
|
||||
'hostgroup' => 'hgo.name1 COLLATE latin1_general_ci',
|
||||
),
|
||||
);
|
||||
|
||||
protected function getDefaultColumns()
|
||||
{
|
||||
return $this->columnMap['eventhistory'];
|
||||
}
|
||||
protected $uglySlowConservativeCount = true;
|
||||
protected $maxCount = 1000;
|
||||
|
||||
protected function joinBaseTables()
|
||||
{
|
||||
$start = date('Y-m-d H:i:s', time() - 3600 * 24 * 30);
|
||||
// $start = date('Y-m-d H:i:s', time() - 3600 * 24 * 1);
|
||||
$start = date('Y-m-d H:i:s', time() - 3600 * 24 * 2);
|
||||
$end = date('Y-m-d H:i:s');
|
||||
$start = null;
|
||||
$end = null;
|
||||
|
||||
$history = $this->db->select()->from(
|
||||
$this->prefix . 'statehistory',
|
||||
array(
|
||||
'state_time' => 'state_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "(CASE WHEN state_type = 1 THEN 'hard_state' ELSE 'soft_state' END)",
|
||||
'state' => 'state',
|
||||
'state_type' => 'state_type',
|
||||
'output' => 'output',
|
||||
'attempt' => 'current_check_attempt',
|
||||
'max_attempts' => 'max_check_attempts',
|
||||
)
|
||||
// TODO: $this->dbTime(...)
|
||||
//$start = null;
|
||||
//$end = null;
|
||||
$columns = array(
|
||||
'raw_timestamp',
|
||||
'timestamp',
|
||||
'object_id',
|
||||
'type',
|
||||
'output',
|
||||
'state',
|
||||
'state_type',
|
||||
'attempt',
|
||||
'max_attempts',
|
||||
);
|
||||
if ($start !== null) {
|
||||
$history->where('state_time >= ?', $start);
|
||||
}
|
||||
// ->where('state_type = 1') ??
|
||||
if ($end !== null) {
|
||||
$history->where('state_time <= ?', $end);
|
||||
}
|
||||
|
||||
$dt_start = $this->db->select()->from(
|
||||
$this->prefix . 'downtimehistory',
|
||||
array(
|
||||
'state_time' => 'actual_start_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "('dt_start')",
|
||||
'state' => '(NULL)',
|
||||
'state_type' => '(NULL)',
|
||||
// 'output' => "CONCAT('[', author_name, '] ', comment_data)",
|
||||
'output' => "('[' || author_name || '] ' || comment_data)",
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
);
|
||||
if ($start !== null) {
|
||||
$dt_start->where('actual_start_time >= ?', $start);
|
||||
}
|
||||
if ($end !== null) {
|
||||
$dt_start->where('actual_start_time <= ?', $end);
|
||||
}
|
||||
|
||||
// TODO: check was_cancelled
|
||||
$dt_end = $this->db->select()->from(
|
||||
$this->prefix . 'downtimehistory',
|
||||
array(
|
||||
'state_time' => 'actual_end_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "('dt_end')",
|
||||
'state' => '(NULL)',
|
||||
'state_type' => '(NULL)',
|
||||
// 'output' => "CONCAT('[', author_name, '] ', comment_data)",
|
||||
'output' => "('[' || author_name || '] ' || comment_data)",
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
);
|
||||
if ($start !== null) {
|
||||
$dt_end->where('actual_end_time >= ?', $start);
|
||||
}
|
||||
if ($end !== null) {
|
||||
$dt_end->where('actual_end_time <= ?', $end);
|
||||
}
|
||||
|
||||
$comments = $this->db->select()->from(
|
||||
$this->prefix . 'commenthistory',
|
||||
array(
|
||||
'state_time' => 'comment_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "(CASE entry_type WHEN 1 THEN 'comment' WHEN 2 THEN 'dt_comment' WHEN 3 THEN 'flapping' WHEN 4 THEN 'ack' END)",
|
||||
'state' => '(NULL)',
|
||||
'state_type' => '(NULL)',
|
||||
// 'output' => "CONCAT('[', author_name, '] ', comment_data)",
|
||||
'output' => "('[' || author_name || '] ' || comment_data)",
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
);
|
||||
|
||||
if ($start !== null) {
|
||||
$comments->where('comment_time >= ?', $start);
|
||||
}
|
||||
if ($end !== null) {
|
||||
$comments->where('comment_time <= ?', $end);
|
||||
}
|
||||
|
||||
// This is one of the db-specific workarounds that could be abstracted
|
||||
// in a better way:
|
||||
switch ($this->ds->getConnection()->getDbType()) {
|
||||
case 'mysql':
|
||||
$concat_contacts = "GROUP_CONCAT(c.alias ORDER BY c.alias SEPARATOR ', ')";
|
||||
break;
|
||||
case 'pgsql':
|
||||
// TODO: Find a way to "ORDER" these:
|
||||
$concat_contacts = "ARRAY_TO_STRING(ARRAY_AGG(c.alias), ', ')";
|
||||
break;
|
||||
case 'oracle':
|
||||
// TODO: This is only valid for Oracle >= 11g Release 2.
|
||||
$concat_contacts = "LISTAGG(c.alias, ', ') WITHIN GROUP (ORDER BY c.alias)";
|
||||
// Alternatives:
|
||||
//
|
||||
// RTRIM(XMLAGG(XMLELEMENT(e, column_name, ',').EXTRACT('//text()')),
|
||||
//
|
||||
// not supported and not documented but works since 10.1,
|
||||
// however it is NOT always present;
|
||||
// WM_CONCAT(c.alias)
|
||||
break;
|
||||
default:
|
||||
die('Not yet'); // TODO: Proper Exception
|
||||
}
|
||||
|
||||
$cndetails = $this->db->select()->from(
|
||||
array('cn' => $this->prefix . 'contactnotifications'),
|
||||
array(
|
||||
'notification_id' => 'notification_id',
|
||||
'cnt' => 'COUNT(*)',
|
||||
'contacts' => $concat_contacts
|
||||
)
|
||||
)->join(
|
||||
array('c' => $this->prefix . 'contacts'),
|
||||
'cn.contact_object_id = c.contact_object_id',
|
||||
array()
|
||||
)->group('notification_id');
|
||||
|
||||
$notifications = $this->db->select()->from(
|
||||
array('n' => $this->prefix . 'notifications'),
|
||||
array(
|
||||
'state_time' => 'start_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "('notify')",
|
||||
'state' => 'state',
|
||||
'state_type' => '(NULL)',
|
||||
// 'output' => "CONCAT('[', cndetails.contacts, '] ', n.output)",
|
||||
'output' => "('[' || cndetails.contacts || '] ' || n.output)",
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
)->join(
|
||||
array('cndetails' => $cndetails),
|
||||
'cndetails.notification_id = n.notification_id',
|
||||
array()
|
||||
);
|
||||
|
||||
if ($start !== null) {
|
||||
$notifications->where('start_time >= ?', $start);
|
||||
}
|
||||
if ($end !== null) {
|
||||
$notifications->where('start_time <= ?', $end);
|
||||
}
|
||||
|
||||
$this->subQueries = array(
|
||||
$history,
|
||||
$dt_start,
|
||||
$dt_end,
|
||||
$comments,
|
||||
$notifications
|
||||
$this->createSubQuery('Statehistory', $columns),
|
||||
$this->createSubQuery('Downtimestarthistory', $columns),
|
||||
$this->createSubQuery('Downtimeendhistory', $columns),
|
||||
$this->createSubQuery('Commenthistory', $columns),
|
||||
$this->createSubQuery('Notificationhistory', $columns)
|
||||
);
|
||||
$sub = $this->db->select()->union($this->subQueries, \Zend_Db_Select::SQL_UNION_ALL);
|
||||
|
||||
if ($start) {
|
||||
foreach ($this->subQueries as $query) {
|
||||
$query->where('raw_timestamp', '>' . $start);
|
||||
}
|
||||
}
|
||||
if ($end) {
|
||||
foreach ($this->subQueries as $query) {
|
||||
$query->where('raw_timestamp', '<' . $start);
|
||||
}
|
||||
}
|
||||
$sub = $this->db->select()->union($this->subQueries, Zend_Db_Select::SQL_UNION_ALL);
|
||||
$this->baseQuery = $this->db->select()->from(
|
||||
array('eho' => $this->prefix . 'objects'),
|
||||
array()
|
||||
|
@ -213,58 +91,24 @@ class EventHistoryQuery extends AbstractQuery
|
|||
$this->joinedVirtualTables = array('eventhistory' => true);
|
||||
}
|
||||
|
||||
// TODO: This duplicates code from AbstractQuery
|
||||
protected function applyAllFilters()
|
||||
protected function joinHostgroups()
|
||||
{
|
||||
$filters = array();
|
||||
$this->baseQuery->join(
|
||||
array('hgm' => $this->prefix . 'hostgroup_members'),
|
||||
'hgm.host_object_id = eho.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()
|
||||
);
|
||||
|
||||
$host = null;
|
||||
$service = null;
|
||||
|
||||
foreach ($this->filters as $f) {
|
||||
$alias = $f[0];
|
||||
$value = $f[1];
|
||||
$this->requireColumn($alias);
|
||||
|
||||
if ($this->hasAliasName($alias)) {
|
||||
$col = $this->aliasToColumnName($alias);
|
||||
} else {
|
||||
throw new ProgrammingError(
|
||||
'If you finished here, code has been messed up'
|
||||
);
|
||||
}
|
||||
|
||||
if (in_array($alias, array('host', 'host_name'))) {
|
||||
$host = $value;
|
||||
continue;
|
||||
}
|
||||
if (in_array($alias, array('service', 'service_description'))) {
|
||||
$service = $value;
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->baseQuery->where($this->prepareFilterStringForColumn($col, $value));
|
||||
}
|
||||
|
||||
$objectQuery = $this->db->select()->from(
|
||||
$this->prefix . 'objects',
|
||||
$this->object_id
|
||||
)->where('is_active = 1');
|
||||
|
||||
if ($service === '*') {
|
||||
$objectQuery->where('name1 = ?', $host)
|
||||
->where('objecttype_id IN (1, 2)');
|
||||
} elseif ($service) {
|
||||
$objectQuery->where('name1 = ?', $host)
|
||||
->where('name2 = ?', $service)
|
||||
->where('objecttype_id = 2');
|
||||
} else {
|
||||
$objectQuery->where('name1 = ?', $host)
|
||||
->where('objecttype_id = 1');
|
||||
}
|
||||
$objectId = $this->db->fetchCol($objectQuery);
|
||||
foreach ($this->subQueries as $query) {
|
||||
$query->where('object_id IN (?)', $objectId);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue