]> granicus.if.org Git - icinga2/commitdiff
Compat: log notifications (wip)
authorMichael Friedrich <michael.friedrich@netways.de>
Fri, 28 Jun 2013 19:31:38 +0000 (21:31 +0200)
committerMichael Friedrich <michael.friedrich@netways.de>
Fri, 28 Jun 2013 19:31:38 +0000 (21:31 +0200)
- 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
components/compat/compatlog.h
lib/icinga/Makefile.am
lib/icinga/icinga.vcxproj
lib/icinga/icinga.vcxproj.filters
lib/icinga/notification.cpp
lib/icinga/notificationmessage.cpp [new file with mode: 0644]
lib/icinga/notificationmessage.h [new file with mode: 0644]
lib/icinga/service-comment.cpp
lib/icinga/service.cpp
lib/icinga/service.h

index 7bb1c74c513a918c9eb78b75e87b2016b8f92d75..2f21b3a5783c7cacb5b92a0dad251aa0d0dd7ec2 100644 (file)
@@ -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<Timer>();
        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(&params))
+                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());
index 519e7af41b64d161af155fa2b12bcb5854c6e532..eb4a3a4167554dabf4ce9470d6020c89a33feca5 100644 (file)
@@ -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);
index 4234db6306be14c4e346a3b40b990ee19fe3fbeb..43a526a839e2eee13314fb7173e8e48f78333acf 100644 (file)
@@ -45,6 +45,8 @@ libicinga_la_SOURCES =  \
        notification.h \
        notificationcommand.cpp \
        notificationcommand.h \
+       notificationmessage.cpp \
+       notificationmessage.h \
        notificationrequestmessage.cpp \
        notificationrequestmessage.h \
        nullchecktask.cpp \
index 310925b45059217bafc077af2e1760746f50c89b..bf5e5404d58c9192dea93e0f49fea06d17ba9995 100644 (file)
@@ -37,6 +37,7 @@
     <ClCompile Include="macroprocessor.cpp" />
     <ClCompile Include="macroresolver.cpp" />
     <ClCompile Include="notification.cpp" />
+    <ClCompile Include="notificationmessage.cpp" />
     <ClCompile Include="notificationrequestmessage.cpp" />
     <ClCompile Include="pluginchecktask.cpp" />
     <ClCompile Include="nullchecktask.cpp" />
@@ -65,6 +66,7 @@
     <ClInclude Include="macroprocessor.h" />
     <ClInclude Include="macroresolver.h" />
     <ClInclude Include="notification.h" />
+    <ClInclude Include="notificationmessage.h" />
     <ClInclude Include="notificationrequestmessage.h" />
     <ClInclude Include="pluginchecktask.h" />
     <ClInclude Include="nullchecktask.h" />
index f170ee25f497876f1a82dcb7d2cd49cebe46e5de..01db5aacc6a26f4165a19f471fc41cd5d45c3755 100644 (file)
@@ -49,6 +49,9 @@
     <ClCompile Include="notification.cpp">
       <Filter>Quelldateien</Filter>
     </ClCompile>
+    <ClCompile Include="notificationmessage.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
     <ClCompile Include="notificationrequestmessage.cpp">
       <Filter>Quelldateien</Filter>
     </ClCompile>
     <ClInclude Include="notification.h">
       <Filter>Headerdateien</Filter>
     </ClInclude>
+    <ClInclude Include="notificationmessage.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
     <ClInclude Include="notificationrequestmessage.h">
       <Filter>Headerdateien</Filter>
     </ClInclude>
index 9460f8fddea319e895f4826e6e7560a92e5b7519..a9def59972647666aa4dd188fcf7db563667b6ce 100644 (file)
@@ -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 (file)
index 0000000..7875899
--- /dev/null
@@ -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<NotificationType>(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 (file)
index 0000000..4348e30
--- /dev/null
@@ -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 */
index 972b71c8da166545ad7f4622d7b8d526ab9301c9..975514d00669c1ad3b44998cc2dda4a7c2890970 100644 (file)
@@ -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;
 }
 
index 8f5251653efb32275ea5b5bf4affebdb1b429cf4..a89e6c41fa01e3ab05b61ac175acfc720ed6ab6f 100644 (file)
@@ -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());
index cb0b96424db794298f49c732e5a50ef31e26ef32..cf3bd9e5bd5b6dcd0ab60a42f579579c58fdf994 100644 (file)
@@ -102,6 +102,7 @@ public:
        Array::Ptr GetGroups(void) const;
        String GetHostName(void) const;
        String GetShortName(void) const;
+       String GetCheckCommandName(void) const;
 
        std::set<Host::Ptr> GetParentHosts(void) const;
        std::set<Service::Ptr> 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<Dictionary::Ptr> m_Comments;
+       Attribute<String> m_LastCommentID;
 
        static void CommentsExpireTimerHandler(void);