Commit 759fd23e authored by Dylan Griffith's avatar Dylan Griffith

Merge branch '213923-add-range-var' into 'master'

Add built in variable called __range

See merge request gitlab-org/gitlab!33521
parents 3dbdca78 fef80491
...@@ -58,7 +58,7 @@ module Prometheus ...@@ -58,7 +58,7 @@ module Prometheus
def substitute_variables(result) def substitute_variables(result)
return success(result) unless query(result) return success(result) unless query(result)
result[:params][:query] = gsub(query(result), full_context) result[:params][:query] = gsub(query(result), full_context(result))
success(result) success(result)
end end
...@@ -75,12 +75,16 @@ module Prometheus ...@@ -75,12 +75,16 @@ module Prometheus
end end
end end
def predefined_context def predefined_context(result)
Gitlab::Prometheus::QueryVariables.call(@environment).stringify_keys Gitlab::Prometheus::QueryVariables.call(
@environment,
start_time: start_timestamp(result),
end_time: end_timestamp(result)
).stringify_keys
end end
def full_context def full_context(result)
@full_context ||= predefined_context.reverse_merge(variables_hash) @full_context ||= predefined_context(result).reverse_merge(variables_hash)
end end
def variables def variables
...@@ -91,6 +95,16 @@ module Prometheus ...@@ -91,6 +95,16 @@ module Prometheus
variables.to_h variables.to_h
end end
def start_timestamp(result)
Time.rfc3339(result[:params][:start])
rescue ArgumentError
end
def end_timestamp(result)
Time.rfc3339(result[:params][:end])
rescue ArgumentError
end
def query(result) def query(result)
result[:params][:query] result[:params][:query]
end end
......
---
title: Provide `__range` variable for Prometheus queries
merge_request: 33521
author:
type: added
...@@ -209,10 +209,19 @@ GitLab supports a limited set of [CI variables](../../../ci/variables/README.md) ...@@ -209,10 +209,19 @@ GitLab supports a limited set of [CI variables](../../../ci/variables/README.md)
- `ci_project_namespace` - `ci_project_namespace`
- `ci_project_path` - `ci_project_path`
- `ci_environment_name` - `ci_environment_name`
- `__range`
NOTE: **Note:** NOTE: **Note:**
Variables for Prometheus queries must be lowercase. Variables for Prometheus queries must be lowercase.
###### __range
The `__range` variable is useful in Prometheus
[range vector selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#range-vector-selectors).
Its value is the total number of seconds in the dashboard's time range.
For example, if the dashboard time range is set to 8 hours, the value of
`__range` is `28800s`.
##### User-defined variables ##### User-defined variables
[Variables can be defined](#templating-templating-properties) in a custom dashboard YAML file. [Variables can be defined](#templating-templating-properties) in a custom dashboard YAML file.
......
...@@ -3,8 +3,10 @@ ...@@ -3,8 +3,10 @@
module Gitlab module Gitlab
module Prometheus module Prometheus
module QueryVariables module QueryVariables
def self.call(environment) # start_time and end_time should be Time objects.
def self.call(environment, start_time: nil, end_time: nil)
{ {
__range: range(start_time, end_time),
ci_environment_slug: environment.slug, ci_environment_slug: environment.slug,
kube_namespace: environment.deployment_namespace || '', kube_namespace: environment.deployment_namespace || '',
environment_filter: %{container_name!="POD",environment="#{environment.slug}"}, environment_filter: %{container_name!="POD",environment="#{environment.slug}"},
...@@ -14,6 +16,16 @@ module Gitlab ...@@ -14,6 +16,16 @@ module Gitlab
ci_environment_name: environment.name ci_environment_name: environment.name
} }
end end
private
def self.range(start_time, end_time)
if start_time && end_time
range_seconds = (end_time - start_time).to_i
"#{range_seconds}s"
end
end
private_class_method :range
end end
end end
end end
...@@ -7,8 +7,9 @@ describe Gitlab::Prometheus::QueryVariables do ...@@ -7,8 +7,9 @@ describe Gitlab::Prometheus::QueryVariables do
let(:project) { environment.project } let(:project) { environment.project }
let(:environment) { create(:environment) } let(:environment) { create(:environment) }
let(:slug) { environment.slug } let(:slug) { environment.slug }
let(:params) { {} }
subject { described_class.call(environment) } subject { described_class.call(environment, params) }
it { is_expected.to include(ci_environment_slug: slug) } it { is_expected.to include(ci_environment_slug: slug) }
it { is_expected.to include(ci_project_name: project.name) } it { is_expected.to include(ci_project_name: project.name) }
...@@ -53,5 +54,42 @@ describe Gitlab::Prometheus::QueryVariables do ...@@ -53,5 +54,42 @@ describe Gitlab::Prometheus::QueryVariables do
it { is_expected.to include(kube_namespace: kube_namespace) } it { is_expected.to include(kube_namespace: kube_namespace) }
end end
end end
context '__range' do
context 'when start_time and end_time are present' do
let(:params) do
{
start_time: Time.rfc3339('2020-05-29T07:23:05.008Z'),
end_time: Time.rfc3339('2020-05-29T15:23:05.008Z')
}
end
it { is_expected.to include(__range: "#{8.hours.to_i}s") }
end
context 'when start_time and end_time are not present' do
it { is_expected.to include(__range: nil) }
end
context 'when end_time is not present' do
let(:params) do
{
start_time: Time.rfc3339('2020-05-29T07:23:05.008Z')
}
end
it { is_expected.to include(__range: nil) }
end
context 'when start_time is not present' do
let(:params) do
{
end_time: Time.rfc3339('2020-05-29T07:23:05.008Z')
}
end
it { is_expected.to include(__range: nil) }
end
end
end end
end end
...@@ -186,5 +186,19 @@ describe Prometheus::ProxyVariableSubstitutionService do ...@@ -186,5 +186,19 @@ describe Prometheus::ProxyVariableSubstitutionService do
end end
end end
end end
context '__range' do
let(:params_keys) do
{
query: 'topk(5, sum by (method) (rate(rest_client_requests_total[{{__range}}])))',
start_time: '2020-05-29T08:19:07.142Z',
end_time: '2020-05-29T16:19:07.142Z'
}
end
it_behaves_like 'success' do
let(:expected_query) { "topk(5, sum by (method) (rate(rest_client_requests_total[#{8.hours.to_i}s])))" }
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