Skip to content

Commit

Permalink
Implement last_notification_result handling for Notification objects
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Friedrich committed Mar 28, 2019
1 parent ac483f2 commit 1706b29
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 18 deletions.
29 changes: 27 additions & 2 deletions lib/icinga/notification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/icinga/notification.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class Notification final : public ObjectImpl<Notification>

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);
Expand Down
4 changes: 4 additions & 0 deletions lib/icinga/notification.ti
Original file line number Diff line number Diff line change
@@ -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"

Expand All @@ -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
Expand Down Expand Up @@ -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 {{{
Expand Down
7 changes: 4 additions & 3 deletions lib/icinga/notificationcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions lib/icinga/notificationcommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ class NotificationCommand final : public ObjectImpl<NotificationCommand>
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);
};
Expand Down
1 change: 0 additions & 1 deletion lib/icinga/notificationresult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

#include "icinga/notificationresult.hpp"
#include "icinga/notificationresult-ti.cpp"
#include "base/scriptglobal.hpp"

using namespace icinga;

Expand Down
26 changes: 19 additions & 7 deletions lib/methods/pluginnotificationtask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@

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);
Expand Down Expand Up @@ -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);
}
5 changes: 3 additions & 2 deletions lib/methods/pluginnotificationtask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};

Expand Down

0 comments on commit 1706b29

Please sign in to comment.