2013-02-09 18:39:43 +01:00
/******************************************************************************
* Icinga 2 *
2013-09-25 07:43:57 +02:00
* Copyright ( C ) 2012 - 2013 Icinga Development Team ( http : //www.icinga.org/) *
2013-02-09 18:39:43 +01:00
* *
* 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 . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2013-03-16 21:18:53 +01:00
# include "icinga/service.h"
2013-06-13 11:33:00 +02:00
# include "icinga/checkcommand.h"
2013-03-17 20:19:29 +01:00
# include "icinga/icingaapplication.h"
# include "icinga/cib.h"
2013-03-16 21:18:53 +01:00
# include "base/dynamictype.h"
# include "base/objectlock.h"
# include "base/logger_fwd.h"
2013-07-01 17:25:30 +02:00
# include "base/convert.h"
2013-08-20 11:06:04 +02:00
# include "base/utility.h"
2013-11-20 21:55:14 +01:00
# include "base/exception.h"
2013-03-16 21:18:53 +01:00
# include <boost/foreach.hpp>
2013-07-30 22:38:33 +02:00
# include <boost/algorithm/string/replace.hpp>
2013-02-09 18:39:43 +01:00
using namespace icinga ;
2013-11-09 14:22:38 +01:00
boost : : signals2 : : signal < void ( const Service : : Ptr & , const CheckResult : : Ptr & , const String & ) > Service : : OnNewCheckResult ;
boost : : signals2 : : signal < void ( const Service : : Ptr & , const CheckResult : : Ptr & , StateType , const String & ) > Service : : OnStateChange ;
boost : : signals2 : : signal < void ( const Service : : Ptr & , NotificationType , const CheckResult : : Ptr & , const String & , const String & ) > Service : : OnNotificationsRequested ;
2013-08-28 11:12:20 +02:00
boost : : signals2 : : signal < void ( const Service : : Ptr & , double , const String & ) > Service : : OnNextCheckChanged ;
boost : : signals2 : : signal < void ( const Service : : Ptr & , bool , const String & ) > Service : : OnForceNextCheckChanged ;
2013-08-29 13:09:26 +02:00
boost : : signals2 : : signal < void ( const Service : : Ptr & , bool , const String & ) > Service : : OnForceNextNotificationChanged ;
2013-08-28 11:12:20 +02:00
boost : : signals2 : : signal < void ( const Service : : Ptr & , bool , const String & ) > Service : : OnEnableActiveChecksChanged ;
boost : : signals2 : : signal < void ( const Service : : Ptr & , bool , const String & ) > Service : : OnEnablePassiveChecksChanged ;
2013-08-29 13:06:36 +02:00
boost : : signals2 : : signal < void ( const Service : : Ptr & , bool , const String & ) > Service : : OnEnableNotificationsChanged ;
boost : : signals2 : : signal < void ( const Service : : Ptr & , bool , const String & ) > Service : : OnEnableFlappingChanged ;
2013-07-01 14:29:07 +02:00
boost : : signals2 : : signal < void ( const Service : : Ptr & , FlappingState ) > Service : : OnFlappingChanged ;
2013-02-09 18:39:43 +01:00
2013-06-13 11:33:00 +02:00
CheckCommand : : Ptr Service : : GetCheckCommand ( void ) const
2013-02-09 18:39:43 +01:00
{
2013-10-26 09:41:45 +02:00
return CheckCommand : : GetByName ( GetCheckCommandRaw ( ) ) ;
2013-02-09 18:39:43 +01:00
}
2013-03-13 16:04:53 +01:00
TimePeriod : : Ptr Service : : GetCheckPeriod ( void ) const
{
2013-10-26 09:41:45 +02:00
return TimePeriod : : GetByName ( GetCheckPeriodRaw ( ) ) ;
2013-03-13 16:04:53 +01:00
}
2013-02-09 18:39:43 +01:00
double Service : : GetCheckInterval ( void ) const
{
2013-10-26 09:41:45 +02:00
if ( ! GetOverrideCheckInterval ( ) . IsEmpty ( ) )
return GetOverrideCheckInterval ( ) ;
2013-10-16 13:02:21 +02:00
else
2013-10-26 09:41:45 +02:00
return GetCheckIntervalRaw ( ) ;
2013-10-16 13:02:21 +02:00
}
2013-02-09 18:39:43 +01:00
2013-10-16 13:02:21 +02:00
void Service : : SetCheckInterval ( double interval )
{
2013-10-26 09:41:45 +02:00
SetOverrideCheckInterval ( interval ) ;
2013-02-09 18:39:43 +01:00
}
double Service : : GetRetryInterval ( void ) const
{
2013-10-26 09:41:45 +02:00
if ( ! GetOverrideRetryInterval ( ) . IsEmpty ( ) )
return GetOverrideRetryInterval ( ) ;
2013-10-16 13:02:21 +02:00
else
2013-10-26 09:41:45 +02:00
return GetRetryIntervalRaw ( ) ;
2013-10-16 13:02:21 +02:00
}
2013-02-09 18:39:43 +01:00
2013-10-16 13:02:21 +02:00
void Service : : SetRetryInterval ( double interval )
{
2013-10-26 09:41:45 +02:00
SetOverrideRetryInterval ( interval ) ;
2013-02-09 18:39:43 +01:00
}
void Service : : SetSchedulingOffset ( long offset )
{
2013-02-26 10:13:54 +01:00
m_SchedulingOffset = offset ;
2013-02-09 18:39:43 +01:00
}
long Service : : GetSchedulingOffset ( void )
{
2013-02-26 10:13:54 +01:00
return m_SchedulingOffset ;
2013-02-09 18:39:43 +01:00
}
2013-08-28 11:12:20 +02:00
void Service : : SetNextCheck ( double nextCheck , const String & authority )
2013-02-09 18:39:43 +01:00
{
2013-10-26 09:41:45 +02:00
SetNextCheckRaw ( nextCheck ) ;
2013-08-20 11:06:04 +02:00
2013-11-10 16:53:57 +01:00
OnNextCheckChanged ( GetSelf ( ) , nextCheck , authority ) ;
2013-02-09 18:39:43 +01:00
}
double Service : : GetNextCheck ( void )
{
2013-10-26 09:41:45 +02:00
return GetNextCheckRaw ( ) ;
2013-02-09 18:39:43 +01:00
}
void Service : : UpdateNextCheck ( void )
{
2013-03-02 09:07:47 +01:00
ObjectLock olock ( this ) ;
2013-02-09 18:39:43 +01:00
double interval ;
2013-11-15 12:50:23 +01:00
if ( GetStateType ( ) = = StateTypeSoft & & GetLastCheckResult ( ) ! = NULL )
2013-02-09 18:39:43 +01:00
interval = GetRetryInterval ( ) ;
else
interval = GetCheckInterval ( ) ;
double now = Utility : : GetTime ( ) ;
double adj = 0 ;
if ( interval > 1 )
2013-03-20 15:25:53 +01:00
adj = fmod ( now * 100 + GetSchedulingOffset ( ) , interval * 100 ) / 100.0 ;
2013-02-09 18:39:43 +01:00
SetNextCheck ( now - adj + interval ) ;
}
2013-07-05 09:35:49 +02:00
bool Service : : HasBeenChecked ( void ) const
{
2013-11-01 00:13:30 +01:00
return GetLastCheckResult ( ) ! = NULL ;
2013-07-05 09:35:49 +02:00
}
double Service : : GetLastCheck ( void ) const
{
2013-11-09 14:22:38 +01:00
CheckResult : : Ptr cr = GetLastCheckResult ( ) ;
2013-07-05 09:35:49 +02:00
double schedule_end = - 1 ;
2013-10-26 09:41:45 +02:00
if ( cr )
2013-11-09 14:22:38 +01:00
schedule_end = cr - > GetScheduleEnd ( ) ;
2013-07-05 09:35:49 +02:00
return schedule_end ;
}
2013-02-09 18:39:43 +01:00
bool Service : : GetEnableActiveChecks ( void ) const
{
2013-10-26 09:41:45 +02:00
if ( ! GetOverrideEnableActiveChecks ( ) . IsEmpty ( ) )
return GetOverrideEnableActiveChecks ( ) ;
2013-10-16 11:46:54 +02:00
else
2013-10-26 09:41:45 +02:00
return GetEnableActiveChecksRaw ( ) ;
2013-02-09 18:39:43 +01:00
}
2013-08-28 11:12:20 +02:00
void Service : : SetEnableActiveChecks ( bool enabled , const String & authority )
2013-02-09 18:39:43 +01:00
{
2013-10-26 09:41:45 +02:00
SetOverrideEnableActiveChecks ( enabled ) ;
2013-08-28 11:12:20 +02:00
2013-11-10 16:53:57 +01:00
OnEnableActiveChecksChanged ( GetSelf ( ) , enabled , authority ) ;
2013-02-09 18:39:43 +01:00
}
bool Service : : GetEnablePassiveChecks ( void ) const
{
2013-10-26 09:41:45 +02:00
if ( ! GetOverrideEnablePassiveChecks ( ) . IsEmpty ( ) )
return GetOverrideEnablePassiveChecks ( ) ;
2013-10-16 11:46:54 +02:00
else
2013-10-26 09:41:45 +02:00
return GetEnablePassiveChecksRaw ( ) ;
2013-02-09 18:39:43 +01:00
}
2013-08-28 11:12:20 +02:00
void Service : : SetEnablePassiveChecks ( bool enabled , const String & authority )
2013-02-09 18:39:43 +01:00
{
2013-10-26 09:41:45 +02:00
SetOverrideEnablePassiveChecks ( enabled ) ;
2013-08-28 11:12:20 +02:00
2013-11-10 16:53:57 +01:00
OnEnablePassiveChecksChanged ( GetSelf ( ) , enabled , authority ) ;
2013-02-09 18:39:43 +01:00
}
bool Service : : GetForceNextCheck ( void ) const
{
2013-10-26 09:41:45 +02:00
return GetForceNextCheckRaw ( ) ;
2013-02-09 18:39:43 +01:00
}
2013-08-28 11:12:20 +02:00
void Service : : SetForceNextCheck ( bool forced , const String & authority )
2013-02-09 18:39:43 +01:00
{
2013-10-26 09:41:45 +02:00
SetForceNextCheckRaw ( forced ) ;
2013-08-28 11:12:20 +02:00
2013-11-10 16:53:57 +01:00
OnForceNextCheckChanged ( GetSelf ( ) , forced , authority ) ;
2013-02-09 18:39:43 +01:00
}
2013-11-09 14:22:38 +01:00
void Service : : ProcessCheckResult ( const CheckResult : : Ptr & cr , const String & authority )
2013-02-09 18:39:43 +01:00
{
2013-03-19 16:20:13 +01:00
double now = Utility : : GetTime ( ) ;
2013-11-09 14:22:38 +01:00
if ( cr - > GetScheduleStart ( ) = = 0 )
cr - > SetScheduleStart ( now ) ;
2013-03-19 16:20:13 +01:00
2013-11-09 14:22:38 +01:00
if ( cr - > GetScheduleEnd ( ) = = 0 )
cr - > SetScheduleEnd ( now ) ;
2013-03-19 16:20:13 +01:00
2013-11-09 14:22:38 +01:00
if ( cr - > GetExecutionStart ( ) = = 0 )
cr - > SetExecutionStart ( now ) ;
2013-03-19 16:20:13 +01:00
2013-11-09 14:22:38 +01:00
if ( cr - > GetExecutionEnd ( ) = = 0 )
cr - > SetExecutionEnd ( now ) ;
2013-03-19 16:20:13 +01:00
2013-11-09 14:22:38 +01:00
String check_source = cr - > GetCheckSource ( ) ;
2013-10-17 12:08:08 +02:00
if ( check_source . IsEmpty ( ) )
2013-11-09 14:22:38 +01:00
cr - > SetCheckSource ( authority ) ;
2013-09-27 07:34:08 +02:00
2013-03-06 11:03:50 +01:00
bool reachable = IsReachable ( ) ;
2013-03-19 13:04:30 +01:00
Host : : Ptr host = GetHost ( ) ;
bool host_reachable = true ;
if ( host )
host_reachable = host - > IsReachable ( ) ;
2013-03-07 16:00:10 +01:00
ASSERT ( ! OwnsLock ( ) ) ;
2013-03-02 09:07:47 +01:00
ObjectLock olock ( this ) ;
2013-11-09 14:22:38 +01:00
CheckResult : : Ptr old_cr = GetLastCheckResult ( ) ;
2013-02-09 18:39:43 +01:00
ServiceState old_state = GetState ( ) ;
2013-03-07 12:04:20 +01:00
StateType old_stateType = GetStateType ( ) ;
2013-10-26 09:41:45 +02:00
long old_attempt = GetCheckAttempt ( ) ;
2013-02-24 01:10:34 +01:00
bool recovery ;
2013-02-09 18:39:43 +01:00
2013-11-09 14:22:38 +01:00
if ( old_cr & & cr - > GetExecutionStart ( ) < old_cr - > GetExecutionStart ( ) )
2013-09-12 17:39:29 +02:00
return ;
2013-03-25 18:36:15 +01:00
/* The ExecuteCheck function already sets the old state, but we need to do it again
2013-03-08 14:43:48 +01:00
* in case this was a passive check result . */
2013-03-07 12:04:20 +01:00
SetLastState ( old_state ) ;
SetLastStateType ( old_stateType ) ;
2013-03-19 13:04:30 +01:00
SetLastReachable ( reachable ) ;
2013-03-07 12:04:20 +01:00
2013-03-19 13:04:30 +01:00
long attempt ;
2013-02-09 18:39:43 +01:00
2013-11-09 14:22:38 +01:00
if ( cr - > GetState ( ) = = StateOK ) {
2013-02-27 12:44:51 +01:00
if ( old_state = = StateOK & & old_stateType = = StateTypeSoft )
2013-03-20 15:25:53 +01:00
SetStateType ( StateTypeHard ) ; // SOFT OK -> HARD OK
2013-02-09 18:39:43 +01:00
attempt = 1 ;
2013-02-24 01:10:34 +01:00
recovery = true ;
2013-07-18 17:04:09 +02:00
ResetNotificationNumbers ( ) ;
2013-07-18 18:16:39 +02:00
SetLastStateOK ( Utility : : GetTime ( ) ) ;
2013-02-09 18:39:43 +01:00
} else {
2013-03-19 13:04:30 +01:00
if ( old_attempt > = GetMaxCheckAttempts ( ) ) {
2013-02-09 18:39:43 +01:00
SetStateType ( StateTypeHard ) ;
attempt = 1 ;
} else if ( GetStateType ( ) = = StateTypeSoft | | GetState ( ) = = StateOK ) {
SetStateType ( StateTypeSoft ) ;
2013-03-19 13:04:30 +01:00
attempt = old_attempt + 1 ;
} else {
attempt = old_attempt ;
2013-02-09 18:39:43 +01:00
}
2013-02-24 01:10:34 +01:00
recovery = false ;
2013-07-18 18:16:39 +02:00
2013-11-09 14:22:38 +01:00
switch ( cr - > GetState ( ) ) {
case StateWarning :
SetLastStateWarning ( Utility : : GetTime ( ) ) ;
break ;
case StateCritical :
SetLastStateCritical ( Utility : : GetTime ( ) ) ;
break ;
case StateUnknown :
SetLastStateUnknown ( Utility : : GetTime ( ) ) ;
break ;
}
2013-02-09 18:39:43 +01:00
}
2013-07-18 18:28:23 +02:00
if ( ! reachable )
SetLastStateUnreachable ( Utility : : GetTime ( ) ) ;
2013-10-26 09:41:45 +02:00
SetCheckAttempt ( attempt ) ;
2013-02-09 18:39:43 +01:00
2013-11-09 14:22:38 +01:00
SetState ( cr - > GetState ( ) ) ;
2013-02-09 18:39:43 +01:00
2013-06-13 11:33:00 +02:00
bool call_eventhandler = false ;
2013-06-21 10:20:29 +02:00
bool stateChange = ( old_state ! = GetState ( ) ) ;
if ( stateChange ) {
2013-02-09 18:39:43 +01:00
SetLastStateChange ( now ) ;
/* remove acknowledgements */
if ( GetAcknowledgement ( ) = = AcknowledgementNormal | |
( GetAcknowledgement ( ) = = AcknowledgementSticky & & GetStateType ( ) = = StateTypeHard & & GetState ( ) = = StateOK ) ) {
2013-08-29 13:48:18 +02:00
ClearAcknowledgement ( ) ;
2013-02-09 18:39:43 +01:00
}
/* reschedule service dependencies */
2013-03-02 09:07:47 +01:00
BOOST_FOREACH ( const Service : : Ptr & parent , GetParentServices ( ) ) {
2013-03-04 15:52:42 +01:00
ObjectLock olock ( parent ) ;
2013-02-09 18:39:43 +01:00
parent - > SetNextCheck ( Utility : : GetTime ( ) ) ;
}
/* reschedule host dependencies */
2013-03-02 09:07:47 +01:00
BOOST_FOREACH ( const Host : : Ptr & parent , GetParentHosts ( ) ) {
2013-09-25 09:12:15 +02:00
Service : : Ptr service = parent - > GetCheckService ( ) ;
2013-02-09 18:39:43 +01:00
2013-03-04 15:52:42 +01:00
if ( service & & service - > GetName ( ) ! = GetName ( ) ) {
2013-02-27 12:44:51 +01:00
ObjectLock olock ( service ) ;
2013-02-09 18:39:43 +01:00
service - > SetNextCheck ( Utility : : GetTime ( ) ) ;
2013-02-27 12:44:51 +01:00
}
2013-02-09 18:39:43 +01:00
}
2013-06-13 11:33:00 +02:00
call_eventhandler = true ;
2013-02-09 18:39:43 +01:00
}
2013-06-19 10:57:07 +02:00
bool remove_acknowledgement_comments = false ;
if ( GetAcknowledgement ( ) = = AcknowledgementNone )
remove_acknowledgement_comments = true ;
2013-03-20 15:25:53 +01:00
bool hardChange = ( GetStateType ( ) = = StateTypeHard & & old_stateType = = StateTypeSoft ) ;
2013-03-21 11:37:34 +01:00
if ( old_state ! = GetState ( ) & & old_stateType = = StateTypeHard & & GetStateType ( ) = = StateTypeHard )
hardChange = true ;
2013-10-26 09:41:45 +02:00
if ( GetVolatile ( ) )
2013-06-13 12:24:20 +02:00
hardChange = true ;
2013-07-05 09:35:49 +02:00
if ( hardChange ) {
SetLastHardState ( GetState ( ) ) ;
2013-03-02 09:07:47 +01:00
SetLastHardStateChange ( now ) ;
2013-07-05 09:35:49 +02:00
}
2013-03-02 09:07:47 +01:00
2013-02-09 18:39:43 +01:00
if ( GetState ( ) ! = StateOK )
TriggerDowntimes ( ) ;
2013-03-02 09:07:47 +01:00
Service : : UpdateStatistics ( cr ) ;
2013-02-09 18:39:43 +01:00
2013-03-18 12:55:41 +01:00
bool in_downtime = IsInDowntime ( ) ;
bool send_notification = hardChange & & reachable & & ! in_downtime & & ! IsAcknowledged ( ) ;
2013-03-20 15:25:53 +01:00
if ( old_state = = StateOK & & old_stateType = = StateTypeSoft )
send_notification = false ; /* Don't send notifications for SOFT-OK -> HARD-OK. */
2013-10-26 09:41:45 +02:00
bool send_downtime_notification = ( GetLastInDowntime ( ) ! = in_downtime ) ;
SetLastInDowntime ( in_downtime ) ;
2013-03-06 11:03:50 +01:00
2013-03-02 09:07:47 +01:00
olock . Unlock ( ) ;
2013-02-09 18:39:43 +01:00
2013-06-19 10:57:07 +02:00
if ( remove_acknowledgement_comments )
RemoveCommentsByType ( CommentAcknowledgement ) ;
2013-11-06 08:51:56 +01:00
Dictionary : : Ptr vars_after = make_shared < Dictionary > ( ) ;
2013-03-19 13:04:30 +01:00
vars_after - > Set ( " state " , GetState ( ) ) ;
vars_after - > Set ( " state_type " , GetStateType ( ) ) ;
2013-10-26 09:41:45 +02:00
vars_after - > Set ( " attempt " , GetCheckAttempt ( ) ) ;
2013-03-19 13:04:30 +01:00
vars_after - > Set ( " reachable " , reachable ) ;
vars_after - > Set ( " host_reachable " , host_reachable ) ;
if ( old_cr )
2013-11-09 14:22:38 +01:00
cr - > SetVarsBefore ( old_cr - > GetVarsAfter ( ) ) ;
2013-03-19 13:04:30 +01:00
2013-11-09 14:22:38 +01:00
cr - > SetVarsAfter ( vars_after ) ;
2013-03-19 13:04:30 +01:00
2013-03-07 15:00:26 +01:00
olock . Lock ( ) ;
SetLastCheckResult ( cr ) ;
2013-06-21 10:20:29 +02:00
bool was_flapping , is_flapping ;
was_flapping = IsFlapping ( ) ;
2013-09-06 15:29:00 +02:00
if ( GetStateType ( ) = = StateTypeHard )
UpdateFlappingStatus ( stateChange ) ;
2013-06-21 10:20:29 +02:00
is_flapping = IsFlapping ( ) ;
2013-03-07 15:00:26 +01:00
olock . Unlock ( ) ;
2013-09-21 09:00:40 +02:00
// Log(LogDebug, "icinga", "Flapping: Service " + GetName() +
// " was: " + Convert::ToString(was_flapping) +
// " is: " + Convert::ToString(is_flapping) +
// " threshold: " + Convert::ToString(GetFlappingThreshold()) +
// "% current: " + Convert::ToString(GetFlappingCurrent()) + "%.");
2013-07-01 17:25:30 +02:00
2013-11-10 16:53:57 +01:00
OnNewCheckResult ( GetSelf ( ) , cr , authority ) ;
2013-08-20 11:06:04 +02:00
OnStateChanged ( GetSelf ( ) ) ;
2013-03-02 09:07:47 +01:00
2013-11-10 16:53:57 +01:00
if ( hardChange )
OnStateChange ( GetSelf ( ) , cr , StateTypeHard , authority ) ;
else if ( stateChange )
OnStateChange ( GetSelf ( ) , cr , StateTypeSoft , authority ) ;
2013-09-25 18:01:08 +02:00
2013-06-13 11:33:00 +02:00
if ( call_eventhandler )
ExecuteEventHandler ( ) ;
2013-03-18 12:55:41 +01:00
if ( send_downtime_notification )
2013-08-20 11:06:04 +02:00
OnNotificationsRequested ( GetSelf ( ) , in_downtime ? NotificationDowntimeStart : NotificationDowntimeEnd , cr , " " , " " ) ;
2013-03-18 12:55:41 +01:00
2013-07-01 14:29:07 +02:00
if ( ! was_flapping & & is_flapping ) {
2013-08-20 11:06:04 +02:00
OnNotificationsRequested ( GetSelf ( ) , NotificationFlappingStart , cr , " " , " " ) ;
2013-07-01 17:25:30 +02:00
Log ( LogDebug , " icinga " , " Flapping: Service " + GetName ( ) + " started flapping ( " + Convert : : ToString ( GetFlappingThreshold ( ) ) + " % < " + Convert : : ToString ( GetFlappingCurrent ( ) ) + " %). " ) ;
2013-08-20 11:06:04 +02:00
OnFlappingChanged ( GetSelf ( ) , FlappingStarted ) ;
} else if ( was_flapping & & ! is_flapping ) {
OnNotificationsRequested ( GetSelf ( ) , NotificationFlappingEnd , cr , " " , " " ) ;
2013-07-01 17:25:30 +02:00
Log ( LogDebug , " icinga " , " Flapping: Service " + GetName ( ) + " stopped flapping ( " + Convert : : ToString ( GetFlappingThreshold ( ) ) + " % >= " + Convert : : ToString ( GetFlappingCurrent ( ) ) + " %). " ) ;
2013-08-20 11:06:04 +02:00
OnFlappingChanged ( GetSelf ( ) , FlappingStopped ) ;
} else if ( send_notification )
OnNotificationsRequested ( GetSelf ( ) , recovery ? NotificationRecovery : NotificationProblem , cr , " " , " " ) ;
2013-02-09 18:39:43 +01:00
}
ServiceState Service : : StateFromString ( const String & state )
{
2013-02-24 01:10:34 +01:00
if ( state = = " OK " )
2013-02-09 18:39:43 +01:00
return StateOK ;
2013-02-24 01:10:34 +01:00
else if ( state = = " WARNING " )
2013-02-09 18:39:43 +01:00
return StateWarning ;
2013-02-24 01:10:34 +01:00
else if ( state = = " CRITICAL " )
2013-02-09 18:39:43 +01:00
return StateCritical ;
else
return StateUnknown ;
}
String Service : : StateToString ( ServiceState state )
{
switch ( state ) {
case StateOK :
2013-02-24 01:10:34 +01:00
return " OK " ;
2013-02-09 18:39:43 +01:00
case StateWarning :
2013-02-24 01:10:34 +01:00
return " WARNING " ;
2013-02-09 18:39:43 +01:00
case StateCritical :
2013-02-24 01:10:34 +01:00
return " CRITICAL " ;
2013-02-09 18:39:43 +01:00
case StateUnknown :
default :
2013-02-24 01:10:34 +01:00
return " UNKNOWN " ;
2013-02-09 18:39:43 +01:00
}
}
2013-03-07 12:04:20 +01:00
StateType Service : : StateTypeFromString ( const String & type )
2013-02-09 18:39:43 +01:00
{
2013-02-24 01:10:34 +01:00
if ( type = = " SOFT " )
2013-02-09 18:39:43 +01:00
return StateTypeSoft ;
else
return StateTypeHard ;
}
2013-03-07 12:04:20 +01:00
String Service : : StateTypeToString ( StateType type )
2013-02-09 18:39:43 +01:00
{
if ( type = = StateTypeSoft )
2013-02-24 01:10:34 +01:00
return " SOFT " ;
2013-02-09 18:39:43 +01:00
else
2013-02-24 01:10:34 +01:00
return " HARD " ;
2013-02-09 18:39:43 +01:00
}
2013-03-25 18:36:15 +01:00
void Service : : ExecuteCheck ( void )
2013-02-09 18:39:43 +01:00
{
2013-03-07 16:00:10 +01:00
ASSERT ( ! OwnsLock ( ) ) ;
2013-02-24 01:10:34 +01:00
2013-03-19 14:13:58 +01:00
bool reachable = IsReachable ( ) ;
2013-03-06 11:03:50 +01:00
{
ObjectLock olock ( this ) ;
/* don't run another check if there is one pending */
2013-03-25 18:36:15 +01:00
if ( m_CheckRunning )
2013-03-06 11:03:50 +01:00
return ;
m_CheckRunning = true ;
2013-03-08 14:43:48 +01:00
SetLastState ( GetState ( ) ) ;
SetLastStateType ( GetLastStateType ( ) ) ;
2013-03-19 14:13:58 +01:00
SetLastReachable ( reachable ) ;
2013-02-09 18:39:43 +01:00
}
/* keep track of scheduling info in case the check type doesn't provide its own information */
2013-11-15 14:26:38 +01:00
double scheduled_start = GetNextCheck ( ) ;
2013-11-09 14:22:38 +01:00
double before_check = Utility : : GetTime ( ) ;
2013-02-24 01:10:34 +01:00
2013-03-04 15:52:42 +01:00
Service : : Ptr self = GetSelf ( ) ;
2013-11-09 14:22:38 +01:00
CheckResult : : Ptr result ;
2013-02-09 18:39:43 +01:00
try {
2013-06-24 09:30:49 +02:00
CheckCommand : : Ptr command = GetCheckCommand ( ) ;
2013-07-06 20:46:09 +02:00
if ( ! command ) {
Log ( LogDebug , " icinga " , " No check_command found for service ' " + GetName ( ) + " '. Skipping execution. " ) ;
2013-06-24 09:30:49 +02:00
return ;
2013-07-06 20:46:09 +02:00
}
2013-06-24 09:30:49 +02:00
result = command - > Execute ( GetSelf ( ) ) ;
2013-03-16 21:18:53 +01:00
} catch ( const std : : exception & ex ) {
std : : ostringstream msgbuf ;
2013-02-09 18:39:43 +01:00
msgbuf < < " Exception occured during check for service ' "
2013-11-20 21:55:14 +01:00
< < GetName ( ) < < " ': " < < DiagnosticInformation ( ex ) ;
2013-02-09 18:39:43 +01:00
String message = msgbuf . str ( ) ;
2013-03-16 21:18:53 +01:00
Log ( LogWarning , " icinga " , message ) ;
2013-02-09 18:39:43 +01:00
2013-11-09 14:22:38 +01:00
result = make_shared < CheckResult > ( ) ;
result - > SetState ( StateUnknown ) ;
result - > SetOutput ( message ) ;
2013-02-09 18:39:43 +01:00
}
2013-11-09 14:22:38 +01:00
double after_check = Utility : : GetTime ( ) ;
2013-03-25 18:36:15 +01:00
2013-02-09 18:39:43 +01:00
if ( result ) {
2013-11-15 14:26:38 +01:00
if ( result - > GetScheduleStart ( ) = = 0 )
result - > SetScheduleStart ( scheduled_start ) ;
2013-02-09 18:39:43 +01:00
2013-11-15 14:26:38 +01:00
if ( result - > GetScheduleEnd ( ) = = 0 )
2013-11-09 14:22:38 +01:00
result - > SetScheduleEnd ( after_check ) ;
2013-02-24 01:10:34 +01:00
2013-11-15 14:26:38 +01:00
if ( result - > GetExecutionStart ( ) = = 0 )
2013-11-09 14:22:38 +01:00
result - > SetExecutionStart ( before_check ) ;
2013-02-09 18:39:43 +01:00
2013-11-15 14:26:38 +01:00
if ( result - > GetExecutionEnd ( ) = = 0 )
2013-11-09 14:22:38 +01:00
result - > SetExecutionEnd ( after_check ) ;
2013-02-09 18:39:43 +01:00
}
2013-03-02 09:07:47 +01:00
if ( result )
ProcessCheckResult ( result ) ;
2013-03-07 12:04:20 +01:00
/* figure out when the next check is for this service; the call to
* ProcessCheckResult ( ) should ' ve already done this but lets do it again
* just in case there was no check result . */
UpdateNextCheck ( ) ;
2013-02-24 01:10:34 +01:00
{
ObjectLock olock ( this ) ;
2013-03-06 11:03:50 +01:00
m_CheckRunning = false ;
2013-02-24 01:10:34 +01:00
}
2013-02-09 18:39:43 +01:00
}
2013-02-11 23:37:39 +01:00
2013-11-09 14:22:38 +01:00
void Service : : UpdateStatistics ( const CheckResult : : Ptr & cr )
2013-02-11 23:37:39 +01:00
{
2013-11-09 14:22:38 +01:00
time_t ts = cr - > GetScheduleEnd ( ) ;
if ( ts = = 0 )
2013-02-11 23:37:39 +01:00
ts = static_cast < time_t > ( Utility : : GetTime ( ) ) ;
2013-11-09 14:22:38 +01:00
if ( cr - > GetActive ( ) )
2013-02-11 23:37:39 +01:00
CIB : : UpdateActiveChecksStatistics ( ts , 1 ) ;
else
CIB : : UpdatePassiveChecksStatistics ( ts , 1 ) ;
}
2013-02-24 01:10:34 +01:00
2013-11-09 14:22:38 +01:00
double Service : : CalculateExecutionTime ( const CheckResult : : Ptr & cr )
2013-02-24 01:10:34 +01:00
{
2013-11-09 14:22:38 +01:00
if ( ! cr )
return 0 ;
2013-02-24 01:10:34 +01:00
2013-11-09 14:22:38 +01:00
return cr - > GetExecutionEnd ( ) - cr - > GetExecutionStart ( ) ;
2013-02-24 01:10:34 +01:00
}
2013-11-09 14:22:38 +01:00
double Service : : CalculateLatency ( const CheckResult : : Ptr & cr )
2013-02-24 01:10:34 +01:00
{
2013-11-09 14:22:38 +01:00
if ( ! cr )
return 0 ;
2013-02-24 01:10:34 +01:00
2013-11-09 14:22:38 +01:00
double latency = ( cr - > GetScheduleEnd ( ) - cr - > GetScheduleStart ( ) ) - CalculateExecutionTime ( cr ) ;
2013-09-12 11:36:31 +02:00
if ( latency < 0 )
latency = 0 ;
return latency ;
2013-02-24 01:10:34 +01:00
}