diff --git a/doc/12-icinga2-api.md b/doc/12-icinga2-api.md
index 725fdb321..15471e9c6 100644
--- a/doc/12-icinga2-api.md
+++ b/doc/12-icinga2-api.md
@@ -1306,15 +1306,18 @@ Example for all downtime events:
#### Event Stream Type: Flapping
- Name | Type | Description
- --------------|---------------|--------------------------
- type | String | Event type `Flapping`.
- timestamp | Timestamp | Unix timestamp when the event happened.
- host | String | [Host](09-object-types.md#objecttype-host) name.
- service | String | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host flapping event.
- state | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
- state\_type | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
- is\_flapping | Boolean | Whether this object is flapping.
+ Name | Type | Description
+ ------------------|---------------|--------------------------
+ type | String | Event type `Flapping`.
+ timestamp | Timestamp | Unix timestamp when the event happened.
+ host | String | [Host](09-object-types.md#objecttype-host) name.
+ service | String | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host flapping event.
+ state | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
+ state\_type | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
+ is\_flapping | Boolean | Whether this object is flapping.
+ current\_flapping | Number | Current flapping value in percent (added in 2.8).
+ threshold\_low | Number | Low threshold in percent (added in 2.8).
+ threshold\_high | Number | High threshold in percent (added in 2.8).
#### Event Stream Type: AcknowledgementSet
diff --git a/lib/icinga/apievents.cpp b/lib/icinga/apievents.cpp
index 0fb38e190..7d0f5cd29 100644
--- a/lib/icinga/apievents.cpp
+++ b/lib/icinga/apievents.cpp
@@ -170,6 +170,9 @@ void ApiEvents::FlappingChangedHandler(const Checkable::Ptr& checkable, const Me
result->Set("state", service ? static_cast(service->GetState()) : static_cast(host->GetState()));
result->Set("state_type", checkable->GetStateType());
result->Set("is_flapping", checkable->IsFlapping());
+ result->Set("flapping_current", checkable->GetFlappingCurrent());
+ result->Set("threshold_low", checkable->GetFlappingThresholdLow());
+ result->Set("threshold_high", checkable->GetFlappingThresholdHigh());
for (const EventQueue::Ptr& queue : queues) {
queue->ProcessEvent(result);
diff --git a/lib/icinga/checkable-check.cpp b/lib/icinga/checkable-check.cpp
index a89fa1463..893903ba4 100644
--- a/lib/icinga/checkable-check.cpp
+++ b/lib/icinga/checkable-check.cpp
@@ -332,12 +332,15 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
olock.Unlock();
-// Log(LogDebug, "Checkable")
-// << "Flapping: Checkable " << GetName()
-// << " was: " << (was_flapping)
-// << " is: " << is_flapping)
-// << " threshold: " << GetFlappingThreshold()
-// << "% current: " + GetFlappingCurrent()) << "%.";
+#ifdef I2_DEBUG /* I2_DEBUG */
+ Log(LogDebug, "Checkable")
+ << "Flapping: Checkable " << GetName()
+ << " was: " << was_flapping
+ << " is: " << is_flapping
+ << " threshold low: " << GetFlappingThresholdLow()
+ << " threshold high: " << GetFlappingThresholdHigh()
+ << "% current: " << GetFlappingCurrent() << "%.";
+#endif /* I2_DEBUG */
OnNewCheckResult(this, cr, origin);
@@ -371,7 +374,8 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
OnNotificationsRequested(this, NotificationFlappingStart, cr, "", "", MessageOrigin::Ptr());
Log(LogNotice, "Checkable")
- << "Flapping: Checkable '" << GetName() << "' started flapping (Current flapping value " << GetFlappingCurrent() << "% > threshold " << GetFlappingThresholdHigh() << "%).";
+ << "Flapping Start: Checkable '" << GetName() << "' started flapping (Current flapping value "
+ << GetFlappingCurrent() << "% > high threshold " << GetFlappingThresholdHigh() << "%).";
NotifyFlapping(origin);
} else if (!in_downtime && was_flapping && !is_flapping) {
@@ -380,7 +384,8 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
OnNotificationsRequested(this, NotificationFlappingEnd, cr, "", "", MessageOrigin::Ptr());
Log(LogNotice, "Checkable")
- << "Flapping: Checkable '" << GetName() << "' stopped flapping (Current flapping value " << GetFlappingCurrent() << "% < threshold " << GetFlappingThresholdLow() << "%).";
+ << "Flapping Stop: Checkable '" << GetName() << "' stopped flapping (Current flapping value "
+ << GetFlappingCurrent() << "% < low threshold " << GetFlappingThresholdLow() << "%).";
NotifyFlapping(origin);
}
diff --git a/lib/icinga/checkable-flapping.cpp b/lib/icinga/checkable-flapping.cpp
index af5ced050..84bba8e5b 100644
--- a/lib/icinga/checkable-flapping.cpp
+++ b/lib/icinga/checkable-flapping.cpp
@@ -27,13 +27,14 @@ using namespace icinga;
void Checkable::UpdateFlappingStatus(bool stateChange)
{
std::bitset<20> stateChangeBuf = GetFlappingBuffer();
- int oldestIndex = (GetFlappingBuffer() & 0xFF00000) >> 20;
+ int oldestIndex = GetFlappingIndex();
stateChangeBuf[oldestIndex] = stateChange;
oldestIndex = (oldestIndex + 1) % 20;
double stateChanges = 0;
+ /* Iterate over our state array and compute a weighted total */
for (int i = 0; i < 20; i++) {
if (stateChangeBuf[(oldestIndex + i) % 20])
stateChanges += 0.8 + (0.02 * i);
@@ -48,12 +49,13 @@ void Checkable::UpdateFlappingStatus(bool stateChange)
else
flapping = flappingValue > GetFlappingThresholdHigh();
+ SetFlappingBuffer(stateChangeBuf.to_ulong());
+ SetFlappingIndex(oldestIndex);
+ SetFlappingCurrent(flappingValue);
+ SetFlapping(flapping, true);
+
if (flapping != GetFlapping())
SetFlappingLastChange(Utility::GetTime());
-
- SetFlappingBuffer((stateChangeBuf.to_ulong() | (oldestIndex << 20)));
- SetFlappingCurrent(flappingValue);
- SetFlapping(flapping);
}
bool Checkable::IsFlapping(void) const
diff --git a/lib/icinga/checkable.hpp b/lib/icinga/checkable.hpp
index 0617eca12..4060f1d00 100644
--- a/lib/icinga/checkable.hpp
+++ b/lib/icinga/checkable.hpp
@@ -181,7 +181,6 @@ public:
/* Flapping Detection */
bool IsFlapping(void) const;
- void UpdateFlappingStatus(bool stateChange);
/* Dependencies */
void AddDependency(const intrusive_ptr& dep);
@@ -237,6 +236,9 @@ private:
std::set > m_ReverseDependencies;
void GetAllChildrenInternal(std::set& children, int level = 0) const;
+
+ /* Flapping */
+ void UpdateFlappingStatus(bool stateChange);
};
}
diff --git a/lib/icinga/checkable.ti b/lib/icinga/checkable.ti
index ced78b8e9..6ecf3ffaf 100644
--- a/lib/icinga/checkable.ti
+++ b/lib/icinga/checkable.ti
@@ -158,7 +158,9 @@ abstract class Checkable : CustomVarObject
default {{{ return 0; }}}
};
[state] Timestamp flapping_last_change;
+
[state, no_user_view, no_user_modify] int flapping_buffer;
+ [state, no_user_view, no_user_modify] int flapping_index;
[state, protected] bool flapping;
[config, navigation] name(Endpoint) command_endpoint (CommandEndpointRaw) {