]> granicus.if.org Git - icinga2/commitdiff
Keep track of time using fractions of seconds.
authorGunnar Beutner <gunnar.beutner@netways.de>
Wed, 25 Jul 2012 10:59:17 +0000 (12:59 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Wed, 25 Jul 2012 10:59:17 +0000 (12:59 +0200)
23 files changed:
base/application.cpp
base/configobject.cpp
base/configobject.h
base/logger.cpp
base/logger.h
base/process.cpp
base/process.h
base/streamlogger.cpp
base/timer.cpp
base/timer.h
base/utility.cpp
base/utility.h
cib/checkresult.cpp
cib/checkresult.h
cib/nagioschecktask.cpp
cib/nullchecktask.cpp
cib/service.cpp
cib/service.h
components/checker/checkercomponent.cpp
components/cibsync/cibsynccomponent.cpp
components/compat/compatcomponent.cpp
components/discovery/discoverycomponent.cpp
components/discovery/discoverycomponent.h

index 6e8f1542e1f4c7279a34fee235a791fc4f52c61f..4e41547240fb10a3426506523ecac442b9336726 100644 (file)
@@ -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();
index de3e24771b870f3e2081ed34f9fb80c2eb360ba7..e0e3bf8fb442c4a5d0bd3094d95a0f6c9893bc43 100644 (file)
@@ -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<long>(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)
index 9b916540ba75f48a62a4288a64f3c7458a3de093..5f3f48b0c8005b082d2f4f23bc5035a94eb184af 100644 (file)
@@ -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<pair<string, string>, Dictionary::Ptr> m_PersistentTags;
 
-       void SetCommitTimestamp(time_t ts);
+       void SetCommitTimestamp(double ts);
 
        static bool TypeAndNameGetter(const ConfigObject::Ptr& object, pair<string, string> *key);
        static bool TypePredicate(const ConfigObject::Ptr& object, string type);
index 4e7f6b83016970f6cf67dc966ce024a8b7ffe586..d9453948f4ba77d9cbd9aeedc8d87c19f75fc2d4 100644 (file)
@@ -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;
index bcbb22051de8b8437b5b8a1e2a79a1dd60e2d48a..e5edf3991737210c5b344235a752986bbb3a3b92 100644 (file)
@@ -42,7 +42,7 @@ enum LogSeverity
  * @ingroup base
  */
 struct LogEntry {
-       time_t Timestamp;
+       double Timestamp;
        LogSeverity Severity;
        string Facility;
        string Message;
index 0ca2b6ba99bf8d45e8cbad9e037b2ac9c16ae3a1..a1b8f43e4decd8efe57ef8d178a608d47bab77af 100644 (file)
@@ -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)) {
index 186f03a35d588780db5564ded4222c1886daeb9a..e04b885ac89bd5b8797510acb8fa2796e167f380 100644 (file)
@@ -25,8 +25,8 @@ namespace icinga
 
 struct ProcessResult
 {
-       time_t ExecutionStart;
-       time_t ExecutionEnd;
+       double ExecutionStart;
+       double ExecutionEnd;
        long ExitStatus;
        string Output;
 };
index 9475d869bb6e7d4a067b8562480847c895a9fe6c..13f2520665793f9067c58f0efd7df0be63ee1a7c 100644 (file)
@@ -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);
 
index a1ea75230c89d048e849d8198d36d4784314cec1..75b927f62976336e9c35697e952f6dc12bf344a1 100644 (file)
@@ -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;
 }
index 37c02935238d125fd9b2c2e22759491adc756a0d..2cde7360ed1b1aa1841af393da79ea88f55e08a5 100644 (file)
@@ -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<void(const Timer::Ptr&)> 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;
 
index c5eb45b7392b43d383d25cdf7c55079ef23c4f31..e2912bfe58028de38a2d71bd5a362755840dd876 100644 (file)
@@ -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;
+}
index 3f89383358d0805a390a0aa653960d06ecf5c95d..754e03507f9e8476b0e04729bb678332ff700318 100644 (file)
@@ -46,6 +46,8 @@ public:
 
        static void NullDeleter(void *obj);
 
+       static double GetTime(void);
+
 private:
        static bool m_SSLInitialized;
 
index 81b51db3bd78942bf4362503b7a0f87dfa98ad62..6d5772d9debae48fdfe39ad1bbf3c14278c64958 100644 (file)
@@ -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<long>(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<time_t>(value);
+       return value;
 }
 
-void CheckResult::SetScheduleEnd(time_t ts)
+void CheckResult::SetScheduleEnd(double ts)
 {
-       Set("schedule_end", static_cast<long>(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<time_t>(value);
+       return value;
 }
 
-void CheckResult::SetExecutionStart(time_t ts)
+void CheckResult::SetExecutionStart(double ts)
 {
-       Set("execution_start", static_cast<long>(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<time_t>(value);
+       return value;
 }
 
-void CheckResult::SetExecutionEnd(time_t ts)
+void CheckResult::SetExecutionEnd(double ts)
 {
-       Set("execution_end", static_cast<long>(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;
 }
index 3feba37c5dc2ff45724de1f2902b4a91f84ee161..b3e30c99a42d477a100e652cb55d2a926aaa285d 100644 (file)
@@ -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;
index b882168eb20493e2da63d694165851e9d3b6cf55..ace7aa1b8ea01d6b9538e1aa40aa24d0cc33746e 100644 (file)
@@ -48,9 +48,7 @@ void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Varia
 
        NagiosCheckTask ct(task, process);
 
-       time_t now;
-       time(&now);
-       ct.m_Result.SetScheduleStart(now);
+       ct.m_Result.SetScheduleStart(Utility::GetTime());
 
        process->Start(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());
 }
index 20553d340a748094e61a7ae56339e4b231fa4666..3f0c0ea9a8d0707870ecd78a9a46346473214e34 100644 (file)
@@ -26,8 +26,7 @@ void NullCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Variant
        if (arguments.size() < 1)
                throw_exception(invalid_argument("Missing argument: Service must be specified."));
 
-       time_t now;
-       time(&now);
+       double now = Utility::GetTime();
 
        CheckResult cr;
        cr.SetScheduleStart(now);
index 2cd8d4a2dc3af45b228c92a59c32e40a2a16cab7..9f05eedda7c597887dbd676a1b4f4aa27c612de9 100644 (file)
@@ -175,35 +175,48 @@ bool Service::IsReachable(void) const
        return true;
 }
 
-void Service::SetNextCheck(time_t nextCheck)
+void Service::SetSchedulingOffset(long offset)
 {
-       SetTag("next_check", (long)nextCheck);
+       SetTag("scheduling_offset", offset);
 }
 
-time_t Service::GetNextCheck(void)
+long Service::GetSchedulingOffset(void)
 {
        long value;
+       if (!GetTag("scheduling_offset", &value)) {
+               value = rand();
+               SetSchedulingOffset(value);
+       }
+       return value;
+}
+
+void Service::SetNextCheck(double nextCheck)
+{
+       SetTag("next_check", nextCheck);
+}
+
+double Service::GetNextCheck(void)
+{
+       double value;
        if (!GetTag("next_check", &value)) {
-               value = time(NULL) + rand() % GetCheckInterval();
-               SetNextCheck(value);
+               UpdateNextCheck();
+               return GetNextCheck();
        }
        return value;
 }
 
 void Service::UpdateNextCheck(void)
 {
-       time_t now, previous, next, interval;
-
-       time(&now);
-       previous = GetNextCheck();
+       double interval;
 
        if (GetStateType() == StateTypeSoft)
                interval = GetRetryInterval();
        else
                interval = GetCheckInterval();
 
-       next = (now - previous % interval) + interval;
-       SetNextCheck(next);
+       double now = Utility::GetTime();
+       double adj = fmod(now + GetSchedulingOffset(), interval);
+       SetNextCheck(now - adj + interval);
 }
 
 void Service::SetChecker(const string& checker)
@@ -273,12 +286,12 @@ CheckResult Service::GetLastCheckResult(void) const
        return CheckResult(value);
 }
 
-void Service::SetLastStateChange(time_t ts)
+void Service::SetLastStateChange(double ts)
 {
        SetTag("last_state_change", static_cast<long>(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<long>(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())
index 9c9d650d3a80fd509252814d5842f12adb63f17f..f2c58fe64a990c9ba9e776d38427cfc5712ba635 100644 (file)
@@ -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);
 
index 2e17707b7c13dbc67f09197078d80719d1f0e0d8..b47d06b60f971a9de70de8e15018c808f934ecc1 100644 (file)
@@ -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()) {
index 59b5509574e7e6488077c1d4733bc4fc1de06b3d..4d7aecda6a13058a1dbdca965e4dc98a405c976e 100644 (file)
@@ -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);
 }
 
index 362cc24f9146560214e6ffa568a2bbb450838727..471a355299627f820f2ffc9aafd410d4cd966584 100644 (file)
@@ -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";
index 3d6ecc943defe135e40b5ae03960776781363299..932894eb33e02a492589e7f6ad16e68a1e577c9c 100644 (file)
@@ -357,7 +357,7 @@ void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const D
 
        ComponentDiscoveryInfo::Ptr info = boost::make_shared<ComponentDiscoveryInfo>();
 
-       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");
index 331030d5ec82165ed34be0b7ae65dd5c1c4caf50..1ddf191ad3a53e5bb0e8486fd8b2c53f08a5f924 100644 (file)
@@ -38,7 +38,7 @@ public:
        set<string> Subscriptions;
        set<string> Publications;
 
-       time_t LastSeen;
+       double LastSeen;
 };
 
 /**