1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# frozen_string_literal: true
module AlertManagement
class ProcessPrometheusAlertService < BaseService
include Gitlab::Utils::StrongMemoize
include ::IncidentManagement::Settings
def execute
return bad_request unless incoming_payload.has_required_attributes?
process_alert_management_alert
ServiceResponse.success
end
private
def process_alert_management_alert
if incoming_payload.resolved?
process_resolved_alert_management_alert
else
process_firing_alert_management_alert
end
end
def process_firing_alert_management_alert
if alert.persisted?
alert.register_new_event!
reset_alert_management_alert_status
else
create_alert_management_alert
end
process_incident_issues if process_issues?
end
def reset_alert_management_alert_status
return if alert.trigger
logger.warn(
message: 'Unable to update AlertManagement::Alert status to triggered',
project_id: project.id,
alert_id: alert.id
)
end
def create_alert_management_alert
if alert.save
alert.execute_services
SystemNoteService.create_new_alert(alert, Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:prometheus])
return
end
logger.warn(
message: 'Unable to create AlertManagement::Alert',
project_id: project.id,
alert_errors: alert.errors.messages
)
end
def process_resolved_alert_management_alert
return unless alert.persisted?
return unless auto_close_incident?
if alert.resolve(incoming_payload.ends_at)
close_issue(alert.issue)
return
end
logger.warn(
message: 'Unable to update AlertManagement::Alert status to resolved',
project_id: project.id,
alert_id: alert.id
)
end
def close_issue(issue)
return if issue.blank? || issue.closed?
Issues::CloseService
.new(project, User.alert_bot)
.execute(issue, system_note: false)
SystemNoteService.auto_resolve_prometheus_alert(issue, project, User.alert_bot) if issue.reset.closed?
end
def process_incident_issues
return unless alert.persisted?
return if alert.issue
IncidentManagement::ProcessAlertWorker.perform_async(nil, nil, alert.id)
end
def logger
@logger ||= Gitlab::AppLogger
end
def alert
strong_memoize(:alert) do
existing_alert || new_alert
end
end
def existing_alert
strong_memoize(:existing_alert) do
AlertManagement::Alert.not_resolved.for_fingerprint(project, incoming_payload.gitlab_fingerprint).first
end
end
def new_alert
strong_memoize(:new_alert) do
AlertManagement::Alert.new(
**incoming_payload.alert_params,
ended_at: nil
)
end
end
def incoming_payload
strong_memoize(:incoming_payload) do
Gitlab::AlertManagement::Payload.parse(
project,
params,
monitoring_tool: Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:prometheus]
)
end
end
def bad_request
ServiceResponse.error(message: 'Bad Request', http_status: :bad_request)
end
end
end
|