]> granicus.if.org Git - icinga2/blob - lib/icinga/checkable-flapping.cpp
Merge pull request #7527 from Icinga/bugfix/checkable-command-endpoint-zone
[icinga2] / lib / icinga / checkable-flapping.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #include "icinga/checkable.hpp"
4 #include "icinga/icingaapplication.hpp"
5 #include "base/utility.hpp"
6
7 using namespace icinga;
8
9 template<typename T>
10 struct Bitset
11 {
12 public:
13         Bitset(T value)
14                 : m_Data(value)
15         { }
16
17         void Modify(int index, bool bit)
18         {
19                 if (bit)
20                         m_Data |= 1 << index;
21                 else
22                         m_Data &= ~(1 << index);
23         }
24
25         bool Get(int index) const
26         {
27                 return m_Data & (1 << index);
28         }
29
30         T GetValue() const
31         {
32                 return m_Data;
33         }
34
35 private:
36         T m_Data{0};
37 };
38
39 void Checkable::UpdateFlappingStatus(bool stateChange)
40 {
41         Bitset<unsigned long> stateChangeBuf = GetFlappingBuffer();
42         int oldestIndex = GetFlappingIndex();
43
44         stateChangeBuf.Modify(oldestIndex, stateChange);
45         oldestIndex = (oldestIndex + 1) % 20;
46
47         double stateChanges = 0;
48
49         /* Iterate over our state array and compute a weighted total */
50         for (int i = 0; i < 20; i++) {
51                 if (stateChangeBuf.Get((oldestIndex + i) % 20))
52                         stateChanges += 0.8 + (0.02 * i);
53         }
54
55         double flappingValue = 100.0 * stateChanges / 20.0;
56
57         bool flapping;
58
59         if (GetFlapping())
60                 flapping = flappingValue > GetFlappingThresholdLow();
61         else
62                 flapping = flappingValue > GetFlappingThresholdHigh();
63
64         SetFlappingBuffer(stateChangeBuf.GetValue());
65         SetFlappingIndex(oldestIndex);
66         SetFlappingCurrent(flappingValue);
67         SetFlapping(flapping, true);
68
69         if (flapping != GetFlapping())
70                 SetFlappingLastChange(Utility::GetTime());
71 }
72
73 bool Checkable::IsFlapping() const
74 {
75         if (!GetEnableFlapping() || !IcingaApplication::GetInstance()->GetEnableFlapping())
76                 return false;
77         else
78                 return GetFlapping();
79 }