diff options
author | syasonik <syasonik@gitlab.com> | 2019-04-16 17:09:10 +0800 |
---|---|---|
committer | syasonik <syasonik@gitlab.com> | 2019-04-24 18:23:03 +0800 |
commit | 35c412327cd0a0897d4d81aa80c88782c98fdd89 (patch) | |
tree | f593de4da583df8bccb9a9e2153d33f9a6e7c288 /lib | |
parent | d307f446d807b03ddc7d55705df5602c275e61fb (diff) | |
download | gitlab-ce-35c412327cd0a0897d4d81aa80c88782c98fdd89.tar.gz |
Refactor dashboard proccesing into stages
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/metrics_dashboard/common_metrics_inserter.rb | 32 | ||||
-rw-r--r-- | lib/gitlab/metrics_dashboard/processor.rb | 20 | ||||
-rw-r--r-- | lib/gitlab/metrics_dashboard/project_metrics_inserter.rb | 70 | ||||
-rw-r--r-- | lib/gitlab/metrics_dashboard/service.rb | 37 | ||||
-rw-r--r-- | lib/gitlab/metrics_dashboard/sorter.rb | 26 |
5 files changed, 185 insertions, 0 deletions
diff --git a/lib/gitlab/metrics_dashboard/common_metrics_inserter.rb b/lib/gitlab/metrics_dashboard/common_metrics_inserter.rb new file mode 100644 index 00000000000..5bc83e6266e --- /dev/null +++ b/lib/gitlab/metrics_dashboard/common_metrics_inserter.rb @@ -0,0 +1,32 @@ +# 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 new file mode 100644 index 00000000000..9e254aa2b37 --- /dev/null +++ b/lib/gitlab/metrics_dashboard/processor.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Gitlab + module MetricsDashboard + class Processor + STAGES = [CommonMetricsInserter, Sorter, ProjectMetricsInserter] + + def initialize(dashboard, project) + @dashboard = dashboard.deep_transform_keys(&:to_sym) + @project = project + end + + def process + STAGES.each { |stage| stage.transform!(@dashboard, @project) } + + @dashboard.to_json + end + end + end +end diff --git a/lib/gitlab/metrics_dashboard/project_metrics_inserter.rb b/lib/gitlab/metrics_dashboard/project_metrics_inserter.rb new file mode 100644 index 00000000000..67300c79e57 --- /dev/null +++ b/lib/gitlab/metrics_dashboard/project_metrics_inserter.rb @@ -0,0 +1,70 @@ +# 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 + + # Looks for an instance of the named resource corresponding to the provided + # metric object. If unavailable, inserts one. + # @param name [Symbol, String] One of :panel_group, :panel, or :metric + # @param existing_resources [Array<Hash>] + # @param metric [PrometheusMetric] + def find_or_create(name, existing_resources, metric) + target = self.send("find_#{name}", existing_resources, metric) + return target if target + + target = self.send("new_#{name}", metric) + existing_resources << target + + target + 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] + target_panel = 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 new file mode 100644 index 00000000000..22e1771cbea --- /dev/null +++ b/lib/gitlab/metrics_dashboard/service.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# Fetches the metrics dashboard layout and supplemented the output with DB info. +module Gitlab + module MetricsDashboard + class Service + SYSTEM_DASHBOARD_NAME = 'common_metrics' + SYSTEM_DASHBOARD_PATH = Rails.root.join('config', 'prometheus', "#{SYSTEM_DASHBOARD_NAME}.yml") + + def initialize(project) + @project = project + end + + # Returns a DB-supplemented json representation of a dashboard config file. + def get_dashboard + dashboard = Rails.cache.fetch(cache_key) { system_dashboard } + + process_dashboard(dashboard) + end + + private + + # Returns the base metrics shipped with every GitLab service. + def system_dashboard + YAML.load_file(SYSTEM_DASHBOARD_PATH) + end + + def cache_key + "metrics_dashboard_#{SYSTEM_DASHBOARD_NAME}" + end + + def process_dashboard(dashboard) + Processor.new(dashboard, @project).process + end + end + end +end diff --git a/lib/gitlab/metrics_dashboard/sorter.rb b/lib/gitlab/metrics_dashboard/sorter.rb new file mode 100644 index 00000000000..ba30c1e4656 --- /dev/null +++ b/lib/gitlab/metrics_dashboard/sorter.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Gitlab + module MetricsDashboard + class Sorter + class << self + def transform!(dashboard, _project) + sort_groups!(dashboard) + sort_panels!(dashboard) + end + + # 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] } + 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] } + end + end + end + end + end +end |