Merge branch 'maint/7.0'
[ninja.git] / modules / reports / libraries / WorstStateCalculator.php
blobd5c7522f7a5a5edc40b53de038a47150cd840486
1 <?php
3 /**
4 * State calculator for not only generating the state for a number of sub-calculators,
5 * but also to sum up according to the worst state of them all.
6 */
7 class WorstStateCalculator extends StateCalculator
9 protected $sub_reports = array(); /**< An array of sub-reports for this report */
10 protected $st_sub = array(); /**< Map of sub report [state => [downtime_status => [indexes]]] */
12 /**
13 * Provide this object with a number of sub reports which we'll keep up to date.
14 * They should all be initialized externally, but other than that, hands off!
16 public function set_sub_reports($subs)
18 $this->sub_reports = $subs;
21 /**
22 * Initializes anything we need for this report to be generated.
23 * Warning: all sub reports must have been initialized at this point.
25 public function initialize($initial_state, $initial_depth, $is_running)
27 parent::initialize($initial_state, $initial_depth, $is_running);
29 $this->st_source = $this->options['objects'];
31 foreach ($this->st_text as $st => $discard)
32 $this->st_sub[$st] = array();
34 foreach ($this->sub_reports as $idx => $rpt) {
35 $this->st_sub[$rpt->st_obj_state][$rpt->st_dt_depth][$idx] = $idx;
37 $this->calculate_object_state();
40 public function add_event($row = false)
42 $this->st_update($row['the_time']);
44 foreach ($this->sub_reports as $idx => $rpt) {
45 unset($this->st_sub[$rpt->st_obj_state][$rpt->st_dt_depth][$idx]);
46 $rpt->add_event($row);
47 $this->st_sub[$rpt->st_obj_state][$rpt->st_dt_depth][$idx] = $idx;
49 switch($row['event_type']) {
50 case Reports_Model::PROCESS_START:
51 $this->st_running = 1;
52 break;
53 case Reports_Model::PROCESS_SHUTDOWN:
54 $this->st_running = 0;
55 break;
56 default:
57 break;
60 $this->calculate_object_state();
61 $this->prev_row = $row;
64 /**
65 * Actually discover the overall state based on the sub-reports
67 protected function calculate_object_state()
70 * Welcome to todays installment of "The world sucks and I'm tired of
71 * trying to fix it"!
73 * So, states. States have codes. If you've written plugins
74 * you'll think the "badness" increases with the numeric code. This is
75 * incorrect, of course, because then state comparison would be simple.
77 if ($this->st_is_service)
78 $states = array(Reports_Model::SERVICE_CRITICAL, Reports_Model::SERVICE_WARNING, Reports_Model::SERVICE_UNKNOWN, Reports_Model::SERVICE_OK, Reports_Model::SERVICE_PENDING, Reports_Model::SERVICE_EXCLUDED);
79 else
80 $states = array(Reports_Model::HOST_DOWN, Reports_Model::HOST_UNREACHABLE, Reports_Model::HOST_UP, Reports_Model::HOST_PENDING, Reports_Model::HOST_EXCLUDED);
82 $final_state = Reports_Model::SERVICE_OK;
84 // Loop through states in order of badness.
85 foreach ($states as $state) {
86 $keys = array_keys($this->st_sub[$state]);
87 // Sort downtime states outside downtime first
88 sort($keys);
89 foreach ($keys as $in_dt) {
90 if (empty($this->st_sub[$state][$in_dt]))
91 continue;
92 // This would look OK but isn't, go look for non-OK
93 // (remember, we sorted, so $in_dt is only true after passing false)
94 if ($this->options['scheduleddowntimeasuptime'] && $in_dt)
95 break 1;
96 // Else, we're done, this is the worst.
97 $this->st_dt_depth = $in_dt;
98 $final_state = $state;
99 break 2;
103 // So, scheduleddowntimeasuptime and worst not in sched_down is OK?
104 // Maybe there's a non-OK in sched_down...
105 if ($this->options['scheduleddowntimeasuptime'] && $final_state === 0) {
106 foreach ($states as $state) {
107 foreach ($this->st_sub[$state] as $dt_depth => $ary) {
108 if (!empty($ary)) {
109 $this->st_dt_depth = $dt_depth;
110 $final_state = $state;
111 break;
117 $this->st_obj_state = $final_state;
120 public function get_data()
122 $converted_state = $this->convert_state_table($this->st_raw, $this->st_text);
124 # state template array depends on what we are checking
125 $tpl = $this->state_tpl_host;
126 if ($this->st_is_service)
127 $tpl = $this->state_tpl_svc;
128 foreach ($tpl as $t => $discard)
129 if (!isset($converted_state[$t]))
130 $converted_state[$t] = 0;
132 # now add the time we didn't count due
133 # to the selected timeperiod
134 $converted_state['TIME_INACTIVE'] = $this->st_inactive;
136 $total_time = $this->options['end_time'] - $this->options['start_time'];
137 $res = array('source' => $this->st_source, 'tot_time' => $total_time);
138 // st_source is always an of objects, but old code assumes the best
139 // way to determine the report type is to look at where the object
140 // names are stored.
141 switch ($this->options['report_type']) {
142 case 'host_name':
143 $converted_state['HOST_NAME'] = $this->st_source;
144 break;
145 case 'service_description':
146 $converted_state['SERVICE_DESCRIPTION'] = $this->st_source;
147 break;
148 case 'hostgroups':
149 case 'servicegroups':
150 $res['groupname'] = $this->options['objects'];
151 break;
153 $res['states'] = $converted_state;
154 foreach ($this->sub_reports as $sr) {
155 $res[] = $sr->get_data();
157 return $res;
160 public function finalize()
162 foreach ($this->sub_reports as $report) {
163 $report->finalize();
165 parent::finalize();