From d11da74931eb7e4b5638b40ab40107ac6214f07f Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Wed, 27 Jun 2012 23:38:50 +0200 Subject: [PATCH] Fixed latency calculation. --- components/checker/checkercomponent.cpp | 3 +- components/compat/compatcomponent.cpp | 35 ++++++++++++++++---- icinga/checkresult.cpp | 40 +++++++++++++++++----- icinga/checkresult.h | 14 +++++--- icinga/checktask.cpp | 7 +++- icinga/checktask.h | 5 +-- icinga/icingaapplication.cpp | 7 ++++ icinga/icingaapplication.h | 4 +++ icinga/nagioschecktask.cpp | 44 ++++++++++++++++--------- icinga/nagioschecktask.h | 2 -- icinga/service.cpp | 10 +++--- 11 files changed, 127 insertions(+), 44 deletions(-) diff --git a/components/checker/checkercomponent.cpp b/components/checker/checkercomponent.cpp index 0e414d68e..488a5c627 100644 --- a/components/checker/checkercomponent.cpp +++ b/components/checker/checkercomponent.cpp @@ -117,7 +117,8 @@ void CheckerComponent::ResultTimerHandler(void) CheckResult result = task->GetResult(); Application::Log(LogDebug, "checker", "Got result for service '" + service.GetName() + "'"); - long latency = result.GetEndTime() - result.GetStartTime(); + long execution_time = result.GetExecutionEnd() - result.GetExecutionStart(); + long latency = (result.GetScheduleEnd() - result.GetScheduleStart()) - execution_time; avg_latency += latency; if (min_latency == -1 || latency < min_latency) diff --git a/components/compat/compatcomponent.cpp b/components/compat/compatcomponent.cpp index a32ee47d1..797b35c5b 100644 --- a/components/compat/compatcomponent.cpp +++ b/components/compat/compatcomponent.cpp @@ -61,6 +61,7 @@ void CompatComponent::DumpHostStatus(ofstream& fp, Host host) << "\t" << "check_execution_time=0" << endl << "\t" << "check_latency=0" << endl << "\t" << "current_state=0" << endl + << "\t" << "state_type=1" << endl << "\t" << "last_check=" << time(NULL) << endl << "\t" << "next_check=" << time(NULL) << endl << "\t" << "current_attempt=1" << endl @@ -91,25 +92,32 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, Service service) cr = service.GetLastCheckResult(); string plugin_output; - long start_time = -1, end_time = -1; + long schedule_start = -1, schedule_end = -1; + long execution_start = -1, execution_end = -1; if (cr) { cr->GetProperty("output", &plugin_output); - cr->GetProperty("start_time", &start_time); - cr->GetProperty("end_time", &end_time); + cr->GetProperty("schedule_start", &schedule_start); + cr->GetProperty("schedule_end", &schedule_end); + cr->GetProperty("execution_start", &execution_start); + cr->GetProperty("execution_end", &execution_end); } + long execution_time = (execution_start - execution_start); + long latency = (schedule_end - schedule_start) - execution_time; + fp << "servicestatus {" << endl << "\t" << "host_name=" << service.GetHost().GetName() << endl << "\t" << "service_description=" << service.GetDisplayName() << endl << "\t" << "check_interval=" << service.GetCheckInterval() / 60.0 << endl << "\t" << "retry_interval=" << service.GetRetryInterval() / 60.0 << endl - << "\t" << "has_been_checked=" << (end_time == -1 ? 0 : 1) << endl + << "\t" << "has_been_checked=" << (cr ? 1 : 0) << endl << "\t" << "should_be_scheduled=1" << endl - << "\t" << "check_execution_time=" << end_time - start_time << endl - << "\t" << "check_latency=0" << endl + << "\t" << "check_execution_time=" << execution_time << endl + << "\t" << "check_latency=" << latency << endl << "\t" << "current_state=" << service.GetState() << endl + << "\t" << "state_type=" << service.GetStateType() << endl << "\t" << "plugin_output=" << plugin_output << endl - << "\t" << "last_check=" << start_time << endl + << "\t" << "last_check=" << schedule_start << endl << "\t" << "next_check=" << service.GetNextCheck() << endl << "\t" << "current_attempt=" << service.GetCurrentCheckAttempt() << endl << "\t" << "max_attempts=" << service.GetMaxCheckAttempts() << endl @@ -155,6 +163,19 @@ void CompatComponent::StatusTimerHandler(void) << "\t" << "}" << endl << endl; + statusfp << "programstatus {" << endl + << "\t" << "daemon_mode=1" << endl + << "\t" << "program_start=" << IcingaApplication::GetInstance()->GetStartTime() << endl + << "\t" << "active_service_checks_enabled=1" << endl + << "\t" << "passive_service_checks_enabled=1" << endl + << "\t" << "active_host_checks_enabled=0" << endl + << "\t" << "passive_host_checks_enabled=0" << endl + << "\t" << "check_service_freshness=1" << endl + << "\t" << "check_host_freshness=0" << endl + << "\t" << "enable_flap_detection=1" << endl + << "\t" << "enable_failure_prediction=0" << endl + << endl; + ofstream objectfp; objectfp.open("objects.cache.tmp", ofstream::out | ofstream::trunc); diff --git a/icinga/checkresult.cpp b/icinga/checkresult.cpp index 4cef02fa9..30e866446 100644 --- a/icinga/checkresult.cpp +++ b/icinga/checkresult.cpp @@ -15,30 +15,54 @@ Dictionary::Ptr CheckResult::GetDictionary(void) const return m_Data; } -void CheckResult::SetStartTime(time_t ts) +void CheckResult::SetScheduleStart(time_t ts) { - m_Data->SetProperty("start_time", static_cast(ts)); + m_Data->SetProperty("schedule_start", static_cast(ts)); } -time_t CheckResult::GetStartTime(void) const +time_t CheckResult::GetScheduleStart(void) const { long value = 0; - m_Data->GetProperty("start_time", &value); + m_Data->GetProperty("schedule_start", &value); return static_cast(value); } -void CheckResult::SetEndTime(time_t ts) +void CheckResult::SetScheduleEnd(time_t ts) { - m_Data->SetProperty("end_time", static_cast(ts)); + m_Data->SetProperty("schedule_end", static_cast(ts)); } -time_t CheckResult::GetEndTime(void) const +time_t CheckResult::GetScheduleEnd(void) const { long value = 0; - m_Data->GetProperty("end_time", &value); + m_Data->GetProperty("schedule_end", &value); return static_cast(value); } +void CheckResult::SetExecutionStart(time_t ts) +{ + m_Data->SetProperty("execution_start", static_cast(ts)); +} + +time_t CheckResult::GetExecutionStart(void) const +{ + long value = 0; + m_Data->GetProperty("execution_start", &value); + return static_cast(value); +} + +void CheckResult::SetExecutionEnd(time_t ts) +{ + m_Data->SetProperty("execution_end", static_cast(ts)); +} + +time_t CheckResult::GetExecutionEnd(void) const +{ + long value = 0; + m_Data->GetProperty("execution_end", &value); + return value; +} + void CheckResult::SetState(ServiceState state) { m_Data->SetProperty("state", static_cast(state)); diff --git a/icinga/checkresult.h b/icinga/checkresult.h index fbd4ebf3d..7093a497a 100644 --- a/icinga/checkresult.h +++ b/icinga/checkresult.h @@ -12,11 +12,17 @@ public: Dictionary::Ptr GetDictionary(void) const; - void SetStartTime(time_t ts); - time_t GetStartTime(void) const; + void SetScheduleStart(time_t ts); + time_t GetScheduleStart(void) const; - void SetEndTime(time_t ts); - time_t GetEndTime(void) const; + void SetScheduleEnd(time_t ts); + time_t GetScheduleEnd(void) const; + + void SetExecutionStart(time_t ts); + time_t GetExecutionStart(void) const; + + void SetExecutionEnd(time_t ts); + time_t GetExecutionEnd(void) const; void SetState(ServiceState state); ServiceState GetState(void) const; diff --git a/icinga/checktask.cpp b/icinga/checktask.cpp index dc7b53f51..e94f7ed00 100644 --- a/icinga/checktask.cpp +++ b/icinga/checktask.cpp @@ -10,11 +10,16 @@ CheckTask::CheckTask(const Service& service) : m_Service(service) { } -Service CheckTask::GetService(void) const +Service& CheckTask::GetService(void) { return m_Service; } +CheckResult& CheckTask::GetResult(void) +{ + return m_Result; +} + void CheckTask::RegisterType(string type, Factory factory, QueueFlusher qflusher) { CheckTaskType ctt; diff --git a/icinga/checktask.h b/icinga/checktask.h index 57bab28c6..92f4f0460 100644 --- a/icinga/checktask.h +++ b/icinga/checktask.h @@ -15,10 +15,10 @@ public: typedef function Factory; typedef function QueueFlusher; - Service GetService(void) const; + Service& GetService(void); + CheckResult& GetResult(void); virtual void Enqueue(void) = 0; - virtual CheckResult GetResult(void) = 0; static void RegisterType(string type, Factory factory, QueueFlusher qflusher); static CheckTask::Ptr CreateTask(const Service& service); @@ -33,6 +33,7 @@ protected: private: Service m_Service; + CheckResult m_Result; static map m_Types; diff --git a/icinga/icingaapplication.cpp b/icinga/icingaapplication.cpp index e200eacd3..d4a92ae78 100644 --- a/icinga/icingaapplication.cpp +++ b/icinga/icingaapplication.cpp @@ -42,6 +42,8 @@ int IcingaApplication::Main(const vector& args) Application::Log(LogInformation, "icinga", "Icinga component loader (version: " ICINGA_VERSION ")"); #endif /* _WIN32 */ + time(&m_StartTime); + if (args.size() < 2) { stringstream msgbuf; msgbuf << "Syntax: " << args[0] << " "; @@ -150,3 +152,8 @@ string IcingaApplication::GetService(void) const { return m_Service; } + +time_t IcingaApplication::GetStartTime(void) const +{ + return m_StartTime; +} diff --git a/icinga/icingaapplication.h b/icinga/icingaapplication.h index ac0717408..e9189b967 100644 --- a/icinga/icingaapplication.h +++ b/icinga/icingaapplication.h @@ -43,12 +43,16 @@ public: string GetNode(void) const; string GetService(void) const; + time_t GetStartTime(void) const; + private: string m_CertificateFile; string m_CAFile; string m_Node; string m_Service; + time_t m_StartTime; + void NewComponentHandler(const ConfigObject::Ptr& object); void DeletedComponentHandler(const ConfigObject::Ptr& object); }; diff --git a/icinga/nagioschecktask.cpp b/icinga/nagioschecktask.cpp index ec39c6af2..39b2d31eb 100644 --- a/icinga/nagioschecktask.cpp +++ b/icinga/nagioschecktask.cpp @@ -22,7 +22,7 @@ void NagiosCheckTask::Enqueue(void) { time_t now; time(&now); - m_Result.SetStartTime(now); + GetResult().SetScheduleStart(now); m_PendingTasks.push_back(GetSelf()); } @@ -37,11 +37,6 @@ void NagiosCheckTask::FlushQueue(void) } } -CheckResult NagiosCheckTask::GetResult(void) -{ - return m_Result; -} - void NagiosCheckTask::CheckThreadProc(void) { mutex::scoped_lock lock(m_Mutex); @@ -76,15 +71,22 @@ void NagiosCheckTask::CheckThreadProc(void) #endif /* _MSC_VER */ for (it = tasks.begin(); it != tasks.end(); ) { + int fd = it->first; + NagiosCheckTask::Ptr task = it->second; + #ifndef _MSC_VER - if (!FD_ISSET(it->first, &readfds)) { + if (!FD_ISSET(fd, &readfds)) { it++; continue; } #endif /* _MSC_VER */ - if (!it->second->RunTask()) { - CheckTask::FinishTask(it->second); + if (!task->RunTask()) { + time_t now; + time(&now); + task->GetResult().SetScheduleEnd(now); + + CheckTask::FinishTask(task); prev = it; it++; tasks.erase(prev); @@ -100,6 +102,10 @@ void NagiosCheckTask::CheckThreadProc(void) NagiosCheckTask::Ptr task = m_Tasks.front(); m_Tasks.pop_front(); if (!task->InitTask()) { + time_t now; + time(&now); + task->GetResult().SetScheduleEnd(now); + CheckTask::FinishTask(task); } else { int fd = task->GetFD(); @@ -128,7 +134,15 @@ bool NagiosCheckTask::InitTask(void) m_FP = popen(m_Command.c_str(), "r"); #endif /* _MSC_VER */ - return (m_FP != NULL); + if (m_FP == NULL) { + time_t now; + time(&now); + GetResult().SetExecutionEnd(now); + + return false; + } + + return true; } bool NagiosCheckTask::RunTask(void) @@ -144,7 +158,7 @@ bool NagiosCheckTask::RunTask(void) string output = m_OutputStream.str(); boost::algorithm::trim(output); - m_Result.SetOutput(output); + GetResult().SetOutput(output); int status, exitcode; #ifdef _MSC_VER @@ -182,19 +196,19 @@ bool NagiosCheckTask::RunTask(void) break; } - m_Result.SetState(state); + GetResult().SetState(state); #ifndef _MSC_VER } else if (WIFSIGNALED(status)) { stringstream outputbuf; outputbuf << "Process was terminated by signal " << WTERMSIG(status); - m_Result.SetOutput(outputbuf.str()); - m_Result.SetState(StateUnknown); + GetResult().SetOutput(outputbuf.str()); + GetResult().SetState(StateUnknown); } #endif /* _MSC_VER */ time_t now; time(&now); - m_Result.SetEndTime(now); + GetResult().SetExecutionEnd(now); return false; } diff --git a/icinga/nagioschecktask.h b/icinga/nagioschecktask.h index 55643eb16..422e90181 100644 --- a/icinga/nagioschecktask.h +++ b/icinga/nagioschecktask.h @@ -15,7 +15,6 @@ public: NagiosCheckTask(const Service& service); virtual void Enqueue(void); - virtual CheckResult GetResult(void); static CheckTask::Ptr CreateTask(const Service& service); static void FlushQueue(void); @@ -24,7 +23,6 @@ public: private: string m_Command; - CheckResult m_Result; FILE *m_FP; stringstream m_OutputStream; diff --git a/icinga/service.cpp b/icinga/service.cpp index 6f64ddd5f..c630b0536 100644 --- a/icinga/service.cpp +++ b/icinga/service.cpp @@ -179,8 +179,9 @@ void Service::SetLastStateChange(time_t ts) time_t Service::GetLastStateChange(void) const { - long value = 0; - GetConfigObject()->GetTag("last_state_change", &value); + long value; + if (!GetConfigObject()->GetTag("last_state_change", &value)) + value = IcingaApplication::GetInstance()->GetStartTime(); return value; } @@ -191,8 +192,9 @@ void Service::SetLastHardStateChange(time_t ts) time_t Service::GetLastHardStateChange(void) const { - long value = 0; - GetConfigObject()->GetTag("last_hard_state_change", &value); + long value; + if (!GetConfigObject()->GetTag("last_hard_state_change", &value)) + value = IcingaApplication::GetInstance()->GetStartTime(); return value; }