diff --git a/modules/monitoring/application/views/scripts/partials/event-history.phtml b/modules/monitoring/application/views/scripts/partials/event-history.phtml
index 0d9c64870..010fb0965 100644
--- a/modules/monitoring/application/views/scripts/partials/event-history.phtml
+++ b/modules/monitoring/application/views/scripts/partials/event-history.phtml
@@ -34,6 +34,7 @@ $history->limit($limit * $page);
translate('%A, %B %e, %Y', 'date.verbose');
$lastDate = null;
+$flappingMsg = $this->translate('Flapping with a %.2f%% state change rate');
?>
class="=$tableCssClass ?>">
@@ -92,12 +93,14 @@ $lastDate = null;
$icon = 'flapping';
$iconTitle = $this->translate('Flapping started', 'tooltip');
$label = $this->translate('FLAPPING');
+ $msg = sprintf($flappingMsg, $msg);
break;
case 'flapping_deleted':
$icon = 'flapping';
$iconCssClass = 'icon-strikethrough';
$iconTitle = $this->translate('Flapping stopped', 'tooltip');
$label = $this->translate('FLAPPING STOPPED');
+ $msg = sprintf($flappingMsg, $msg);
break;
case 'hard_state':
if ((int) $event->state === 0) {
diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/EventhistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/EventhistoryQuery.php
index c8ee0b8a3..956e87450 100644
--- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/EventhistoryQuery.php
+++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/EventhistoryQuery.php
@@ -67,7 +67,9 @@ class EventhistoryQuery extends IdoQuery
$this->createSubQuery('Downtimeendhistory', $columns),
$this->createSubQuery('Commenthistory', $columns),
$this->createSubQuery('Commentdeletionhistory', $columns),
- $this->createSubQuery('Notificationhistory', $columns)
+ $this->createSubQuery('Notificationhistory', $columns),
+ $this->createSubQuery('Flappingstarthistory', $columns),
+ $this->createSubQuery('Flappingendhistory', $columns)
);
$sub = $this->db->select()->union($this->subQueries, Zend_Db_Select::SQL_UNION_ALL);
$this->select->from(array('eh' => $sub), array());
diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingendhistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingendhistoryQuery.php
new file mode 100644
index 000000000..7bdf332e5
--- /dev/null
+++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingendhistoryQuery.php
@@ -0,0 +1,49 @@
+columnMap['flappinghistory'] + $this->columnMap['hosts']
+ );
+ foreach ($this->columnMap['services'] as $column => $_) {
+ $columns[$column] = new Zend_Db_Expr('NULL');
+ }
+ if ($this->fetchHistoryColumns) {
+ $columns = array_merge($columns, array_keys($this->columnMap['history']));
+ }
+ $hosts = $this->createSubQuery('Hostflappingendhistory', $columns);
+ $this->subQueries[] = $hosts;
+ $this->flappingStartHistoryQuery->union(array($hosts), Zend_Db_Select::SQL_UNION_ALL);
+ }
+
+ /**
+ * Join services
+ */
+ protected function joinServices()
+ {
+ $columns = array_keys(
+ $this->columnMap['flappinghistory'] + $this->columnMap['hosts'] + $this->columnMap['services']
+ );
+ if ($this->fetchHistoryColumns) {
+ $columns = array_merge($columns, array_keys($this->columnMap['history']));
+ }
+ $services = $this->createSubQuery('Serviceflappingendhistory', $columns);
+ $this->subQueries[] = $services;
+ $this->flappingStartHistoryQuery->union(array($services), Zend_Db_Select::SQL_UNION_ALL);
+ }
+}
diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingstarthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingstarthistoryQuery.php
new file mode 100644
index 000000000..ec203d743
--- /dev/null
+++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/FlappingstarthistoryQuery.php
@@ -0,0 +1,167 @@
+ array(
+ 'object_type' => 'fsh.object_type'
+ ),
+ 'history' => array(
+ 'type' => 'fsh.type',
+ 'timestamp' => 'fsh.timestamp',
+ 'object_id' => 'fsh.object_id',
+ 'state' => 'fsh.state',
+ 'output' => 'fsh.output'
+ ),
+ 'hosts' => array(
+ 'host_display_name' => 'fsh.host_display_name',
+ 'host_name' => 'fsh.host_name'
+ ),
+ 'services' => array(
+ 'service_description' => 'fsh.service_description',
+ 'service_display_name' => 'fsh.service_display_name',
+ 'service_host_name' => 'fsh.service_host_name'
+ )
+ );
+
+ /**
+ * The union
+ *
+ * @var Zend_Db_Select
+ */
+ protected $flappingStartHistoryQuery;
+
+ /**
+ * Subqueries used for the flapping start history query
+ *
+ * @var IdoQuery[]
+ */
+ protected $subQueries = array();
+
+ /**
+ * Whether to additionally select all history columns
+ *
+ * @var bool
+ */
+ protected $fetchHistoryColumns = false;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function allowsCustomVars()
+ {
+ foreach ($this->subQueries as $query) {
+ if (! $query->allowsCustomVars()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function joinBaseTables()
+ {
+ $this->flappingStartHistoryQuery = $this->db->select();
+ $this->select->from(
+ array('fsh' => $this->flappingStartHistoryQuery),
+ array()
+ );
+ $this->joinedVirtualTables['flappinghistory'] = true;
+ }
+
+ /**
+ * Join history related columns and tables
+ */
+ protected function joinHistory()
+ {
+ // TODO: Ensure that one is selecting the history columns first...
+ $this->fetchHistoryColumns = true;
+ $this->requireVirtualTable('hosts');
+ $this->requireVirtualTable('services');
+ }
+
+ /**
+ * Join hosts
+ */
+ protected function joinHosts()
+ {
+ $columns = array_keys(
+ $this->columnMap['flappinghistory'] + $this->columnMap['hosts']
+ );
+ foreach ($this->columnMap['services'] as $column => $_) {
+ $columns[$column] = new Zend_Db_Expr('NULL');
+ }
+ if ($this->fetchHistoryColumns) {
+ $columns = array_merge($columns, array_keys($this->columnMap['history']));
+ }
+ $hosts = $this->createSubQuery('Hostflappingstarthistory', $columns);
+ $this->subQueries[] = $hosts;
+ $this->flappingStartHistoryQuery->union(array($hosts), Zend_Db_Select::SQL_UNION_ALL);
+ }
+
+ /**
+ * Join services
+ */
+ protected function joinServices()
+ {
+ $columns = array_keys(
+ $this->columnMap['flappinghistory'] + $this->columnMap['hosts'] + $this->columnMap['services']
+ );
+ if ($this->fetchHistoryColumns) {
+ $columns = array_merge($columns, array_keys($this->columnMap['history']));
+ }
+ $services = $this->createSubQuery('Serviceflappingstarthistory', $columns);
+ $this->subQueries[] = $services;
+ $this->flappingStartHistoryQuery->union(array($services), Zend_Db_Select::SQL_UNION_ALL);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function order($columnOrAlias, $dir = null)
+ {
+ foreach ($this->subQueries as $sub) {
+ $sub->requireColumn($columnOrAlias);
+ }
+ return parent::order($columnOrAlias, $dir);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function where($condition, $value = null)
+ {
+ $this->requireColumn($condition);
+ foreach ($this->subQueries as $sub) {
+ $sub->where($condition, $value);
+ }
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addFilter(Filter $filter)
+ {
+ foreach ($this->subQueries as $sub) {
+ $sub->applyFilter(clone $filter);
+ }
+ return $this;
+ }
+}
diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostflappingendhistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostflappingendhistoryQuery.php
new file mode 100644
index 000000000..ebc346b95
--- /dev/null
+++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostflappingendhistoryQuery.php
@@ -0,0 +1,31 @@
+select->from(
+ array('hfh' => $this->prefix . 'flappinghistory'),
+ array()
+ )->join(
+ array('ho' => $this->prefix . 'objects'),
+ 'ho.object_id = hfh.object_id AND ho.is_active = 1 AND ho.objecttype_id = 1',
+ array()
+ );
+
+ $this->select->where('hfh.event_type = 1001');
+
+ $this->joinedVirtualTables['flappinghistory'] = true;
+
+ $this->columnMap['flappinghistory']['type'] = '(\'flapping_deleted\')';
+ }
+}
diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostflappingstarthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostflappingstarthistoryQuery.php
new file mode 100644
index 000000000..a8af45c55
--- /dev/null
+++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostflappingstarthistoryQuery.php
@@ -0,0 +1,172 @@
+ array('hfh.flappinghistory_id', 'ho.object_id'));
+
+ /**
+ * {@inheritdoc}
+ */
+ protected $groupOrigin = array('hostgroups', 'services');
+
+ /**
+ * {@inheritdoc}
+ */
+ protected $columnMap = array(
+ 'flappinghistory' => array(
+ 'host_name' => 'ho.name1',
+ 'object_id' => 'hfh.object_id',
+ 'object_type' => '(\'host\')',
+ 'output' => '(hfh.percent_state_change || \'\')',
+ 'state' => '(-1)',
+ 'timestamp' => 'UNIX_TIMESTAMP(hfh.event_time)',
+ 'type' => '(\'flapping\')'
+ ),
+ 'hostgroups' => array(
+ 'hostgroup_alias' => 'hg.alias COLLATE latin1_general_ci',
+ 'hostgroup_name' => 'hgo.name1'
+ ),
+ 'hosts' => array(
+ 'host_alias' => 'h.alias',
+ 'host_display_name' => 'h.display_name COLLATE latin1_general_ci'
+ ),
+ 'instances' => array(
+ 'instance_name' => 'i.instance_name'
+ ),
+ 'servicegroups' => array(
+ 'servicegroup_name' => 'sgo.name1',
+ 'servicegroup_alias' => 'sg.alias COLLATE latin1_general_ci'
+ ),
+ 'services' => array(
+ 'service_description' => 'so.name2',
+ 'service_display_name' => 's.display_name COLLATE latin1_general_ci',
+ 'service_host_name' => 'so.name1'
+ )
+ );
+
+ /**
+ * {@inheritdoc}
+ */
+ public function whereToSql($col, $sign, $expression)
+ {
+ if ($col === 'UNIX_TIMESTAMP(hfh.event_time)') {
+ return 'hfh.event_time ' . $sign . ' ' . $this->timestampForSql($this->valueToTimestamp($expression));
+ } else {
+ return parent::whereToSql($col, $sign, $expression);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function joinBaseTables()
+ {
+ $this->select->from(
+ array('hfh' => $this->prefix . 'flappinghistory'),
+ array()
+ )->join(
+ array('ho' => $this->prefix . 'objects'),
+ 'ho.object_id = hfh.object_id AND ho.is_active = 1 AND ho.objecttype_id = 1',
+ array()
+ );
+
+ $this->select->where('hfh.event_type = 1000');
+
+ $this->joinedVirtualTables['flappinghistory'] = true;
+ }
+
+ /**
+ * Join host groups
+ */
+ protected function joinHostgroups()
+ {
+ $this->select->joinLeft(
+ array('hgm' => $this->prefix . 'hostgroup_members'),
+ 'hgm.host_object_id = ho.object_id',
+ array()
+ )->joinLeft(
+ array('hg' => $this->prefix . 'hostgroups'),
+ 'hg.hostgroup_id = hgm.hostgroup_id',
+ array()
+ )->joinLeft(
+ array('hgo' => $this->prefix . 'objects'),
+ 'hgo.object_id = hg.hostgroup_object_id AND hgo.is_active = 1 AND hgo.objecttype_id = 3',
+ array()
+ );
+ }
+
+ /**
+ * Join hosts
+ */
+ protected function joinHosts()
+ {
+ $this->select->join(
+ array('h' => $this->prefix . 'hosts'),
+ 'h.host_object_id = ho.object_id',
+ array()
+ );
+ }
+
+ /**
+ * Join instances
+ */
+ protected function joinInstances()
+ {
+ $this->select->join(
+ array('i' => $this->prefix . 'instances'),
+ 'i.instance_id = hfh.instance_id',
+ array()
+ );
+ }
+
+ /**
+ * Join service groups
+ */
+ protected function joinServicegroups()
+ {
+ $this->requireVirtualTable('services');
+ $this->select->joinLeft(
+ array('sgm' => $this->prefix . 'servicegroup_members'),
+ 'sgm.service_object_id = s.service_object_id',
+ array()
+ )->joinLeft(
+ array('sg' => $this->prefix . 'servicegroups'),
+ 'sg.' . $this->servicegroup_id . ' = sgm.servicegroup_id',
+ array()
+ )->joinLeft(
+ array('sgo' => $this->prefix . 'objects'),
+ 'sgo.object_id = sg.servicegroup_object_id AND sgo.is_active = 1 AND sgo.objecttype_id = 4',
+ array()
+ );
+ }
+
+ /**
+ * Join services
+ */
+ protected function joinServices()
+ {
+ $this->select->joinLeft(
+ array('s' => $this->prefix . 'services'),
+ 's.host_object_id = ho.object_id',
+ array()
+ )->joinLeft(
+ array('so' => $this->prefix . 'objects'),
+ 'so.object_id = s.service_object_id AND so.is_active = 1 AND so.objecttype_id = 2',
+ array()
+ );
+ }
+}
diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServiceflappingendhistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServiceflappingendhistoryQuery.php
new file mode 100644
index 000000000..48fb0bc49
--- /dev/null
+++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServiceflappingendhistoryQuery.php
@@ -0,0 +1,31 @@
+select->from(
+ array('sfh' => $this->prefix . 'flappinghistory'),
+ array()
+ )->join(
+ array('so' => $this->prefix . 'objects'),
+ 'so.object_id = sfh.object_id AND so.is_active = 1 AND so.objecttype_id = 2',
+ array()
+ );
+
+ $this->select->where('sfh.event_type = 1001');
+
+ $this->joinedVirtualTables['flappinghistory'] = true;
+
+ $this->columnMap['flappinghistory']['type'] = '(\'flapping_deleted\')';
+ }
+}
diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServiceflappingstarthistoryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServiceflappingstarthistoryQuery.php
new file mode 100644
index 000000000..f5dcfbd12
--- /dev/null
+++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServiceflappingstarthistoryQuery.php
@@ -0,0 +1,171 @@
+ array('sfh.flappinghistory_id', 'so.object_id'));
+
+ /**
+ * {@inheritdoc}
+ */
+ protected $groupOrigin = array('hostgroups', 'servicegroups');
+
+ /**
+ * {@inheritdoc}
+ */
+ protected $columnMap = array(
+ 'flappinghistory' => array(
+ 'host_name' => 'so.name1',
+ 'object_id' => 'sfh.object_id',
+ 'object_type' => '(\'service\')',
+ 'output' => '(sfh.percent_state_change || \'\')',
+ 'service_description' => 'so.name2',
+ 'service_host_name' => 'so.name1',
+ 'state' => '(-1)',
+ 'timestamp' => 'UNIX_TIMESTAMP(sfh.event_time)',
+ 'type' => "('flapping')"
+ ),
+ 'hostgroups' => array(
+ 'hostgroup_alias' => 'hg.alias COLLATE latin1_general_ci',
+ 'hostgroup_name' => 'hgo.name1'
+ ),
+ 'hosts' => array(
+ 'host_alias' => 'h.alias',
+ 'host_display_name' => 'h.display_name COLLATE latin1_general_ci'
+ ),
+ 'instances' => array(
+ 'instance_name' => 'i.instance_name'
+ ),
+ 'servicegroups' => array(
+ 'servicegroup_name' => 'sgo.name1',
+ 'servicegroup_alias' => 'sg.alias COLLATE latin1_general_ci'
+ ),
+ 'services' => array(
+ 'service_display_name' => 's.display_name COLLATE latin1_general_ci'
+ )
+ );
+
+ /**
+ * {@inheritdoc}
+ */
+ public function whereToSql($col, $sign, $expression)
+ {
+ if ($col === 'UNIX_TIMESTAMP(sfh.event_time)') {
+ return 'sfh.event_time ' . $sign . ' ' . $this->timestampForSql(
+ $this->valueToTimestamp($expression)
+ );
+ } else {
+ return parent::whereToSql($col, $sign, $expression);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function joinBaseTables()
+ {
+ $this->select->from(
+ array('sfh' => $this->prefix . 'flappinghistory'),
+ array()
+ )->join(
+ array('so' => $this->prefix . 'objects'),
+ 'so.object_id = sfh.object_id AND so.is_active = 1 AND so.objecttype_id = 2',
+ array()
+ );
+
+ $this->select->where('sfh.event_type = 1000');
+
+ $this->joinedVirtualTables['flappinghistory'] = true;
+ }
+
+ /**
+ * Join host groups
+ */
+ protected function joinHostgroups()
+ {
+ $this->requireVirtualTable('services');
+ $this->select->joinLeft(
+ array('hgm' => $this->prefix . 'hostgroup_members'),
+ 'hgm.host_object_id = s.host_object_id',
+ array()
+ )->joinLeft(
+ array('hg' => $this->prefix . 'hostgroups'),
+ 'hg.hostgroup_id = hgm.hostgroup_id',
+ array()
+ )->joinLeft(
+ array('hgo' => $this->prefix . 'objects'),
+ 'hgo.object_id = hg.hostgroup_object_id AND hgo.is_active = 1 AND hgo.objecttype_id = 3',
+ array()
+ );
+ }
+
+ /**
+ * Join hosts
+ */
+ protected function joinHosts()
+ {
+ $this->requireVirtualTable('services');
+ $this->select->join(
+ array('h' => $this->prefix . 'hosts'),
+ 'h.host_object_id = s.host_object_id',
+ array()
+ );
+ }
+
+ /**
+ * Join instances
+ */
+ protected function joinInstances()
+ {
+ $this->select->join(
+ array('i' => $this->prefix . 'instances'),
+ 'i.instance_id = sfh.instance_id',
+ array()
+ );
+ }
+
+ /**
+ * Join service groups
+ */
+ protected function joinServicegroups()
+ {
+ $this->select->joinLeft(
+ array('sgm' => $this->prefix . 'servicegroup_members'),
+ 'sgm.service_object_id = so.object_id',
+ array()
+ )->joinLeft(
+ array('sg' => $this->prefix . 'servicegroups'),
+ 'sg.' . $this->servicegroup_id . ' = sgm.servicegroup_id',
+ array()
+ )->joinLeft(
+ array('sgo' => $this->prefix . 'objects'),
+ 'sgo.object_id = sg.servicegroup_object_id AND sgo.is_active = 1 AND sgo.objecttype_id = 4',
+ array()
+ );
+ }
+
+ /**
+ * Join services
+ */
+ protected function joinServices()
+ {
+ $this->select->join(
+ array('s' => $this->prefix . 'services'),
+ 's.service_object_id = so.object_id',
+ array()
+ );
+ }
+}