4 * State calculator for a single object - thus more of a state.. keeper?
6 class SingleStateCalculator
extends StateCalculator
8 protected $st_last_dt_init = 1; /**< set to FALSE on nagios restart, and a timestamp on first DT start after restart, so we can exclude duplicate downtime_start */
9 protected $st_real_state = false; /**< The real state of the object */
10 public $st_log = false; /**< The log array, only used for treds, should use summary reports for this */
12 public function initialize($initial_state, $initial_depth, $is_running)
14 parent
::initialize($initial_state, $initial_depth, $is_running);
16 # if user asked for it, we preserve the log
18 if ($this->options
['include_trends']) {
19 $this->st_log
= array();
22 $this->st_real_state
= $initial_state;
24 # In this particular instance, everything array-related breaks if the
25 # array is stored in an array object. Hence, recover and then call current()
26 if ($this->st_is_service
) {
27 $arr = $this->options
['service_description'];
28 $this->st_source
= current($arr);
29 $srv = explode(';', $this->st_source
);
30 $this->host_name
= $srv[0];
31 $this->service_description
= $srv[1];
33 $arr = $this->options
['host_name'];
34 $this->host_name
= $this->st_source
= current($arr);
36 $this->calculate_object_state();
37 $this->prev_row
['state'] = $this->st_obj_state
;
41 * Take a database row object, and parse it
42 * @param $row Database row
44 public function add_event($row = false)
46 $obj_name = $obj_type = false;
47 if (!empty($row['service_description'])) {
48 $obj_name = $row['host_name'] . ";" . $row['service_description'];
49 $obj_type = 'Service';
51 elseif (!empty($row['host_name'])) {
52 $obj_name = $row['host_name'];
56 if ($obj_name !== $this->st_source
&& ($obj_name !== $this->host_name ||
$row['event_type'] < Reports_Model
::DOWNTIME_START
) && $row['event_type'] > Reports_Model
::PROCESS_SHUTDOWN
)
59 $this->st_update($row['the_time']);
61 switch($row['event_type']) {
62 case Reports_Model
::PROCESS_START
:
63 case Reports_Model
::PROCESS_SHUTDOWN
:
64 if ($row['event_type'] == Reports_Model
::PROCESS_START
) {
65 $row['output'] = 'Monitor started';
68 $row['output'] = 'Monitor shut down';
70 $this->st_last_dt_init
= false;
71 if ($row['event_type'] == Reports_Model
::PROCESS_START
) {
72 $row['state'] = $this->st_real_state
;
73 $this->st_running
= 1;
74 } else if ($this->options
['assumestatesduringnotrunning']) {
75 $row['state'] = $this->st_real_state
;
78 $this->st_running
= 0;
81 case Reports_Model
::DOWNTIME_START
:
82 if(!isset($row['output']) ||
!$row['output']) {
83 $row['output'] = $obj_type . ' has entered a period of scheduled downtime';
86 # we are always spammed with downtime events after restart, so
87 # don't increase the downtime depth if we're already in downtime
88 if (!$this->st_last_dt_init ||
$this->st_last_dt_init
=== $row['the_time']) {
89 $this->st_last_dt_init
= $row['the_time'];
90 if (!$this->st_dt_depth
) {
98 $this->st_dt_depth+
=1;
101 case Reports_Model
::DOWNTIME_STOP
:
102 if(!isset($row['output']) ||
!$row['output']) {
103 $row['output'] = $obj_type . ' has exited a period of scheduled downtime';
105 # old merlin versions created more end events than start events, so
106 # never decrement if we're already at 0.
107 if ($this->st_dt_depth
) {
108 $this->st_dt_depth
-=1;
111 case Reports_Model
::SERVICECHECK
:
112 case Reports_Model
::HOSTCHECK
:
113 $state = $row['state'];
115 # update the real state of the object
116 if ($this->st_source
=== $obj_name) {
117 $this->st_real_state
= $row['state'];
124 $this->calculate_object_state();
126 $this->st_update_log($row);
130 * Manually excluded states are excluded here.
135 protected function filter_excluded_state($state) {
136 if ($this->st_is_service
&& isset($this->options
['service_filter_status'][$state]))
137 return $this->options
['service_filter_status'][$state];
138 else if (isset($this->options
['host_filter_status'][$state]))
139 return $this->options
['host_filter_status'][$state];
144 * Calculate the object state, based on the chosen state calculator.
146 * If there is sub reports, the argument will be ignored. Otherwise, use
147 * either the argument or the object's real state, according to magical
148 * properties inherent in the numbers themselves.
150 public function calculate_object_state()
152 $this->st_obj_state
= $this->filter_excluded_state($this->st_real_state
);
155 public function get_data()
157 $converted_state = $this->convert_state_table($this->st_raw
, $this->st_text
);
159 # state template array depends on what we are checking
160 $tpl = $this->state_tpl_host
;
161 if ($this->st_is_service
)
162 $tpl = $this->state_tpl_svc
;
163 foreach ($tpl as $t => $discard)
164 if (!isset($converted_state[$t]))
165 $converted_state[$t] = 0;
167 $converted_state['HOST_NAME'] = $this->host_name
;
168 if ($this->st_is_service
)
169 $converted_state['SERVICE_DESCRIPTION'] = $this->service_description
;
171 # now add the time we didn't count due
172 # to the selected timeperiod
173 $converted_state['TIME_INACTIVE'] = $this->st_inactive
;
175 $total_time = $this->options
['end_time'] - $this->options
['start_time'];
177 return array('source' => $this->st_source
, 'log' => $this->st_log
, 'states' => $converted_state, 'tot_time' => $total_time);
181 * Deprecated method that keeps the log around for the benefit of the trend graph
183 protected function st_update_log($row = false)
186 $row['state'] = $this->st_obj_state
;
188 if (!$this->options
['include_trends']) {
189 $this->prev_row
= $row;
193 # called from finalize(), so bail out early
195 $this->prev_row
['duration'] = $this->options
['end_time'] - $this->prev_row
['the_time'];
196 $active = $this->timeperiod
->active_time($this->prev_row
['the_time'], $this->options
['end_time']);
197 if ($active > 0 ||
$active === $this->prev_row
['duration'])
198 $this->st_log
[] = $this->prev_row
;
200 $this->st_log
[] = array(
201 'output' => '(event outside of timeperiod)',
202 'the_time' => $this->prev_row
['the_time'],
203 'duration' => $this->prev_row
['duration'],
207 // This prevents the close event from being added multiple times
208 $this->prev_row
['the_time']= $this->options
['end_time'];
212 # we mangle $row here, since $this->prev_row is always
213 # derived from it, except when it's the initial
214 # state which always has (faked) output
215 if (empty($row['output']))
216 $row['output'] = '(No output)';
218 if ($this->options
['scheduleddowntimeasuptime'] && $this->st_dt_depth
)
219 $row['state'] = Reports_Model
::STATE_OK
;
221 # don't save states without duration for master objects
222 $duration = $row['the_time'] - $this->prev_row
['the_time'];
224 $this->prev_row
['duration'] = $duration;
225 $active = $this->timeperiod
->active_time($this->prev_row
['the_time'], $row['the_time']);
226 if ($active > 0 ||
($duration === $active))
227 $this->st_log
[] = $this->prev_row
;
229 $this->st_log
[] = array(
230 'output' => '(event outside of timeperiod)',
231 'the_time' => $this->prev_row
['the_time'],
232 'duration' => $this->prev_row
['duration'],
238 $this->prev_row
= $row;
241 public function finalize()
245 $this->st_update_log();