Bring in line with EE needs

This commit is contained in:
syasonik 2019-04-17 19:37:42 +08:00
parent f029c3dd39
commit 671f698845
10 changed files with 93 additions and 56 deletions

View file

@ -162,7 +162,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
respond_to do |format|
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
render status: :ok, json: {

View file

@ -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

View file

@ -3,17 +3,24 @@
module Gitlab
module MetricsDashboard
class Processor
STAGES = [CommonMetricsInserter, ProjectMetricsInserter, Sorter].freeze
def initialize(dashboard, project)
def initialize(dashboard, project, environment)
@dashboard = dashboard.deep_transform_keys(&:to_sym)
@project = project
@environment = environment
end
def stages
@stages ||= [
Stages::CommonMetricsInserter,
Stages::ProjectMetricsInserter,
Stages::Sorter
].freeze
end
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

View file

@ -11,7 +11,7 @@ module Gitlab
def get_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)
end
@ -28,7 +28,7 @@ module Gitlab
end
def process_dashboard(dashboard)
Processor.new(dashboard, @project).process
Processor.new(dashboard, project, params[:environment]).process
end
end
end

View 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

View file

@ -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

View file

@ -2,13 +2,11 @@
module Gitlab
module MetricsDashboard
class ProjectMetricsInserter
DEFAULT_PANEL_TYPE = 'area-chart'
class << self
module Stages
class ProjectMetricsInserter < BaseStage
# Inserts project-specific metrics into the dashboard config.
# 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|
group = find_or_create_panel_group(dashboard[:panel_groups], project_metric)
panel = find_or_create_panel(group[:panels], project_metric)

View file

@ -2,22 +2,22 @@
module Gitlab
module MetricsDashboard
class Sorter
class << self
def transform!(dashboard, _project)
sort_groups!(dashboard)
sort_panels!(dashboard)
module Stages
class Sorter < BaseStage
def transform!
sort_groups!
sort_panels!
end
private
# 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 }
end
# Sorts the panels in the dashboard by the :weight key
def sort_panels!(dashboard)
def sort_panels!
dashboard[:panel_groups].each do |group|
group[:panels] = group[:panels].sort_by { |panel| -panel[:weight].to_i }
end

View file

@ -4,10 +4,12 @@ require 'spec_helper'
describe Gitlab::MetricsDashboard::Processor do
let(:project) { build(:project) }
let(:environment) { build(:environment) }
let(:dashboard_yml) { YAML.load_file('spec/fixtures/lib/gitlab/metrics_dashboard/sample_dashboard.yml') }
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
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' }
expect(target_metric).to include(:metric_id)
expect(target_metric[:metric_id]).to eq(common_metric.id)
end
end

View file

@ -4,12 +4,13 @@ require 'spec_helper'
describe Gitlab::MetricsDashboard::Service, :use_clean_rails_memory_store_caching do
let(:project) { build(:project) }
let(:environment) { build(:environment) }
describe 'get_dashboard' do
let(:dashboard_schema) { JSON.parse(fixture_file('lib/gitlab/metrics_dashboard/schemas/dashboard.json')) }
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[: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
expect(YAML).to receive(:load_file).once.and_call_original
described_class.new(project).get_dashboard
described_class.new(project).get_dashboard
described_class.new(project, environment).get_dashboard
described_class.new(project, environment).get_dashboard
end
end
end