diff options
Diffstat (limited to 'app/models/alert_management/alert.rb')
-rw-r--r-- | app/models/alert_management/alert.rb | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/app/models/alert_management/alert.rb b/app/models/alert_management/alert.rb index af60ddd6f9a..fb166fb56b7 100644 --- a/app/models/alert_management/alert.rb +++ b/app/models/alert_management/alert.rb @@ -10,6 +10,7 @@ module AlertManagement include Sortable include Noteable include Gitlab::SQL::Pattern + include Presentable STATUSES = { triggered: 0, @@ -25,8 +26,17 @@ module AlertManagement ignored: :ignore }.freeze + OPEN_STATUSES = [ + :triggered, + :acknowledged + ].freeze + + DETAILS_IGNORED_PARAMS = %w(start_time).freeze + belongs_to :project belongs_to :issue, optional: true + belongs_to :prometheus_alert, optional: true + belongs_to :environment, optional: true has_many :alert_assignees, inverse_of: :alert has_many :assignees, through: :alert_assignees @@ -50,8 +60,12 @@ module AlertManagement validates :severity, presence: true validates :status, presence: true validates :started_at, presence: true - validates :fingerprint, uniqueness: { scope: :project }, allow_blank: true - validate :hosts_length + validates :fingerprint, allow_blank: true, uniqueness: { + scope: :project, + conditions: -> { not_resolved }, + message: -> (object, data) { _('Cannot have multiple unresolved alerts') } + }, unless: :resolved? + validate :hosts_length enum severity: { critical: 0, @@ -108,15 +122,30 @@ module AlertManagement scope :for_iid, -> (iid) { where(iid: iid) } scope :for_status, -> (status) { where(status: status) } scope :for_fingerprint, -> (project, fingerprint) { where(project: project, fingerprint: fingerprint) } + scope :for_environment, -> (environment) { where(environment: environment) } scope :search, -> (query) { fuzzy_search(query, [:title, :description, :monitoring_tool, :service]) } + scope :open, -> { with_status(OPEN_STATUSES) } + scope :not_resolved, -> { where.not(status: STATUSES[:resolved]) } + scope :with_prometheus_alert, -> { includes(:prometheus_alert) } scope :order_start_time, -> (sort_order) { order(started_at: sort_order) } scope :order_end_time, -> (sort_order) { order(ended_at: sort_order) } scope :order_event_count, -> (sort_order) { order(events: sort_order) } - scope :order_severity, -> (sort_order) { order(severity: sort_order) } - scope :order_status, -> (sort_order) { order(status: sort_order) } + + # Ascending sort order sorts severity from less critical to more critical. + # Descending sort order sorts severity from more critical to less critical. + # https://gitlab.com/gitlab-org/gitlab/-/issues/221242#what-is-the-expected-correct-behavior + scope :order_severity, -> (sort_order) { order(severity: sort_order == :asc ? :desc : :asc) } + + # Ascending sort order sorts statuses: Ignored > Resolved > Acknowledged > Triggered + # Descending sort order sorts statuses: Triggered > Acknowledged > Resolved > Ignored + # https://gitlab.com/gitlab-org/gitlab/-/issues/221242#what-is-the-expected-correct-behavior + scope :order_status, -> (sort_order) { order(status: sort_order == :asc ? :desc : :asc) } scope :counts_by_status, -> { group(:status).count } + scope :counts_by_project_id, -> { group(:project_id).count } + + alias_method :state, :status_name def self.sort_by_attribute(method) case method.to_s @@ -135,8 +164,13 @@ module AlertManagement end end + def self.last_prometheus_alert_by_project_id + ids = select(arel_table[:id].maximum).group(:project_id) + with_prometheus_alert.where(id: ids) + 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 @@ -161,6 +195,12 @@ module AlertManagement project.execute_services(hook_data, :alert_hooks) end + def present + return super(presenter_class: AlertManagement::PrometheusAlertPresenter) if prometheus? + + super + end + private def hook_data |