1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ 2 3 #ifndef CHECKABLE_H 4 #define CHECKABLE_H 5 6 #include "base/atomic.hpp" 7 #include "base/timer.hpp" 8 #include "base/process.hpp" 9 #include "icinga/i2-icinga.hpp" 10 #include "icinga/checkable-ti.hpp" 11 #include "icinga/timeperiod.hpp" 12 #include "icinga/notification.hpp" 13 #include "icinga/comment.hpp" 14 #include "icinga/downtime.hpp" 15 #include "remote/endpoint.hpp" 16 #include "remote/messageorigin.hpp" 17 #include <condition_variable> 18 #include <cstdint> 19 #include <functional> 20 21 namespace icinga 22 { 23 24 /** 25 * @ingroup icinga 26 */ 27 enum DependencyType 28 { 29 DependencyState, 30 DependencyCheckExecution, 31 DependencyNotification 32 }; 33 34 /** 35 * Checkable Types 36 * 37 * @ingroup icinga 38 */ 39 enum CheckableType 40 { 41 CheckableHost, 42 CheckableService 43 }; 44 45 /** 46 * @ingroup icinga 47 */ 48 enum FlappingStateFilter 49 { 50 FlappingStateFilterOk = 1, 51 FlappingStateFilterWarning = 2, 52 FlappingStateFilterCritical = 4, 53 FlappingStateFilterUnknown = 8, 54 }; 55 56 class CheckCommand; 57 class EventCommand; 58 class Dependency; 59 60 /** 61 * An Icinga service. 62 * 63 * @ingroup icinga 64 */ 65 class Checkable : public ObjectImpl<Checkable> 66 { 67 public: 68 DECLARE_OBJECT(Checkable); 69 DECLARE_OBJECTNAME(Checkable); 70 71 static void StaticInitialize(); 72 static thread_local std::function<void(const Value& commandLine, const ProcessResult&)> ExecuteCommandProcessFinishedHandler; 73 74 Checkable(); 75 76 std::set<Checkable::Ptr> GetParents() const; 77 std::set<Checkable::Ptr> GetChildren() const; 78 std::set<Checkable::Ptr> GetAllChildren() const; 79 80 void AddGroup(const String& name); 81 82 bool IsReachable(DependencyType dt = DependencyState, intrusive_ptr<Dependency> *failedDependency = nullptr, int rstack = 0) const; 83 84 AcknowledgementType GetAcknowledgement(); 85 86 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); 87 void ClearAcknowledgement(const String& removedBy, double changeTime = Utility::GetTime(), const MessageOrigin::Ptr& origin = nullptr); 88 89 int GetSeverity() const override; 90 bool GetProblem() const override; 91 bool GetHandled() const override; 92 Timestamp GetNextUpdate() const override; 93 94 /* Checks */ 95 intrusive_ptr<CheckCommand> GetCheckCommand() const; 96 TimePeriod::Ptr GetCheckPeriod() const; 97 98 long GetSchedulingOffset(); 99 void SetSchedulingOffset(long offset); 100 101 void UpdateNextCheck(const MessageOrigin::Ptr& origin = nullptr); 102 103 bool HasBeenChecked() const; 104 virtual bool IsStateOK(ServiceState state) const = 0; 105 106 double GetLastCheck() const final; 107 108 virtual void SaveLastState(ServiceState state, double timestamp) = 0; 109 110 static void UpdateStatistics(const CheckResult::Ptr& cr, CheckableType type); 111 112 void ExecuteRemoteCheck(const Dictionary::Ptr& resolvedMacros = nullptr); 113 void ExecuteCheck(); 114 void ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin = nullptr); 115 116 Endpoint::Ptr GetCommandEndpoint() const; 117 118 static boost::signals2::signal<void (const Checkable::Ptr&, const CheckResult::Ptr&, const MessageOrigin::Ptr&)> OnNewCheckResult; 119 static boost::signals2::signal<void (const Checkable::Ptr&, const CheckResult::Ptr&, StateType, const MessageOrigin::Ptr&)> OnStateChange; 120 static boost::signals2::signal<void (const Checkable::Ptr&, const CheckResult::Ptr&, std::set<Checkable::Ptr>, const MessageOrigin::Ptr&)> OnReachabilityChanged; 121 static boost::signals2::signal<void (const Checkable::Ptr&, NotificationType, const CheckResult::Ptr&, 122 const String&, const String&, const MessageOrigin::Ptr&)> OnNotificationsRequested; 123 static boost::signals2::signal<void (const Notification::Ptr&, const Checkable::Ptr&, const User::Ptr&, 124 const NotificationType&, const CheckResult::Ptr&, const String&, const String&, const String&, 125 const MessageOrigin::Ptr&)> OnNotificationSentToUser; 126 static boost::signals2::signal<void (const Notification::Ptr&, const Checkable::Ptr&, const std::set<User::Ptr>&, 127 const NotificationType&, const CheckResult::Ptr&, const String&, 128 const String&, const MessageOrigin::Ptr&)> OnNotificationSentToAllUsers; 129 static boost::signals2::signal<void (const Checkable::Ptr&, const String&, const String&, AcknowledgementType, 130 bool, bool, double, double, const MessageOrigin::Ptr&)> OnAcknowledgementSet; 131 static boost::signals2::signal<void (const Checkable::Ptr&, const String&, double, const MessageOrigin::Ptr&)> OnAcknowledgementCleared; 132 static boost::signals2::signal<void (const Checkable::Ptr&, double)> OnFlappingChange; 133 static boost::signals2::signal<void (const Checkable::Ptr&)> OnNextCheckUpdated; 134 static boost::signals2::signal<void (const Checkable::Ptr&)> OnEventCommandExecuted; 135 136 static Atomic<uint_fast64_t> CurrentConcurrentChecks; 137 138 /* Downtimes */ 139 int GetDowntimeDepth() const final; 140 141 void RemoveAllDowntimes(); 142 void TriggerDowntimes(); 143 bool IsInDowntime() const; 144 bool IsAcknowledged() const; 145 146 std::set<Downtime::Ptr> GetDowntimes() const; 147 void RegisterDowntime(const Downtime::Ptr& downtime); 148 void UnregisterDowntime(const Downtime::Ptr& downtime); 149 150 /* Comments */ 151 void RemoveAllComments(); 152 void RemoveCommentsByType(int type, const String& removedBy = String()); 153 154 std::set<Comment::Ptr> GetComments() const; 155 Comment::Ptr GetLastComment() const; 156 void RegisterComment(const Comment::Ptr& comment); 157 void UnregisterComment(const Comment::Ptr& comment); 158 159 /* Notifications */ 160 void SendNotifications(NotificationType type, const CheckResult::Ptr& cr, const String& author = "", const String& text = ""); 161 162 std::set<Notification::Ptr> GetNotifications() const; 163 void RegisterNotification(const Notification::Ptr& notification); 164 void UnregisterNotification(const Notification::Ptr& notification); 165 166 void ResetNotificationNumbers(); 167 168 /* Event Handler */ 169 void ExecuteEventHandler(const Dictionary::Ptr& resolvedMacros = nullptr, 170 bool useResolvedMacros = false); 171 172 intrusive_ptr<EventCommand> GetEventCommand() const; 173 174 /* Flapping Detection */ 175 bool IsFlapping() const; 176 177 /* Dependencies */ 178 void AddDependency(const intrusive_ptr<Dependency>& dep); 179 void RemoveDependency(const intrusive_ptr<Dependency>& dep); 180 std::vector<intrusive_ptr<Dependency> > GetDependencies() const; 181 182 void AddReverseDependency(const intrusive_ptr<Dependency>& dep); 183 void RemoveReverseDependency(const intrusive_ptr<Dependency>& dep); 184 std::vector<intrusive_ptr<Dependency> > GetReverseDependencies() const; 185 186 void ValidateCheckInterval(const Lazy<double>& lvalue, const ValidationUtils& value) final; 187 void ValidateRetryInterval(const Lazy<double>& lvalue, const ValidationUtils& value) final; 188 void ValidateMaxCheckAttempts(const Lazy<int>& lvalue, const ValidationUtils& value) final; 189 190 bool NotificationReasonApplies(NotificationType type); 191 bool NotificationReasonSuppressed(NotificationType type); 192 bool IsLikelyToBeCheckedSoon(); 193 194 static void IncreasePendingChecks(); 195 static void DecreasePendingChecks(); 196 static int GetPendingChecks(); 197 static void AquirePendingCheckSlot(int maxPendingChecks); 198 199 static Object::Ptr GetPrototype(); 200 201 protected: 202 void Start(bool runtimeCreated) override; 203 void OnConfigLoaded() override; 204 void OnAllConfigLoaded() override; 205 206 private: 207 mutable std::mutex m_CheckableMutex; 208 bool m_CheckRunning{false}; 209 long m_SchedulingOffset; 210 211 static std::mutex m_StatsMutex; 212 static int m_PendingChecks; 213 static std::condition_variable m_PendingChecksCV; 214 215 /* Downtimes */ 216 std::set<Downtime::Ptr> m_Downtimes; 217 mutable std::mutex m_DowntimeMutex; 218 219 static void NotifyFixedDowntimeStart(const Downtime::Ptr& downtime); 220 static void NotifyFlexibleDowntimeStart(const Downtime::Ptr& downtime); 221 static void NotifyDowntimeInternal(const Downtime::Ptr& downtime); 222 223 static void NotifyDowntimeEnd(const Downtime::Ptr& downtime); 224 225 static void FireSuppressedNotifications(const Timer * const&); 226 static void CleanDeadlinedExecutions(const Timer * const&); 227 228 /* Comments */ 229 std::set<Comment::Ptr> m_Comments; 230 mutable std::mutex m_CommentMutex; 231 232 /* Notifications */ 233 std::set<Notification::Ptr> m_Notifications; 234 mutable std::mutex m_NotificationMutex; 235 236 /* Dependencies */ 237 mutable std::mutex m_DependencyMutex; 238 std::set<intrusive_ptr<Dependency> > m_Dependencies; 239 std::set<intrusive_ptr<Dependency> > m_ReverseDependencies; 240 241 void GetAllChildrenInternal(std::set<Checkable::Ptr>& children, int level = 0) const; 242 243 /* Flapping */ 244 static const std::map<String, int> m_FlappingStateFilterMap; 245 246 void UpdateFlappingStatus(ServiceState newState); 247 static int ServiceStateToFlappingFilter(ServiceState state); 248 }; 249 250 } 251 252 #endif /* CHECKABLE_H */ 253 254 #include "icinga/dependency.hpp" 255