]> granicus.if.org Git - icinga2/blob - components/notification/notificationcomponent.cpp
compatlog: refactor custom/acknowledgement notifications with author/commenttext
[icinga2] / components / notification / notificationcomponent.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "notification/notificationcomponent.h"
21 #include "icinga/service.h"
22 #include "base/dynamictype.h"
23 #include "base/objectlock.h"
24 #include "base/logger_fwd.h"
25 #include "base/utility.h"
26 #include <boost/smart_ptr/make_shared.hpp>
27 #include <boost/foreach.hpp>
28
29 using namespace icinga;
30
31 REGISTER_TYPE(NotificationComponent);
32
33 NotificationComponent::NotificationComponent(const Dictionary::Ptr& serializedUpdate)
34         : DynamicObject(serializedUpdate)
35 { }
36
37 /**
38  * Starts the component.
39  */
40 void NotificationComponent::Start(void)
41 {
42         m_Endpoint = Endpoint::MakeEndpoint("notification", false);
43         m_Endpoint->RegisterTopicHandler("icinga::SendNotifications",
44             boost::bind(&NotificationComponent::SendNotificationsRequestHandler, this, _2,
45             _3));
46
47         m_NotificationTimer = boost::make_shared<Timer>();
48         m_NotificationTimer->SetInterval(5);
49         m_NotificationTimer->OnTimerExpired.connect(boost::bind(&NotificationComponent::NotificationTimerHandler, this));
50         m_NotificationTimer->Start();
51 }
52
53 /**
54  * Stops the component.
55  */
56 void NotificationComponent::Stop(void)
57 {
58         m_Endpoint->Unregister();
59 }
60
61 /**
62  * Periodically sends notifications.
63  *
64  * @param - Event arguments for the timer.
65  */
66 void NotificationComponent::NotificationTimerHandler(void)
67 {
68         double now = Utility::GetTime();
69
70         BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Notification")) {
71                 Notification::Ptr notification = dynamic_pointer_cast<Notification>(object);
72
73                 if (notification->GetNotificationInterval() <= 0)
74                         continue;
75
76                 if (notification->GetNextNotification() > now)
77                         continue;
78
79                 Service::Ptr service = notification->GetService();
80                 bool reachable = service->IsReachable();
81
82                 {
83                         ObjectLock olock(notification);
84                         notification->SetNextNotification(Utility::GetTime() + notification->GetNotificationInterval());
85                 }
86
87                 bool send_notification;
88
89                 {
90                         ObjectLock olock(service);
91
92                         if (service->GetStateType() == StateTypeSoft)
93                                 continue;
94
95                         if (service->GetState() == StateOK)
96                                 continue;
97
98                         if (!reachable || service->IsInDowntime() || service->IsAcknowledged())
99                                 continue;
100                 }
101
102                 try {
103                         Log(LogInformation, "notification", "Sending reminder notification for service '" + service->GetName() + "'");
104                         notification->BeginExecuteNotification(NotificationProblem, service->GetLastCheckResult(), false);
105                 } catch (const std::exception& ex) {
106                         std::ostringstream msgbuf;
107                         msgbuf << "Exception occured during notification for service '"
108                                << GetName() << "': " << boost::diagnostic_information(ex);
109                         String message = msgbuf.str();
110
111                         Log(LogWarning, "icinga", message);
112                 }
113         }
114 }
115
116 /**
117  * Processes icinga::SendNotifications messages.
118  */
119 void NotificationComponent::SendNotificationsRequestHandler(const Endpoint::Ptr& sender,
120     const RequestMessage& request)
121 {
122         MessagePart params;
123         if (!request.GetParams(&params))
124                 return;
125
126         String svc;
127         if (!params.Get("service", &svc))
128                 return;
129
130         int type;
131         if (!params.Get("type", &type))
132                 return;
133
134         Dictionary::Ptr cr;
135         if (!params.Get("check_result", &cr))
136                 return;
137
138         Service::Ptr service = Service::GetByName(svc);
139
140         if (!service)
141                 return;
142
143         String author;
144         params.Get("author", &author);
145         String text;
146         params.Get("text", &text);
147
148         service->SendNotifications(static_cast<NotificationType>(type), cr, author, text);
149 }