From 4de7908b94b043745d624fadbb33490be2989fa3 Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Mon, 1 Jul 2013 14:29:07 +0200 Subject: [PATCH] compatlog: add flapping messages refs #4360 --- components/compat/compatlog.cpp | 65 +++++++++++++++++++++++++ components/compat/compatlog.h | 1 + lib/icinga/Makefile.am | 2 + lib/icinga/externalcommandprocessor.cpp | 13 +++++ lib/icinga/flappingmessage.cpp | 46 +++++++++++++++++ lib/icinga/flappingmessage.h | 50 +++++++++++++++++++ lib/icinga/icinga.vcxproj | 2 + lib/icinga/icinga.vcxproj.filters | 6 +++ lib/icinga/service-check.cpp | 30 +++++++++++- lib/icinga/service-flapping.cpp | 13 +++++ lib/icinga/service.cpp | 2 + lib/icinga/service.h | 15 ++++++ 12 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 lib/icinga/flappingmessage.cpp create mode 100644 lib/icinga/flappingmessage.h diff --git a/components/compat/compatlog.cpp b/components/compat/compatlog.cpp index 52fcfa06a..d251975ad 100644 --- a/components/compat/compatlog.cpp +++ b/components/compat/compatlog.cpp @@ -72,6 +72,7 @@ void CompatLog::Start(void) boost::bind(&CompatLog::NotificationSentRequestHandler, this, _3)); Service::OnDowntimeChanged.connect(bind(&CompatLog::DowntimeHandler, this, _1, _2)); + Service::OnFlappingChanged.connect(bind(&CompatLog::FlappingHandler, this, _1, _2)); m_RotationTimer = boost::make_shared(); m_RotationTimer->OnTimerExpired.connect(boost::bind(&CompatLog::RotationTimerHandler, this)); @@ -357,6 +358,70 @@ void CompatLog::NotificationSentRequestHandler(const RequestMessage& request) } } +/** + * @threadsafety Always. + */ +void CompatLog::FlappingHandler(const Service::Ptr& service, FlappingState flapping_state) +{ + Host::Ptr host = service->GetHost(); + + if (!host) + return; + + String flapping_state_str; + String flapping_output; + + switch (flapping_state) { + case FlappingStarted: + flapping_output = "Service appears to have started flapping (00.0% change >= 00.0% threshold)"; + flapping_state_str = "STARTED"; + break; + case FlappingStopped: + flapping_output = "Service appears to have stopped flapping (00.0% change < 00.1% threshold)"; + flapping_state_str = "STOPPED"; + break; + case FlappingDisabled: + flapping_output = "Flap detection has been disabled"; + flapping_state_str = "DISABLED"; + break; + default: + Log(LogCritical, "compat", "Unknown flapping state: " + Convert::ToString(flapping_state)); + return; + } + + std::ostringstream msgbuf; + msgbuf << "SERVICE FLAPPING ALERT: " + << host->GetName() << ";" + << service->GetShortName() << ";" + << flapping_state_str << "; " + << flapping_output + << ""; + + { + ObjectLock oLock(this); + WriteLine(msgbuf.str()); + } + + if (service == host->GetHostCheckService()) { + std::ostringstream msgbuf; + msgbuf << "HOST FLAPPING ALERT: " + << host->GetName() << ";" + << flapping_state_str << "; " + << flapping_output + << ""; + + { + ObjectLock oLock(this); + WriteLine(msgbuf.str()); + } + } + + { + ObjectLock oLock(this); + Flush(); + } + +} void CompatLog::WriteLine(const String& line) { diff --git a/components/compat/compatlog.h b/components/compat/compatlog.h index 259842230..cef9a2037 100644 --- a/components/compat/compatlog.h +++ b/components/compat/compatlog.h @@ -66,6 +66,7 @@ private: void CheckResultRequestHandler(const RequestMessage& request); void NotificationSentRequestHandler(const RequestMessage& request); void DowntimeHandler(const Service::Ptr& service, DowntimeState downtime_state); + void FlappingHandler(const Service::Ptr& service, FlappingState flapping_state); Timer::Ptr m_RotationTimer; void RotationTimerHandler(void); diff --git a/lib/icinga/Makefile.am b/lib/icinga/Makefile.am index 43a526a83..9e2eeeb78 100644 --- a/lib/icinga/Makefile.am +++ b/lib/icinga/Makefile.am @@ -27,6 +27,8 @@ libicinga_la_SOURCES = \ eventcommand.h \ externalcommandprocessor.cpp \ externalcommandprocessor.h \ + flappingmessage.cpp \ + flappingmessage.h \ host.cpp \ hostgroup.cpp \ hostgroup.h \ diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index ccc83279a..aba9168c2 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -24,11 +24,13 @@ #include "icinga/hostgroup.h" #include "icinga/servicegroup.h" #include "icinga/pluginchecktask.h" +#include "icinga/flappingmessage.h" #include "base/convert.h" #include "base/logger_fwd.h" #include "base/objectlock.h" #include "base/application.h" #include "base/utility.h" +#include "remoting/endpointmanager.h" #include #include #include @@ -1499,5 +1501,16 @@ void ExternalCommandProcessor::DisableSvcFlapping(double, const std::vectorSetEnableFlapping(false); + + RequestMessage rm; + rm.SetMethod("icinga::Flapping"); + + FlappingMessage params; + params.SetService(service->GetName()); + params.SetState(FlappingDisabled); + + rm.SetParams(params); + + EndpointManager::GetInstance()->SendMulticastMessage(rm); } } diff --git a/lib/icinga/flappingmessage.cpp b/lib/icinga/flappingmessage.cpp new file mode 100644 index 000000000..2b4bc4372 --- /dev/null +++ b/lib/icinga/flappingmessage.cpp @@ -0,0 +1,46 @@ +/****************************************************************************** + * 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/flappingmessage.h" + +using namespace icinga; + +String FlappingMessage::GetService(void) const +{ + String service; + Get("service", &service); + return service; +} + +void FlappingMessage::SetService(const String& service) +{ + Set("service", service); +} + +FlappingState FlappingMessage::GetState(void) const +{ + long state; + Get("state", &state); + return static_cast(state); +} + +void FlappingMessage::SetState(FlappingState state) +{ + Set("state", state); +} diff --git a/lib/icinga/flappingmessage.h b/lib/icinga/flappingmessage.h new file mode 100644 index 000000000..59a586b42 --- /dev/null +++ b/lib/icinga/flappingmessage.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * 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 FLAPPINGMESSAGE_H +#define FLAPPINGMESSAGE_H + +#include "icinga/i2-icinga.h" +#include "icinga/service.h" +#include "remoting/messagepart.h" + +namespace icinga +{ + +/** + * A downtime message for a service. + * + * @ingroup icinga + */ +class I2_ICINGA_API FlappingMessage : public MessagePart +{ +public: + FlappingMessage(void) : MessagePart() { } + explicit FlappingMessage(const MessagePart& message) : MessagePart(message) { } + + String GetService(void) const; + void SetService(const String& service); + + FlappingState GetState(void) const; + void SetState(FlappingState state); +}; + +} + +#endif /* FLAPPINGMESSAGE_H */ diff --git a/lib/icinga/icinga.vcxproj b/lib/icinga/icinga.vcxproj index bf5e5404d..7e078b8d0 100644 --- a/lib/icinga/icinga.vcxproj +++ b/lib/icinga/icinga.vcxproj @@ -24,6 +24,7 @@ + @@ -58,6 +59,7 @@ + diff --git a/lib/icinga/icinga.vcxproj.filters b/lib/icinga/icinga.vcxproj.filters index 01db5aacc..f3bd9db10 100644 --- a/lib/icinga/icinga.vcxproj.filters +++ b/lib/icinga/icinga.vcxproj.filters @@ -37,6 +37,9 @@ Quelldateien + + Quelldateien + Quelldateien @@ -117,6 +120,9 @@ Headerdateien + + Headerdateien + Headerdateien diff --git a/lib/icinga/service-check.cpp b/lib/icinga/service-check.cpp index ff787b827..961c21d91 100644 --- a/lib/icinga/service-check.cpp +++ b/lib/icinga/service-check.cpp @@ -21,6 +21,7 @@ #include "icinga/checkcommand.h" #include "icinga/icingaapplication.h" #include "icinga/checkresultmessage.h" +#include "icinga/flappingmessage.h" #include "icinga/cib.h" #include "remoting/endpointmanager.h" #include "base/dynamictype.h" @@ -38,6 +39,7 @@ const double Service::CheckIntervalDivisor = 5.0; boost::signals2::signal Service::OnCheckerChanged; boost::signals2::signal Service::OnNextCheckChanged; +boost::signals2::signal Service::OnFlappingChanged; CheckCommand::Ptr Service::GetCheckCommand(void) const { @@ -480,10 +482,34 @@ void Service::ProcessCheckResult(const Dictionary::Ptr& cr) if (send_downtime_notification) RequestNotifications(in_downtime ? NotificationDowntimeStart : NotificationDowntimeEnd, cr); - if (!was_flapping && is_flapping) + if (!was_flapping && is_flapping) { RequestNotifications(NotificationFlappingStart, cr); - else if (was_flapping && !is_flapping) + + RequestMessage rm; + rm.SetMethod("icinga::Flapping"); + + FlappingMessage params; + params.SetService(GetName()); + params.SetState(FlappingStarted); + + rm.SetParams(params); + + EndpointManager::GetInstance()->SendMulticastMessage(rm); + } + else if (was_flapping && !is_flapping) { RequestNotifications(NotificationFlappingEnd, cr); + + RequestMessage rm; + rm.SetMethod("icinga::Flapping"); + + FlappingMessage params; + params.SetService(GetName()); + params.SetState(FlappingStopped); + + rm.SetParams(params); + + EndpointManager::GetInstance()->SendMulticastMessage(rm); + } else if (send_notification) RequestNotifications(recovery ? NotificationRecovery : NotificationProblem, cr); } diff --git a/lib/icinga/service-flapping.cpp b/lib/icinga/service-flapping.cpp index 1c353d97f..cdac8a310 100644 --- a/lib/icinga/service-flapping.cpp +++ b/lib/icinga/service-flapping.cpp @@ -18,6 +18,7 @@ ******************************************************************************/ #include "icinga/service.h" +#include "icinga/flappingmessage.h" #include "base/dynamictype.h" #include "base/objectlock.h" #include "base/logger_fwd.h" @@ -48,6 +49,18 @@ double Service::GetFlappingThreshold(void) const return m_FlappingThreshold; } +void Service::FlappingRequestHandler(const RequestMessage& request) +{ + FlappingMessage params; + if (!request.GetParams(¶ms)) + return; + + String svcname = params.GetService(); + Service::Ptr service = Service::GetByName(svcname); + + OnFlappingChanged(service, params.GetState()); +} + bool Service::GetEnableFlapping(void) const { if (m_EnableFlapping.IsEmpty()) diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index 2b8c9a38e..5f04c44ef 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -111,6 +111,8 @@ void Service::Initialize(void) m_Endpoint = Endpoint::MakeEndpoint("service", false); m_Endpoint->RegisterTopicHandler("icinga::Downtime", boost::bind(&Service::DowntimeRequestHandler, _3)); + m_Endpoint->RegisterTopicHandler("icinga::Flapping", + boost::bind(&Service::FlappingRequestHandler, _3)); } void Service::OnRegistrationCompleted(void) diff --git a/lib/icinga/service.h b/lib/icinga/service.h index 824036f6b..8a4381186 100644 --- a/lib/icinga/service.h +++ b/lib/icinga/service.h @@ -73,6 +73,18 @@ enum DowntimeState DowntimeStopped = 2 }; +/** + * The sate of service flapping. + * + * @ingroup icinga + */ +enum FlappingState +{ + FlappingStarted = 0, + FlappingDisabled = 1, + FlappingStopped = 2 +}; + class CheckCommand; class EventCommand; @@ -196,6 +208,7 @@ public: static boost::signals2::signal OnCheckerChanged; static boost::signals2::signal OnNextCheckChanged; static boost::signals2::signal OnDowntimeChanged; + static boost::signals2::signal OnFlappingChanged; virtual bool ResolveMacro(const String& macro, const Dictionary::Ptr& cr, String *result) const; @@ -359,6 +372,8 @@ private: Attribute m_FlappingNegative; Attribute m_FlappingLastChange; Attribute m_FlappingThreshold; + + static void FlappingRequestHandler(const RequestMessage& request); }; }