debian-mirror-gitlab/app/services/metrics/dashboard/base_service.rb

142 lines
4.2 KiB
Ruby
Raw Normal View History

2019-10-12 21:52:04 +05:30
# frozen_string_literal: true
# Searches a projects repository for a metrics dashboard and formats the output.
# Expects any custom dashboards will be located in `.gitlab/dashboards`
module Metrics
module Dashboard
class BaseService < ::BaseService
include Gitlab::Metrics::Dashboard::Errors
2019-12-04 20:38:33 +05:30
STAGES = ::Gitlab::Metrics::Dashboard::Stages
SEQUENCE = [
STAGES::CommonMetricsInserter,
2020-07-28 23:09:34 +05:30
STAGES::MetricEndpointInserter,
STAGES::VariableEndpointInserter,
2020-04-22 19:07:51 +05:30
STAGES::PanelIdsInserter,
2020-10-24 23:57:45 +05:30
STAGES::TrackPanelType,
2020-06-23 00:09:42 +05:30
STAGES::AlertsInserter,
STAGES::UrlValidator
2019-12-04 20:38:33 +05:30
].freeze
2019-10-12 21:52:04 +05:30
def get_dashboard
return error('Insufficient permissions.', :unauthorized) unless allowed?
success(dashboard: process_dashboard)
rescue StandardError => e
handle_errors(e)
end
# Summary of all known dashboards for the service.
# @return [Array<Hash>] ex) [{ path: String, default: Boolean }]
def self.all_dashboard_paths(_project)
raise NotImplementedError
end
# Returns an un-processed dashboard from the cache.
def raw_dashboard
2020-10-24 23:57:45 +05:30
Gitlab::Metrics::Dashboard::Cache.for(project).fetch(cache_key) { get_raw_dashboard }
2019-10-12 21:52:04 +05:30
end
2020-07-28 23:09:34 +05:30
# Should return true if this dashboard service is for an out-of-the-box
# dashboard.
# This method is overridden in app/services/metrics/dashboard/predefined_dashboard_service.rb.
# @return Boolean
def self.out_of_the_box_dashboard?
false
end
2019-10-12 21:52:04 +05:30
private
# Determines whether users should be able to view
# dashboards at all.
def allowed?
2020-03-13 15:44:24 +05:30
return false unless params[:environment]
2020-05-24 23:13:21 +05:30
project&.feature_available?(:metrics_dashboard, current_user)
2019-10-12 21:52:04 +05:30
end
# Returns a new dashboard Hash, supplemented with DB info
def process_dashboard
2020-04-22 19:07:51 +05:30
# Get the dashboard from cache/disk before beginning the benchmark.
dashboard = raw_dashboard
processed_dashboard = nil
benchmark_processing do
processed_dashboard = ::Gitlab::Metrics::Dashboard::Processor
.new(project, dashboard, sequence, process_params)
.process
end
processed_dashboard
end
def benchmark_processing
output = nil
processing_time_seconds = Benchmark.realtime { output = yield }
if output
processing_time_metric.observe(
processing_time_metric_labels,
processing_time_seconds * 1_000
)
end
2019-10-12 21:52:04 +05:30
end
2020-03-13 15:44:24 +05:30
def process_params
params
end
2019-10-12 21:52:04 +05:30
# @return [String] Relative filepath of the dashboard yml
def dashboard_path
params[:dashboard_path]
end
2020-07-28 23:09:34 +05:30
def load_yaml(data)
::Gitlab::Config::Loader::Yaml.new(data).load_raw!
rescue Gitlab::Config::Loader::Yaml::NotHashError
# Raise more informative error in app/models/performance_monitoring/prometheus_dashboard.rb.
{}
rescue Gitlab::Config::Loader::Yaml::DataTooLargeError => exception
raise Gitlab::Metrics::Dashboard::Errors::LayoutError, exception.message
rescue Gitlab::Config::Loader::FormatError
raise Gitlab::Metrics::Dashboard::Errors::LayoutError, _('Invalid yaml')
end
2019-10-12 21:52:04 +05:30
# @return [Hash] an unmodified dashboard
def get_raw_dashboard
raise NotImplementedError
end
# @return [String]
def cache_key
raise NotImplementedError
end
2019-12-04 20:38:33 +05:30
def sequence
SEQUENCE
2019-10-12 21:52:04 +05:30
end
2020-04-22 19:07:51 +05:30
def processing_time_metric
@processing_time_metric ||= ::Gitlab::Metrics.summary(
:gitlab_metrics_dashboard_processing_time_ms,
'Metrics dashboard processing time in milliseconds'
)
end
def processing_time_metric_labels
{
stages: sequence_string,
service: self.class.name
}
end
# If @sequence is [STAGES::CommonMetricsInserter, STAGES::CustomMetricsInserter],
# this function will output `CommonMetricsInserter-CustomMetricsInserter`.
def sequence_string
sequence.map { |stage_class| stage_class.to_s.split('::').last }.join('-')
end
2019-10-12 21:52:04 +05:30
end
end
end