Bring in line with EE needs
This commit is contained in:
parent
f029c3dd39
commit
671f698845
10 changed files with 93 additions and 56 deletions
|
@ -162,7 +162,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json do
|
format.json do
|
||||||
result = Gitlab::MetricsDashboard::Service.new(@project).get_dashboard
|
result = Gitlab::MetricsDashboard::Service.new(@project, @current_user, environment: environment).get_dashboard
|
||||||
|
|
||||||
if result[:status] == :success
|
if result[:status] == :success
|
||||||
render status: :ok, json: {
|
render status: :ok, json: {
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Gitlab
|
|
||||||
module MetricsDashboard
|
|
||||||
class CommonMetricsInserter
|
|
||||||
class << self
|
|
||||||
# For each metric in the dashboard config, attempts to find a corresponding
|
|
||||||
# database record. If found, includes the record's id in the dashboard config.
|
|
||||||
def transform!(dashboard, _project)
|
|
||||||
common_metrics = ::PrometheusMetric.common
|
|
||||||
|
|
||||||
for_metrics(dashboard) do |metric|
|
|
||||||
metric_record = common_metrics.find { |m| m.identifier == metric[:id] }
|
|
||||||
metric[:metric_id] = metric_record.id if metric_record
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def for_metrics(dashboard)
|
|
||||||
dashboard[:panel_groups].each do |panel_group|
|
|
||||||
panel_group[:panels].each do |panel|
|
|
||||||
panel[:metrics].each do |metric|
|
|
||||||
yield metric
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -3,17 +3,24 @@
|
||||||
module Gitlab
|
module Gitlab
|
||||||
module MetricsDashboard
|
module MetricsDashboard
|
||||||
class Processor
|
class Processor
|
||||||
STAGES = [CommonMetricsInserter, ProjectMetricsInserter, Sorter].freeze
|
def initialize(dashboard, project, environment)
|
||||||
|
|
||||||
def initialize(dashboard, project)
|
|
||||||
@dashboard = dashboard.deep_transform_keys(&:to_sym)
|
@dashboard = dashboard.deep_transform_keys(&:to_sym)
|
||||||
@project = project
|
@project = project
|
||||||
|
@environment = environment
|
||||||
|
end
|
||||||
|
|
||||||
|
def stages
|
||||||
|
@stages ||= [
|
||||||
|
Stages::CommonMetricsInserter,
|
||||||
|
Stages::ProjectMetricsInserter,
|
||||||
|
Stages::Sorter
|
||||||
|
].freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
def process
|
def process
|
||||||
STAGES.each { |stage| stage.transform!(@dashboard, @project) }
|
stages.each { |stage| stage.new(@dashboard, @project, @environment).transform! }
|
||||||
|
|
||||||
@dashboard.to_json
|
@dashboard
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,7 @@ module Gitlab
|
||||||
def get_dashboard
|
def get_dashboard
|
||||||
dashboard_string = Rails.cache.fetch(cache_key) { system_dashboard }
|
dashboard_string = Rails.cache.fetch(cache_key) { system_dashboard }
|
||||||
|
|
||||||
dashboard = JSON.parse(process_dashboard(dashboard_string))
|
dashboard = process_dashboard(dashboard_string)
|
||||||
|
|
||||||
success(dashboard: dashboard)
|
success(dashboard: dashboard)
|
||||||
end
|
end
|
||||||
|
@ -28,7 +28,7 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_dashboard(dashboard)
|
def process_dashboard(dashboard)
|
||||||
Processor.new(dashboard, @project).process
|
Processor.new(dashboard, project, params[:environment]).process
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
39
lib/gitlab/metrics_dashboard/stages/base_stage.rb
Normal file
39
lib/gitlab/metrics_dashboard/stages/base_stage.rb
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Gitlab
|
||||||
|
module MetricsDashboard
|
||||||
|
module Stages
|
||||||
|
class BaseStage
|
||||||
|
DEFAULT_PANEL_TYPE = 'area-chart'
|
||||||
|
|
||||||
|
attr_reader :dashboard, :project, :environment
|
||||||
|
|
||||||
|
def initialize(dashboard, project, environment)
|
||||||
|
@dashboard = dashboard
|
||||||
|
@project = project
|
||||||
|
@environment = environment
|
||||||
|
end
|
||||||
|
|
||||||
|
# Entry-point to the stage
|
||||||
|
# @param dashboard [Hash]
|
||||||
|
# @param project [Project]
|
||||||
|
# @param environment [Environment]
|
||||||
|
def transform!
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def for_metrics
|
||||||
|
dashboard[:panel_groups].each do |panel_group|
|
||||||
|
panel_group[:panels].each do |panel|
|
||||||
|
panel[:metrics].each do |metric|
|
||||||
|
yield metric
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,21 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Gitlab
|
||||||
|
module MetricsDashboard
|
||||||
|
module Stages
|
||||||
|
class CommonMetricsInserter < BaseStage
|
||||||
|
# For each metric in the dashboard config, attempts to
|
||||||
|
# find a corresponding database record. If found,
|
||||||
|
# includes the record's id in the dashboard config.
|
||||||
|
def transform!
|
||||||
|
common_metrics = ::PrometheusMetric.common
|
||||||
|
|
||||||
|
for_metrics do |metric|
|
||||||
|
metric_record = common_metrics.find { |m| m.identifier == metric[:id] }
|
||||||
|
metric[:metric_id] = metric_record.id if metric_record
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,13 +2,11 @@
|
||||||
|
|
||||||
module Gitlab
|
module Gitlab
|
||||||
module MetricsDashboard
|
module MetricsDashboard
|
||||||
class ProjectMetricsInserter
|
module Stages
|
||||||
DEFAULT_PANEL_TYPE = 'area-chart'
|
class ProjectMetricsInserter < BaseStage
|
||||||
|
|
||||||
class << self
|
|
||||||
# Inserts project-specific metrics into the dashboard config.
|
# Inserts project-specific metrics into the dashboard config.
|
||||||
# If there are no project-specific metrics, this will have no effect.
|
# If there are no project-specific metrics, this will have no effect.
|
||||||
def transform!(dashboard, project)
|
def transform!
|
||||||
project.prometheus_metrics.each do |project_metric|
|
project.prometheus_metrics.each do |project_metric|
|
||||||
group = find_or_create_panel_group(dashboard[:panel_groups], project_metric)
|
group = find_or_create_panel_group(dashboard[:panel_groups], project_metric)
|
||||||
panel = find_or_create_panel(group[:panels], project_metric)
|
panel = find_or_create_panel(group[:panels], project_metric)
|
|
@ -2,22 +2,22 @@
|
||||||
|
|
||||||
module Gitlab
|
module Gitlab
|
||||||
module MetricsDashboard
|
module MetricsDashboard
|
||||||
class Sorter
|
module Stages
|
||||||
class << self
|
class Sorter < BaseStage
|
||||||
def transform!(dashboard, _project)
|
def transform!
|
||||||
sort_groups!(dashboard)
|
sort_groups!
|
||||||
sort_panels!(dashboard)
|
sort_panels!
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Sorts the groups in the dashboard by the :priority key
|
# Sorts the groups in the dashboard by the :priority key
|
||||||
def sort_groups!(dashboard)
|
def sort_groups!
|
||||||
dashboard[:panel_groups] = dashboard[:panel_groups].sort_by { |group| -group[:priority].to_i }
|
dashboard[:panel_groups] = dashboard[:panel_groups].sort_by { |group| -group[:priority].to_i }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sorts the panels in the dashboard by the :weight key
|
# Sorts the panels in the dashboard by the :weight key
|
||||||
def sort_panels!(dashboard)
|
def sort_panels!
|
||||||
dashboard[:panel_groups].each do |group|
|
dashboard[:panel_groups].each do |group|
|
||||||
group[:panels] = group[:panels].sort_by { |panel| -panel[:weight].to_i }
|
group[:panels] = group[:panels].sort_by { |panel| -panel[:weight].to_i }
|
||||||
end
|
end
|
|
@ -4,10 +4,12 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe Gitlab::MetricsDashboard::Processor do
|
describe Gitlab::MetricsDashboard::Processor do
|
||||||
let(:project) { build(:project) }
|
let(:project) { build(:project) }
|
||||||
|
let(:environment) { build(:environment) }
|
||||||
let(:dashboard_yml) { YAML.load_file('spec/fixtures/lib/gitlab/metrics_dashboard/sample_dashboard.yml') }
|
let(:dashboard_yml) { YAML.load_file('spec/fixtures/lib/gitlab/metrics_dashboard/sample_dashboard.yml') }
|
||||||
|
|
||||||
describe 'process' do
|
describe 'process' do
|
||||||
let(:dashboard) { JSON.parse(described_class.new(dashboard_yml, project).process, symbolize_names: true) }
|
let(:process_params) { [dashboard_yml, project, environment] }
|
||||||
|
let(:dashboard) { described_class.new(*process_params).process }
|
||||||
|
|
||||||
context 'when dashboard config corresponds to common metrics' do
|
context 'when dashboard config corresponds to common metrics' do
|
||||||
let!(:common_metric) { create(:prometheus_metric, :common, identifier: 'metric_a1') }
|
let!(:common_metric) { create(:prometheus_metric, :common, identifier: 'metric_a1') }
|
||||||
|
@ -16,6 +18,7 @@ describe Gitlab::MetricsDashboard::Processor do
|
||||||
target_metric = all_metrics.find { |metric| metric[:id] == 'metric_a1' }
|
target_metric = all_metrics.find { |metric| metric[:id] == 'metric_a1' }
|
||||||
|
|
||||||
expect(target_metric).to include(:metric_id)
|
expect(target_metric).to include(:metric_id)
|
||||||
|
expect(target_metric[:metric_id]).to eq(common_metric.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,13 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe Gitlab::MetricsDashboard::Service, :use_clean_rails_memory_store_caching do
|
describe Gitlab::MetricsDashboard::Service, :use_clean_rails_memory_store_caching do
|
||||||
let(:project) { build(:project) }
|
let(:project) { build(:project) }
|
||||||
|
let(:environment) { build(:environment) }
|
||||||
|
|
||||||
describe 'get_dashboard' do
|
describe 'get_dashboard' do
|
||||||
let(:dashboard_schema) { JSON.parse(fixture_file('lib/gitlab/metrics_dashboard/schemas/dashboard.json')) }
|
let(:dashboard_schema) { JSON.parse(fixture_file('lib/gitlab/metrics_dashboard/schemas/dashboard.json')) }
|
||||||
|
|
||||||
it 'returns a json representation of the environment dashboard' do
|
it 'returns a json representation of the environment dashboard' do
|
||||||
result = described_class.new(project).get_dashboard
|
result = described_class.new(project, environment).get_dashboard
|
||||||
|
|
||||||
expect(result.keys).to contain_exactly(:dashboard, :status)
|
expect(result.keys).to contain_exactly(:dashboard, :status)
|
||||||
expect(result[:status]).to eq(:success)
|
expect(result[:status]).to eq(:success)
|
||||||
|
@ -20,8 +21,8 @@ describe Gitlab::MetricsDashboard::Service, :use_clean_rails_memory_store_cachin
|
||||||
it 'caches the dashboard for subsequent calls' do
|
it 'caches the dashboard for subsequent calls' do
|
||||||
expect(YAML).to receive(:load_file).once.and_call_original
|
expect(YAML).to receive(:load_file).once.and_call_original
|
||||||
|
|
||||||
described_class.new(project).get_dashboard
|
described_class.new(project, environment).get_dashboard
|
||||||
described_class.new(project).get_dashboard
|
described_class.new(project, environment).get_dashboard
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue