Merge pull request #7667 from Icinga/feature/icingadb-acks-history

IcingaDB: populate icinga:history:stream:acknowledgement
This commit is contained in:
Noah Hilverling 2019-12-05 09:20:36 +01:00 committed by GitHub
commit 71ef1de964
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 149 additions and 17 deletions

View File

@ -244,8 +244,10 @@ Dictionary::Ptr ApiActions::RemoveAcknowledgement(const ConfigObject::Ptr& objec
"Cannot remove acknowledgement for non-existent checkable object " "Cannot remove acknowledgement for non-existent checkable object "
+ object->GetName() + "."); + object->GetName() + ".");
checkable->ClearAcknowledgement(); String removedBy (HttpUtility::GetLastParameter(params, "author"));
checkable->RemoveCommentsByType(CommentAcknowledgement, HttpUtility::GetLastParameter(params, "author"));
checkable->ClearAcknowledgement(removedBy);
checkable->RemoveCommentsByType(CommentAcknowledgement, removedBy);
return ApiActions::CreateResult(200, "Successfully removed acknowledgement for object '" + checkable->GetName() + "'."); return ApiActions::CreateResult(200, "Successfully removed acknowledgement for object '" + checkable->GetName() + "'.");
} }

View File

@ -221,7 +221,7 @@ void ApiEvents::AcknowledgementSetHandler(const Checkable::Ptr& checkable,
inboxes.Push(std::move(result)); inboxes.Push(std::move(result));
} }
void ApiEvents::AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const MessageOrigin::Ptr& origin) void ApiEvents::AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const String& removedBy, const MessageOrigin::Ptr& origin)
{ {
std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("AcknowledgementCleared"); std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("AcknowledgementCleared");
auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::AcknowledgementCleared)); auto inboxes (EventsRouter::GetInstance().GetInboxes(EventType::AcknowledgementCleared));

View File

@ -30,7 +30,7 @@ public:
static void AcknowledgementSetHandler(const Checkable::Ptr& checkable, static void AcknowledgementSetHandler(const Checkable::Ptr& checkable,
const String& author, const String& comment, AcknowledgementType type, const String& author, const String& comment, AcknowledgementType type,
bool notify, bool persistent, double expiry, const MessageOrigin::Ptr& origin); bool notify, bool persistent, double expiry, const MessageOrigin::Ptr& origin);
static void AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const MessageOrigin::Ptr& origin); static void AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const String& removedBy, const MessageOrigin::Ptr& origin);
static void CommentAddedHandler(const Comment::Ptr& comment); static void CommentAddedHandler(const Comment::Ptr& comment);
static void CommentRemovedHandler(const Comment::Ptr& comment); static void CommentRemovedHandler(const Comment::Ptr& comment);

View File

@ -280,7 +280,7 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
/* remove acknowledgements */ /* remove acknowledgements */
if (GetAcknowledgement() == AcknowledgementNormal || if (GetAcknowledgement() == AcknowledgementNormal ||
(GetAcknowledgement() == AcknowledgementSticky && IsStateOK(new_state))) { (GetAcknowledgement() == AcknowledgementSticky && IsStateOK(new_state))) {
ClearAcknowledgement(); ClearAcknowledgement("");
} }
/* reschedule direct parents */ /* reschedule direct parents */

View File

@ -16,7 +16,7 @@ REGISTER_TYPE_WITH_PROTOTYPE(Checkable, Checkable::GetPrototype());
INITIALIZE_ONCE(&Checkable::StaticInitialize); INITIALIZE_ONCE(&Checkable::StaticInitialize);
boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType, bool, bool, double, const MessageOrigin::Ptr&)> Checkable::OnAcknowledgementSet; boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType, bool, bool, double, const MessageOrigin::Ptr&)> Checkable::OnAcknowledgementSet;
boost::signals2::signal<void (const Checkable::Ptr&, const MessageOrigin::Ptr&)> Checkable::OnAcknowledgementCleared; boost::signals2::signal<void (const Checkable::Ptr&, const String&, const MessageOrigin::Ptr&)> Checkable::OnAcknowledgementCleared;
static Timer::Ptr l_CheckablesFireSuppressedNotifications; static Timer::Ptr l_CheckablesFireSuppressedNotifications;
@ -110,7 +110,7 @@ AcknowledgementType Checkable::GetAcknowledgement()
if (expiry != 0 && expiry < Utility::GetTime()) { if (expiry != 0 && expiry < Utility::GetTime()) {
avalue = AcknowledgementNone; avalue = AcknowledgementNone;
ClearAcknowledgement(); ClearAcknowledgement("");
} }
} }
@ -136,7 +136,7 @@ void Checkable::AcknowledgeProblem(const String& author, const String& comment,
OnAcknowledgementSet(this, author, comment, type, notify, persistent, expiry, origin); OnAcknowledgementSet(this, author, comment, type, notify, persistent, expiry, origin);
} }
void Checkable::ClearAcknowledgement(const MessageOrigin::Ptr& origin) void Checkable::ClearAcknowledgement(const String& removedBy, const MessageOrigin::Ptr& origin)
{ {
SetAcknowledgementRaw(AcknowledgementNone); SetAcknowledgementRaw(AcknowledgementNone);
SetAcknowledgementExpiry(0); SetAcknowledgementExpiry(0);
@ -144,7 +144,7 @@ void Checkable::ClearAcknowledgement(const MessageOrigin::Ptr& origin)
Log(LogInformation, "Checkable") Log(LogInformation, "Checkable")
<< "Acknowledgement cleared for checkable '" << GetName() << "'."; << "Acknowledgement cleared for checkable '" << GetName() << "'.";
OnAcknowledgementCleared(this, origin); OnAcknowledgementCleared(this, removedBy, origin);
} }
Endpoint::Ptr Checkable::GetCommandEndpoint() const Endpoint::Ptr Checkable::GetCommandEndpoint() const

View File

@ -69,7 +69,7 @@ public:
AcknowledgementType GetAcknowledgement(); AcknowledgementType GetAcknowledgement();
void AcknowledgeProblem(const String& author, const String& comment, AcknowledgementType type, bool notify = true, bool persistent = false, double expiry = 0, const MessageOrigin::Ptr& origin = nullptr); void AcknowledgeProblem(const String& author, const String& comment, AcknowledgementType type, bool notify = true, bool persistent = false, double expiry = 0, const MessageOrigin::Ptr& origin = nullptr);
void ClearAcknowledgement(const MessageOrigin::Ptr& origin = nullptr); void ClearAcknowledgement(const String& removedBy, const MessageOrigin::Ptr& origin = nullptr);
int GetSeverity() const override; int GetSeverity() const override;
bool GetProblem() const override; bool GetProblem() const override;
@ -113,7 +113,7 @@ public:
const String&, const MessageOrigin::Ptr&)> OnNotificationSentToAllUsers; const String&, const MessageOrigin::Ptr&)> OnNotificationSentToAllUsers;
static boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType, static boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType,
bool, bool, double, const MessageOrigin::Ptr&)> OnAcknowledgementSet; bool, bool, double, const MessageOrigin::Ptr&)> OnAcknowledgementSet;
static boost::signals2::signal<void (const Checkable::Ptr&, const MessageOrigin::Ptr&)> OnAcknowledgementCleared; static boost::signals2::signal<void (const Checkable::Ptr&, const String&, const MessageOrigin::Ptr&)> OnAcknowledgementCleared;
static boost::signals2::signal<void (const Checkable::Ptr&)> OnNextCheckUpdated; static boost::signals2::signal<void (const Checkable::Ptr&)> OnNextCheckUpdated;
static boost::signals2::signal<void (const Checkable::Ptr&)> OnEventCommandExecuted; static boost::signals2::signal<void (const Checkable::Ptr&)> OnEventCommandExecuted;

View File

@ -542,7 +542,7 @@ Value ClusterEvents::AcknowledgementSetAPIHandler(const MessageOrigin::Ptr& orig
return Empty; return Empty;
} }
void ClusterEvents::AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const MessageOrigin::Ptr& origin) void ClusterEvents::AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const String& removedBy, const MessageOrigin::Ptr& origin)
{ {
ApiListener::Ptr listener = ApiListener::GetInstance(); ApiListener::Ptr listener = ApiListener::GetInstance();
@ -557,6 +557,7 @@ void ClusterEvents::AcknowledgementClearedHandler(const Checkable::Ptr& checkabl
params->Set("host", host->GetName()); params->Set("host", host->GetName());
if (service) if (service)
params->Set("service", service->GetShortName()); params->Set("service", service->GetShortName());
params->Set("author", removedBy);
Dictionary::Ptr message = new Dictionary(); Dictionary::Ptr message = new Dictionary();
message->Set("jsonrpc", "2.0"); message->Set("jsonrpc", "2.0");
@ -598,7 +599,7 @@ Value ClusterEvents::AcknowledgementClearedAPIHandler(const MessageOrigin::Ptr&
return Empty; return Empty;
} }
checkable->ClearAcknowledgement(origin); checkable->ClearAcknowledgement(params->Get("author"), origin);
return Empty; return Empty;
} }

View File

@ -42,7 +42,7 @@ public:
bool notify, bool persistent, double expiry, const MessageOrigin::Ptr& origin); bool notify, bool persistent, double expiry, const MessageOrigin::Ptr& origin);
static Value AcknowledgementSetAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params); static Value AcknowledgementSetAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
static void AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const MessageOrigin::Ptr& origin); static void AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const String& removedBy, const MessageOrigin::Ptr& origin);
static Value AcknowledgementClearedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params); static Value AcknowledgementClearedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);
static Value ExecuteCommandAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params); static Value ExecuteCommandAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params);

View File

@ -639,7 +639,7 @@ void ExternalCommandProcessor::RemoveSvcAcknowledgement(double, const std::vecto
{ {
ObjectLock olock(service); ObjectLock olock(service);
service->ClearAcknowledgement(); service->ClearAcknowledgement("");
} }
service->RemoveCommentsByType(CommentAcknowledgement); service->RemoveCommentsByType(CommentAcknowledgement);
@ -703,7 +703,7 @@ void ExternalCommandProcessor::RemoveHostAcknowledgement(double, const std::vect
{ {
ObjectLock olock(host); ObjectLock olock(host);
host->ClearAcknowledgement(); host->ClearAcknowledgement("");
} }
host->RemoveCommentsByType(CommentAcknowledgement); host->RemoveCommentsByType(CommentAcknowledgement);
} }

View File

@ -60,8 +60,15 @@ void IcingaDB::ConfigStaticInitialize()
IcingaDB::StateChangeHandler(checkable, cr, type); IcingaDB::StateChangeHandler(checkable, cr, type);
}); });
Checkable::OnAcknowledgementSet.connect([](const Checkable::Ptr& checkable, const String& author, const String& comment, AcknowledgementType type, bool, bool persistent, double expiry, const MessageOrigin::Ptr&) {
AcknowledgementSetHandler(checkable, author, comment, type, persistent, expiry);
});
Checkable::OnAcknowledgementCleared.connect([](const Checkable::Ptr& checkable, const String& removedBy, const MessageOrigin::Ptr&) {
AcknowledgementClearedHandler(checkable, removedBy);
});
/* triggered when acknowledged host/service goes back to ok and when the acknowledgement gets deleted */ /* triggered when acknowledged host/service goes back to ok and when the acknowledgement gets deleted */
Checkable::OnAcknowledgementCleared.connect([](const Checkable::Ptr& checkable, const MessageOrigin::Ptr&) { Checkable::OnAcknowledgementCleared.connect([](const Checkable::Ptr& checkable, const String&, const MessageOrigin::Ptr&) {
IcingaDB::StateChangeHandler(checkable); IcingaDB::StateChangeHandler(checkable);
}); });
@ -1662,6 +1669,92 @@ void IcingaDB::SendNextUpdate(const Checkable::Ptr& checkable)
); );
} }
void IcingaDB::SendAcknowledgementSet(const Checkable::Ptr& checkable, const String& author, const String& comment, AcknowledgementType type, bool persistent, double expiry)
{
if (!m_Rcon || !m_Rcon->IsConnected())
return;
Host::Ptr host;
Service::Ptr service;
tie(host, service) = GetHostService(checkable);
std::vector<String> xAdd ({
"XADD", "icinga:history:stream:acknowledgement", "*",
"id", Utility::NewUniqueID(),
"environment_id", SHA1(GetEnvironment()),
"host_id", GetObjectIdentifier(host),
"event_time", Convert::ToString(TimestampToMilliseconds(Utility::GetTime())),
"event_type", "ack_set",
"author", author,
"comment", comment,
"is_sticky", Convert::ToString((unsigned short)(type == AcknowledgementSticky)),
"is_persistent", Convert::ToString((unsigned short)persistent)
});
if (service) {
xAdd.emplace_back("object_type");
xAdd.emplace_back("service");
xAdd.emplace_back("service_id");
xAdd.emplace_back(GetObjectIdentifier(checkable));
} else {
xAdd.emplace_back("object_type");
xAdd.emplace_back("host");
}
auto endpoint (Endpoint::GetLocalEndpoint());
if (endpoint) {
xAdd.emplace_back("endpoint_id");
xAdd.emplace_back(GetObjectIdentifier(endpoint));
}
if (expiry > 0) {
xAdd.emplace_back("expire_time");
xAdd.emplace_back(Convert::ToString(TimestampToMilliseconds(expiry)));
}
m_Rcon->FireAndForgetQuery(std::move(xAdd), Prio::History);
}
void IcingaDB::SendAcknowledgementCleared(const Checkable::Ptr& checkable, const String& removedBy)
{
if (!m_Rcon || !m_Rcon->IsConnected())
return;
Host::Ptr host;
Service::Ptr service;
tie(host, service) = GetHostService(checkable);
std::vector<String> xAdd ({
"XADD", "icinga:history:stream:acknowledgement", "*",
"id", Utility::NewUniqueID(),
"environment_id", SHA1(GetEnvironment()),
"host_id", GetObjectIdentifier(host),
"event_time", Convert::ToString(TimestampToMilliseconds(Utility::GetTime())),
"event_type", "ack_clear",
"author", removedBy
});
if (service) {
xAdd.emplace_back("object_type");
xAdd.emplace_back("service");
xAdd.emplace_back("service_id");
xAdd.emplace_back(GetObjectIdentifier(checkable));
} else {
xAdd.emplace_back("object_type");
xAdd.emplace_back("host");
}
auto endpoint (Endpoint::GetLocalEndpoint());
if (endpoint) {
xAdd.emplace_back("endpoint_id");
xAdd.emplace_back(GetObjectIdentifier(endpoint));
}
m_Rcon->FireAndForgetQuery(std::move(xAdd), Prio::History);
}
Dictionary::Ptr IcingaDB::SerializeState(const Checkable::Ptr& checkable) Dictionary::Ptr IcingaDB::SerializeState(const Checkable::Ptr& checkable)
{ {
Dictionary::Ptr attrs = new Dictionary(); Dictionary::Ptr attrs = new Dictionary();
@ -1907,3 +2000,35 @@ void IcingaDB::NewCheckResultHandler(const Checkable::Ptr& checkable)
rw->m_WorkQueue.Enqueue([rw, checkable]() { rw->SendNextUpdate(checkable); }); rw->m_WorkQueue.Enqueue([rw, checkable]() { rw->SendNextUpdate(checkable); });
} }
} }
struct AuthorComment
{
String Author;
String Comment;
};
void IcingaDB::AcknowledgementSetHandler(const Checkable::Ptr& checkable, const String& author, const String& comment, AcknowledgementType type, bool persistent, double expiry)
{
auto rws (ConfigType::GetObjectsByType<IcingaDB>());
if (!rws.empty()) {
auto ac (Shared<AuthorComment>::Make(AuthorComment{author, comment}));
for (auto& rw : rws) {
rw->m_WorkQueue.Enqueue([rw, checkable, ac, type, persistent, expiry]() { rw->SendAcknowledgementSet(checkable, ac->Author, ac->Comment, type, persistent, expiry); });
}
}
}
void IcingaDB::AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const String& removedBy)
{
auto rws (ConfigType::GetObjectsByType<IcingaDB>());
if (!rws.empty()) {
auto rb (Shared<String>::Make(removedBy));
for (auto& rw : rws) {
rw->m_WorkQueue.Enqueue([rw, checkable, rb]() { rw->SendAcknowledgementCleared(checkable, *rb); });
}
}
}

View File

@ -67,6 +67,8 @@ private:
void SendRemovedComment(const Comment::Ptr& comment); void SendRemovedComment(const Comment::Ptr& comment);
void SendFlappingChanged(const Checkable::Ptr& checkable, const Value& value); void SendFlappingChanged(const Checkable::Ptr& checkable, const Value& value);
void SendNextUpdate(const Checkable::Ptr& checkable); void SendNextUpdate(const Checkable::Ptr& checkable);
void SendAcknowledgementSet(const Checkable::Ptr& checkable, const String& author, const String& comment, AcknowledgementType type, bool persistent, double expiry);
void SendAcknowledgementCleared(const Checkable::Ptr& checkable, const String& removedBy);
std::vector<String> UpdateObjectAttrs(const ConfigObject::Ptr& object, int fieldType, const String& typeNameOverride); std::vector<String> UpdateObjectAttrs(const ConfigObject::Ptr& object, int fieldType, const String& typeNameOverride);
Dictionary::Ptr SerializeState(const Checkable::Ptr& checkable); Dictionary::Ptr SerializeState(const Checkable::Ptr& checkable);
@ -109,6 +111,8 @@ private:
static void CommentRemovedHandler(const Comment::Ptr& comment); static void CommentRemovedHandler(const Comment::Ptr& comment);
static void FlappingChangedHandler(const Checkable::Ptr& checkable, const Value& value); static void FlappingChangedHandler(const Checkable::Ptr& checkable, const Value& value);
static void NewCheckResultHandler(const Checkable::Ptr& checkable); static void NewCheckResultHandler(const Checkable::Ptr& checkable);
static void AcknowledgementSetHandler(const Checkable::Ptr& checkable, const String& author, const String& comment, AcknowledgementType type, bool persistent, double expiry);
static void AcknowledgementClearedHandler(const Checkable::Ptr& checkable, const String& removedBy);
void AssertOnWorkQueue(); void AssertOnWorkQueue();