Commit 9198002e authored by Sarah Yasonik's avatar Sarah Yasonik Committed by Peter Leitzen

Expose metrics dashboard url for graphql alert

parent e22534e9
...@@ -91,6 +91,12 @@ module Types ...@@ -91,6 +91,12 @@ module Types
null: true, null: true,
description: 'Assignees of the alert' description: 'Assignees of the alert'
field :metrics_dashboard_url,
GraphQL::STRING_TYPE,
null: true,
description: 'URL for metrics embed for the alert',
resolve: -> (alert, _args, _context) { alert.present.metrics_dashboard_url }
def notes def notes
object.ordered_notes object.ordered_notes
end end
......
...@@ -37,6 +37,8 @@ module AlertManagement ...@@ -37,6 +37,8 @@ module AlertManagement
MARKDOWN MARKDOWN
end end
def metrics_dashboard_url; end
private private
attr_reader :alert, :project attr_reader :alert, :project
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
module AlertManagement module AlertManagement
class PrometheusAlertPresenter < AlertManagement::AlertPresenter class PrometheusAlertPresenter < AlertManagement::AlertPresenter
def metrics_dashboard_url
alerting_alert.metrics_dashboard_url
end
private private
def alert_markdown def alert_markdown
......
...@@ -68,9 +68,13 @@ module Projects ...@@ -68,9 +68,13 @@ module Projects
end end
def metric_embed_for_alert def metric_embed_for_alert
url = embed_url_for_gitlab_alert || embed_url_for_self_managed_alert "\n[](#{metrics_dashboard_url})" if metrics_dashboard_url
end
"\n[](#{url})" if url def metrics_dashboard_url
strong_memoize(:metrics_dashboard_url) do
embed_url_for_gitlab_alert || embed_url_for_self_managed_alert
end
end end
private private
...@@ -133,6 +137,7 @@ module Projects ...@@ -133,6 +137,7 @@ module Projects
project, project,
gitlab_alert.prometheus_metric_id, gitlab_alert.prometheus_metric_id,
environment_id: environment.id, environment_id: environment.id,
embedded: true,
**alert_embed_window_params(embed_time) **alert_embed_window_params(embed_time)
) )
end end
...@@ -144,6 +149,7 @@ module Projects ...@@ -144,6 +149,7 @@ module Projects
project, project,
environment, environment,
embed_json: dashboard_for_self_managed_alert.to_json, embed_json: dashboard_for_self_managed_alert.to_json,
embedded: true,
**alert_embed_window_params(embed_time) **alert_embed_window_params(embed_time)
) )
end end
......
---
title: Expose metrics dashboard URL for alert GraphQL query
merge_request: 35293
author:
type: added
...@@ -259,6 +259,11 @@ type AlertManagementAlert implements Noteable { ...@@ -259,6 +259,11 @@ type AlertManagementAlert implements Noteable {
""" """
issueIid: ID issueIid: ID
"""
URL for metrics embed for the alert
"""
metricsDashboardUrl: String
""" """
Monitoring tool the alert came from Monitoring tool the alert came from
""" """
......
...@@ -716,6 +716,20 @@ ...@@ -716,6 +716,20 @@
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
}, },
{
"name": "metricsDashboardUrl",
"description": "URL for metrics embed for the alert",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{ {
"name": "monitoringTool", "name": "monitoringTool",
"description": "Monitoring tool the alert came from", "description": "Monitoring tool the alert came from",
...@@ -69,6 +69,7 @@ Describes an alert from the project's Alert Management ...@@ -69,6 +69,7 @@ Describes an alert from the project's Alert Management
| `hosts` | String! => Array | List of hosts the alert came from | | `hosts` | String! => Array | List of hosts the alert came from |
| `iid` | ID! | Internal ID of the alert | | `iid` | ID! | Internal ID of the alert |
| `issueIid` | ID | Internal ID of the GitLab issue attached to the alert | | `issueIid` | ID | Internal ID of the GitLab issue attached to the alert |
| `metricsDashboardUrl` | String | URL for metrics embed for the alert |
| `monitoringTool` | String | Monitoring tool the alert came from | | `monitoringTool` | String | Monitoring tool the alert came from |
| `service` | String | Service the alert came from | | `service` | String | Service the alert came from |
| `severity` | AlertManagementSeverity | Severity of the alert | | `severity` | AlertManagementSeverity | Severity of the alert |
......
...@@ -27,6 +27,7 @@ RSpec.describe GitlabSchema.types['AlertManagementAlert'] do ...@@ -27,6 +27,7 @@ RSpec.describe GitlabSchema.types['AlertManagementAlert'] do
assignees assignees
notes notes
discussions discussions
metrics_dashboard_url
] ]
expect(described_class).to have_graphql_fields(*expected_fields) expect(described_class).to have_graphql_fields(*expected_fields)
......
...@@ -38,4 +38,10 @@ RSpec.describe AlertManagement::AlertPresenter do ...@@ -38,4 +38,10 @@ RSpec.describe AlertManagement::AlertPresenter do
) )
end end
end end
describe '#metrics_dashboard_url' do
it 'is not defined' do
expect(presenter.metrics_dashboard_url).to be_nil
end
end
end end
...@@ -45,4 +45,10 @@ RSpec.describe AlertManagement::PrometheusAlertPresenter do ...@@ -45,4 +45,10 @@ RSpec.describe AlertManagement::PrometheusAlertPresenter do
) )
end end
end end
describe '#metrics_dashboard_url' do
it 'is not defined' do
expect(presenter.metrics_dashboard_url).to be_nil
end
end
end end
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Projects::Prometheus::AlertPresenter do RSpec.describe Projects::Prometheus::AlertPresenter do
include Gitlab::Routing.url_helpers
let_it_be(:project, reload: true) { create(:project) } let_it_be(:project, reload: true) { create(:project) }
let(:presenter) { described_class.new(alert) } let(:presenter) { described_class.new(alert) }
...@@ -14,7 +16,39 @@ RSpec.describe Projects::Prometheus::AlertPresenter do ...@@ -14,7 +16,39 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
let(:metric_id) { gitlab_alert.prometheus_metric_id } let(:metric_id) { gitlab_alert.prometheus_metric_id }
let(:alert) do let(:alert) do
create(:alerting_alert, project: project, metric_id: metric_id) create(:alerting_alert, project: project, metric_id: metric_id, payload: payload)
end
end
shared_context 'self-managed prometheus alert with metrics data' do
let!(:environment) { create(:environment, project: project, name: 'production') }
let(:title) { 'title' }
let(:y_label) { 'y_label' }
let(:query) { 'avg(metric) > 1.0' }
let(:embed_content) do
{
panel_groups: [{
panels: [{
type: 'line-graph',
title: title,
y_label: y_label,
metrics: [{ query_range: query }]
}]
}]
}
end
before do
payload['startsAt'] = starts_at
payload['generatorURL'] = "http://host?g0.expr=#{CGI.escape(query)}"
payload['labels'] ||= {}
payload['labels']['gitlab_environment_name'] = 'production'
payload['annotations'] ||= {}
payload['annotations']['title'] = 'title'
payload['annotations']['gitlab_y_label'] = 'y_label'
end end
end end
...@@ -171,7 +205,7 @@ RSpec.describe Projects::Prometheus::AlertPresenter do ...@@ -171,7 +205,7 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
**Start time:** #{presenter.start_time}#{markdown_line_break} **Start time:** #{presenter.start_time}#{markdown_line_break}
**full_query:** `avg(metric) > 1.0` **full_query:** `avg(metric) > 1.0`
[](#{url}) [](#{presenter.metrics_dashboard_url})
MARKDOWN MARKDOWN
end end
...@@ -193,55 +227,17 @@ RSpec.describe Projects::Prometheus::AlertPresenter do ...@@ -193,55 +227,17 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
end end
context 'for gitlab-managed prometheus alerts' do context 'for gitlab-managed prometheus alerts' do
let(:gitlab_alert) { create(:prometheus_alert, project: project) } include_context 'gitlab alert'
let(:metric_id) { gitlab_alert.prometheus_metric_id }
let(:env_id) { gitlab_alert.environment_id }
before do before do
payload['labels'] = { 'gitlab_alert_id' => metric_id } payload['labels'] = { 'gitlab_alert_id' => metric_id }
end end
let(:url) { "http://localhost/#{project.full_path}/prometheus/alerts/#{metric_id}/metrics_dashboard?end=2018-03-12T09%3A36%3A00Z&environment_id=#{env_id}&start=2018-03-12T08%3A36%3A00Z" }
it_behaves_like 'markdown with metrics embed' it_behaves_like 'markdown with metrics embed'
end end
context 'for alerts from a self-managed prometheus' do context 'for alerts from a self-managed prometheus' do
let!(:environment) { create(:environment, project: project, name: 'production') } include_context 'self-managed prometheus alert with metrics data'
let(:url) { "http://localhost/#{project.full_path}/-/environments/#{environment.id}/metrics_dashboard?embed_json=#{CGI.escape(embed_content.to_json)}&end=2018-03-12T09%3A36%3A00Z&start=2018-03-12T08%3A36%3A00Z" }
let(:title) { 'title' }
let(:y_label) { 'y_label' }
let(:query) { 'avg(metric) > 1.0' }
let(:embed_content) do
{
panel_groups: [{
panels: [{
type: 'line-graph',
title: title,
y_label: y_label,
metrics: [{ query_range: query }]
}]
}]
}
end
before do
# Setup embed time range
payload['startsAt'] = starts_at
# Setup query
payload['generatorURL'] = "http://host?g0.expr=#{CGI.escape(query)}"
# Setup environment
payload['labels'] ||= {}
payload['labels']['gitlab_environment_name'] = 'production'
# Setup chart title & axis labels
payload['annotations'] ||= {}
payload['annotations']['title'] = 'title'
payload['annotations']['gitlab_y_label'] = 'y_label'
end
it_behaves_like 'markdown with metrics embed' it_behaves_like 'markdown with metrics embed'
...@@ -359,10 +355,7 @@ RSpec.describe Projects::Prometheus::AlertPresenter do ...@@ -359,10 +355,7 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
end end
describe '#performance_dashboard_link' do describe '#performance_dashboard_link' do
let(:expected_link) do let(:expected_link) { metrics_project_environment_url(project, alert.environment) }
Gitlab::Routing.url_helpers
.metrics_project_environment_url(project, alert.environment)
end
subject { presenter.performance_dashboard_link } subject { presenter.performance_dashboard_link }
...@@ -370,15 +363,34 @@ RSpec.describe Projects::Prometheus::AlertPresenter do ...@@ -370,15 +363,34 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
end end
describe '#incident_issues_link' do describe '#incident_issues_link' do
let(:expected_link) do let(:expected_link) { project_issues_url(project, label_name: described_class::INCIDENT_LABEL_NAME) }
Gitlab::Routing.url_helpers
.project_issues_url(project, label_name: described_class::INCIDENT_LABEL_NAME)
end
subject { presenter.incident_issues_link } subject { presenter.incident_issues_link }
it { is_expected.to eq(expected_link) } it { is_expected.to eq(expected_link) }
end end
describe '#metrics_dashboard_url' do
let(:starts_at) { '2018-03-12T09:06:00Z' }
let(:expected_url) do
metrics_dashboard_project_prometheus_alert_url(
project,
metric_id,
environment_id: gitlab_alert.environment_id,
embedded: true,
end: '2018-03-12T09:36:00Z',
start: '2018-03-12T08:36:00Z'
)
end
subject { presenter.metrics_dashboard_url }
before do
payload['startsAt'] = starts_at
end
it { is_expected.to eq(expected_url) }
end
end end
context 'without gitlab alert' do context 'without gitlab alert' do
...@@ -413,13 +425,39 @@ RSpec.describe Projects::Prometheus::AlertPresenter do ...@@ -413,13 +425,39 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
end end
describe '#performance_dashboard_link' do describe '#performance_dashboard_link' do
let(:expected_link) do let(:expected_link) { metrics_project_environments_url(project) }
Gitlab::Routing.url_helpers.metrics_project_environments_url(project)
end
subject { presenter.performance_dashboard_link } subject { presenter.performance_dashboard_link }
it { is_expected.to eq(expected_link) } it { is_expected.to eq(expected_link) }
end end
describe '#metrics_dashboard_url' do
subject { presenter.metrics_dashboard_url }
it { is_expected.to be_nil }
end
end
context 'with self-managed prometheus alert with metrics data' do
include_context 'self-managed prometheus alert with metrics data'
describe '#metrics_dashboard_url' do
let(:starts_at) { '2018-03-12T09:06:00Z' }
let(:expected_url) do
metrics_dashboard_project_environment_url(
project,
environment,
embed_json: embed_content.to_json,
embedded: true,
end: '2018-03-12T09:36:00Z',
start: '2018-03-12T08:36:00Z'
)
end
subject { presenter.metrics_dashboard_url }
it { is_expected.to eq(expected_url) }
end
end end
end end
...@@ -73,7 +73,8 @@ RSpec.describe 'getting Alert Management Alerts' do ...@@ -73,7 +73,8 @@ RSpec.describe 'getting Alert Management Alerts' do
'endedAt' => nil, 'endedAt' => nil,
'details' => { 'custom.alert' => 'payload' }, 'details' => { 'custom.alert' => 'payload' },
'createdAt' => triggered_alert.created_at.strftime('%Y-%m-%dT%H:%M:%SZ'), 'createdAt' => triggered_alert.created_at.strftime('%Y-%m-%dT%H:%M:%SZ'),
'updatedAt' => triggered_alert.updated_at.strftime('%Y-%m-%dT%H:%M:%SZ') 'updatedAt' => triggered_alert.updated_at.strftime('%Y-%m-%dT%H:%M:%SZ'),
'metricsDashboardUrl' => nil
) )
expect(second_alert).to include( expect(second_alert).to include(
...@@ -135,6 +136,28 @@ RSpec.describe 'getting Alert Management Alerts' do ...@@ -135,6 +136,28 @@ RSpec.describe 'getting Alert Management Alerts' do
it { expect(alerts.size).to eq(0) } it { expect(alerts.size).to eq(0) }
end end
end end
context 'with prometheus payload' do
let_it_be(:gitlab_alert) { create(:prometheus_alert, project: project) }
let_it_be(:metric_id) { gitlab_alert.prometheus_metric_id }
let_it_be(:prometheus_payload) { { 'labels' => { 'gitlab_alert_id' => metric_id }, 'startsAt' => '2018-03-12T09:06:00Z' } }
let_it_be(:self_managed_alert) { create(:alert_management_alert, :prometheus, project: project, payload: prometheus_payload) }
let(:expected_url) do
Gitlab::Routing.url_helpers.metrics_dashboard_project_prometheus_alert_url(
project,
metric_id,
environment_id: gitlab_alert.environment_id,
start: '2018-03-12T08:36:00Z',
end: '2018-03-12T09:36:00Z',
embedded: true
)
end
it 'includes a metrics dashboard url' do
expect(first_alert).to include('metricsDashboardUrl' => expected_url)
end
end
end end
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