Ejemplo n.º 1
0
void StatusDataWriter::DumpCheckableStatusAttrs(std::ostream& fp, const Checkable::Ptr& checkable)
{
	CheckResult::Ptr cr = checkable->GetLastCheckResult();

	EventCommand::Ptr eventcommand = checkable->GetEventCommand();
	CheckCommand::Ptr checkcommand = checkable->GetCheckCommand();

	fp << "\t" << "check_command=" << CompatUtility::GetCommandName(checkcommand) << "!" << CompatUtility::GetCheckableCommandArgs(checkable) << "\n"
		"\t" "event_handler=" << CompatUtility::GetCommandName(eventcommand) << "\n"
		"\t" "check_interval=" << (checkable->GetCheckInterval() / 60.0) << "\n"
		"\t" "retry_interval=" << (checkable->GetRetryInterval() / 60.0) << "\n"
		"\t" "has_been_checked=" << Convert::ToLong(checkable->HasBeenChecked()) << "\n"
		"\t" "should_be_scheduled=" << checkable->GetEnableActiveChecks() << "\n"
		"\t" "event_handler_enabled=" << Convert::ToLong(checkable->GetEnableEventHandler()) << "\n";

	TimePeriod::Ptr checkPeriod = checkable->GetCheckPeriod();
	if (checkPeriod)
		fp << "\t" "check_period" "\t" << checkPeriod->GetName() << "\n";

	if (cr) {
		fp << "\t" << "check_execution_time=" << Convert::ToString(cr->CalculateExecutionTime()) << "\n"
			"\t" "check_latency=" << Convert::ToString(cr->CalculateLatency()) << "\n";
	}

	Host::Ptr host;
	Service::Ptr service;
	tie(host, service) = GetHostService(checkable);

	if (service) {
		fp << "\t" "current_state=" << service->GetState() << "\n"
			"\t" "last_hard_state=" << service->GetLastHardState() << "\n"
			"\t" "last_time_ok=" << static_cast<int>(service->GetLastStateOK()) << "\n"
			"\t" "last_time_warn=" << static_cast<int>(service->GetLastStateWarning()) << "\n"
			"\t" "last_time_critical=" << static_cast<int>(service->GetLastStateCritical()) << "\n"
			"\t" "last_time_unknown=" << static_cast<int>(service->GetLastStateUnknown()) << "\n";
	} else {
		int currentState = host->GetState();

		if (currentState != HostUp && !host->IsReachable())
			currentState = 2; /* hardcoded compat state */

		fp << "\t" "current_state=" << currentState << "\n"
			"\t" "last_hard_state=" << host->GetLastHardState() << "\n"
			"\t" "last_time_up=" << static_cast<int>(host->GetLastStateUp()) << "\n"
			"\t" "last_time_down=" << static_cast<int>(host->GetLastStateDown()) << "\n";
	}

	fp << "\t" "state_type=" << checkable->GetStateType() << "\n"
		"\t" "last_check=" << static_cast<long>(host->GetLastCheck()) << "\n";

	if (cr) {
		fp << "\t" "plugin_output=" << CompatUtility::GetCheckResultOutput(cr) << "\n"
			"\t" "long_plugin_output=" << CompatUtility::GetCheckResultLongOutput(cr) << "\n"
			"\t" "performance_data=" << PluginUtility::FormatPerfdata(cr->GetPerformanceData()) << "\n";
	}

	fp << "\t" << "next_check=" << static_cast<long>(checkable->GetNextCheck()) << "\n"
		"\t" "current_attempt=" << checkable->GetCheckAttempt() << "\n"
		"\t" "max_attempts=" << checkable->GetMaxCheckAttempts() << "\n"
		"\t" "last_state_change=" << static_cast<long>(checkable->GetLastStateChange()) << "\n"
		"\t" "last_hard_state_change=" << static_cast<long>(checkable->GetLastHardStateChange()) << "\n"
		"\t" "last_update=" << static_cast<long>(Utility::GetTime()) << "\n"
		"\t" "notifications_enabled=" << Convert::ToLong(checkable->GetEnableNotifications()) << "\n"
		"\t" "active_checks_enabled=" << Convert::ToLong(checkable->GetEnableActiveChecks()) << "\n"
		"\t" "passive_checks_enabled=" << Convert::ToLong(checkable->GetEnablePassiveChecks()) << "\n"
		"\t" "flap_detection_enabled=" << Convert::ToLong(checkable->GetEnableFlapping()) << "\n"
		"\t" "is_flapping=" << Convert::ToLong(checkable->IsFlapping()) << "\n"
		"\t" "percent_state_change=" << checkable->GetFlappingCurrent() << "\n"
		"\t" "problem_has_been_acknowledged=" << (checkable->GetAcknowledgement() != AcknowledgementNone ? 1 : 0) << "\n"
		"\t" "acknowledgement_type=" << checkable->GetAcknowledgement() << "\n"
		"\t" "acknowledgement_end_time=" << checkable->GetAcknowledgementExpiry() << "\n"
		"\t" "scheduled_downtime_depth=" << checkable->GetDowntimeDepth() << "\n"
		"\t" "last_notification=" << CompatUtility::GetCheckableNotificationLastNotification(checkable) << "\n"
		"\t" "next_notification=" << CompatUtility::GetCheckableNotificationNextNotification(checkable) << "\n"
		"\t" "current_notification_number=" << CompatUtility::GetCheckableNotificationNotificationNumber(checkable) << "\n"
		"\t" "is_reachable=" << Convert::ToLong(checkable->IsReachable()) << "\n";
}
Ejemplo n.º 2
0
void Notification::BeginExecuteNotification(NotificationType type, const CheckResult::Ptr& cr, bool force, bool reminder, const String& author, const String& text)
{
	Log(LogNotice, "Notification")
	    << "Attempting to send " << (reminder ? "reminder " : " ") << "notifications for notification object '" << GetName() << "'.";

	Checkable::Ptr checkable = GetCheckable();

	if (!force) {
		TimePeriod::Ptr tp = GetPeriod();

		if (tp && !tp->IsInside(Utility::GetTime())) {
			Log(LogNotice, "Notification")
			    << "Not sending " << (reminder ? "reminder " : " ") << "notifications for notification object '" << GetName()
			    << "': not in timeperiod '" << tp->GetName() << "'";
			return;
		}

		double now = Utility::GetTime();
		Dictionary::Ptr times = GetTimes();

		if (times && type == NotificationProblem) {
			Value timesBegin = times->Get("begin");
			Value timesEnd = times->Get("end");

			if (timesBegin != Empty && timesBegin >= 0 && now < checkable->GetLastHardStateChange() + timesBegin) {
				Log(LogNotice, "Notification")
				    << "Not sending " << (reminder ? "reminder " : " ") << "notifications for notification object '" << GetName()
				    << "': before specified begin time (" << Utility::FormatDuration(timesBegin) << ")";

				/* we need to adjust the next notification time
				 * to now + begin delaying the first notification
				 */
				double nextProposedNotification = now + timesBegin + 1.0;
				if (GetNextNotification() > nextProposedNotification)
					SetNextNotification(nextProposedNotification);

				return;
			}

			if (timesEnd != Empty && timesEnd >= 0 && now > checkable->GetLastHardStateChange() + timesEnd) {
				Log(LogNotice, "Notification")
				    << "Not sending " << (reminder ? "reminder " : " ") << "notifications for notification object '" << GetName()
				    << "': after specified end time (" << Utility::FormatDuration(timesEnd) << ")";
				return;
			}
		}

		unsigned long ftype = type;

		Log(LogDebug, "Notification")
		    << "Type '" << NotificationTypeToStringInternal(type)
		    << "', TypeFilter: " << NotificationFilterToString(GetTypeFilter(), GetTypeFilterMap())
		    << " (FType=" << ftype << ", TypeFilter=" << GetTypeFilter() << ")";

		if (!(ftype & GetTypeFilter())) {
			Log(LogNotice, "Notification")
			    << "Not sending " << (reminder ? "reminder " : " ") << "notifications for notification object '" << GetName() << "': type '"
			    << NotificationTypeToStringInternal(type) << "' does not match type filter: "
			    << NotificationFilterToString(GetTypeFilter(), GetTypeFilterMap()) << ".";
			return;
		}

		/* ensure that recovery notifications are always sent, no state filter checks necessary */
		if (type != NotificationRecovery) {
			Host::Ptr host;
			Service::Ptr service;
			tie(host, service) = GetHostService(checkable);

			unsigned long fstate;
			String stateStr;

			if (service) {
				fstate = ServiceStateToFilter(service->GetState());
				stateStr = NotificationServiceStateToString(service->GetState());
			} else {
				fstate = HostStateToFilter(host->GetState());
				stateStr = NotificationHostStateToString(host->GetState());
			}

			Log(LogDebug, "Notification")
			    << "State '" << stateStr << "', StateFilter: " << NotificationFilterToString(GetStateFilter(), GetStateFilterMap())
			    << " (FState=" << fstate << ", StateFilter=" << GetStateFilter() << ")";

			if (!(fstate & GetStateFilter())) {
				Log(LogNotice, "Notification")
				    << "Not sending " << (reminder ? "reminder " : " ") << "notifications for notification object '" << GetName() << "': state '" << stateStr
				    << "' does not match state filter: " << NotificationFilterToString(GetStateFilter(), GetStateFilterMap()) << ".";
				return;
			}
		}
	} else {
		Log(LogNotice, "Notification")
		    << "Not checking " << (reminder ? "reminder " : " ") << "notification filters for notification object '" << GetName() << "': Notification was forced.";
	}

	{
		ObjectLock olock(this);

		UpdateNotificationNumber();
		double now = Utility::GetTime();
		SetLastNotification(now);

		if (type == NotificationProblem && GetInterval() <= 0)
			SetNoMoreNotifications(true);
		else
			SetNoMoreNotifications(false);

		if (type == NotificationProblem && GetInterval() > 0)
			SetNextNotification(now + GetInterval());

		if (type == NotificationProblem)
			SetLastProblemNotification(now);
	}

	std::set<User::Ptr> allUsers;

	std::set<User::Ptr> users = GetUsers();
	std::copy(users.begin(), users.end(), std::inserter(allUsers, allUsers.begin()));

	for (const UserGroup::Ptr& ug : GetUserGroups()) {
		std::set<User::Ptr> members = ug->GetMembers();
		std::copy(members.begin(), members.end(), std::inserter(allUsers, allUsers.begin()));
	}

	std::set<User::Ptr> allNotifiedUsers;
	Array::Ptr notifiedProblemUsers = GetNotifiedProblemUsers();

	for (const User::Ptr& user : allUsers) {
		String userName = user->GetName();

		if (!user->GetEnableNotifications()) {
			Log(LogNotice, "Notification")
			    << "Disabled notifications for user '" << userName << "'. Not sending notification.";
			continue;
		}

		if (!CheckNotificationUserFilters(type, user, force, reminder)) {
			Log(LogNotice, "Notification")
			    << "Notification filters for user '" << userName << "' not matched. Not sending notification.";
			continue;
		}

		/* on recovery, check if user was notified before */
		if (type == NotificationRecovery) {
			if (!notifiedProblemUsers->Contains(userName)) {
				Log(LogNotice, "Notification")
				    << "We did not notify user '" << userName << "' for a problem before. Not sending recovery notification.";
				continue;
			}
		}

		Log(LogInformation, "Notification")
		    << "Sending " << (reminder ? "reminder " : "") << "'" << NotificationTypeToStringInternal(type) << "' notification '"
		    << GetName() << " for user '" << userName << "'";

		Utility::QueueAsyncCallback(boost::bind(&Notification::ExecuteNotificationHelper, this, type, user, cr, force, author, text));

		/* collect all notified users */
		allNotifiedUsers.insert(user);

		/* store all notified users for later recovery checks */
		if (type == NotificationProblem && !notifiedProblemUsers->Contains(userName))
			notifiedProblemUsers->Add(userName);
	}

	/* if this was a recovery notification, reset all notified users */
	if (type == NotificationRecovery)
		notifiedProblemUsers->Clear();

	/* used in db_ido for notification history */
	Service::OnNotificationSentToAllUsers(this, checkable, allNotifiedUsers, type, cr, author, text, MessageOrigin::Ptr());
}