|
11 | 11 | use Icinga\Module\Notifications\Common\IncidentHistoryType; |
12 | 12 | use Icinga\Module\Notifications\Model\IncidentHistory; |
13 | 13 | use Icinga\Module\Notifications\Model\NotificationHistory; |
| 14 | +use Icinga\Module\Notifications\Model\Rule; |
| 15 | +use Icinga\Module\Notifications\Model\RuleEscalation; |
14 | 16 | use Icinga\Module\Notifications\View\IncidentRenderer; |
15 | 17 | use Icinga\Module\Notifications\Widget\ItemList\ObjectList; |
16 | 18 | use ipl\Html\Attributes; |
@@ -120,16 +122,35 @@ protected function createIncident(): array |
120 | 122 |
|
121 | 123 | protected function createReason(): array |
122 | 124 | { |
| 125 | + [$reason, $rule, $ruleEscalation] = $this->resolveTriggerChain(); |
123 | 126 | $triggerChain = new HtmlElement( |
124 | 127 | 'div', |
125 | 128 | Attributes::create(['class' => 'trigger-chain']), |
126 | 129 | new HtmlElement( |
127 | 130 | 'span', |
128 | 131 | Attributes::create(['class' => 'item']), |
129 | | - Text::create($this->resolveReason()->getLabel()) |
| 132 | + Text::create($reason->getLabel()) |
130 | 133 | ) |
131 | 134 | ); |
132 | 135 |
|
| 136 | + if ($rule !== null) { |
| 137 | + $triggerChain->addHtml( |
| 138 | + new HtmlElement( |
| 139 | + 'span', |
| 140 | + Attributes::create(['class' => 'item']), |
| 141 | + Text::create(sprintf($this->translate('Rule %s matched'), $rule->name)) |
| 142 | + ), |
| 143 | + new HtmlElement( |
| 144 | + 'span', |
| 145 | + Attributes::create(['class' => 'item']), |
| 146 | + Text::create(sprintf( |
| 147 | + $this->translate('Escalation triggered (%s)'), |
| 148 | + EscalationConditionDescriber::describe($ruleEscalation?->condition) |
| 149 | + )) |
| 150 | + ) |
| 151 | + ); |
| 152 | + } |
| 153 | + |
133 | 154 | $triggerChain->addHtml( |
134 | 155 | new HtmlElement( |
135 | 156 | 'span', |
@@ -193,17 +214,41 @@ protected function createReason(): array |
193 | 214 | ]; |
194 | 215 | } |
195 | 216 |
|
196 | | - protected function resolveReason(): IncidentHistoryType |
| 217 | + /** |
| 218 | + * Get the root cause and the matching rule and escalation that triggered the notification |
| 219 | + * |
| 220 | + * @return array{IncidentHistoryType, ?Rule, ?RuleEscalation} |
| 221 | + */ |
| 222 | + protected function resolveTriggerChain(): array |
197 | 223 | { |
198 | | - /** @var ?IncidentHistory $entry */ |
199 | | - $entry = IncidentHistory::on(Database::get()) |
200 | | - ->filter(Filter::all( |
201 | | - Filter::equal('incident_id', $this->notificationHistory->incident_id), |
202 | | - Filter::equal('event_id', $this->notificationHistory->event_id) |
203 | | - )) |
204 | | - ->first(); |
205 | | - |
206 | | - return $entry?->type ?? $this->notificationHistory->incident_history->type; |
| 224 | + $reason = $this->notificationHistory->incident_history->type; |
| 225 | + $rule = null; |
| 226 | + $ruleEscalation = null; |
| 227 | + |
| 228 | + $triggeredBy = $this->notificationHistory->incident_history->triggered_by_id; |
| 229 | + while ($triggeredBy !== null) { |
| 230 | + $node = IncidentHistory::on(Database::get()) |
| 231 | + ->with(['rule', 'rule_escalation']) |
| 232 | + ->filter(Filter::equal('id', $triggeredBy)) |
| 233 | + ->first(); |
| 234 | + |
| 235 | + if ($node === null) { |
| 236 | + break; |
| 237 | + } |
| 238 | + |
| 239 | + if ($node->rule_id !== null) { |
| 240 | + $rule = $node->rule; |
| 241 | + } |
| 242 | + |
| 243 | + if ($node->rule_escalation_id !== null) { |
| 244 | + $ruleEscalation = $node->rule_escalation; |
| 245 | + } |
| 246 | + |
| 247 | + $reason = $node->type; |
| 248 | + $triggeredBy = $node->triggered_by_id; |
| 249 | + } |
| 250 | + |
| 251 | + return [$reason, $rule, $ruleEscalation]; |
207 | 252 | } |
208 | 253 |
|
209 | 254 | protected function assemble(): void |
|
0 commit comments