diff --git a/components/db_ido_mysql/idomysqlconnection.cpp b/components/db_ido_mysql/idomysqlconnection.cpp index 0de8992d0..2e449bced 100644 --- a/components/db_ido_mysql/idomysqlconnection.cpp +++ b/components/db_ido_mysql/idomysqlconnection.cpp @@ -129,7 +129,7 @@ void IdoMysqlConnection::ReconnectTimerHandler(void) std::ostringstream msgbuf; msgbuf << "MySQL IDO instance id: " << static_cast(m_InstanceID); - Log(LogInformation, "ido_mysql", msgbuf.str()); + Log(LogInformation, "db_ido_mysql", msgbuf.str()); ClearConfigTables(); @@ -190,7 +190,7 @@ void IdoMysqlConnection::ClearConfigTable(const String& table) Array::Ptr IdoMysqlConnection::Query(const String& query) { - Log(LogDebug, "ido_mysql", "Query: " + query); + Log(LogDebug, "db_ido_mysql", "Query: " + query); if (mysql_query(&m_Connection, query.CStr()) != 0) BOOST_THROW_EXCEPTION(std::runtime_error(mysql_error(&m_Connection))); @@ -382,10 +382,10 @@ void IdoMysqlConnection::ExecuteQuery(const DbQuery& query) where << " WHERE "; ObjectLock olock(query.WhereCriteria); - String key; Value value; bool first = true; + BOOST_FOREACH(boost::tie(key, value), query.WhereCriteria) { if (!FieldToEscapedString(key, value, &value)) return; @@ -401,7 +401,7 @@ void IdoMysqlConnection::ExecuteQuery(const DbQuery& query) } if ((query.Type & DbQueryInsert) && (query.Type & DbQueryUpdate)) { - bool hasid; + bool hasid = false; ASSERT(query.Object); @@ -489,6 +489,18 @@ void IdoMysqlConnection::ExecuteQuery(const DbQuery& query) } } +void IdoMysqlConnection::CleanUpExecuteQuery(const String& table, const String& time_key, double time_value) +{ + boost::mutex::scoped_lock lock(m_ConnectionMutex); + + if (!m_Connected) + return; + + Query("DELETE FROM " + GetTablePrefix() + table + " WHERE instance_id = " + + Convert::ToString(static_cast(m_InstanceID)) + " AND " + time_key + + "(time_value)) + ")"); +} + void IdoMysqlConnection::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) const { DbConnection::InternalSerialize(bag, attributeTypes); diff --git a/components/db_ido_mysql/idomysqlconnection.h b/components/db_ido_mysql/idomysqlconnection.h index 7b002db0d..c77757061 100644 --- a/components/db_ido_mysql/idomysqlconnection.h +++ b/components/db_ido_mysql/idomysqlconnection.h @@ -51,6 +51,7 @@ protected: virtual void ActivateObject(const DbObject::Ptr& dbobj); virtual void DeactivateObject(const DbObject::Ptr& dbobj); virtual void ExecuteQuery(const DbQuery& query); + virtual void CleanUpExecuteQuery(const String& table, const String& time_key, double time_value); private: String m_Host; diff --git a/lib/db_ido/db_ido-type.conf b/lib/db_ido/db_ido-type.conf index 6bf9d85dc..c1a1fc32b 100644 --- a/lib/db_ido/db_ido-type.conf +++ b/lib/db_ido/db_ido-type.conf @@ -18,5 +18,23 @@ ******************************************************************************/ type DbConnection { - %attribute string "table_prefix" + %attribute string "table_prefix", + + %attribute dictionary "cleanup" { + %attribute number "acknowledgements_age", + %attribute number "commenthistory_age", + %attribute number "contactnotifications_age", + %attribute number "contactnotificationmethods_age", + %attribute number "downtimehistory_age", + %attribute number "eventhandlers_age", + %attribute number "externalcommands_age", + %attribute number "flappinghistory_age", + %attribute number "hostchecks_age", + %attribute number "logentries_age", + %attribute number "notifications_age", + %attribute number "processevents_age", + %attribute number "statehistory_age", + %attribute number "servicechecks_age", + %attribute number "systemcommands_age", + }, } diff --git a/lib/db_ido/dbconnection.cpp b/lib/db_ido/dbconnection.cpp index f56c6034b..a87b2077c 100644 --- a/lib/db_ido/dbconnection.cpp +++ b/lib/db_ido/dbconnection.cpp @@ -23,8 +23,10 @@ #include "icinga/host.h" #include "icinga/service.h" #include "base/dynamictype.h" +#include "base/convert.h" #include "base/utility.h" #include "base/initialize.h" +#include "base/logger_fwd.h" #include using namespace icinga; @@ -38,6 +40,11 @@ void DbConnection::Start(void) DynamicObject::Start(); DbObject::OnQuery.connect(boost::bind(&DbConnection::ExecuteQuery, this, _1)); + + m_CleanUpTimer = boost::make_shared(); + m_CleanUpTimer->SetInterval(60); + m_CleanUpTimer->OnTimerExpired.connect(boost::bind(&DbConnection::CleanUpHandler, this)); + m_CleanUpTimer->Start(); } void DbConnection::StaticInitialize(void) @@ -111,6 +118,265 @@ void DbConnection::ProgramStatusHandler(void) InsertRuntimeVariable("total_scheduled_hosts", DynamicType::GetObjects().size()); } +void DbConnection::CleanUpHandler(void) +{ + long now = static_cast(Utility::GetTime()); + + if (GetCleanUpAcknowledgementsAge() > 0) { + CleanUpExecuteQuery("acknowledgements", "entry_time", now - GetCleanUpAcknowledgementsAge()); + Log(LogDebug, "db_ido", "GetCleanUpAcknowledgementsAge: " + Convert::ToString(GetCleanUpAcknowledgementsAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpAcknowledgementsAge())); + } + if (GetCleanUpCommentHistoryAge() > 0) { + CleanUpExecuteQuery("commenthistory", "entry_time", now - GetCleanUpCommentHistoryAge()); + Log(LogDebug, "db_ido", "GetCleanUpCommentHistoryAge: " + Convert::ToString(GetCleanUpCommentHistoryAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpCommentHistoryAge())); + } + if (GetCleanUpContactNotificationsAge() > 0) { + CleanUpExecuteQuery("contactnotifications", "start_time", now - GetCleanUpContactNotificationsAge()); + Log(LogDebug, "db_ido", "GetCleanUpContactNotificationsAge: " + Convert::ToString(GetCleanUpContactNotificationsAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpContactNotificationsAge())); + } + if (GetCleanUpContactNotificationMethodsAge() > 0) { + CleanUpExecuteQuery("contactnotificationmethods", "start_time", now - GetCleanUpContactNotificationMethodsAge()); + Log(LogDebug, "db_ido", "GetCleanUpContactNotificationMethodsAge: " + Convert::ToString(GetCleanUpContactNotificationMethodsAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpContactNotificationMethodsAge())); + } + if (GetCleanUpDowntimeHistoryAge() > 0) { + CleanUpExecuteQuery("downtimehistory", "entry_time", now - GetCleanUpDowntimeHistoryAge()); + Log(LogDebug, "db_ido", "CleanUpDowntimeHistoryAge: " + Convert::ToString(GetCleanUpDowntimeHistoryAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpDowntimeHistoryAge())); + } + if (GetCleanUpEventHandlersAge() > 0) { + CleanUpExecuteQuery("eventhandlers", "start_time", now - GetCleanUpEventHandlersAge()); + Log(LogDebug, "db_ido", "GetCleanUpEventHandlersAge: " + Convert::ToString(GetCleanUpEventHandlersAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpEventHandlersAge())); + } + if (GetCleanUpExternalCommandsAge() > 0) { + CleanUpExecuteQuery("externalcommands", "entry_time", now - GetCleanUpExternalCommandsAge()); + Log(LogDebug, "db_ido", "GetCleanUpExternalCommandsAge: " + Convert::ToString(GetCleanUpExternalCommandsAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpExternalCommandsAge())); + } + if (GetCleanUpFlappingHistoryAge() > 0) { + CleanUpExecuteQuery("flappinghistory", "event_time", now - GetCleanUpFlappingHistoryAge()); + Log(LogDebug, "db_ido", "GetCleanUpFlappingHistoryAge: " + Convert::ToString(GetCleanUpFlappingHistoryAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpFlappingHistoryAge())); + } + if (GetCleanUpHostChecksAge() > 0) { + CleanUpExecuteQuery("hostchecks", "start_time", now - GetCleanUpHostChecksAge()); + Log(LogDebug, "db_ido", "GetCleanUpHostChecksAge: " + Convert::ToString(GetCleanUpHostChecksAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpHostChecksAge())); + } + if (GetCleanUpLogEntriesAge() > 0) { + CleanUpExecuteQuery("logentries", "logentry_time", now - GetCleanUpLogEntriesAge()); + Log(LogDebug, "db_ido", "GetCleanUpLogEntriesAge: " + Convert::ToString(GetCleanUpLogEntriesAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpLogEntriesAge())); + } + if (GetCleanUpNotificationsAge() > 0) { + CleanUpExecuteQuery("notifications", "start_time", now - GetCleanUpNotificationsAge()); + Log(LogDebug, "db_ido", "GetCleanUpNotificationsAge: " + Convert::ToString(GetCleanUpNotificationsAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpNotificationsAge())); + } + if (GetCleanUpProcessEventsAge() > 0) { + CleanUpExecuteQuery("processevents", "event_time", now - GetCleanUpProcessEventsAge()); + Log(LogDebug, "db_ido", "GetCleanUpProcessEventsAge: " + Convert::ToString(GetCleanUpProcessEventsAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpProcessEventsAge())); + } + if (GetCleanUpStateHistoryAge() > 0) { + CleanUpExecuteQuery("statehistory", "state_time", now - GetCleanUpStateHistoryAge()); + Log(LogDebug, "db_ido", "GetCleanUpStateHistoryAge: " + Convert::ToString(GetCleanUpStateHistoryAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpStateHistoryAge())); + } + if (GetCleanUpServiceChecksAge() > 0) { + CleanUpExecuteQuery("servicechecks", "start_time", now - GetCleanUpServiceChecksAge()); + Log(LogDebug, "db_ido", "GetCleanUpServiceChecksAge: " + Convert::ToString(GetCleanUpServiceChecksAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpServiceChecksAge())); + } + if (GetCleanUpSystemCommandsAge() > 0) { + CleanUpExecuteQuery("systemcommands", "start_time", now - GetCleanUpSystemCommandsAge()); + Log(LogDebug, "db_ido", "GetCleanUpSystemCommandsAge: " + Convert::ToString(GetCleanUpSystemCommandsAge()) + + " now: " + Convert::ToString(now) + + " old: " + Convert::ToString(now - GetCleanUpSystemCommandsAge())); + } +} + +void DbConnection::CleanUpExecuteQuery(const String& table, const String& time_key, double time_value) +{ + /* Default handler does nothing. */ +} + +Dictionary::Ptr DbConnection::GetCleanUp(void) const +{ + if (!m_CleanUp) + return Empty; + else + return m_CleanUp; +} + +Value DbConnection::GetCleanUpAcknowledgementsAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("acknowledgement_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("acknowledgement_age"); +} + +Value DbConnection::GetCleanUpCommentHistoryAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("commenthistory_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("commenthistory_age"); +} + +Value DbConnection::GetCleanUpContactNotificationsAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("contactnotifications_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("contactnotifications_age"); +} + +Value DbConnection::GetCleanUpContactNotificationMethodsAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("contactnotificationmethods_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("contactnotificationmethods_age"); +} + +Value DbConnection::GetCleanUpDowntimeHistoryAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("downtimehistory_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("downtimehistory_age"); +} + +Value DbConnection::GetCleanUpEventHandlersAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("eventhandlers_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("eventhandlers_age"); +} + +Value DbConnection::GetCleanUpExternalCommandsAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("externalcommands_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("externalcommands_age"); +} + +Value DbConnection::GetCleanUpFlappingHistoryAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("flappinghistory_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("flappinghistory_age"); +} + +Value DbConnection::GetCleanUpHostChecksAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("hostchecks_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("hostchecks_age"); +} + +Value DbConnection::GetCleanUpLogEntriesAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("logentries_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("logentries_age"); +} + +Value DbConnection::GetCleanUpNotificationsAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("notifications_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("notifications_age"); +} + +Value DbConnection::GetCleanUpProcessEventsAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("processevents_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("processevents_age"); +} + +Value DbConnection::GetCleanUpStateHistoryAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("statehistory_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("statehistory_age"); +} + +Value DbConnection::GetCleanUpServiceChecksAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("servicechecks_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("servicechecks_age"); +} + +Value DbConnection::GetCleanUpSystemCommandsAge(void) const +{ + Dictionary::Ptr cleanup = GetCleanUp(); + + if (!cleanup || cleanup->Get("systemcommands_age").IsEmpty()) + return CleanUpAgeNone; + else + return cleanup->Get("systemcommands_age"); +} + void DbConnection::SetObjectID(const DbObject::Ptr& dbobj, const DbReference& dbref) { if (dbref.IsValid()) @@ -202,14 +468,18 @@ void DbConnection::InternalSerialize(const Dictionary::Ptr& bag, int attributeTy { DynamicObject::InternalSerialize(bag, attributeTypes); - if (attributeTypes & Attribute_Config) + if (attributeTypes & Attribute_Config) { bag->Set("table_prefix", m_TablePrefix); + bag->Set("cleanup", m_CleanUp); + } } void DbConnection::InternalDeserialize(const Dictionary::Ptr& bag, int attributeTypes) { DynamicObject::InternalDeserialize(bag, attributeTypes); - if (attributeTypes & Attribute_Config) + if (attributeTypes & Attribute_Config) { m_TablePrefix = bag->Get("table_prefix"); + m_CleanUp = bag->Get("cleanup"); + } } \ No newline at end of file diff --git a/lib/db_ido/dbconnection.h b/lib/db_ido/dbconnection.h index ef30f426b..bb546cf4f 100644 --- a/lib/db_ido/dbconnection.h +++ b/lib/db_ido/dbconnection.h @@ -28,6 +28,14 @@ namespace icinga { +enum CleanUpAge +{ + CleanUpAgeNone = 0, + CleanUpAgeOneMonth = 44640, + CleanUpAgeOneMeek = 10080, + CleanUpAgeOneDay = 1440, +}; + /** * A database connection. * @@ -53,6 +61,22 @@ public: bool GetStatusUpdate(const DbObject::Ptr& dbobj) const; String GetTablePrefix(void) const; + Dictionary::Ptr GetCleanUp(void) const; + Value GetCleanUpAcknowledgementsAge(void) const; + Value GetCleanUpCommentHistoryAge(void) const; + Value GetCleanUpContactNotificationsAge(void) const; + Value GetCleanUpContactNotificationMethodsAge(void) const; + Value GetCleanUpDowntimeHistoryAge(void) const; + Value GetCleanUpEventHandlersAge(void) const; + Value GetCleanUpExternalCommandsAge(void) const; + Value GetCleanUpFlappingHistoryAge(void) const; + Value GetCleanUpHostChecksAge(void) const; + Value GetCleanUpLogEntriesAge(void) const; + Value GetCleanUpNotificationsAge(void) const; + Value GetCleanUpProcessEventsAge(void) const; + Value GetCleanUpStateHistoryAge(void) const; + Value GetCleanUpServiceChecksAge(void) const; + Value GetCleanUpSystemCommandsAge(void) const; protected: virtual void Start(void); @@ -64,15 +88,22 @@ protected: virtual void ActivateObject(const DbObject::Ptr& dbobj) = 0; virtual void DeactivateObject(const DbObject::Ptr& dbobj) = 0; + virtual void CleanUpExecuteQuery(const String& table, const String& time_key, double time_value) = 0; + void UpdateAllObjects(void); private: String m_TablePrefix; + Dictionary::Ptr m_CleanUp; std::map m_ObjectIDs; std::map m_InsertIDs; std::set m_ConfigUpdates; std::set m_StatusUpdates; + Timer::Ptr m_CleanUpTimer; + + void CleanUpHandler(void); + static Timer::Ptr m_ProgramStatusTimer; static void InsertRuntimeVariable(const String& key, const Value& value); diff --git a/lib/db_ido/dbvalue.h b/lib/db_ido/dbvalue.h index 6713721a0..76ac1d8d6 100644 --- a/lib/db_ido/dbvalue.h +++ b/lib/db_ido/dbvalue.h @@ -54,6 +54,7 @@ public: static bool IsTimestamp(const Value& value); static bool IsTimestampNow(const Value& value); static bool IsObjectInsertID(const Value& value); + static Value ExtractValue(const Value& value); DbValueType GetType(void) const;