From e060995fd846bb48197050be6b18d15c2c2f7191 Mon Sep 17 00:00:00 2001 From: Noah Hilverling Date: Wed, 11 Nov 2020 17:43:30 +0100 Subject: [PATCH] Flapping: Allow to ignore states in flapping calculation --- doc/08-advanced-topics.md | 2 ++ doc/09-object-types.md | 2 ++ lib/icinga/checkable-check.cpp | 2 +- lib/icinga/checkable-flapping.cpp | 29 ++++++++++++++++++++++++++++- lib/icinga/checkable.cpp | 16 ++++++++++++++++ lib/icinga/checkable.hpp | 17 ++++++++++++++++- lib/icinga/checkable.ti | 6 ++++++ 7 files changed, 71 insertions(+), 3 deletions(-) diff --git a/doc/08-advanced-topics.md b/doc/08-advanced-topics.md index 252910ac5..d098da740 100644 --- a/doc/08-advanced-topics.md +++ b/doc/08-advanced-topics.md @@ -468,6 +468,8 @@ when a [host](09-object-types.md#objecttype-host) or [service](09-object-types.m The default thresholds are 30% for high and 25% for low. If the computed flapping value exceeds the high threshold a host or service is considered flapping until it drops below the low flapping threshold. +The attribute `flapping_ignore_states` allows to ignore state changes to specified states during the flapping calculation. + `FlappingStart` and `FlappingEnd` notifications will be sent out accordingly, if configured. See the chapter on [notifications](alert-notifications) for details diff --git a/doc/09-object-types.md b/doc/09-object-types.md index b1dfc4993..e7d6c521d 100644 --- a/doc/09-object-types.md +++ b/doc/09-object-types.md @@ -359,6 +359,7 @@ Configuration Attributes: event\_command | Object name | **Optional.** The name of an event command that should be executed every time the host's state changes or the host is in a `SOFT` state. flapping\_threshold\_high | Number | **Optional.** Flapping upper bound in percent for a host to be considered flapping. Default `30.0` flapping\_threshold\_low | Number | **Optional.** Flapping lower bound in percent for a host to be considered not flapping. Default `25.0` + flapping\_ignore\_states | Array | **Optional.** A list of states that should be ignored during flapping calculation. By default no state is ignored. volatile | Boolean | **Optional.** Treat all state changes as HARD changes. See [here](08-advanced-topics.md#volatile-services-hosts) for details. Defaults to `false`. zone | Object name | **Optional.** The zone this object is a member of. Please read the [distributed monitoring](06-distributed-monitoring.md#distributed-monitoring) chapter for details. command\_endpoint | Object name | **Optional.** The endpoint where commands are executed on. @@ -721,6 +722,7 @@ Configuration Attributes: enable\_flapping | Boolean | **Optional.** Whether flap detection is enabled. Defaults to `false`. flapping\_threshold\_high | Number | **Optional.** Flapping upper bound in percent for a service to be considered flapping. `30.0` flapping\_threshold\_low | Number | **Optional.** Flapping lower bound in percent for a service to be considered not flapping. `25.0` + flapping\_ignore\_states | Array | **Optional.** A list of states that should be ignored during flapping calculation. By default no state is ignored. enable\_perfdata | Boolean | **Optional.** Whether performance data processing is enabled. Defaults to `true`. event\_command | Object name | **Optional.** The name of an event command that should be executed every time the service's state changes or the service is in a `SOFT` state. volatile | Boolean | **Optional.** Treat all state changes as HARD changes. See [here](08-advanced-topics.md#volatile-services-hosts) for details. Defaults to `false`. diff --git a/lib/icinga/checkable-check.cpp b/lib/icinga/checkable-check.cpp index d0c49b80e..c84a0dd3b 100644 --- a/lib/icinga/checkable-check.cpp +++ b/lib/icinga/checkable-check.cpp @@ -369,7 +369,7 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig bool was_flapping = IsFlapping(); - UpdateFlappingStatus(old_state != cr->GetState()); + UpdateFlappingStatus(cr->GetState()); bool is_flapping = IsFlapping(); diff --git a/lib/icinga/checkable-flapping.cpp b/lib/icinga/checkable-flapping.cpp index 3b49a6cdd..e905e05f5 100644 --- a/lib/icinga/checkable-flapping.cpp +++ b/lib/icinga/checkable-flapping.cpp @@ -36,11 +36,22 @@ private: T m_Data{0}; }; -void Checkable::UpdateFlappingStatus(bool stateChange) +void Checkable::UpdateFlappingStatus(ServiceState newState) { Bitset stateChangeBuf = GetFlappingBuffer(); int oldestIndex = GetFlappingIndex(); + ServiceState lastState = GetFlappingLastState(); + bool stateChange = false; + + int stateFilter = GetFlappingIgnoreStatesFilter(); + + /* Only count as state change if no state filter is set or the new state isn't filtered out */ + if (stateFilter == -1 || !(ServiceStateToFlappingFilter(newState) & stateFilter)) { + stateChange = newState != lastState; + SetFlappingLastState(newState); + } + stateChangeBuf.Modify(oldestIndex, stateChange); oldestIndex = (oldestIndex + 1) % 20; @@ -85,3 +96,19 @@ bool Checkable::IsFlapping() const else return GetFlapping(); } + +int Checkable::ServiceStateToFlappingFilter(ServiceState state) +{ + switch (state) { + case ServiceOK: + return StateFilterOK; + case ServiceWarning: + return StateFilterWarning; + case ServiceCritical: + return StateFilterCritical; + case ServiceUnknown: + return StateFilterUnknown; + default: + VERIFY(!"Invalid state type."); + } +} diff --git a/lib/icinga/checkable.cpp b/lib/icinga/checkable.cpp index 8f21e71f1..acf8b2a87 100644 --- a/lib/icinga/checkable.cpp +++ b/lib/icinga/checkable.cpp @@ -15,6 +15,15 @@ using namespace icinga; REGISTER_TYPE_WITH_PROTOTYPE(Checkable, Checkable::GetPrototype()); INITIALIZE_ONCE(&Checkable::StaticInitialize); +const std::map Checkable::m_FlappingStateFilterMap ({ + {"OK", FlappingStateFilterOk}, + {"Warning", FlappingStateFilterWarning}, + {"Critical", FlappingStateFilterCritical}, + {"Unknown", FlappingStateFilterUnknown}, + {"Up", FlappingStateFilterOk}, + {"Down", FlappingStateFilterCritical}, +}); + boost::signals2::signal Checkable::OnAcknowledgementSet; boost::signals2::signal Checkable::OnAcknowledgementCleared; boost::signals2::signal Checkable::OnFlappingChange; @@ -36,6 +45,13 @@ Checkable::Checkable() SetSchedulingOffset(Utility::Random()); } +void Checkable::OnConfigLoaded() +{ + ObjectImpl::OnConfigLoaded(); + + SetFlappingIgnoreStatesFilter(FilterArrayToInt(GetFlappingIgnoreStates(), m_FlappingStateFilterMap, ~0)); +} + void Checkable::OnAllConfigLoaded() { ObjectImpl::OnAllConfigLoaded(); diff --git a/lib/icinga/checkable.hpp b/lib/icinga/checkable.hpp index dc782aca5..7def86b59 100644 --- a/lib/icinga/checkable.hpp +++ b/lib/icinga/checkable.hpp @@ -39,6 +39,17 @@ enum CheckableType CheckableService }; +/** + * @ingroup icinga + */ +enum FlappingStateFilter +{ + FlappingStateFilterOk = 1, + FlappingStateFilterWarning = 2, + FlappingStateFilterCritical = 4, + FlappingStateFilterUnknown = 8, +}; + class CheckCommand; class EventCommand; class Dependency; @@ -183,6 +194,7 @@ public: protected: void Start(bool runtimeCreated) override; + void OnConfigLoaded() override; void OnAllConfigLoaded() override; private: @@ -222,7 +234,10 @@ private: void GetAllChildrenInternal(std::set& children, int level = 0) const; /* Flapping */ - void UpdateFlappingStatus(bool stateChange); + static const std::map m_FlappingStateFilterMap; + + void UpdateFlappingStatus(ServiceState newState); + static int ServiceStateToFlappingFilter(ServiceState state); }; } diff --git a/lib/icinga/checkable.ti b/lib/icinga/checkable.ti index ad34f6d42..8c75542c1 100644 --- a/lib/icinga/checkable.ti +++ b/lib/icinga/checkable.ti @@ -73,6 +73,9 @@ abstract class Checkable : CustomVarObject default {{{ return true; }}} }; + [config] array(String) flapping_ignore_states; + [no_user_view, no_user_modify] int flapping_ignore_states_filter_real (FlappingIgnoreStatesFilter); + [config, deprecated] double flapping_threshold; [config] double flapping_threshold_low { @@ -163,6 +166,9 @@ abstract class Checkable : CustomVarObject }; [state] Timestamp flapping_last_change; + [state, enum, no_user_view, no_user_modify] ServiceState flapping_last_state { + default {{{ return ServiceUnknown; }}} + }; [state, no_user_view, no_user_modify] int flapping_buffer; [state, no_user_view, no_user_modify] int flapping_index; [state, protected] bool flapping;