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 $arr = $this->options
['objects'];
27 if ($this->st_is_service
) {
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 $this->host_name
= $this->st_source
= current($arr);
35 $this->calculate_object_state();
36 $this->prev_row
['state'] = $this->st_obj_state
;
40 * Take a database row object, and parse it
41 * @param $row Database row
43 public function add_event($row = false)
45 $obj_name = $obj_type = false;
46 if (!empty($row['service_description'])) {
47 $obj_name = $row['host_name'] . ";" . $row['service_description'];
48 $obj_type = 'Service';
50 elseif (!empty($row['host_name'])) {
51 $obj_name = $row['host_name'];
55 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
)
58 $this->st_update($row['the_time']);
60 switch($row['event_type']) {
61 case Reports_Model
::PROCESS_START
:
62 case Reports_Model
::PROCESS_SHUTDOWN
:
63 if ($row['event_type'] == Reports_Model
::PROCESS_START
) {
64 $row['output'] = 'Monitor started';
67 $row['output'] = 'Monitor shut down';
69 $this->st_last_dt_init
= false;
70 if ($row['event_type'] == Reports_Model
::PROCESS_START
) {
71 $row['state'] = $this->st_real_state
;
72 $this->st_running
= 1;
73 } else if ($this->options
['assumestatesduringnotrunning']) {
74 $row['state'] = $this->st_real_state
;
77 $this->st_running
= 0;
80 case Reports_Model
::DOWNTIME_START
:
81 if(!isset($row['output']) ||
!$row['output']) {
82 $row['output'] = $obj_type . ' has entered a period of scheduled downtime';
85 # we are always spammed with downtime events after restart, so
86 # don't increase the downtime depth if we're already in downtime
87 if (!$this->st_last_dt_init ||
$this->st_last_dt_init
=== $row['the_time']) {
88 $this->st_last_dt_init
= $row['the_time'];
89 if (!$this->st_dt_depth
) {
97 $this->st_dt_depth+
=1;
100 case Reports_Model
::DOWNTIME_STOP
:
101 if(!isset($row['output']) ||
!$row['output']) {
102 $row['output'] = $obj_type . ' has exited a period of scheduled downtime';
104 # old merlin versions created more end events than start events, so
105 # never decrement if we're already at 0.
106 if ($this->st_dt_depth
) {
107 $this->st_dt_depth
-=1;
110 case Reports_Model
::SERVICECHECK
:
111 case Reports_Model
::HOSTCHECK
:
112 $state = $row['state'];
114 # update the real state of the object
115 if ($this->st_source
=== $obj_name) {
116 $this->st_real_state
= $row['state'];
123 $this->calculate_object_state();
125 $this->st_update_log($row);
129 * Manually excluded states are excluded here.
134 protected function filter_excluded_state($state) {
135 if ($this->st_is_service
&& isset($this->options
['service_filter_status'][$state]))
136 return $this->options
['service_filter_status'][$state];
137 else if (isset($this->options
['host_filter_status'][$state]))
138 return $this->options
['host_filter_status'][$state];
143 * Calculate the object state, based on the chosen state calculator.
145 * If there is sub reports, the argument will be ignored. Otherwise, use
146 * either the argument or the object's real state, according to magical
147 * properties inherent in the numbers themselves.
149 public function calculate_object_state()
151 $this->st_obj_state
= $this->filter_excluded_state($this->st_real_state
);
154 public function get_data()
156 $converted_state = $this->convert_state_table($this->st_raw
, $this->st_text
);
158 # state template array depends on what we are checking
159 $tpl = $this->state_tpl_host
;
160 if ($this->st_is_service
)
161 $tpl = $this->state_tpl_svc
;
162 foreach ($tpl as $t => $discard)
163 if (!isset($converted_state[$t]))
164 $converted_state[$t] = 0;
166 $converted_state['HOST_NAME'] = $this->host_name
;
167 if ($this->st_is_service
)
168 $converted_state['SERVICE_DESCRIPTION'] = $this->service_description
;
170 # now add the time we didn't count due
171 # to the selected timeperiod
172 $converted_state['TIME_INACTIVE'] = $this->st_inactive
;
174 $total_time = $this->options
['end_time'] - $this->options
['start_time'];
176 return array('source' => $this->st_source
, 'log' => $this->st_log
, 'states' => $converted_state, 'tot_time' => $total_time);
180 * Deprecated method that keeps the log around for the benefit of the trend graph
182 protected function st_update_log($row = false)
185 $row['state'] = $this->st_obj_state
;
187 if (!$this->options
['include_trends']) {
188 $this->prev_row
= $row;
192 # called from finalize(), so bail out early
194 $this->prev_row
['duration'] = $this->options
['end_time'] - $this->prev_row
['the_time'];
195 $active = $this->timeperiod
->active_time($this->prev_row
['the_time'], $this->options
['end_time']);
196 if ($active > 0 ||
$active === $this->prev_row
['duration'])
197 $this->st_log
[] = $this->prev_row
;
199 $this->st_log
[] = array(
200 'output' => '(event outside of timeperiod)',
201 'the_time' => $this->prev_row
['the_time'],
202 'duration' => $this->prev_row
['duration'],
206 // This prevents the close event from being added multiple times
207 $this->prev_row
['the_time']= $this->options
['end_time'];
211 # we mangle $row here, since $this->prev_row is always
212 # derived from it, except when it's the initial
213 # state which always has (faked) output
214 if (empty($row['output']))
215 $row['output'] = '(No output)';
217 if ($this->options
['scheduleddowntimeasuptime'] && $this->st_dt_depth
)
218 $row['state'] = Reports_Model
::STATE_OK
;
220 # don't save states without duration for master objects
221 $duration = $row['the_time'] - $this->prev_row
['the_time'];
223 $this->prev_row
['duration'] = $duration;
224 $active = $this->timeperiod
->active_time($this->prev_row
['the_time'], $row['the_time']);
225 if ($active > 0 ||
($duration === $active))
226 $this->st_log
[] = $this->prev_row
;
228 $this->st_log
[] = array(
229 'output' => '(event outside of timeperiod)',
230 'the_time' => $this->prev_row
['the_time'],
231 'duration' => $this->prev_row
['duration'],
237 $this->prev_row
= $row;
240 public function finalize()
244 $this->st_update_log();