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();
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;
}
assert(!dobj || dobj == self);
m_Container->CheckObject(self);
- time_t now;
- time(&now);
- SetCommitTimestamp(now);
+ SetCommitTimestamp(Utility::GetTime());
}
void ConfigObject::Unregister(void)
void SetSource(const string& value);
string GetSource(void) const;
- time_t GetCommitTimestamp(void) const;
+ double GetCommitTimestamp(void) const;
void Commit(void);
void Unregister(void);
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);
const string& message)
{
LogEntry entry;
- time(&entry.Timestamp);
+ entry.Timestamp = Utility::GetTime();
entry.Severity = severity;
entry.Facility = facility;
entry.Message = message;
* @ingroup base
*/
struct LogEntry {
- time_t Timestamp;
+ double Timestamp;
LogSeverity Severity;
string Facility;
string Message;
void Process::InitTask(void)
{
- time(&m_Result.ExecutionStart);
+ m_Result.ExecutionStart = Utility::GetTime();
#ifdef _MSC_VER
m_FP = _popen(m_Command.c_str(), "r");
}
#endif /* _MSC_VER */
- time(&m_Result.ExecutionEnd);
+ m_Result.ExecutionEnd = Utility::GetTime();
#ifndef _MSC_VER
if (WIFEXITED(status)) {
struct ProcessResult
{
- time_t ExecutionStart;
- time_t ExecutionEnd;
+ double ExecutionStart;
+ double ExecutionEnd;
long ExitStatus;
string Output;
};
{
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);
*
* @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(); ) {
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());
}
assert(wakeup > 0);
- time_t et;
- time(&et);
+ double et = Utility::GetTime();
stringstream msgbuf;
msgbuf << "Timers took " << et - st << " seconds";
*/
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;
*
* @param interval The new interval.
*/
-void Timer::SetInterval(unsigned long interval)
+void Timer::SetInterval(double interval)
{
m_Interval = interval;
}
*
* @returns The interval.
*/
-unsigned long Timer::GetInterval(void) const
+double Timer::GetInterval(void) const
{
return m_Interval;
}
m_Timers.push_back(GetSelf());
- Reschedule(time(NULL) + m_Interval);
+ Reschedule(Utility::GetTime() + m_Interval);
}
/**
*
* @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;
}
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;
{
/* 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;
+}
static void NullDeleter(void *obj);
+ static double GetTime(void);
+
private:
static bool m_SSLInitialized;
: 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;
}
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;
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));
}
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());
}
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);
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)
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))
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;
void Service::ApplyCheckResult(const CheckResult& cr)
{
- time_t now;
- time(&now);
-
ServiceState old_state = GetState();
ServiceStateType old_stateType = GetStateType();
SetLastCheckResult(cr);
if (old_state != GetState()) {
+ double now = Utility::GetTime();
+
SetLastStateChange(now);
if (old_stateType != GetStateType())
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);
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);
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()) {
CIB::OnCheckResultReceived(params);
service.ApplyCheckResult(cr);
- time_t now;
- time(&now);
+ time_t now = Utility::GetTime();
CIB::UpdateTaskStatistics(now, 1);
}
{
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();
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();
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";
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";
ComponentDiscoveryInfo::Ptr info = boost::make_shared<ComponentDiscoveryInfo>();
- time(&(info->LastSeen));
+ info->LastSeen = Utility::GetTime();
string node;
if (message.GetNode(&node) && !node.empty())
{
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");
set<string> Subscriptions;
set<string> Publications;
- time_t LastSeen;
+ double LastSeen;
};
/**