Commit 342aa58a authored by Vitali Tatarintev's avatar Vitali Tatarintev

Present generic alert data

Reimplement generic alert related methods in
`AlertManagement::AlertPresenter`.

Makes generic alert independent from `Alerting::Alert`.
parent e90c1b4a
......@@ -26,6 +26,8 @@ module AlertManagement
ignored: :ignore
}.freeze
DETAILS_IGNORED_PARAMS = %w(start_time).freeze
belongs_to :project
belongs_to :issue, optional: true
......@@ -137,7 +139,7 @@ module AlertManagement
end
def details
details_payload = payload.except(*attributes.keys)
details_payload = payload.except(*attributes.keys, *DETAILS_IGNORED_PARAMS)
Gitlab::Utils::InlineHash.merge_keys(details_payload)
end
......
......@@ -5,6 +5,8 @@ module AlertManagement
include Gitlab::Utils::StrongMemoize
include IncidentManagement::Settings
MARKDOWN_LINE_BREAK = " \n".freeze
def initialize(alert, _attributes = {})
super
......@@ -12,8 +14,6 @@ module AlertManagement
@project = alert.project
end
delegate :alert_markdown, :issue_summary_markdown, to: :alerting_alert
def issue_description
horizontal_line = "\n\n---\n\n"
......@@ -24,22 +24,87 @@ module AlertManagement
].compact.join(horizontal_line)
end
def start_time
started_at&.strftime('%d %B %Y, %-l:%M%p (%Z)')
end
def issue_summary_markdown
<<~MARKDOWN.chomp
#### Summary
#{metadata_list}
#{alert_details}#{metric_embed_for_alert}
MARKDOWN
end
private
attr_reader :alert, :project
def alert_payload
if alert.prometheus?
alert.payload
else
Gitlab::Alerting::NotificationPayloadParser.call(alert.payload.to_h)
def alerting_alert
strong_memoize(:alerting_alert) do
Gitlab::Alerting::Alert.new(project: project, payload: alert.payload).present
end
end
def alerting_alert
strong_memoize(:alertign_alert) do
Gitlab::Alerting::Alert.new(project: project, payload: alert_payload).present
def alert_markdown
return unless alert.prometheus?
alerting_alert.alert_markdown
end
def metadata_list
metadata = []
metadata << list_item('Start time', start_time)
metadata << list_item('Severity', severity)
metadata << list_item('full_query', backtick(full_query)) if full_query
metadata << list_item('Service', service) if service
metadata << list_item('Monitoring tool', monitoring_tool) if monitoring_tool
metadata << list_item('Hosts', host_links) if hosts.any?
metadata.join(MARKDOWN_LINE_BREAK)
end
def alert_details
if details.present?
<<~MARKDOWN.chomp
#### Alert Details
#{details_list}
MARKDOWN
end
end
def details_list
return alerting_alert.annotation_list if alert.prometheus?
alert.details
.map { |label, value| list_item(label, value) }
.join(MARKDOWN_LINE_BREAK)
end
def metric_embed_for_alert
return unless alert.prometheus?
alerting_alert.metric_embed_for_alert
end
def full_query
alert.prometheus? ? alerting_alert.full_query : nil
end
def list_item(key, value)
"**#{key}:** #{value}".strip
end
def backtick(value)
"`#{value}`"
end
def host_links
hosts.join(' ')
end
end
end
......@@ -58,6 +58,21 @@ module Projects
MARKDOWN
end
def annotation_list
strong_memoize(:annotation_list) do
annotations
.reject { |annotation| annotation.label.in?(RESERVED_ANNOTATIONS | GENERIC_ALERT_SUMMARY_ANNOTATIONS) }
.map { |annotation| list_item(annotation.label, annotation.value) }
.join(MARKDOWN_LINE_BREAK)
end
end
def metric_embed_for_alert
url = embed_url_for_gitlab_alert || embed_url_for_self_managed_alert
"\n[](#{url})" if url
end
private
def alert_title
......@@ -93,15 +108,6 @@ module Projects
end
end
def annotation_list
strong_memoize(:annotation_list) do
annotations
.reject { |annotation| annotation.label.in?(RESERVED_ANNOTATIONS | GENERIC_ALERT_SUMMARY_ANNOTATIONS) }
.map { |annotation| list_item(annotation.label, annotation.value) }
.join(MARKDOWN_LINE_BREAK)
end
end
def list_item(key, value)
"**#{key}:** #{value}".strip
end
......@@ -120,12 +126,6 @@ module Projects
Array(hosts.value).join(' ')
end
def metric_embed_for_alert
url = embed_url_for_gitlab_alert || embed_url_for_self_managed_alert
"\n[](#{url})" if url
end
def embed_url_for_gitlab_alert
return unless gitlab_alert
......
......@@ -12,13 +12,14 @@ RSpec.describe AlertManagement::AlertPresenter do
}
end
let_it_be(:generic_alert) do
create(:alert_management_alert, project: project, payload: generic_payload)
create(:alert_management_alert, :with_host, :with_service, :with_monitoring_tool, project: project, payload: generic_payload)
end
let_it_be(:prometheus_payload) do
{
'annotations' => {
'title' => 'Alert title',
'gitlab_incident_markdown' => '**`markdown example`**'
'gitlab_incident_markdown' => '**`markdown example`**',
'custom annotation' => 'custom annotation value'
},
'startsAt' => '2020-04-27T10:10:22.265949279Z',
'generatorURL' => 'http://8d467bd4607a:9090/graph?g0.expr=vector%281%29&g0.tab=1'
......@@ -28,27 +29,29 @@ RSpec.describe AlertManagement::AlertPresenter do
create(:alert_management_alert, :prometheus, project: project, payload: prometheus_payload)
end
let(:alert) { generic_alert }
let(:presenter) { described_class.new(alert) }
subject(:presenter) { described_class.new(alert) }
describe '#issue_description' do
let(:markdown_line_break) { ' ' }
context 'with generic alert' do
let(:alert) { generic_alert }
let(:parsed_payload) { Gitlab::Alerting::NotificationPayloadParser.call(generic_payload.to_h) }
let(:alert_presenter) { Gitlab::Alerting::Alert.new(project: project, payload: parsed_payload).present }
it 'returns an alert issue description' do
expect(presenter.issue_description).to eq(
<<~MARKDOWN.chomp
#### Summary
**Start time:** #{alert_presenter.start_time}
**Start time:** #{presenter.start_time}#{markdown_line_break}
**Severity:** #{presenter.severity}#{markdown_line_break}
**Service:** #{alert.service}#{markdown_line_break}
**Monitoring tool:** #{alert.monitoring_tool}#{markdown_line_break}
**Hosts:** #{alert.hosts.join(' ')}
#### Alert Details
**custom.param:** 73#{markdown_line_break}
**severity:** critical
**custom.param:** 73
MARKDOWN
)
end
......@@ -56,16 +59,20 @@ RSpec.describe AlertManagement::AlertPresenter do
context 'with prometheus alert' do
let(:alert) { prometheus_alert }
let(:alert_presenter) { Gitlab::Alerting::Alert.new(project: project, payload: prometheus_payload).present }
it 'returns an alert issue description' do
expect(presenter.issue_description).to eq(
<<~MARKDOWN.chomp
#### Summary
**Start time:** #{alert_presenter.start_time}#{markdown_line_break}
**full_query:** `vector(1)`
**Start time:** #{presenter.start_time}#{markdown_line_break}
**Severity:** #{presenter.severity}#{markdown_line_break}
**full_query:** `vector(1)`#{markdown_line_break}
**Monitoring tool:** Prometheus
#### Alert Details
**custom annotation:** custom annotation value
---
......
......@@ -15,6 +15,7 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
let_it_be(:generic_alert, reload: true) { create(:alert_management_alert, :triggered, project: project, payload: payload) }
let_it_be(:prometheus_alert, reload: true) { create(:alert_management_alert, :triggered, :prometheus, project: project, payload: payload) }
let(:alert) { generic_alert }
let(:alert_presenter) { alert.present }
let(:created_issue) { Issue.last! }
describe '#execute' do
......@@ -161,9 +162,6 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
context 'when the alert is prometheus alert' do
let(:alert) { prometheus_alert }
let(:alert_presenter) do
Gitlab::Alerting::Alert.new(project: project, payload: alert.payload).present
end
it_behaves_like 'creating an alert issue'
it_behaves_like 'setting an issue attributes'
......@@ -172,10 +170,6 @@ RSpec.describe AlertManagement::CreateAlertIssueService do
context 'when the alert is generic' do
let(:alert) { generic_alert }
let(:alert_presenter) do
alert_payload = Gitlab::Alerting::NotificationPayloadParser.call(alert.payload.to_h)
Gitlab::Alerting::Alert.new(project: project, payload: alert_payload).present
end
it_behaves_like 'creating an alert issue'
it_behaves_like 'setting an issue attributes'
......
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