db_ido: Add cleanup for history tables.

refs #4567
This commit is contained in:
Michael Friedrich 2013-09-26 15:22:21 +02:00
parent 105dd71ba5
commit f1c0ce3b23
6 changed files with 340 additions and 7 deletions

View File

@ -129,7 +129,7 @@ void IdoMysqlConnection::ReconnectTimerHandler(void)
std::ostringstream msgbuf;
msgbuf << "MySQL IDO instance id: " << static_cast<long>(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<long>(m_InstanceID)) + " AND " + time_key +
"<FROM_UNIXTIME(" + Convert::ToString(static_cast<long>(time_value)) + ")");
}
void IdoMysqlConnection::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) const
{
DbConnection::InternalSerialize(bag, attributeTypes);

View File

@ -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;

View File

@ -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",
},
}

View File

@ -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 <boost/foreach.hpp>
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<Timer>();
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<Host>().size());
}
void DbConnection::CleanUpHandler(void)
{
long now = static_cast<long>(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");
}
}

View File

@ -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<DbObject::Ptr, DbReference> m_ObjectIDs;
std::map<DbObject::Ptr, DbReference> m_InsertIDs;
std::set<DbObject::Ptr> m_ConfigUpdates;
std::set<DbObject::Ptr> m_StatusUpdates;
Timer::Ptr m_CleanUpTimer;
void CleanUpHandler(void);
static Timer::Ptr m_ProgramStatusTimer;
static void InsertRuntimeVariable(const String& key, const Value& value);

View File

@ -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;