Module: check_mk
Branch: master
Commit: 19e8f0b63b685298fa9eba50674ddc57cc3e95a3
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=19e8f0b63b6852…
Author: Sven Panne <sp(a)mathias-kettner.de>
Date: Mon Nov 6 15:16:11 2017 +0100
Unify special double column implementations.
Change-Id: I00d64bff1dfbf80c890fe26ac327fd0c5d6e71f9
---
livestatus/src/HostSpecialDoubleColumn.cc | 100 ++++++++++++++++++++++++++-
livestatus/src/HostSpecialDoubleColumn.h | 11 ++-
livestatus/src/ServiceSpecialDoubleColumn.cc | 29 ++++++--
livestatus/src/ServiceSpecialDoubleColumn.h | 3 +-
4 files changed, 131 insertions(+), 12 deletions(-)
diff --git a/livestatus/src/HostSpecialDoubleColumn.cc
b/livestatus/src/HostSpecialDoubleColumn.cc
index aca26bd..9ff0c44 100644
--- a/livestatus/src/HostSpecialDoubleColumn.cc
+++ b/livestatus/src/HostSpecialDoubleColumn.cc
@@ -23,21 +23,115 @@
// Boston, MA 02110-1301 USA.
#include "HostSpecialDoubleColumn.h"
-#include <ctime>
#include "Row.h"
-#include "nagios.h"
-extern int interval_length;
+#ifdef CMC
+// duration_cast uses enable_if as an implementation detail, similar bug as
+//
https://github.com/include-what-you-use/include-what-you-use/issues/434
+// IWYU pragma: no_include <type_traits>
+#include <chrono>
+#include <ratio>
+#include "Object.h"
+#include "State.h"
+#include "Timeperiod.h"
+#else
+#include <ctime>
+#include "nagios.h"
+#endif
double HostSpecialDoubleColumn::getValue(Row row) const {
+#ifdef CMC
+ if (auto object = columnData<Object>(row)) {
+ switch (_type) {
+ case Type::staleness:
+ return staleness(object);
+ }
+ }
+#else
if (auto hst = columnData<host>(row)) {
switch (_type) {
case Type::staleness: {
+ extern int interval_length;
return (time(nullptr) - hst->last_check) /
((hst->check_interval == 0 ? 1 : hst->check_interval) *
interval_length);
}
}
}
+#endif
return 0;
}
+
+#ifdef CMC
+// static
+double HostSpecialDoubleColumn::staleness(const Object *object) {
+ auto state = object->state();
+ std::chrono::system_clock::duration check_result_age;
+ Timeperiod *check_period = object->_check_period;
+ std::chrono::system_clock::time_point last_period_change =
+ check_period->lastStateChange();
+ std::chrono::system_clock::time_point last_check = state->_last_check;
+
+ // Compute the age of the check result. When the check is currently in its
+ // check period then...
+ auto m_now = std::chrono::system_clock::now();
+ if (check_period->isActive()) {
+ // Has a check happened since the beginning of the current phase? Then
+ // simply compare last check with current time. This should be the 99%
+ // case.
+ if (last_check >= last_period_change) {
+ check_result_age = m_now - last_check;
+
+ } else {
+ // otherwise the active phase has just begun. Take the time since
+ // the beginning of the phase.
+ check_result_age = m_now - last_period_change;
+
+ // Add time at the end of the pre-last transition
+ std::chrono::system_clock::time_point prelast_period_change =
+ check_period->previousLastStateChange();
+ if (prelast_period_change !=
+ std::chrono::system_clock::time_point()) {
+ if (last_check < prelast_period_change) {
+ check_result_age += prelast_period_change - last_check;
+ }
+ // else: a check happend out of the check period. Ignore this
+ }
+ // else: no information about past. Ignore this
+ }
+ } else {
+ // Check is currently out of its check period? Then use the beginning of
+ // the inactive phase as reference for computing the check age. This
+ // effectively freezes the staleness value when a goes goes into its
+ // inactive phase.
+ if (last_period_change != std::chrono::system_clock::time_point()) {
+ check_result_age = last_period_change - last_check;
+ } else {
+ // e.g. for timeperiod "never"
+ check_result_age = std::chrono::seconds(0);
+ }
+ }
+
+ // Is the checks' result based on cached agent data? Then use the age of
+ // that data as check result age
+ std::chrono::duration<double> interval;
+ if (state->_cached_at != std::chrono::system_clock::time_point()) {
+ // Cache interval and check interval can add up in the worst case.
+ interval = state->_cache_interval + object->_check_interval;
+
+ std::chrono::system_clock::duration cached_age =
+ m_now - state->_cached_at;
+ if (cached_age > check_result_age) {
+ check_result_age = cached_age;
+ }
+ } else {
+ interval = object->_check_interval;
+ }
+
+ // Check_MK configures the interval for its passive checks correctly. Just
+ // make sure that we do not fail if it is set to 0 by some error.
+ return std::chrono::duration_cast<std::chrono::seconds>(check_result_age)
+ .count() /
+ (interval == std::chrono::seconds(0) ? 1 : interval.count());
+}
+#endif
diff --git a/livestatus/src/HostSpecialDoubleColumn.h
b/livestatus/src/HostSpecialDoubleColumn.h
index afe0bce..ba6e437 100644
--- a/livestatus/src/HostSpecialDoubleColumn.h
+++ b/livestatus/src/HostSpecialDoubleColumn.h
@@ -30,6 +30,10 @@
#include "DoubleColumn.h"
class Row;
+#ifdef CMC
+class Object;
+#endif
+
class HostSpecialDoubleColumn : public DoubleColumn {
public:
enum class Type { staleness };
@@ -41,10 +45,15 @@ public:
: DoubleColumn(name, description, indirect, extra_offset,
extra_extra_offset, offset)
, _type(hsdc_type) {}
+
double getValue(Row row) const override;
+#ifdef CMC
+ static double staleness(const Object* object);
+#endif
+
private:
- Type _type;
+ const Type _type;
};
#endif // HostSpecialDoubleColumn_h
diff --git a/livestatus/src/ServiceSpecialDoubleColumn.cc
b/livestatus/src/ServiceSpecialDoubleColumn.cc
index 747543d..0266947 100644
--- a/livestatus/src/ServiceSpecialDoubleColumn.cc
+++ b/livestatus/src/ServiceSpecialDoubleColumn.cc
@@ -23,17 +23,30 @@
// Boston, MA 02110-1301 USA.
#include "ServiceSpecialDoubleColumn.h"
+#include "Row.h"
+
+#ifdef CMC
+#include "HostSpecialDoubleColumn.h"
+class Object;
+#else
#include <cstring>
#include <ctime>
-#include "Row.h"
#include "nagios.h"
-
-extern int interval_length;
+#endif
double ServiceSpecialDoubleColumn::getValue(Row row) const {
+#ifdef CMC
+ if (auto object = columnData<Object>(row)) {
+ switch (_type) {
+ case Type::staleness:
+ return HostSpecialDoubleColumn::staleness(object);
+ }
+ }
+#else
if (auto svc = columnData<service>(row)) {
switch (_type) {
case Type::staleness: {
+ extern int interval_length;
time_t check_result_age = time(nullptr) - svc->last_check;
if (svc->check_interval != 0) {
return check_result_age /
@@ -58,13 +71,15 @@ double ServiceSpecialDoubleColumn::getValue(Row row) const {
interval_length);
}
}
- return 1; // Shouldnt happen! We always expect a check-mk
- // service
- } // Other non-cmk passive and active checks without
- // check_interval
+ // Shouldn't happen! We always expect a check-mk service
+ return 1;
+ }
+ // Other non-cmk passive and active checks without
+ // check_interval
return check_result_age / interval_length;
}
}
}
+#endif
return 0;
}
diff --git a/livestatus/src/ServiceSpecialDoubleColumn.h
b/livestatus/src/ServiceSpecialDoubleColumn.h
index 190c3f0..e6e2ae7 100644
--- a/livestatus/src/ServiceSpecialDoubleColumn.h
+++ b/livestatus/src/ServiceSpecialDoubleColumn.h
@@ -41,10 +41,11 @@ public:
: DoubleColumn(name, description, indirect, extra_offset,
extra_extra_offset, offset)
, _type(ssdc_type) {}
+
double getValue(Row row) const override;
private:
- Type _type;
+ const Type _type;
};
#endif // ServiceSpecialDoubleColumn_h