Added filterable to summary and histogram controllers
[ninja.git] / modules / reports / libraries / SingleStateCalculator.php
blob888499e805fcbb4448b69f166eba36285ef4217a
1 <?php
3 /**
4 * State calculator for a single object - thus more of a state.. keeper?
5 */
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
17 # TODO: noes :(
18 if ($this->options['include_trends']) {
19 $this->st_log = array();
22 $this->st_real_state = $initial_state;
23 # Warning: PHP sucks.
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];
32 } else {
33 $this->host_name = $this->st_source = current($arr);
35 $this->calculate_object_state();
36 $this->prev_row['state'] = $this->st_obj_state;
39 /**
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'];
52 $obj_type = 'Host';
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)
56 return;
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';
66 else {
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;
75 } else {
76 $row['state'] = -1;
77 $this->st_running = 0;
79 break;
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';
84 $add = 0;
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) {
90 $add = 1;
93 else {
94 $add = 1;
96 if ($add) {
97 $this->st_dt_depth+=1;
99 break;
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;
109 break;
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'];
118 break;
119 default:
120 //ERROR
123 $this->calculate_object_state();
124 # TODO: Ahrm...
125 $this->st_update_log($row);
129 * Manually excluded states are excluded here.
131 * @param $state int
132 * @return int
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];
139 return $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)
184 if($row) {
185 $row['state'] = $this->st_obj_state;
187 if (!$this->options['include_trends']) {
188 $this->prev_row = $row;
189 return;
192 # called from finalize(), so bail out early
193 if (!$row) {
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;
198 else
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'],
203 'state' => -2,
204 'hard' => 1
206 // This prevents the close event from being added multiple times
207 $this->prev_row['the_time']= $this->options['end_time'];
208 return;
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'];
222 if ($duration) {
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;
227 else
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'],
232 'state' => -2,
233 'hard' => 1
237 $this->prev_row = $row;
240 public function finalize()
242 parent::finalize();
243 // TODO: Ahrm...
244 $this->st_update_log();