Matched Metrics tests
This commit is contained in:
parent
7e17d763ac
commit
e74896df0c
5 changed files with 97 additions and 39 deletions
|
@ -3,25 +3,31 @@
|
|||
metrics:
|
||||
- title: "Memory usage"
|
||||
y_label: "Values"
|
||||
detect: container_memory_usage_bytes
|
||||
required_metrics:
|
||||
- container_memory_usage_bytes
|
||||
weight: 1
|
||||
queries:
|
||||
- query_range: 'avg(container_memory_usage_bytes{%{environment_filter}}) / 2^20'
|
||||
label: Container memory
|
||||
display_empty: true
|
||||
unit: MiB
|
||||
- title: "Current memory usage"
|
||||
detect: container_memory_usage_bytes
|
||||
required_metrics:
|
||||
- container_memory_usage_bytes
|
||||
weight: 1
|
||||
queries:
|
||||
- query: 'avg(container_memory_usage_bytes{%{environment_filter}}) / 2^20'
|
||||
display_empty: false
|
||||
unit: MiB
|
||||
- title: "CPU usage"
|
||||
detect: container_cpu_usage_seconds_total
|
||||
required_metrics:
|
||||
- container_cpu_usage_seconds_total
|
||||
weight: 1
|
||||
queries:
|
||||
- query_range: 'avg(rate(container_cpu_usage_seconds_total{%{environment_filter}}[2m])) * 100'
|
||||
- title: "Current CPU usage"
|
||||
detect: container_cpu_usage_seconds_total
|
||||
required_metrics:
|
||||
- container_cpu_usage_seconds_total
|
||||
weight: 1
|
||||
queries:
|
||||
- query: 'avg(rate(container_cpu_usage_seconds_total{%{environment_filter}}[2m])) * 100'
|
||||
|
|
|
@ -1,29 +1,24 @@
|
|||
module Gitlab::Prometheus
|
||||
class Metric
|
||||
attr_reader :group, :title, :detect, :weight, :y_label, :queries
|
||||
attr_reader :group, :title, :required_metrics, :weight, :y_label, :queries
|
||||
|
||||
def initialize(group, title, detect, weight, y_label, queries = [])
|
||||
@group = group
|
||||
def initialize(title, required_metrics, weight, y_label, queries = [])
|
||||
@title = title
|
||||
@detect = detect
|
||||
@required_metrics = required_metrics
|
||||
@weight = weight
|
||||
@y_label = y_label || 'Values'
|
||||
@queries = queries
|
||||
end
|
||||
|
||||
def self.metric_from_entry(group, entry)
|
||||
missing_fields = [:title, :detect, :weight, :queries].select { |key| !entry.has_key?(key) }
|
||||
def self.metric_from_entry(entry)
|
||||
missing_fields = [:title, :required_metrics, :weight, :queries].select { |key| !entry.has_key?(key) }
|
||||
raise ParsingError.new("entry missing required fields #{missing_fields}") unless missing_fields.empty?
|
||||
|
||||
Metric.new(group, entry[:title], entry[:detect], entry[:weight], entry[:y_label],entry[:queries])
|
||||
Metric.new(entry[:title], entry[:required_metrics], entry[:weight], entry[:y_label], entry[:queries])
|
||||
end
|
||||
|
||||
def self.metrics_from_list(group, list)
|
||||
list.map { |entry| metric_from_entry(group, entry) }
|
||||
end
|
||||
|
||||
def self.additional_metrics_raw
|
||||
@additional_metrics_raw ||= YAML.load_file(Rails.root.join('config/additional_metrics.yml')).map(&:deep_symbolize_keys)
|
||||
def self.metrics_from_list(list)
|
||||
list.map { |entry| metric_from_entry(entry) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,7 +22,7 @@ module Gitlab::Prometheus
|
|||
raise ParsingError.new("entry missing required fields #{missing_fields}") unless missing_fields.empty?
|
||||
|
||||
group = MetricGroup.new(entry[:group], entry[:priority])
|
||||
group.metrics = Metric.metrics_from_list(group, entry[:metrics])
|
||||
group.metrics = Metric.metrics_from_list(entry[:metrics])
|
||||
group
|
||||
end
|
||||
|
||||
|
|
|
@ -16,31 +16,28 @@ module Gitlab::Prometheus::Queries
|
|||
private
|
||||
|
||||
def groups_data
|
||||
metrics_series = metrics_with_series(Gitlab::Prometheus::MetricGroup.all)
|
||||
lookup = active_series_lookup(metrics_series)
|
||||
metrics_groups = groups_with_active_metrics(Gitlab::Prometheus::MetricGroup.all)
|
||||
lookup = active_series_lookup(metrics_groups)
|
||||
|
||||
groups = {}
|
||||
|
||||
metrics_series.each do |metrics, series|
|
||||
groups[metrics.group] ||= { active_metrics: 0, metrics_missing_requirements: 0 }
|
||||
group = groups[metrics.group]
|
||||
metrics_groups.each do |group|
|
||||
groups[group] ||= { active_metrics: 0, metrics_missing_requirements: 0 }
|
||||
metrics = group.metrics.flat_map(&:required_metrics)
|
||||
active_metrics = metrics.count(&lookup.method(:has_key?))
|
||||
|
||||
if series.all?(&lookup.method(:has_key?))
|
||||
group[:active_metrics] += 1
|
||||
else
|
||||
group[:metrics_missing_requirements] += 1
|
||||
end
|
||||
group
|
||||
groups[group][:active_metrics] += active_metrics
|
||||
groups[group][:metrics_missing_requirements] += metrics.count - active_metrics
|
||||
end
|
||||
|
||||
groups
|
||||
end
|
||||
|
||||
def active_series_lookup(metrics)
|
||||
def active_series_lookup(metric_groups)
|
||||
timeframe_start = 8.hours.ago
|
||||
timeframe_end = Time.now
|
||||
|
||||
series = metrics.flat_map { |metrics, series| series }.uniq
|
||||
series = metric_groups.flat_map(&:metrics).flat_map(&:required_metrics).uniq
|
||||
|
||||
lookup = series.each_slice(MAX_QUERY_ITEMS).flat_map do |batched_series|
|
||||
client_series(*batched_series, start: timeframe_start, stop: timeframe_end)
|
||||
|
@ -54,17 +51,27 @@ module Gitlab::Prometheus::Queries
|
|||
series_info.has_key?('environment')
|
||||
end
|
||||
|
||||
def metrics_with_series(metric_groups)
|
||||
label_values = client_label_values || []
|
||||
def available_metrics
|
||||
@available_metrics ||= client_label_values || []
|
||||
end
|
||||
|
||||
metrics = metric_groups.flat_map do |group|
|
||||
group.metrics.map do |metric|
|
||||
matcher = Regexp.compile(metric.detect)
|
||||
[metric, label_values.select(&matcher.method(:match))]
|
||||
def filter_active_metrics(metric_group)
|
||||
metric_group.metrics.select! do |metric|
|
||||
metric.required_metrics.all?(&available_metrics.method(:include?))
|
||||
end
|
||||
metric_group
|
||||
end
|
||||
|
||||
def groups_with_active_metrics(metric_groups)
|
||||
metric_groups.map(&method(:filter_active_metrics)).select { |group| group.metrics.any? }
|
||||
end
|
||||
|
||||
def metrics_with_required_series(metric_groups)
|
||||
metric_groups.flat_map do |group|
|
||||
group.metrics.select do |metric|
|
||||
metric.required_metrics.all?(&available_metrics.method(:include?))
|
||||
end
|
||||
end
|
||||
|
||||
metrics.select { |metric, labels| labels&.any? }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::Prometheus::Queries::MatchedMetricsQuery, lib: true do
|
||||
let(:environment) { create(:environment, slug: 'environment-slug') }
|
||||
let(:deployment) { create(:deployment, environment: environment) }
|
||||
|
||||
let(:client) { double('prometheus_client') }
|
||||
subject { described_class.new(client) }
|
||||
|
||||
around do |example|
|
||||
time_without_subsecond_values = Time.local(2008, 9, 1, 12, 0, 0)
|
||||
Timecop.freeze(time_without_subsecond_values) { example.run }
|
||||
end
|
||||
|
||||
let(:metric_group_class) { Gitlab::Prometheus::MetricGroup }
|
||||
let(:metric_class) { Gitlab::Prometheus::Metric }
|
||||
|
||||
let(:simple_metrics) do
|
||||
[
|
||||
metric_class.new('title', ['metrica', 'metricb'], '1', 'y_label', [{ :query_range => 'avg' }])
|
||||
]
|
||||
end
|
||||
|
||||
let(:simple_metric_group) do
|
||||
metric_group_class.new('name', 1, simple_metrics)
|
||||
end
|
||||
|
||||
let(:xx) do
|
||||
[{
|
||||
'__name__': 'metrica',
|
||||
'environment': 'mattermost'
|
||||
},
|
||||
{
|
||||
'__name__': 'metricb',
|
||||
'environment': 'mattermost'
|
||||
}]
|
||||
end
|
||||
|
||||
before do
|
||||
allow(metric_group_class).to receive(:all).and_return([simple_metric_group])
|
||||
|
||||
allow(client).to receive(:label_values).and_return(['metrica', 'metricb'])
|
||||
allow(client).to receive(:series).and_return(xx)
|
||||
end
|
||||
|
||||
it "something something" do
|
||||
|
||||
expect(subject.query).to eq("asf")
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue