From 671f698845339563852abcb0b9607632fd8076a6 Mon Sep 17 00:00:00 2001 From: syasonik Date: Wed, 17 Apr 2019 19:37:42 +0800 Subject: Bring in line with EE needs --- .../projects/environments_controller.rb | 2 +- .../metrics_dashboard/common_metrics_inserter.rb | 32 ------- lib/gitlab/metrics_dashboard/processor.rb | 17 ++-- .../metrics_dashboard/project_metrics_inserter.rb | 99 ---------------------- lib/gitlab/metrics_dashboard/service.rb | 4 +- lib/gitlab/metrics_dashboard/sorter.rb | 28 ------ lib/gitlab/metrics_dashboard/stages/base_stage.rb | 39 +++++++++ .../stages/common_metrics_inserter.rb | 21 +++++ .../stages/project_metrics_inserter.rb | 97 +++++++++++++++++++++ lib/gitlab/metrics_dashboard/stages/sorter.rb | 28 ++++++ .../lib/gitlab/metrics_dashboard/processor_spec.rb | 5 +- spec/lib/gitlab/metrics_dashboard/service_spec.rb | 7 +- 12 files changed, 208 insertions(+), 171 deletions(-) delete mode 100644 lib/gitlab/metrics_dashboard/common_metrics_inserter.rb delete mode 100644 lib/gitlab/metrics_dashboard/project_metrics_inserter.rb delete mode 100644 lib/gitlab/metrics_dashboard/sorter.rb create mode 100644 lib/gitlab/metrics_dashboard/stages/base_stage.rb create mode 100644 lib/gitlab/metrics_dashboard/stages/common_metrics_inserter.rb create mode 100644 lib/gitlab/metrics_dashboard/stages/project_metrics_inserter.rb create mode 100644 lib/gitlab/metrics_dashboard/stages/sorter.rb diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 25815b92a0f..52736bcf3f8 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -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: { diff --git a/lib/gitlab/metrics_dashboard/common_metrics_inserter.rb b/lib/gitlab/metrics_dashboard/common_metrics_inserter.rb deleted file mode 100644 index 5bc83e6266e..00000000000 --- a/lib/gitlab/metrics_dashboard/common_metrics_inserter.rb +++ /dev/null @@ -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 diff --git a/lib/gitlab/metrics_dashboard/processor.rb b/lib/gitlab/metrics_dashboard/processor.rb index 518e0123220..14ee12049d0 100644 --- a/lib/gitlab/metrics_dashboard/processor.rb +++ b/lib/gitlab/metrics_dashboard/processor.rb @@ -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 diff --git a/lib/gitlab/metrics_dashboard/project_metrics_inserter.rb b/lib/gitlab/metrics_dashboard/project_metrics_inserter.rb deleted file mode 100644 index f4463645d2c..00000000000 --- a/lib/gitlab/metrics_dashboard/project_metrics_inserter.rb +++ /dev/null @@ -1,99 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module MetricsDashboard - class ProjectMetricsInserter - DEFAULT_PANEL_TYPE = 'area-chart' - - class << self - # Inserts project-specific metrics into the dashboard config. - # If there are no project-specific metrics, this will have no effect. - def transform!(dashboard, project) - 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) - find_or_create_metric(panel[:metrics], project_metric) - end - end - - private - - # Looks for a panel_group corresponding to the provided metric object. - # If unavailable, inserts one. - # @param panel_groups [Array] - # @param metric [PrometheusMetric] - def find_or_create_panel_group(panel_groups, metric) - panel_group = find_panel_group(panel_groups, metric) - return panel_group if panel_group - - panel_group = new_panel_group(metric) - panel_groups << panel_group - - panel_group - end - - # Looks for a panel corresponding to the provided metric object. - # If unavailable, inserts one. - # @param panels [Array] - # @param metric [PrometheusMetric] - def find_or_create_panel(panels, metric) - panel = find_panel(panels, metric) - return panel if panel - - panel = new_panel(metric) - panels << panel - - panel - end - - # Looks for a metric corresponding to the provided metric object. - # If unavailable, inserts one. - # @param metrics [Array] - # @param metric [PrometheusMetric] - def find_or_create_metric(metrics, metric) - target_metric = find_metric(metrics, metric) - return target_metric if target_metric - - target_metric = new_metric(metric) - metrics << target_metric - - target_metric - end - - def find_panel_group(panel_groups, metric) - panel_groups.find { |group| group[:group] == metric.group_title } - end - - def find_panel(panels, metric) - panel_identifiers = [DEFAULT_PANEL_TYPE, metric.title, metric.y_label] - panels.find { |panel| panel.values_at(:type, :title, :y_label) == panel_identifiers } - end - - def find_metric(metrics, metric) - metrics.find { |m| m[:id] == metric.identifier } - end - - def new_panel_group(metric) - { - group: metric.group_title, - priority: metric.priority, - panels: [] - } - end - - def new_panel(metric) - { - type: DEFAULT_PANEL_TYPE, - title: metric.title, - y_label: metric.y_label, - metrics: [] - } - end - - def new_metric(metric) - metric.queries.first.merge(metric_id: metric.id) - end - end - end - end -end diff --git a/lib/gitlab/metrics_dashboard/service.rb b/lib/gitlab/metrics_dashboard/service.rb index 521a3914e9e..01e61b257e2 100644 --- a/lib/gitlab/metrics_dashboard/service.rb +++ b/lib/gitlab/metrics_dashboard/service.rb @@ -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 diff --git a/lib/gitlab/metrics_dashboard/sorter.rb b/lib/gitlab/metrics_dashboard/sorter.rb deleted file mode 100644 index 59b21d207e1..00000000000 --- a/lib/gitlab/metrics_dashboard/sorter.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module MetricsDashboard - class Sorter - class << self - def transform!(dashboard, _project) - sort_groups!(dashboard) - sort_panels!(dashboard) - end - - private - - # Sorts the groups in the dashboard by the :priority key - def sort_groups!(dashboard) - 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) - dashboard[:panel_groups].each do |group| - group[:panels] = group[:panels].sort_by { |panel| -panel[:weight].to_i } - end - end - end - end - end -end diff --git a/lib/gitlab/metrics_dashboard/stages/base_stage.rb b/lib/gitlab/metrics_dashboard/stages/base_stage.rb new file mode 100644 index 00000000000..72085e0c09e --- /dev/null +++ b/lib/gitlab/metrics_dashboard/stages/base_stage.rb @@ -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 diff --git a/lib/gitlab/metrics_dashboard/stages/common_metrics_inserter.rb b/lib/gitlab/metrics_dashboard/stages/common_metrics_inserter.rb new file mode 100644 index 00000000000..e85bdb2700b --- /dev/null +++ b/lib/gitlab/metrics_dashboard/stages/common_metrics_inserter.rb @@ -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 diff --git a/lib/gitlab/metrics_dashboard/stages/project_metrics_inserter.rb b/lib/gitlab/metrics_dashboard/stages/project_metrics_inserter.rb new file mode 100644 index 00000000000..7b694c6e5fa --- /dev/null +++ b/lib/gitlab/metrics_dashboard/stages/project_metrics_inserter.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +module Gitlab + module MetricsDashboard + 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! + 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) + find_or_create_metric(panel[:metrics], project_metric) + end + end + + private + + # Looks for a panel_group corresponding to the provided metric object. + # If unavailable, inserts one. + # @param panel_groups [Array] + # @param metric [PrometheusMetric] + def find_or_create_panel_group(panel_groups, metric) + panel_group = find_panel_group(panel_groups, metric) + return panel_group if panel_group + + panel_group = new_panel_group(metric) + panel_groups << panel_group + + panel_group + end + + # Looks for a panel corresponding to the provided metric object. + # If unavailable, inserts one. + # @param panels [Array] + # @param metric [PrometheusMetric] + def find_or_create_panel(panels, metric) + panel = find_panel(panels, metric) + return panel if panel + + panel = new_panel(metric) + panels << panel + + panel + end + + # Looks for a metric corresponding to the provided metric object. + # If unavailable, inserts one. + # @param metrics [Array] + # @param metric [PrometheusMetric] + def find_or_create_metric(metrics, metric) + target_metric = find_metric(metrics, metric) + return target_metric if target_metric + + target_metric = new_metric(metric) + metrics << target_metric + + target_metric + end + + def find_panel_group(panel_groups, metric) + panel_groups.find { |group| group[:group] == metric.group_title } + end + + def find_panel(panels, metric) + panel_identifiers = [DEFAULT_PANEL_TYPE, metric.title, metric.y_label] + panels.find { |panel| panel.values_at(:type, :title, :y_label) == panel_identifiers } + end + + def find_metric(metrics, metric) + metrics.find { |m| m[:id] == metric.identifier } + end + + def new_panel_group(metric) + { + group: metric.group_title, + priority: metric.priority, + panels: [] + } + end + + def new_panel(metric) + { + type: DEFAULT_PANEL_TYPE, + title: metric.title, + y_label: metric.y_label, + metrics: [] + } + end + + def new_metric(metric) + metric.queries.first.merge(metric_id: metric.id) + end + end + end + end +end diff --git a/lib/gitlab/metrics_dashboard/stages/sorter.rb b/lib/gitlab/metrics_dashboard/stages/sorter.rb new file mode 100644 index 00000000000..74b596038fe --- /dev/null +++ b/lib/gitlab/metrics_dashboard/stages/sorter.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Gitlab + module MetricsDashboard + 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[: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[:panel_groups].each do |group| + group[:panels] = group[:panels].sort_by { |panel| -panel[:weight].to_i } + end + end + end + end + end +end diff --git a/spec/lib/gitlab/metrics_dashboard/processor_spec.rb b/spec/lib/gitlab/metrics_dashboard/processor_spec.rb index 9cf5b00e915..bc5f6527ad7 100644 --- a/spec/lib/gitlab/metrics_dashboard/processor_spec.rb +++ b/spec/lib/gitlab/metrics_dashboard/processor_spec.rb @@ -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 diff --git a/spec/lib/gitlab/metrics_dashboard/service_spec.rb b/spec/lib/gitlab/metrics_dashboard/service_spec.rb index 127fc28bcd6..710c71fd6bd 100644 --- a/spec/lib/gitlab/metrics_dashboard/service_spec.rb +++ b/spec/lib/gitlab/metrics_dashboard/service_spec.rb @@ -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 -- cgit v1.2.1