Added serialization support for check results.

Bugfixes.
This commit is contained in:
Gunnar Beutner 2012-06-25 14:13:24 +02:00
parent 3d6df6611c
commit 593e329248
12 changed files with 183 additions and 42 deletions

View File

@ -329,7 +329,7 @@ void Socket::ReadThreadProc(void)
HandleException(); HandleException();
if (WantsToWrite()) if (WantsToWrite())
; /* notify Write thread */ m_WriteCV.notify_all(); /* notify Write thread */
} }
} }
@ -342,17 +342,18 @@ void Socket::WriteThreadProc(void)
FD_ZERO(&writefds); FD_ZERO(&writefds);
int fd = GetFD();
while (!WantsToWrite()) { while (!WantsToWrite()) {
m_WriteCV.timed_wait(lock, boost::posix_time::seconds(1));
if (GetFD() == INVALID_SOCKET) if (GetFD() == INVALID_SOCKET)
return; return;
lock.unlock();
Sleep(500);
lock.lock();
} }
int fd = GetFD();
if (fd == INVALID_SOCKET)
return;
FD_SET(fd, &writefds); FD_SET(fd, &writefds);
lock.unlock(); lock.unlock();

View File

@ -83,6 +83,8 @@ private:
thread m_ReadThread; thread m_ReadThread;
thread m_WriteThread; thread m_WriteThread;
condition_variable m_WriteCV;
void ReadThreadProc(void); void ReadThreadProc(void);
void WriteThreadProc(void); void WriteThreadProc(void);

View File

@ -117,7 +117,7 @@ void CheckerComponent::ResultTimerHandler(void)
CheckResult result = task->GetResult(); CheckResult result = task->GetResult();
Application::Log(LogDebug, "checker", "Got result for service '" + service.GetName() + "'"); Application::Log(LogDebug, "checker", "Got result for service '" + service.GetName() + "'");
long latency = result.EndTime - result.StartTime; long latency = result.GetEndTime() - result.GetStartTime();
avg_latency += latency; avg_latency += latency;
if (min_latency == -1 || latency < min_latency) if (min_latency == -1 || latency < min_latency)
@ -128,9 +128,22 @@ void CheckerComponent::ResultTimerHandler(void)
results++; results++;
if (result.State != StateOK) if (result.GetState() != StateOK)
failed++; failed++;
RequestMessage rm;
rm.SetMethod("checker::CheckResult");
MessagePart params;
params.SetProperty("service", service.GetName());
params.SetProperty("result", result.GetDictionary());
rm.SetParams(params);
GetEndpointManager()->SendMulticastMessage(m_CheckerEndpoint, rm);
service.ApplyCheckResult(result);
service.SetNextCheck(now + service.GetCheckInterval()); service.SetNextCheck(now + service.GetCheckInterval());
m_PendingServices.erase(service.GetConfigObject()); m_PendingServices.erase(service.GetConfigObject());
m_Services.push(service); m_Services.push(service);

View File

@ -41,6 +41,7 @@ void DelegationComponent::Start(void)
m_DelegationEndpoint = boost::make_shared<VirtualEndpoint>(); m_DelegationEndpoint = boost::make_shared<VirtualEndpoint>();
m_DelegationEndpoint->RegisterPublication("checker::AssignService"); m_DelegationEndpoint->RegisterPublication("checker::AssignService");
m_DelegationEndpoint->RegisterPublication("checker::ClearServices"); m_DelegationEndpoint->RegisterPublication("checker::ClearServices");
m_DelegationEndpoint->RegisterSubscription("checker::CheckResult");
GetEndpointManager()->RegisterEndpoint(m_DelegationEndpoint); GetEndpointManager()->RegisterEndpoint(m_DelegationEndpoint);
GetEndpointManager()->OnNewEndpoint.connect(bind(&DelegationComponent::NewEndpointHandler, this, _2)); GetEndpointManager()->OnNewEndpoint.connect(bind(&DelegationComponent::NewEndpointHandler, this, _2));

View File

@ -5,6 +5,8 @@ pkglib_LTLIBRARIES = \
libicinga.la libicinga.la
libicinga_la_SOURCES = \ libicinga_la_SOURCES = \
checkresult.cpp \
checkresult.h \
checktask.cpp \ checktask.cpp \
checktask.h \ checktask.h \
configobjectadapter.cpp \ configobjectadapter.cpp \

76
icinga/checkresult.cpp Normal file
View File

@ -0,0 +1,76 @@
#include "i2-icinga.h"
using namespace icinga;
CheckResult::CheckResult(void)
: m_Data(boost::make_shared<Dictionary>())
{ }
CheckResult::CheckResult(const Dictionary::Ptr& dictionary)
: m_Data(dictionary)
{ }
Dictionary::Ptr CheckResult::GetDictionary(void) const
{
return m_Data;
}
void CheckResult::SetStartTime(time_t ts)
{
m_Data->SetProperty("start_time", static_cast<long>(ts));
}
time_t CheckResult::GetStartTime(void) const
{
long value = 0;
m_Data->GetProperty("start_time", &value);
return static_cast<time_t>(value);
}
void CheckResult::SetEndTime(time_t ts)
{
m_Data->SetProperty("end_time", static_cast<long>(ts));
}
time_t CheckResult::GetEndTime(void) const
{
long value = 0;
m_Data->GetProperty("end_time", &value);
return static_cast<time_t>(value);
}
void CheckResult::SetState(CheckState state)
{
m_Data->SetProperty("state", static_cast<long>(state));
}
CheckState CheckResult::GetState(void) const
{
long value = StateUnknown;
m_Data->GetProperty("state", &value);
return static_cast<CheckState>(value);
}
void CheckResult::SetOutput(string output)
{
m_Data->SetProperty("output", output);
}
string CheckResult::GetOutput(void) const
{
string value;
m_Data->GetProperty("output", &value);
return value;
}
void CheckResult::SetPerformanceData(const Dictionary::Ptr& pd)
{
m_Data->SetProperty("performance_data", pd);
}
Dictionary::Ptr CheckResult::GetPerformanceData(void) const
{
Dictionary::Ptr value;
m_Data->GetProperty("performance_data", &value);
return value;
}

46
icinga/checkresult.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef CHECKRESULT_H
#define CHECKRESULT_H
namespace icinga
{
enum CheckState
{
StateOK,
StateWarning,
StateCritical,
StateUnreachable,
StateUncheckable,
StateUnknown
};
struct CheckResult
{
public:
CheckResult(void);
CheckResult(const Dictionary::Ptr& dictionary);
Dictionary::Ptr GetDictionary(void) const;
void SetStartTime(time_t ts);
time_t GetStartTime(void) const;
void SetEndTime(time_t ts);
time_t GetEndTime(void) const;
void SetState(CheckState state);
CheckState GetState(void) const;
void SetOutput(string output);
string GetOutput(void) const;
void SetPerformanceData(const Dictionary::Ptr& pd);
Dictionary::Ptr GetPerformanceData(void) const;
private:
Dictionary::Ptr m_Data;
};
}
#endif /* CHECKRESULT_H */

View File

@ -4,26 +4,6 @@
namespace icinga namespace icinga
{ {
enum CheckState
{
StateOK,
StateWarning,
StateCritical,
StateUnreachable,
StateUncheckable,
StateUnknown
};
struct CheckResult
{
time_t StartTime;
time_t EndTime;
CheckState State;
string Output;
Dictionary::Ptr PerformanceData;
};
struct CheckTaskType; struct CheckTaskType;
class I2_ICINGA_API CheckTask : public Object class I2_ICINGA_API CheckTask : public Object

View File

@ -53,6 +53,7 @@ using boost::unique_future;
#include "service.h" #include "service.h"
#include "macroprocessor.h" #include "macroprocessor.h"
#include "checkresult.h"
#include "checktask.h" #include "checktask.h"
#include "nagioschecktask.h" #include "nagioschecktask.h"

View File

@ -20,7 +20,10 @@ NagiosCheckTask::NagiosCheckTask(const Service& service)
void NagiosCheckTask::Enqueue(void) void NagiosCheckTask::Enqueue(void)
{ {
time(&m_Result.StartTime); time_t now;
time(&now);
m_Result.SetStartTime(now);
m_PendingTasks.push_back(GetSelf()); m_PendingTasks.push_back(GetSelf());
} }
@ -44,7 +47,6 @@ void NagiosCheckTask::CheckThreadProc(void)
mutex::scoped_lock lock(m_Mutex); mutex::scoped_lock lock(m_Mutex);
map<int, NagiosCheckTask::Ptr> tasks; map<int, NagiosCheckTask::Ptr> tasks;
const int maxTasks = 128;
for (;;) { for (;;) {
while (m_Tasks.empty() || tasks.size() >= MaxChecksPerThread) { while (m_Tasks.empty() || tasks.size() >= MaxChecksPerThread) {
@ -94,7 +96,7 @@ void NagiosCheckTask::CheckThreadProc(void)
lock.lock(); lock.lock();
} }
while (!m_Tasks.empty() && tasks.size() < maxTasks) { while (!m_Tasks.empty() && tasks.size() < MaxChecksPerThread) {
NagiosCheckTask::Ptr task = m_Tasks.front(); NagiosCheckTask::Ptr task = m_Tasks.front();
m_Tasks.pop_front(); m_Tasks.pop_front();
if (!task->InitTask()) { if (!task->InitTask()) {
@ -140,8 +142,9 @@ bool NagiosCheckTask::RunTask(void)
if (!feof(m_FP)) if (!feof(m_FP))
return true; return true;
m_Result.Output = m_OutputStream.str(); string output = m_OutputStream.str();
boost::algorithm::trim(m_Result.Output); boost::algorithm::trim(output);
m_Result.SetOutput(output);
int status, exitcode; int status, exitcode;
#ifdef _MSC_VER #ifdef _MSC_VER
@ -162,28 +165,36 @@ bool NagiosCheckTask::RunTask(void)
exitcode = status; exitcode = status;
#endif /* _MSC_VER */ #endif /* _MSC_VER */
CheckState state;
switch (exitcode) { switch (exitcode) {
case 0: case 0:
m_Result.State = StateOK; state = StateOK;
break; break;
case 1: case 1:
m_Result.State = StateWarning; state = StateWarning;
break; break;
case 2: case 2:
m_Result.State = StateCritical; state = StateCritical;
break; break;
default: default:
m_Result.State = StateUnknown; state = StateUnknown;
break; break;
} }
m_Result.SetState(state);
#ifndef _MSC_VER #ifndef _MSC_VER
} else if (WIFSIGNALED(status)) { } else if (WIFSIGNALED(status)) {
m_Result.Output = "Process was terminated by signal " + WTERMSIG(status); stringstream outputbuf;
m_Result.State = StateUnknown; outputbuf << "Process was terminated by signal " << WTERMSIG(status);
m_Result.SetOutput(outputbuf.str());
m_Result.SetState(StateUnknown);
} }
#endif /* _MSC_VER */ #endif /* _MSC_VER */
time(&m_Result.EndTime); time_t now;
time(&now);
m_Result.SetEndTime(now);
return false; return false;
} }

View File

@ -95,3 +95,7 @@ string Service::GetChecker(void) const
return value; return value;
} }
void Service::ApplyCheckResult(const CheckResult& cr)
{
}

View File

@ -4,6 +4,8 @@
namespace icinga namespace icinga
{ {
struct CheckResult;
class I2_ICINGA_API Service : public ConfigObjectAdapter class I2_ICINGA_API Service : public ConfigObjectAdapter
{ {
public: public:
@ -24,6 +26,8 @@ public:
time_t GetNextCheck(void); time_t GetNextCheck(void);
void SetChecker(string checker); void SetChecker(string checker);
string GetChecker(void) const; string GetChecker(void) const;
void ApplyCheckResult(const CheckResult& cr);
}; };
} }