objectset.h \
objectmap.cpp \
objectmap.h \
+ ringbuffer.cpp \
+ ringbuffer.h \
socket.cpp \
socket.h \
tcpclient.cpp \
#include "event.h"
#include "variant.h"
#include "dictionary.h"
+#include "ringbuffer.h"
#include "timer.h"
#include "fifo.h"
#include "socket.h"
--- /dev/null
+#include "i2-base.h"
+
+using namespace icinga;
+
+Ringbuffer::Ringbuffer(int slots)
+ : m_Slots(slots, 0), m_Offset(0)
+{ }
+
+int Ringbuffer::GetLength(void) const
+{
+ return m_Slots.size();
+}
+
+void Ringbuffer::InsertValue(long tv, int num)
+{
+ int offsetTarget = tv % m_Slots.size();
+
+ /* walk towards the target offset, resetting slots to 0 */
+ while (m_Offset != offsetTarget) {
+ m_Offset++;
+
+ if (m_Offset >= m_Slots.size())
+ m_Offset = 0;
+
+ m_Slots[m_Offset] = 0;
+ }
+
+ m_Slots[m_Offset] += num;
+}
+
+int Ringbuffer::GetValues(long span) const
+{
+ if (span > m_Slots.size())
+ span = m_Slots.size();
+
+ int off = m_Offset;
+ int sum = 0;
+ while (span > 0) {
+ sum += m_Slots[off];
+
+ if (off == 0)
+ off = m_Slots.size();
+
+ off--;
+ span--;
+ }
+
+ return sum;
+}
--- /dev/null
+#ifndef RINGBUFFER_H
+#define RINGBUFFER_H
+
+namespace icinga
+{
+
+class Ringbuffer
+{
+public:
+ Ringbuffer(int slots);
+
+ int GetLength(void) const;
+ void InsertValue(long tv, int num);
+ int GetValues(long span) const;
+
+private:
+ vector<int> m_Slots;
+ int m_Offset;
+};
+
+}
+
+#endif /* RINGBUFFER_H */
<< "\t" << "current_state=" << service.GetState() << endl
<< "\t" << "state_type=" << service.GetStateType() << endl
<< "\t" << "plugin_output=" << plugin_output << endl
- << "\t" << "last_check=" << schedule_start << endl
+ << "\t" << "last_check=" << schedule_end << endl
<< "\t" << "next_check=" << service.GetNextCheck() << endl
<< "\t" << "current_attempt=" << service.GetCurrentCheckAttempt() << endl
<< "\t" << "max_attempts=" << service.GetMaxCheckAttempts() << endl
<< "\t" << "check_host_freshness=0" << endl
<< "\t" << "enable_flap_detection=1" << endl
<< "\t" << "enable_failure_prediction=0" << endl
+ << "\t" << "active_scheduled_service_check_stats=" << CheckTask::GetTaskStatistics(60) << "," << CheckTask::GetTaskStatistics(5 * 60) << "," << CheckTask::GetTaskStatistics(15 * 60) << endl
<< endl;
ofstream objectfp;
map<string, CheckTaskType> CheckTask::m_Types;
vector<CheckTask::Ptr> CheckTask::m_FinishedTasks;
mutex CheckTask::m_FinishedTasksMutex;
+Ringbuffer CheckTask::m_TaskStatistics(15 * 60);
CheckTask::CheckTask(const Service& service)
: m_Service(service)
{
mutex::scoped_lock lock(m_FinishedTasksMutex);
m_FinishedTasks.push_back(task);
+ m_TaskStatistics.InsertValue(task->GetResult().GetScheduleEnd(), 1);
+}
+
+int CheckTask::GetTaskStatistics(time_t timespan)
+{
+ mutex::scoped_lock lock(m_FinishedTasksMutex);
+ return m_TaskStatistics.GetValues(timespan);
}
static void Enqueue(const CheckTask::Ptr& task);
static void FlushQueue(void);
+ static int GetTaskHistogramSlots(void);
static void FinishTask(const CheckTask::Ptr& task);
static vector<CheckTask::Ptr> GetFinishedTasks(void);
+ static int GetTaskStatistics(time_t timespan);
+
protected:
CheckTask(const Service& service);
static vector<CheckTask::Ptr> m_FinishedTasks;
static mutex m_FinishedTasksMutex;
+ static Ringbuffer m_TaskStatistics;
};
struct CheckTaskType