From 3af0559b4ae26fc12dd32fb0b69ab8c85d1e1ed1 Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Fri, 28 Jun 2013 21:31:38 +0200 Subject: [PATCH] Compat: log notifications (wip) - we need a way to figure out which last commend id (or, author and text) where set when type is CUSTOM or ACKNOWLEDGEMENT - GetCheckCommandName was required too - not sure if notifications.cpp is the correct location refs #4361 refs #3985 refs #2750 --- components/compat/compatlog.cpp | 91 ++++++++++++++++++++++++++++ components/compat/compatlog.h | 1 + lib/icinga/Makefile.am | 2 + lib/icinga/icinga.vcxproj | 2 + lib/icinga/icinga.vcxproj.filters | 6 ++ lib/icinga/notification.cpp | 27 +++++++++ lib/icinga/notificationmessage.cpp | 95 ++++++++++++++++++++++++++++++ lib/icinga/notificationmessage.h | 62 +++++++++++++++++++ lib/icinga/service-comment.cpp | 12 ++++ lib/icinga/service.cpp | 5 ++ lib/icinga/service.h | 4 ++ 11 files changed, 307 insertions(+) create mode 100644 lib/icinga/notificationmessage.cpp create mode 100644 lib/icinga/notificationmessage.h diff --git a/components/compat/compatlog.cpp b/components/compat/compatlog.cpp index 7bb1c74c5..2f21b3a57 100644 --- a/components/compat/compatlog.cpp +++ b/components/compat/compatlog.cpp @@ -21,6 +21,8 @@ #include "icinga/checkresultmessage.h" #include "icinga/downtimemessage.h" #include "icinga/service.h" +#include "icinga/notification.h" +#include "icinga/notificationmessage.h" #include "icinga/macroprocessor.h" #include "config/configcompilercontext.h" #include "base/dynamictype.h" @@ -67,6 +69,8 @@ void CompatLog::Start(void) boost::bind(&CompatLog::CheckResultRequestHandler, this, _3)); m_Endpoint->RegisterTopicHandler("icinga::Downtime", boost::bind(&CompatLog::DowntimeRequestHandler, this, _3)); + m_Endpoint->RegisterTopicHandler("icinga::NotificationSent", + boost::bind(&CompatLog::NotificationSentRequestHandler, this, _3)); m_RotationTimer = boost::make_shared(); m_RotationTimer->OnTimerExpired.connect(boost::bind(&CompatLog::RotationTimerHandler, this)); @@ -272,6 +276,93 @@ void CompatLog::DowntimeRequestHandler(const RequestMessage& request) } } +/** + * @threadsafety Always. + */ +void CompatLog::NotificationSentRequestHandler(const RequestMessage& request) +{ + Log(LogWarning, "compat", "Got notification"); + + NotificationMessage params; + if (!request.GetParams(¶ms)) + return; + + String svcname = params.GetService(); + Service::Ptr service = Service::GetByName(svcname); + + Log(LogWarning, "compat", "Got notification for service" + svcname); + + Host::Ptr host = service->GetHost(); + + if (!host) + return; + + String username = params.GetUser(); + String author = params.GetAuthor(); + String comment_text = params.GetCommentText(); + + NotificationType notification_type = params.GetType(); + String notification_type_str = Notification::NotificationTypeToString(notification_type); + + String author_comment = ""; + if (notification_type == NotificationCustom || notification_type == NotificationAcknowledgement) { + author_comment = ";" + author + ";" + comment_text; + } + + Dictionary::Ptr cr = params.GetCheckResult(); + if (!cr) + return; + + String output; + String raw_output; + + if (cr) { + raw_output = cr->Get("output"); + size_t line_end = raw_output.Find("\n"); + + output = raw_output.SubStr(0, line_end); + } + + std::ostringstream msgbuf; + msgbuf << "SERVICE NOTIFICATION: " + << username << ";" + << host->GetName() << ";" + << service->GetShortName() << ";" + << notification_type_str << " " + << "(" << Service::StateToString(service->GetState()) << ");" + << service->GetCheckCommandName() << ";" + << raw_output << author_comment + << ""; + + { + ObjectLock oLock(this); + WriteLine(msgbuf.str()); + } + + if (service == host->GetHostCheckService()) { + std::ostringstream msgbuf; + msgbuf << "HOST NOTIFICATION: " + << username << ";" + << host->GetName() << ";" + << notification_type_str << " " + << "(" << Service::StateToString(service->GetState()) << ");" + << service->GetCheckCommandName() << ";" + << raw_output << author_comment + << ""; + + { + ObjectLock oLock(this); + WriteLine(msgbuf.str()); + } + } + + { + ObjectLock oLock(this); + Flush(); + } +} + + void CompatLog::WriteLine(const String& line) { ASSERT(OwnsLock()); diff --git a/components/compat/compatlog.h b/components/compat/compatlog.h index 519e7af41..eb4a3a416 100644 --- a/components/compat/compatlog.h +++ b/components/compat/compatlog.h @@ -64,6 +64,7 @@ private: Endpoint::Ptr m_Endpoint; void CheckResultRequestHandler(const RequestMessage& request); void DowntimeRequestHandler(const RequestMessage& request); + void NotificationSentRequestHandler(const RequestMessage& request); Timer::Ptr m_RotationTimer; void RotationTimerHandler(void); diff --git a/lib/icinga/Makefile.am b/lib/icinga/Makefile.am index 4234db630..43a526a83 100644 --- a/lib/icinga/Makefile.am +++ b/lib/icinga/Makefile.am @@ -45,6 +45,8 @@ libicinga_la_SOURCES = \ notification.h \ notificationcommand.cpp \ notificationcommand.h \ + notificationmessage.cpp \ + notificationmessage.h \ notificationrequestmessage.cpp \ notificationrequestmessage.h \ nullchecktask.cpp \ diff --git a/lib/icinga/icinga.vcxproj b/lib/icinga/icinga.vcxproj index 310925b45..bf5e5404d 100644 --- a/lib/icinga/icinga.vcxproj +++ b/lib/icinga/icinga.vcxproj @@ -37,6 +37,7 @@ + @@ -65,6 +66,7 @@ + diff --git a/lib/icinga/icinga.vcxproj.filters b/lib/icinga/icinga.vcxproj.filters index f170ee25f..01db5aacc 100644 --- a/lib/icinga/icinga.vcxproj.filters +++ b/lib/icinga/icinga.vcxproj.filters @@ -49,6 +49,9 @@ Quelldateien + + Quelldateien + Quelldateien @@ -120,6 +123,9 @@ Headerdateien + + Headerdateien + Headerdateien diff --git a/lib/icinga/notification.cpp b/lib/icinga/notification.cpp index 9460f8fdd..a9def5997 100644 --- a/lib/icinga/notification.cpp +++ b/lib/icinga/notification.cpp @@ -21,6 +21,8 @@ #include "icinga/notificationcommand.h" #include "icinga/macroprocessor.h" #include "icinga/service.h" +#include "icinga/notificationmessage.h" +#include "remoting/endpointmanager.h" #include "base/dynamictype.h" #include "base/objectlock.h" #include "base/logger_fwd.h" @@ -330,6 +332,31 @@ void Notification::ExecuteNotificationHelper(NotificationType type, const User:: try { GetNotificationCommand()->Execute(GetSelf(), user, cr, type); + RequestMessage rm; + rm.SetMethod("icinga::NotificationSent"); + + NotificationMessage params; + String comment_id = GetService()->GetLastCommentID(); + Dictionary::Ptr comment = Service::GetCommentByID(comment_id); + + String author = ""; + String text = ""; + if (comment) { + author = comment->Get("author"); + text = comment->Get("text"); + Log(LogDebug, "icinga", "notification for service '" + GetService()->GetName() + "' with author " + author + "and text " + text); + } + params.SetService(GetService()->GetName()); + params.SetUser(user->GetName()); + params.SetType(type); + params.SetAuthor(author); // figure out how to receive these attributes properly from service->comments TODO + params.SetCommentText(text); + params.SetCheckResult(cr); + + rm.SetParams(params); + + EndpointManager::GetInstance()->SendMulticastMessage(rm); + Log(LogInformation, "icinga", "Completed sending notification for service '" + GetService()->GetName() + "'"); } catch (const std::exception& ex) { std::ostringstream msgbuf; diff --git a/lib/icinga/notificationmessage.cpp b/lib/icinga/notificationmessage.cpp new file mode 100644 index 000000000..7875899bc --- /dev/null +++ b/lib/icinga/notificationmessage.cpp @@ -0,0 +1,95 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#include "icinga/notificationmessage.h" + +using namespace icinga; + +String NotificationMessage::GetService(void) const +{ + String service; + Get("service", &service); + return service; +} + +void NotificationMessage::SetService(const String& service) +{ + Set("service", service); +} + +String NotificationMessage::GetUser(void) const +{ + String user; + Get("user", &user); + return user; +} + +void NotificationMessage::SetUser(const String& user) +{ + Set("user", user); +} + +NotificationType NotificationMessage::GetType(void) const +{ + long type; + Get("type", &type); + return static_cast(type); +} + +void NotificationMessage::SetType(NotificationType type) +{ + Set("type", type); +} + +String NotificationMessage::GetAuthor(void) const +{ + String author; + Get("author", &author); + return author; +} + +void NotificationMessage::SetAuthor(const String& author) +{ + Set("author", author); +} + +String NotificationMessage::GetCommentText(void) const +{ + String comment_text; + Get("comment_text", &comment_text); + return comment_text; +} + +void NotificationMessage::SetCommentText(const String& comment_text) +{ + Set("comment_text", comment_text); +} + +Dictionary::Ptr NotificationMessage::GetCheckResult(void) const +{ + Dictionary::Ptr cr; + Get("check_result", &cr); + return cr; +} + +void NotificationMessage::SetCheckResult(const Dictionary::Ptr& result) +{ + Set("check_result", result); +} + diff --git a/lib/icinga/notificationmessage.h b/lib/icinga/notificationmessage.h new file mode 100644 index 000000000..4348e3076 --- /dev/null +++ b/lib/icinga/notificationmessage.h @@ -0,0 +1,62 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#ifndef NOTIFICATIONMESSAGE_H +#define NOTIFICATIONMESSAGE_H + +#include "icinga/i2-icinga.h" +#include "icinga/notification.h" +#include "remoting/messagepart.h" + +namespace icinga +{ + +/** + * A notification message for a service. + * + * @ingroup icinga + */ +class I2_ICINGA_API NotificationMessage : public MessagePart +{ +public: + NotificationMessage(void) : MessagePart() { } + explicit NotificationMessage(const MessagePart& message) : MessagePart(message) { } + + String GetService(void) const; + void SetService(const String& service); + + String GetUser(void) const; + void SetUser(const String& user); + + NotificationType GetType(void) const; + void SetType(NotificationType type); + + String GetAuthor(void) const; + void SetAuthor(const String& author); + + String GetCommentText(void) const; + void SetCommentText(const String& comment_text); + + Dictionary::Ptr GetCheckResult(void) const; + void SetCheckResult(const Dictionary::Ptr& result); +}; + +} + +#endif /* NOTIFICATIONMESSAGE_H */ diff --git a/lib/icinga/service-comment.cpp b/lib/icinga/service-comment.cpp index 972b71c8d..975514d00 100644 --- a/lib/icinga/service-comment.cpp +++ b/lib/icinga/service-comment.cpp @@ -44,6 +44,16 @@ int Service::GetNextCommentID(void) return l_NextCommentID; } +String Service::GetLastCommentID(void) const +{ + return m_LastCommentID; +} + +void Service::SetLastCommentID(String id) +{ + m_LastCommentID = id; +} + Dictionary::Ptr Service::GetComments(void) const { return m_Comments; @@ -90,6 +100,8 @@ String Service::AddComment(CommentType entryType, const String& author, Touch("comments"); } + SetLastCommentID(id); + return id; } diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index 8f5251653..a89e6c41f 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -176,6 +176,11 @@ String Service::GetShortName(void) const return m_ShortName; } +String Service::GetCheckCommandName(void) const +{ + return m_CheckCommand; +} + bool Service::IsReachable(void) const { ASSERT(!OwnsLock()); diff --git a/lib/icinga/service.h b/lib/icinga/service.h index cb0b96424..cf3bd9e5b 100644 --- a/lib/icinga/service.h +++ b/lib/icinga/service.h @@ -102,6 +102,7 @@ public: Array::Ptr GetGroups(void) const; String GetHostName(void) const; String GetShortName(void) const; + String GetCheckCommandName(void) const; std::set GetParentHosts(void) const; std::set GetParentServices(void) const; @@ -222,6 +223,8 @@ public: /* Comments */ static int GetNextCommentID(void); + String GetLastCommentID(void) const; + void SetLastCommentID(String id); Dictionary::Ptr GetComments(void) const; @@ -322,6 +325,7 @@ private: /* Comments */ Attribute m_Comments; + Attribute m_LastCommentID; static void CommentsExpireTimerHandler(void); -- 2.40.0