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
null: true,
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
object.ordered_notes
end
......
......@@ -37,6 +37,8 @@ module AlertManagement
MARKDOWN
end
def metrics_dashboard_url; end
private
attr_reader :alert, :project
......
......@@ -2,6 +2,10 @@
module AlertManagement
class PrometheusAlertPresenter < AlertManagement::AlertPresenter
def metrics_dashboard_url
alerting_alert.metrics_dashboard_url
end
private
def alert_markdown
......
......@@ -68,9 +68,13 @@ module Projects
end
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
private
......@@ -133,6 +137,7 @@ module Projects
project,
gitlab_alert.prometheus_metric_id,
environment_id: environment.id,
embedded: true,
**alert_embed_window_params(embed_time)
)
end
......@@ -144,6 +149,7 @@ module Projects
project,
environment,
embed_json: dashboard_for_self_managed_alert.to_json,
embedded: true,
**alert_embed_window_params(embed_time)
)
end
......
---
title: Expose metrics dashboard URL for alert GraphQL query
merge_request: 35293
author:
type: added
......@@ -259,6 +259,11 @@ type AlertManagementAlert implements Noteable {
"""
issueIid: ID
"""
URL for metrics embed for the alert
"""
metricsDashboardUrl: String
"""
Monitoring tool the alert came from
"""
......
......@@ -716,6 +716,20 @@
"isDeprecated": false,
"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",
"description": "Monitoring tool the alert came from",
......@@ -69,6 +69,7 @@ Describes an alert from the project's Alert Management
| `hosts` | String! => Array | List of hosts the alert came from |
| `iid` | ID! | Internal ID of 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 |
| `service` | String | Service the alert came from |
| `severity` | AlertManagementSeverity | Severity of the alert |
......
......@@ -27,6 +27,7 @@ RSpec.describe GitlabSchema.types['AlertManagementAlert'] do
assignees
notes
discussions
metrics_dashboard_url
]
expect(described_class).to have_graphql_fields(*expected_fields)
......
......@@ -38,4 +38,10 @@ RSpec.describe AlertManagement::AlertPresenter do
)
end
end
describe '#metrics_dashboard_url' do
it 'is not defined' do
expect(presenter.metrics_dashboard_url).to be_nil
end
end
end
......@@ -45,4 +45,10 @@ RSpec.describe AlertManagement::PrometheusAlertPresenter do
)
end
end
describe '#metrics_dashboard_url' do
it 'is not defined' do
expect(presenter.metrics_dashboard_url).to be_nil
end
end
end
......@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Projects::Prometheus::AlertPresenter do
include Gitlab::Routing.url_helpers
let_it_be(:project, reload: true) { create(:project) }
let(:presenter) { described_class.new(alert) }
......@@ -14,7 +16,39 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
let(:metric_id) { gitlab_alert.prometheus_metric_id }
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
......@@ -171,7 +205,7 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
**Start time:** #{presenter.start_time}#{markdown_line_break}
**full_query:** `avg(metric) > 1.0`
[](#{url})
[](#{presenter.metrics_dashboard_url})
MARKDOWN
end
......@@ -193,55 +227,17 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
end
context 'for gitlab-managed prometheus alerts' do
let(:gitlab_alert) { create(:prometheus_alert, project: project) }
let(:metric_id) { gitlab_alert.prometheus_metric_id }
let(:env_id) { gitlab_alert.environment_id }
include_context 'gitlab alert'
before do
payload['labels'] = { 'gitlab_alert_id' => metric_id }
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'
end
context 'for alerts from a self-managed prometheus' do
let!(:environment) { create(:environment, project: project, name: 'production') }
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
include_context 'self-managed prometheus alert with metrics data'
it_behaves_like 'markdown with metrics embed'
......@@ -359,10 +355,7 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
end
describe '#performance_dashboard_link' do
let(:expected_link) do
Gitlab::Routing.url_helpers
.metrics_project_environment_url(project, alert.environment)
end
let(:expected_link) { metrics_project_environment_url(project, alert.environment) }
subject { presenter.performance_dashboard_link }
......@@ -370,15 +363,34 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
end
describe '#incident_issues_link' do
let(:expected_link) do
Gitlab::Routing.url_helpers
.project_issues_url(project, label_name: described_class::INCIDENT_LABEL_NAME)
end
let(:expected_link) { project_issues_url(project, label_name: described_class::INCIDENT_LABEL_NAME) }
subject { presenter.incident_issues_link }
it { is_expected.to eq(expected_link) }
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
context 'without gitlab alert' do
......@@ -413,13 +425,39 @@ RSpec.describe Projects::Prometheus::AlertPresenter do
end
describe '#performance_dashboard_link' do
let(:expected_link) do
Gitlab::Routing.url_helpers.metrics_project_environments_url(project)
end
let(:expected_link) { metrics_project_environments_url(project) }
subject { presenter.performance_dashboard_link }
it { is_expected.to eq(expected_link) }
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
......@@ -73,7 +73,8 @@ RSpec.describe 'getting Alert Management Alerts' do
'endedAt' => nil,
'details' => { 'custom.alert' => 'payload' },
'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(
......@@ -135,6 +136,28 @@ RSpec.describe 'getting Alert Management Alerts' do
it { expect(alerts.size).to eq(0) }
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
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