Commit 0f316dd2 authored by Peter Leitzen's avatar Peter Leitzen

Revise the list of severities

Creates a clear list of the various severities, and what strings
map to each one.
parent 01031763
---
title: Map common severity values from a Prometheus alert payload
merge_request: 50871
author:
type: added
...@@ -110,6 +110,14 @@ values extracted from the [`alerts` field in webhook payload](https://prometheus ...@@ -110,6 +110,14 @@ values extracted from the [`alerts` field in webhook payload](https://prometheus
- `full_query`: Alert query extracted from the payload's `generatorURL` field - `full_query`: Alert query extracted from the payload's `generatorURL` field
- Optional list of attached annotations extracted from `annotations/*` - Optional list of attached annotations extracted from `annotations/*`
- Alert [GFM](../../user/markdown.md): GitLab Flavored Markdown from the payload's `annotations/gitlab_incident_markdown` field. - Alert [GFM](../../user/markdown.md): GitLab Flavored Markdown from the payload's `annotations/gitlab_incident_markdown` field.
- Alert Severity (introduced in GitLab version [13.9](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50871):
Extracted from the alert payload field `labels/severity`. Maps case-insensitive
value to [Alert's severity](../incident_management/alerts.md#alert-severity):
- **Critical**: `critical`, `s1`, `p1`, `emergency`, `fatal`, or any value not in this list
- **High**: `high`, `s2`, `p2`, `major`, `page`
- **Medium**: `medium`, `s3`, `p3`, `error`, `alert`
- **Low**: `low`, `s4`, `p4`, `warn`, `warning`
- **Info**: `info`, `s5`, `p5`, `debug`, `information`, `notice`
When GitLab receives a **Recovery Alert**, it closes the associated issue. When GitLab receives a **Recovery Alert**, it closes the associated issue.
This action is recorded as a system message on the issue indicating that it This action is recorded as a system message on the issue indicating that it
......
# frozen_string_literal: true # frozen_string_literal: true
# Attribute mapping for alerts via prometheus alerting integration.
module Gitlab module Gitlab
module AlertManagement module AlertManagement
module Payload module Payload
# Attribute mapping for alerts via prometheus alerting integration.
class Prometheus < Base class Prometheus < Base
attribute :alert_markdown, paths: %w(annotations gitlab_incident_markdown) attribute :alert_markdown, paths: %w(annotations gitlab_incident_markdown)
attribute :annotations, paths: 'annotations' attribute :annotations, paths: 'annotations'
...@@ -26,13 +26,49 @@ module Gitlab ...@@ -26,13 +26,49 @@ module Gitlab
paths: [%w(annotations title), paths: [%w(annotations title),
%w(annotations summary), %w(annotations summary),
%w(labels alertname)] %w(labels alertname)]
attribute :starts_at_raw, attribute :starts_at_raw,
paths: [%w(startsAt)] paths: [%w(startsAt)]
private :starts_at_raw private :starts_at_raw
attribute :severity_raw, paths: %w(labels severity)
private :severity_raw
METRIC_TIME_WINDOW = 30.minutes METRIC_TIME_WINDOW = 30.minutes
SEVERITY_MAP = {
'critical' => :critical,
'high' => :high,
'medium' => :medium,
'low' => :low,
'info' => :info,
's1' => :critical,
's2' => :high,
's3' => :medium,
's4' => :low,
's5' => :info,
'p1' => :critical,
'p2' => :high,
'p3' => :medium,
'p4' => :low,
'p5' => :info,
'debug' => :info,
'information' => :info,
'notice' => :info,
'warn' => :low,
'warning' => :low,
'minor' => :low,
'error' => :medium,
'major' => :high,
'emergency' => :critical,
'fatal' => :critical,
'alert' => :medium,
'page' => :high
}.freeze
# Handle an unmapped severity value the same way we treat missing values
# so we can fallback to alert's default severity `critical`.
UNMAPPED_SEVERITY = nil
def monitoring_tool def monitoring_tool
Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:prometheus] Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:prometheus]
end end
...@@ -65,6 +101,12 @@ module Gitlab ...@@ -65,6 +101,12 @@ module Gitlab
project && title && starts_at_raw project && title && starts_at_raw
end end
def severity
return unless severity_raw
SEVERITY_MAP.fetch(severity_raw.to_s.downcase, UNMAPPED_SEVERITY)
end
private private
def plain_gitlab_fingerprint def plain_gitlab_fingerprint
......
...@@ -156,8 +156,6 @@ RSpec.describe Gitlab::AlertManagement::Payload::Prometheus do ...@@ -156,8 +156,6 @@ RSpec.describe Gitlab::AlertManagement::Payload::Prometheus do
end end
describe '#gitlab_fingerprint' do describe '#gitlab_fingerprint' do
subject { parsed_payload.gitlab_fingerprint }
let(:raw_payload) do let(:raw_payload) do
{ {
'startsAt' => Time.current.to_s, 'startsAt' => Time.current.to_s,
...@@ -166,6 +164,8 @@ RSpec.describe Gitlab::AlertManagement::Payload::Prometheus do ...@@ -166,6 +164,8 @@ RSpec.describe Gitlab::AlertManagement::Payload::Prometheus do
} }
end end
subject { parsed_payload.gitlab_fingerprint }
it 'returns a fingerprint' do it 'returns a fingerprint' do
plain_fingerprint = [ plain_fingerprint = [
parsed_payload.send(:starts_at_raw), parsed_payload.send(:starts_at_raw),
...@@ -237,4 +237,65 @@ RSpec.describe Gitlab::AlertManagement::Payload::Prometheus do ...@@ -237,4 +237,65 @@ RSpec.describe Gitlab::AlertManagement::Payload::Prometheus do
it { is_expected.to be_falsey } it { is_expected.to be_falsey }
end end
end end
describe '#severity' do
using RSpec::Parameterized::TableSyntax
let(:raw_payload) { { 'labels' => { 'severity' => payload_severity } } }
subject { parsed_payload.severity }
context 'when set' do
where(:payload_severity, :expected_severity) do
'critical' | :critical
'high' | :high
'medium' | :medium
'low' | :low
'info' | :info
's1' | :critical
's2' | :high
's3' | :medium
's4' | :low
's5' | :info
'p1' | :critical
'p2' | :high
'p3' | :medium
'p4' | :low
'p5' | :info
'CRITICAL' | :critical
'cRiTiCaL' | :critical
'S1' | :critical
'unmapped' | nil
1 | nil
nil | nil
'debug' | :info
'information' | :info
'notice' | :info
'warn' | :low
'warning' | :low
'minor' | :low
'error' | :medium
'major' | :high
'emergency' | :critical
'fatal' | :critical
'alert' | :medium
'page' | :high
end
with_them do
it { is_expected.to eq(expected_severity) }
end
end
context 'without key' do
let(:raw_payload) { {} }
it { is_expected.to be_nil }
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment