/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ #ifndef CHECKABLE_H #define CHECKABLE_H #include "base/atomic.hpp" #include "base/timer.hpp" #include "base/process.hpp" #include "icinga/i2-icinga.hpp" #include "icinga/checkable-ti.hpp" #include "icinga/timeperiod.hpp" #include "icinga/notification.hpp" #include "icinga/comment.hpp" #include "icinga/downtime.hpp" #include "remote/endpoint.hpp" #include "remote/messageorigin.hpp" #include #include #include #include namespace icinga { /** * @ingroup icinga */ enum DependencyType { DependencyState, DependencyCheckExecution, DependencyNotification }; /** * Checkable Types * * @ingroup icinga */ enum CheckableType { CheckableHost, CheckableService }; /** * @ingroup icinga */ enum FlappingStateFilter { FlappingStateFilterOk = 1, FlappingStateFilterWarning = 2, FlappingStateFilterCritical = 4, FlappingStateFilterUnknown = 8, }; class CheckCommand; class EventCommand; class Dependency; /** * An Icinga service. * * @ingroup icinga */ class Checkable : public ObjectImpl { public: DECLARE_OBJECT(Checkable); DECLARE_OBJECTNAME(Checkable); static void StaticInitialize(); static thread_local std::function ExecuteCommandProcessFinishedHandler; Checkable(); std::set GetParents() const; std::set GetChildren() const; std::set GetAllChildren() const; void AddGroup(const String& name); bool IsReachable(DependencyType dt = DependencyState, intrusive_ptr *failedDependency = nullptr, int rstack = 0) const; AcknowledgementType GetAcknowledgement(); void AcknowledgeProblem(const String& author, const String& comment, AcknowledgementType type, bool notify = true, bool persistent = false, double changeTime = Utility::GetTime(), double expiry = 0, const MessageOrigin::Ptr& origin = nullptr); void ClearAcknowledgement(const String& removedBy, double changeTime = Utility::GetTime(), const MessageOrigin::Ptr& origin = nullptr); int GetSeverity() const override; bool GetProblem() const override; bool GetHandled() const override; Timestamp GetNextUpdate() const override; /* Checks */ intrusive_ptr GetCheckCommand() const; TimePeriod::Ptr GetCheckPeriod() const; long GetSchedulingOffset(); void SetSchedulingOffset(long offset); void UpdateNextCheck(const MessageOrigin::Ptr& origin = nullptr); bool HasBeenChecked() const; virtual bool IsStateOK(ServiceState state) const = 0; double GetLastCheck() const final; virtual void SaveLastState(ServiceState state, double timestamp) = 0; static void UpdateStatistics(const CheckResult::Ptr& cr, CheckableType type); void ExecuteRemoteCheck(const Dictionary::Ptr& resolvedMacros = nullptr); void ExecuteCheck(); enum class ProcessingResult { Ok, NoCheckResult, CheckableInactive, NewerCheckResultPresent, }; ProcessingResult ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin = nullptr); Endpoint::Ptr GetCommandEndpoint() const; static boost::signals2::signal OnNewCheckResult; static boost::signals2::signal OnStateChange; static boost::signals2::signal, const MessageOrigin::Ptr&)> OnReachabilityChanged; static boost::signals2::signal OnNotificationsRequested; static boost::signals2::signal OnNotificationSentToUser; static boost::signals2::signal&, const NotificationType&, const CheckResult::Ptr&, const String&, const String&, const MessageOrigin::Ptr&)> OnNotificationSentToAllUsers; static boost::signals2::signal OnAcknowledgementSet; static boost::signals2::signal OnAcknowledgementCleared; static boost::signals2::signal OnFlappingChange; static boost::signals2::signal OnNextCheckUpdated; static boost::signals2::signal OnEventCommandExecuted; static Atomic CurrentConcurrentChecks; /* Downtimes */ int GetDowntimeDepth() const final; void RemoveAllDowntimes(); void TriggerDowntimes(double triggerTime); bool IsInDowntime() const; bool IsAcknowledged() const; std::set GetDowntimes() const; void RegisterDowntime(const Downtime::Ptr& downtime); void UnregisterDowntime(const Downtime::Ptr& downtime); /* Comments */ void RemoveAllComments(); void RemoveAckComments(const String& removedBy = String(), double createdBefore = std::numeric_limits::max()); std::set GetComments() const; Comment::Ptr GetLastComment() const; void RegisterComment(const Comment::Ptr& comment); void UnregisterComment(const Comment::Ptr& comment); /* Notifications */ void SendNotifications(NotificationType type, const CheckResult::Ptr& cr, const String& author = "", const String& text = ""); std::set GetNotifications() const; void RegisterNotification(const Notification::Ptr& notification); void UnregisterNotification(const Notification::Ptr& notification); void ResetNotificationNumbers(); /* Event Handler */ void ExecuteEventHandler(const Dictionary::Ptr& resolvedMacros = nullptr, bool useResolvedMacros = false); intrusive_ptr GetEventCommand() const; /* Flapping Detection */ bool IsFlapping() const; /* Dependencies */ void AddDependency(const intrusive_ptr& dep); void RemoveDependency(const intrusive_ptr& dep); std::vector > GetDependencies() const; void AddReverseDependency(const intrusive_ptr& dep); void RemoveReverseDependency(const intrusive_ptr& dep); std::vector > GetReverseDependencies() const; void ValidateCheckInterval(const Lazy& lvalue, const ValidationUtils& value) final; void ValidateRetryInterval(const Lazy& lvalue, const ValidationUtils& value) final; void ValidateMaxCheckAttempts(const Lazy& lvalue, const ValidationUtils& value) final; bool NotificationReasonApplies(NotificationType type); bool NotificationReasonSuppressed(NotificationType type); bool IsLikelyToBeCheckedSoon(); void FireSuppressedNotifications(); static void IncreasePendingChecks(); static void DecreasePendingChecks(); static int GetPendingChecks(); static void AquirePendingCheckSlot(int maxPendingChecks); static Object::Ptr GetPrototype(); protected: void Start(bool runtimeCreated) override; void OnConfigLoaded() override; void OnAllConfigLoaded() override; private: mutable std::mutex m_CheckableMutex; bool m_CheckRunning{false}; long m_SchedulingOffset; static std::mutex m_StatsMutex; static int m_PendingChecks; static std::condition_variable m_PendingChecksCV; /* Downtimes */ std::set m_Downtimes; mutable std::mutex m_DowntimeMutex; static void NotifyFixedDowntimeStart(const Downtime::Ptr& downtime); static void NotifyFlexibleDowntimeStart(const Downtime::Ptr& downtime); static void NotifyDowntimeInternal(const Downtime::Ptr& downtime); static void NotifyDowntimeEnd(const Downtime::Ptr& downtime); static void FireSuppressedNotificationsTimer(const Timer * const&); static void CleanDeadlinedExecutions(const Timer * const&); /* Comments */ std::set m_Comments; mutable std::mutex m_CommentMutex; /* Notifications */ std::set m_Notifications; mutable std::mutex m_NotificationMutex; /* Dependencies */ mutable std::mutex m_DependencyMutex; std::set > m_Dependencies; std::set > m_ReverseDependencies; void GetAllChildrenInternal(std::set& children, int level = 0) const; /* Flapping */ static const std::map m_FlappingStateFilterMap; void UpdateFlappingStatus(ServiceState newState); static int ServiceStateToFlappingFilter(ServiceState state); }; } #endif /* CHECKABLE_H */ #include "icinga/dependency.hpp"