]> granicus.if.org Git - icinga2/commitdiff
Implement last_notification_result handling for Notification objects
authorMichael Friedrich <michael.friedrich@icinga.com>
Wed, 25 Jul 2018 12:33:28 +0000 (14:33 +0200)
committerMichael Friedrich <michael.friedrich@icinga.com>
Thu, 28 Mar 2019 09:43:35 +0000 (10:43 +0100)
lib/icinga/notification.cpp
lib/icinga/notification.hpp
lib/icinga/notification.ti
lib/icinga/notificationcommand.cpp
lib/icinga/notificationcommand.hpp
lib/icinga/notificationresult.cpp
lib/methods/pluginnotificationtask.cpp
lib/methods/pluginnotificationtask.hpp

index ad33fc3192d22cc2856aa69052916d0d73338d14..32a091a30e5c2d30cd6080db95588b176313f1d1 100644 (file)
@@ -532,10 +532,14 @@ void Notification::ExecuteNotificationHelper(NotificationType type, const User::
        String commandName = command->GetName();
 
        try {
-               command->Execute(this, user, cr, type, author, text);
+               NotificationResult::Ptr nr = new NotificationResult();
+
+               nr->SetExecutionStart(Utility::GetTime());
+
+               command->Execute(this, user, cr, nr, type, author, text);
 
                /* required by compatlogger */
-               Service::OnNotificationSentToUser(this, GetCheckable(), user, type, cr, author, text, commandName, nullptr);
+               Checkable::OnNotificationSentToUser(this, GetCheckable(), user, type, cr, author, text, command->GetName(), nullptr);
 
                Log(LogInformation, "Notification")
                        << "Completed sending '" << NotificationTypeToStringInternal(type)
@@ -556,6 +560,27 @@ void Notification::ProcessNotificationResult(const NotificationResult::Ptr& nr,
        if (!nr)
                return;
 
+       double now = Utility::GetTime();
+
+       if (nr->GetExecutionStart() == 0)
+               nr->SetExecutionStart(now);
+
+       if (nr->GetExecutionEnd() == 0)
+               nr->SetExecutionEnd(now);
+
+       /* Determine the execution endpoint from a locally executed check. */
+       if (!origin || origin->IsLocal())
+               nr->SetExecutionEndpoint(IcingaApplication::GetInstance()->GetNodeName());
+
+       if (!IsActive())
+               return;
+
+       {
+               ObjectLock olock(this);
+
+               SetLastNotificationResult(nr);
+       }
+
        /* Notify cluster, API and feature events. */
        OnNewNotificationResult(this, nr, origin);
 }
index e227867993f2ea8e8b1db4a0dc56de505ea807d9..5006e89d857c8fd45bad46ccf0297aa9f3bea586 100644 (file)
@@ -83,7 +83,7 @@ public:
 
        Endpoint::Ptr GetCommandEndpoint() const;
 
-       void ProcessNotificationResult(const NotificationResult::Ptr& nr, const MessageOrigin::Ptr& origin);
+       void ProcessNotificationResult(const NotificationResult::Ptr& nr, const MessageOrigin::Ptr& origin = nullptr);
 
        static String NotificationTypeToString(NotificationType type);
        static String NotificationFilterToString(int filter, const std::map<String, int>& filterMap);
index 04e6214ea7c5319b1cd710f2ff86ed37496e0013..f2aa77ed12dba1c6ff7a5e30d9003e350451ce75 100644 (file)
@@ -1,6 +1,8 @@
 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
 
 #include "icinga/customvarobject.hpp"
+#include "icinga/notificationresult.hpp"
+#include "base/array.hpp"
 #impl_include "icinga/notificationcommand.hpp"
 #impl_include "icinga/service.hpp"
 
@@ -16,6 +18,7 @@ public:
        virtual String MakeName(const String& shortName, const Object::Ptr& context) const;
        virtual Dictionary::Ptr ParseName(const String& name) const;
 };
+
 }}}
 
 class Notification : CustomVarObject < NotificationNameComposer
@@ -81,6 +84,7 @@ class Notification : CustomVarObject < NotificationNameComposer
        [state] Timestamp next_notification;
        [state] int notification_number;
        [state] Timestamp last_problem_notification;
+       [state] NotificationResult::Ptr last_notification_result;
 
        [config, navigation] name(Endpoint) command_endpoint (CommandEndpointRaw) {
                navigate {{{
index 8ae3e82a57411ab948204051510a94649f233bd9..dc9edb4f3659938cdb29935c35b19561ab46a089 100644 (file)
@@ -8,14 +8,15 @@ using namespace icinga;
 REGISTER_TYPE(NotificationCommand);
 
 Dictionary::Ptr NotificationCommand::Execute(const Notification::Ptr& notification,
-       const User::Ptr& user, const CheckResult::Ptr& cr, const NotificationType& type,
-       const String& author, const String& comment, const Dictionary::Ptr& resolvedMacros,
-       bool useResolvedMacros)
+       const User::Ptr& user, const CheckResult::Ptr& cr, const NotificationResult::Ptr& nr,
+       const NotificationType& type, const String& author, const String& comment,
+       const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
 {
        return GetExecute()->Invoke({
                notification,
                user,
                cr,
+               nr,
                type,
                author,
                comment,
index 210c91e86eed4362d626b584459e6e897233e636..0c76a0142376bb1ff4e87ae7b39ff02ec4be92b7 100644 (file)
@@ -23,8 +23,8 @@ public:
        DECLARE_OBJECTNAME(NotificationCommand);
 
        virtual Dictionary::Ptr Execute(const intrusive_ptr<Notification>& notification,
-               const User::Ptr& user, const CheckResult::Ptr& cr, const NotificationType& type,
-               const String& author, const String& comment,
+               const User::Ptr& user, const CheckResult::Ptr& cr, const NotificationResult::Ptr& nr,
+               const NotificationType& type, const String& author, const String& comment,
                const Dictionary::Ptr& resolvedMacros = nullptr,
                bool useResolvedMacros = false);
 };
index 30b46607550ee3d5c621312a852d62963eb6e658..699270e017e62b1216ee2228b7f1fec45656df09 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "icinga/notificationresult.hpp"
 #include "icinga/notificationresult-ti.cpp"
-#include "base/scriptglobal.hpp"
 
 using namespace icinga;
 
index 08ba4e2ebc9eedcd9b2eec1c98863fd56ea65069..8b8539139537cc79c8a07e421daf2861b84158fd 100644 (file)
 
 using namespace icinga;
 
-REGISTER_FUNCTION_NONCONST(Internal, PluginNotification, &PluginNotificationTask::ScriptFunc, "notification:user:cr:itype:author:comment:resolvedMacros:useResolvedMacros");
+REGISTER_FUNCTION_NONCONST(Internal, PluginNotification, &PluginNotificationTask::ScriptFunc, "notification:user:cr:nr:itype:author:comment:resolvedMacros:useResolvedMacros");
 
 void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification,
-       const User::Ptr& user, const CheckResult::Ptr& cr, int itype,
-       const String& author, const String& comment, const Dictionary::Ptr& resolvedMacros,
-       bool useResolvedMacros)
+       const User::Ptr& user, const CheckResult::Ptr& cr, const NotificationResult::Ptr& nr,
+       int itype, const String& author, const String& comment,
+       const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros)
 {
        REQUIRE_NOT_NULL(notification);
        REQUIRE_NOT_NULL(user);
@@ -55,16 +55,28 @@ void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification,
 
        PluginUtility::ExecuteCommand(commandObj, checkable, cr, resolvers,
                resolvedMacros, useResolvedMacros, timeout,
-               std::bind(&PluginNotificationTask::ProcessFinishedHandler, checkable, _1, _2));
+               std::bind(&PluginNotificationTask::ProcessFinishedHandler, checkable, notification, nr, _1, _2));
 }
 
-void PluginNotificationTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const Value& commandLine, const ProcessResult& pr)
+void PluginNotificationTask::ProcessFinishedHandler(const Checkable::Ptr& checkable,
+       const Notification::Ptr& notification, const NotificationResult::Ptr& nr, const Value& commandLine, const ProcessResult& pr)
 {
        if (pr.ExitStatus != 0) {
                Process::Arguments parguments = Process::PrepareCommand(commandLine);
                Log(LogWarning, "PluginNotificationTask")
-                       << "Notification command for object '" << checkable->GetName() << "' (PID: " << pr.PID
+                       << "Notification command for checkable '" << checkable->GetName()
+                       << "' and notification '" << notification->GetName() << "' (PID: " << pr.PID
                        << ", arguments: " << Process::PrettyPrintArguments(parguments) << ") terminated with exit code "
                        << pr.ExitStatus << ", output: " << pr.Output;
        }
+
+       String output = pr.Output.Trim();
+
+       nr->SetCommand(commandLine);
+       nr->SetOutput(output);
+       nr->SetExitStatus(pr.ExitStatus);
+       nr->SetExecutionStart(pr.ExecutionStart);
+       nr->SetExecutionEnd(pr.ExecutionEnd);
+
+       notification->ProcessNotificationResult(nr);
 }
index 66d6539245140a34a228e1a3ca60d4fbbb80116f..6a741b73b499d0af2b277ad3b0335e5b54bcfe9a 100644 (file)
@@ -20,14 +20,15 @@ class PluginNotificationTask
 {
 public:
        static void ScriptFunc(const Notification::Ptr& notification,
-               const User::Ptr& user, const CheckResult::Ptr& cr, int itype,
-               const String& author, const String& comment,
+               const User::Ptr& user, const CheckResult::Ptr& cr, const NotificationResult::Ptr& nr,
+               int itype, const String& author, const String& comment,
                const Dictionary::Ptr& resolvedMacros, bool useResolvedMacros);
 
 private:
        PluginNotificationTask();
 
        static void ProcessFinishedHandler(const Checkable::Ptr& checkable,
+               const Notification::Ptr& notification, const NotificationResult::Ptr& nr,
                const Value& commandLine, const ProcessResult& pr);
 };