]> granicus.if.org Git - icinga2/blob - lib/icinga/checkable-flapping.cpp
Merge pull request #6719 from Icinga/fix/finished-reconnect-message
[icinga2] / lib / icinga / checkable-flapping.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2018 Icinga Development Team (https://icinga.com/)      *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "icinga/checkable.hpp"
21 #include "icinga/icingaapplication.hpp"
22 #include "base/utility.hpp"
23
24 using namespace icinga;
25
26 template<typename T>
27 struct Bitset
28 {
29 public:
30         Bitset(T value)
31                 : m_Data(value)
32         { }
33
34         void Modify(int index, bool bit)
35         {
36                 if (bit)
37                         m_Data |= 1 << index;
38                 else
39                         m_Data &= ~(1 << index);
40         }
41
42         bool Get(int index) const
43         {
44                 return m_Data & (1 << index);
45         }
46
47         T GetValue() const
48         {
49                 return m_Data;
50         }
51
52 private:
53         T m_Data{0};
54 };
55
56 void Checkable::UpdateFlappingStatus(bool stateChange)
57 {
58         Bitset<unsigned long> stateChangeBuf = GetFlappingBuffer();
59         int oldestIndex = GetFlappingIndex();
60
61         stateChangeBuf.Modify(oldestIndex, stateChange);
62         oldestIndex = (oldestIndex + 1) % 20;
63
64         double stateChanges = 0;
65
66         /* Iterate over our state array and compute a weighted total */
67         for (int i = 0; i < 20; i++) {
68                 if (stateChangeBuf.Get((oldestIndex + i) % 20))
69                         stateChanges += 0.8 + (0.02 * i);
70         }
71
72         double flappingValue = 100.0 * stateChanges / 20.0;
73
74         bool flapping;
75
76         if (GetFlapping())
77                 flapping = flappingValue > GetFlappingThresholdLow();
78         else
79                 flapping = flappingValue > GetFlappingThresholdHigh();
80
81         SetFlappingBuffer(stateChangeBuf.GetValue());
82         SetFlappingIndex(oldestIndex);
83         SetFlappingCurrent(flappingValue);
84         SetFlapping(flapping, true);
85
86         if (flapping != GetFlapping())
87                 SetFlappingLastChange(Utility::GetTime());
88 }
89
90 bool Checkable::IsFlapping() const
91 {
92         if (!GetEnableFlapping() || !IcingaApplication::GetInstance()->GetEnableFlapping())
93                 return false;
94         else
95                 return GetFlapping();
96 }