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
This commit is contained in:
Michael Friedrich 2013-06-28 21:31:38 +02:00
parent aa3196407a
commit 3af0559b4a
11 changed files with 307 additions and 0 deletions

View 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());

View 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);

View File

@ -45,6 +45,8 @@ libicinga_la_SOURCES = \
notification.h \
notificationcommand.cpp \
notificationcommand.h \
notificationmessage.cpp \
notificationmessage.h \
notificationrequestmessage.cpp \
notificationrequestmessage.h \
nullchecktask.cpp \

View 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" />

View 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>
@ -120,6 +123,9 @@
<ClInclude Include="notification.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="notificationmessage.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="notificationrequestmessage.h">
<Filter>Headerdateien</Filter>
</ClInclude>

View 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;

View File

@ -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);
}

View File

@ -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 */

View 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;
}

View 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());

View 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);