diff --git a/base/application.cpp b/base/application.cpp index 6e8f1542e..4e4154724 100644 --- a/base/application.cpp +++ b/base/application.cpp @@ -82,12 +82,12 @@ void Application::RunEventLoop(void) while (!m_ShuttingDown) { Object::ClearHeldObjects(); - long sleep = Timer::ProcessTimers(); + double sleep = Timer::ProcessTimers(); if (m_ShuttingDown) break; - Event::ProcessEvents(boost::get_system_time() + boost::posix_time::seconds(sleep)); + Event::ProcessEvents(boost::get_system_time() + boost::posix_time::milliseconds(sleep * 1000)); } Component::UnloadAll(); diff --git a/base/configobject.cpp b/base/configobject.cpp index de3e24771..e0e3bf8fb 100644 --- a/base/configobject.cpp +++ b/base/configobject.cpp @@ -96,14 +96,14 @@ string ConfigObject::GetSource(void) const return value; } -void ConfigObject::SetCommitTimestamp(time_t ts) +void ConfigObject::SetCommitTimestamp(double ts) { - GetProperties()->Set("__tx", static_cast(ts)); + GetProperties()->Set("__tx", ts); } -time_t ConfigObject::GetCommitTimestamp(void) const +double ConfigObject::GetCommitTimestamp(void) const { - long value = 0; + double value = 0; GetProperties()->Get("__tx", &value); return value; } @@ -117,9 +117,7 @@ void ConfigObject::Commit(void) assert(!dobj || dobj == self); m_Container->CheckObject(self); - time_t now; - time(&now); - SetCommitTimestamp(now); + SetCommitTimestamp(Utility::GetTime()); } void ConfigObject::Unregister(void) diff --git a/base/configobject.h b/base/configobject.h index 9b916540b..5f3f48b0c 100644 --- a/base/configobject.h +++ b/base/configobject.h @@ -78,7 +78,7 @@ public: void SetSource(const string& value); string GetSource(void) const; - time_t GetCommitTimestamp(void) const; + double GetCommitTimestamp(void) const; void Commit(void); void Unregister(void); @@ -104,7 +104,7 @@ private: static map, Dictionary::Ptr> m_PersistentTags; - void SetCommitTimestamp(time_t ts); + void SetCommitTimestamp(double ts); static bool TypeAndNameGetter(const ConfigObject::Ptr& object, pair *key); static bool TypePredicate(const ConfigObject::Ptr& object, string type); diff --git a/base/logger.cpp b/base/logger.cpp index 4e7f6b830..d9453948f 100644 --- a/base/logger.cpp +++ b/base/logger.cpp @@ -44,7 +44,7 @@ void Logger::Write(LogSeverity severity, const string& facility, const string& message) { LogEntry entry; - time(&entry.Timestamp); + entry.Timestamp = Utility::GetTime(); entry.Severity = severity; entry.Facility = facility; entry.Message = message; diff --git a/base/logger.h b/base/logger.h index bcbb22051..e5edf3991 100644 --- a/base/logger.h +++ b/base/logger.h @@ -42,7 +42,7 @@ enum LogSeverity * @ingroup base */ struct LogEntry { - time_t Timestamp; + double Timestamp; LogSeverity Severity; string Facility; string Message; diff --git a/base/process.cpp b/base/process.cpp index 0ca2b6ba9..a1b8f43e4 100644 --- a/base/process.cpp +++ b/base/process.cpp @@ -130,7 +130,7 @@ void Process::WorkerThreadProc(void) void Process::InitTask(void) { - time(&m_Result.ExecutionStart); + m_Result.ExecutionStart = Utility::GetTime(); #ifdef _MSC_VER m_FP = _popen(m_Command.c_str(), "r"); @@ -178,7 +178,7 @@ bool Process::RunTask(void) } #endif /* _MSC_VER */ - time(&m_Result.ExecutionEnd); + m_Result.ExecutionEnd = Utility::GetTime(); #ifndef _MSC_VER if (WIFEXITED(status)) { diff --git a/base/process.h b/base/process.h index 186f03a35..e04b885ac 100644 --- a/base/process.h +++ b/base/process.h @@ -25,8 +25,8 @@ namespace icinga struct ProcessResult { - time_t ExecutionStart; - time_t ExecutionEnd; + double ExecutionStart; + double ExecutionEnd; long ExitStatus; string Output; }; diff --git a/base/streamlogger.cpp b/base/streamlogger.cpp index 9475d869b..13f252066 100644 --- a/base/streamlogger.cpp +++ b/base/streamlogger.cpp @@ -57,7 +57,8 @@ void StreamLogger::ProcessLogEntry(const LogEntry& entry) { char timestamp[100]; - tm tmnow = *localtime(&entry.Timestamp); + time_t ts = entry.Timestamp; + tm tmnow = *localtime(&ts); strftime(timestamp, sizeof(timestamp), "%Y/%m/%d %H:%M:%S", &tmnow); diff --git a/base/timer.cpp b/base/timer.cpp index a1ea75230..75b927f62 100644 --- a/base/timer.cpp +++ b/base/timer.cpp @@ -36,12 +36,11 @@ Timer::Timer(void) * * @returns Time when the next timer is due. */ -long Timer::ProcessTimers(void) +double Timer::ProcessTimers(void) { - long wakeup = 30; + double wakeup = 30; - time_t st; - time(&st); + double st = Utility::GetTime(); Timer::CollectionType::iterator prev, i; for (i = m_Timers.begin(); i != m_Timers.end(); ) { @@ -55,15 +54,14 @@ long Timer::ProcessTimers(void) continue; } - time_t now; - time(&now); + double now = Utility::GetTime(); if (timer->m_Next <= now) { timer->Call(); /* time may have changed depending on how long the * timer call took - we need to fetch the current time */ - time(&now); + now = Utility::GetTime(); timer->Reschedule(now + timer->GetInterval()); } @@ -76,8 +74,7 @@ long Timer::ProcessTimers(void) assert(wakeup > 0); - time_t et; - time(&et); + double et = Utility::GetTime(); stringstream msgbuf; msgbuf << "Timers took " << et - st << " seconds"; @@ -93,13 +90,11 @@ long Timer::ProcessTimers(void) */ void Timer::Call(void) { - time_t st; - time(&st); + double st = Utility::GetTime(); OnTimerExpired(GetSelf()); - time_t et; - time(&et); + double et = Utility::GetTime(); if (et - st > 3) { stringstream msgbuf; @@ -113,7 +108,7 @@ void Timer::Call(void) * * @param interval The new interval. */ -void Timer::SetInterval(unsigned long interval) +void Timer::SetInterval(double interval) { m_Interval = interval; } @@ -123,7 +118,7 @@ void Timer::SetInterval(unsigned long interval) * * @returns The interval. */ -unsigned long Timer::GetInterval(void) const +double Timer::GetInterval(void) const { return m_Interval; } @@ -139,7 +134,7 @@ void Timer::Start(void) m_Timers.push_back(GetSelf()); - Reschedule(time(NULL) + m_Interval); + Reschedule(Utility::GetTime() + m_Interval); } /** @@ -157,7 +152,7 @@ void Timer::Stop(void) * * @param next The time when this timer should be called again. */ -void Timer::Reschedule(time_t next) +void Timer::Reschedule(double next) { m_Next = next; } diff --git a/base/timer.h b/base/timer.h index 37c029352..2cde7360e 100644 --- a/base/timer.h +++ b/base/timer.h @@ -39,21 +39,21 @@ public: Timer(void); - void SetInterval(unsigned long interval); - unsigned long GetInterval(void) const; + void SetInterval(double interval); + double GetInterval(void) const; - static long ProcessTimers(void); + static double ProcessTimers(void); void Start(void); void Stop(void); - void Reschedule(time_t next); + void Reschedule(double next); boost::signal OnTimerExpired; private: - unsigned long m_Interval; /**< The interval of the timer. */ - time_t m_Next; /**< When the next event should happen. */ + double m_Interval; /**< The interval of the timer. */ + double m_Next; /**< When the next event should happen. */ static Timer::CollectionType m_Timers; diff --git a/base/utility.cpp b/base/utility.cpp index c5eb45b73..e2912bfe5 100644 --- a/base/utility.cpp +++ b/base/utility.cpp @@ -255,3 +255,18 @@ void Utility::NullDeleter(void *obj) { /* Nothing to do here. */ } + +/** + * Returns the current UNIX timestamp including fractions of seconds. + * + * @returns The current time. + */ +double Utility::GetTime(void) +{ + struct timeval tv; + + if (gettimeofday(&tv, NULL) < 0) + throw PosixException("gettimeofday() failed", errno); + + return tv.tv_sec + tv.tv_usec / 1000000.0; +} diff --git a/base/utility.h b/base/utility.h index 3f8938335..754e03507 100644 --- a/base/utility.h +++ b/base/utility.h @@ -46,6 +46,8 @@ public: static void NullDeleter(void *obj); + static double GetTime(void); + private: static bool m_SSLInitialized; diff --git a/cib/checkresult.cpp b/cib/checkresult.cpp index 81b51db3b..6d5772d9d 100644 --- a/cib/checkresult.cpp +++ b/cib/checkresult.cpp @@ -29,50 +29,50 @@ CheckResult::CheckResult(const MessagePart& message) : MessagePart(message) { } -void CheckResult::SetScheduleStart(time_t ts) +void CheckResult::SetScheduleStart(double ts) { - Set("schedule_start", static_cast(ts)); + Set("schedule_start", ts); } -time_t CheckResult::GetScheduleStart(void) const +double CheckResult::GetScheduleStart(void) const { - long value = 0; + double value = 0; Get("schedule_start", &value); - return static_cast(value); + return value; } -void CheckResult::SetScheduleEnd(time_t ts) +void CheckResult::SetScheduleEnd(double ts) { - Set("schedule_end", static_cast(ts)); + Set("schedule_end", ts); } -time_t CheckResult::GetScheduleEnd(void) const +double CheckResult::GetScheduleEnd(void) const { - long value = 0; + double value = 0; Get("schedule_end", &value); - return static_cast(value); + return value; } -void CheckResult::SetExecutionStart(time_t ts) +void CheckResult::SetExecutionStart(double ts) { - Set("execution_start", static_cast(ts)); + Set("execution_start", ts); } -time_t CheckResult::GetExecutionStart(void) const +double CheckResult::GetExecutionStart(void) const { - long value = 0; + double value = 0; Get("execution_start", &value); - return static_cast(value); + return value; } -void CheckResult::SetExecutionEnd(time_t ts) +void CheckResult::SetExecutionEnd(double ts) { - Set("execution_end", static_cast(ts)); + Set("execution_end", ts); } -time_t CheckResult::GetExecutionEnd(void) const +double CheckResult::GetExecutionEnd(void) const { - long value = 0; + double value = 0; Get("execution_end", &value); return value; } diff --git a/cib/checkresult.h b/cib/checkresult.h index 3feba37c5..b3e30c99a 100644 --- a/cib/checkresult.h +++ b/cib/checkresult.h @@ -29,17 +29,17 @@ public: CheckResult(void); CheckResult(const MessagePart& message); - void SetScheduleStart(time_t ts); - time_t GetScheduleStart(void) const; + void SetScheduleStart(double ts); + double GetScheduleStart(void) const; - void SetScheduleEnd(time_t ts); - time_t GetScheduleEnd(void) const; + void SetScheduleEnd(double ts); + double GetScheduleEnd(void) const; - void SetExecutionStart(time_t ts); - time_t GetExecutionStart(void) const; + void SetExecutionStart(double ts); + double GetExecutionStart(void) const; - void SetExecutionEnd(time_t ts); - time_t GetExecutionEnd(void) const; + void SetExecutionEnd(double ts); + double GetExecutionEnd(void) const; void SetState(ServiceState state); ServiceState GetState(void) const; diff --git a/cib/nagioschecktask.cpp b/cib/nagioschecktask.cpp index b882168eb..ace7aa1b8 100644 --- a/cib/nagioschecktask.cpp +++ b/cib/nagioschecktask.cpp @@ -48,9 +48,7 @@ void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vectorStart(boost::bind(&NagiosCheckTask::ProcessFinishedHandler, ct)); } @@ -92,9 +90,7 @@ void NagiosCheckTask::ProcessFinishedHandler(NagiosCheckTask ct) ct.m_Result.SetState(state); - time_t now; - time(&now); - ct.m_Result.SetScheduleEnd(now); + ct.m_Result.SetScheduleEnd(Utility::GetTime()); ct.m_Task->FinishResult(ct.m_Result.GetDictionary()); } diff --git a/cib/nullchecktask.cpp b/cib/nullchecktask.cpp index 20553d340..3f0c0ea9a 100644 --- a/cib/nullchecktask.cpp +++ b/cib/nullchecktask.cpp @@ -26,8 +26,7 @@ void NullCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector(ts)); } -time_t Service::GetLastStateChange(void) const +double Service::GetLastStateChange(void) const { long value; if (!GetTag("last_state_change", &value)) @@ -286,14 +299,14 @@ time_t Service::GetLastStateChange(void) const return value; } -void Service::SetLastHardStateChange(time_t ts) +void Service::SetLastHardStateChange(double ts) { - SetTag("last_hard_state_change", static_cast(ts)); + SetTag("last_hard_state_change", ts); } -time_t Service::GetLastHardStateChange(void) const +double Service::GetLastHardStateChange(void) const { - long value; + double value; if (!GetTag("last_hard_state_change", &value)) value = IcingaApplication::GetInstance()->GetStartTime(); return value; @@ -301,9 +314,6 @@ time_t Service::GetLastHardStateChange(void) const void Service::ApplyCheckResult(const CheckResult& cr) { - time_t now; - time(&now); - ServiceState old_state = GetState(); ServiceStateType old_stateType = GetStateType(); @@ -330,6 +340,8 @@ void Service::ApplyCheckResult(const CheckResult& cr) SetLastCheckResult(cr); if (old_state != GetState()) { + double now = Utility::GetTime(); + SetLastStateChange(now); if (old_stateType != GetStateType()) diff --git a/cib/service.h b/cib/service.h index 9c9d650d3..f2c58fe64 100644 --- a/cib/service.h +++ b/cib/service.h @@ -63,8 +63,11 @@ public: bool IsReachable(void) const; - void SetNextCheck(time_t nextCheck); - time_t GetNextCheck(void); + long GetSchedulingOffset(void); + void SetSchedulingOffset(long offset); + + void SetNextCheck(double nextCheck); + double GetNextCheck(void); void UpdateNextCheck(void); void SetChecker(const string& checker); @@ -85,11 +88,11 @@ public: void SetLastCheckResult(const CheckResult& result); CheckResult GetLastCheckResult(void) const; - void SetLastStateChange(time_t ts); - time_t GetLastStateChange(void) const; + void SetLastStateChange(double ts); + double GetLastStateChange(void) const; - void SetLastHardStateChange(time_t ts); - time_t GetLastHardStateChange(void) const; + void SetLastHardStateChange(double ts); + double GetLastHardStateChange(void) const; void ApplyCheckResult(const CheckResult& cr); diff --git a/components/checker/checkercomponent.cpp b/components/checker/checkercomponent.cpp index 2e17707b7..b47d06b60 100644 --- a/components/checker/checkercomponent.cpp +++ b/components/checker/checkercomponent.cpp @@ -60,11 +60,9 @@ void CheckerComponent::Stop(void) void CheckerComponent::CheckTimerHandler(void) { - time_t now; - time(&now); - Logger::Write(LogDebug, "checker", "CheckTimerHandler entered."); + double now = Utility::GetTime(); long tasks = 0; while (!m_Services.empty()) { diff --git a/components/cibsync/cibsynccomponent.cpp b/components/cibsync/cibsynccomponent.cpp index 59b550957..4d7aecda6 100644 --- a/components/cibsync/cibsynccomponent.cpp +++ b/components/cibsync/cibsynccomponent.cpp @@ -96,8 +96,7 @@ void CIBSyncComponent::CheckResultRequestHandler(const Endpoint::Ptr& sender, co CIB::OnCheckResultReceived(params); service.ApplyCheckResult(cr); - time_t now; - time(&now); + time_t now = Utility::GetTime(); CIB::UpdateTaskStatistics(now, 1); } diff --git a/components/compat/compatcomponent.cpp b/components/compat/compatcomponent.cpp index 362cc24f9..471a35529 100644 --- a/components/compat/compatcomponent.cpp +++ b/components/compat/compatcomponent.cpp @@ -112,8 +112,8 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, Service service) { string output; string perfdata; - time_t schedule_start = -1, schedule_end = -1; - time_t execution_start = -1, execution_end = -1; + double schedule_start = -1, schedule_end = -1; + double execution_start = -1, execution_end = -1; if (service.HasLastCheckResult()) { CheckResult cr = service.GetLastCheckResult(); output = cr.GetOutput(); @@ -124,8 +124,8 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, Service service) perfdata = cr.GetPerformanceDataRaw(); } - time_t execution_time = (execution_end - execution_start); - time_t latency = (schedule_end - schedule_start) - execution_time; + double execution_time = (execution_end - execution_start); + double latency = (schedule_end - schedule_start) - execution_time; int state = service.GetState(); @@ -194,6 +194,8 @@ void CompatComponent::StatusTimerHandler(void) ofstream statusfp; statusfp.open("status.dat.tmp", ofstream::out | ofstream::trunc); + statusfp << std::fixed; + statusfp << "# Icinga status file" << "\n" << "# This file is auto-generated. Do not modify this file." << "\n" << "\n"; @@ -222,6 +224,8 @@ void CompatComponent::StatusTimerHandler(void) ofstream objectfp; objectfp.open("objects.cache.tmp", ofstream::out | ofstream::trunc); + objectfp << std::fixed; + objectfp << "# Icinga object cache file" << "\n" << "# This file is auto-generated. Do not modify this file." << "\n" << "\n"; diff --git a/components/discovery/discoverycomponent.cpp b/components/discovery/discoverycomponent.cpp index 3d6ecc943..932894eb3 100644 --- a/components/discovery/discoverycomponent.cpp +++ b/components/discovery/discoverycomponent.cpp @@ -357,7 +357,7 @@ void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const D ComponentDiscoveryInfo::Ptr info = boost::make_shared(); - time(&(info->LastSeen)); + info->LastSeen = Utility::GetTime(); string node; if (message.GetNode(&node) && !node.empty()) @@ -451,8 +451,7 @@ void DiscoveryComponent::DiscoveryTimerHandler(void) { EndpointManager::Ptr endpointManager = EndpointManager::GetInstance(); - time_t now; - time(&now); + double now = Utility::GetTime(); /* check whether we have to reconnect to one of our upstream endpoints */ ConfigObject::TMap::Range range = ConfigObject::GetObjects("endpoint"); diff --git a/components/discovery/discoverycomponent.h b/components/discovery/discoverycomponent.h index 331030d5e..1ddf191ad 100644 --- a/components/discovery/discoverycomponent.h +++ b/components/discovery/discoverycomponent.h @@ -38,7 +38,7 @@ public: set Subscriptions; set Publications; - time_t LastSeen; + double LastSeen; }; /**