diff options
author | Pawel Chojnacki <pawel@chojnacki.ws> | 2018-01-16 14:06:56 +0100 |
---|---|---|
committer | Pawel Chojnacki <pawel@chojnacki.ws> | 2018-01-29 15:13:03 +0100 |
commit | 53f818fdac35d1c0810faa81a8dde20bbf8a3697 (patch) | |
tree | 7112880079fe0ed6daaa5bb6af797d56d3b4da60 /lib/gitlab/metrics | |
parent | e56b3d180dc9b251f00f0611435a6f25d708d2b6 (diff) | |
download | gitlab-ce-53f818fdac35d1c0810faa81a8dde20bbf8a3697.tar.gz |
Refactor method concern to use hashes
Diffstat (limited to 'lib/gitlab/metrics')
-rw-r--r-- | lib/gitlab/metrics/concern.rb | 138 | ||||
-rw-r--r-- | lib/gitlab/metrics/concern/metric_options.rb | 48 |
2 files changed, 135 insertions, 51 deletions
diff --git a/lib/gitlab/metrics/concern.rb b/lib/gitlab/metrics/concern.rb index 940337deb74..a9c45380a5d 100644 --- a/lib/gitlab/metrics/concern.rb +++ b/lib/gitlab/metrics/concern.rb @@ -2,86 +2,122 @@ module Gitlab module Metrics module Concern extend ActiveSupport::Concern + + included do + @@_metrics_provider_mutex ||= Mutex.new + @@_metrics_provider_cache ||= {} + end + class_methods do private - def metrics_provider(type, name, docstring, options = {}) - @@_metrics_provider_mutex ||= Mutex.new - + def define_metric(type, name, opts = {}, &block) if instance_methods(false).include?(name) raise ArgumentError, "metrics method #{name} already exists" end - options[:base_labels] ||= {} - args = [name.inspect, %{"#{docstring}"}, options[:base_labels].inspect] + define_method(name) do + # avoid unnecessary method call to speed up metric access + return @@_metrics_provider_cache[name] if @@_metrics_provider_cache.has_key?(name) + + fetch_metric(type, name, opts, &block) + end + end + + def fetch_metric(type, name, opts = {}, &block) + # avoid synchronization to speed up metrics access + return @@_metrics_provider_cache[name] if @@_metrics_provider_cache.has_key?(name) + + options = MetricOptions.new(opts) + options.evaluate(&block) + + @@_metrics_provider_mutex.synchronize do + @@_metrics_provider_cache[name] ||= build_metric!(type, name, options) + end + + @@_metrics_provider_cache[name] + end + + def build_metric!(type, name, options) + unless options.with_feature.nil? || Feature.get(options.with_feature).enabled? + return NullMetric.new + end case type when :gauge - options[:multiprocess_mode] ||= :all - args << options[:multiprocess_mode].inspect + Gitlab::Metrics.gauge(name, options.docs, options.base_labels, options.multiprocess_mode) + when :counter + Gitlab::Metrics.counter(name, options.docs, options.base_labels) when :histogram options[:buckets] ||= ::Prometheus::Client::Histogram::DEFAULT_BUCKETS - args << options[:buckets].inspect + Gitlab::Metrics.histogram(name, options.docs, options.base_labels, options.buckets) + when :summary + raise NotImplementedError, "summary metrics are not currently supported" + else + raise ArgumentError, "uknown metric type #{type}" end + end - metric_fetching_code = %{Gitlab::Metrics.#{type}(#{args.join(', ')})} - - # optionally wrap in feature - if options[:with_feature].is_a?(Symbol) - metric_fetching_code = <<-FETCH.strip_heredoc - if Feature.get(#{options[:with_feature].inspect}).enabled? - #{metric_fetching_code} - else - Gitlab::Metrics::NullMetric.new - end - FETCH - end + counter :global do + docstring "Global counter" + multiprocess_mode :all + buckets [0, 1] + end - method_code, line = <<-METRIC, __LINE__ + 1 - @@_metric_provider_cached_#{name} = nil - def #{name} - return @@_metric_provider_cached_#{name} if @@_metric_provider_cached_#{name} + # Fetch and/or initialize counter metric + # @param [Symbol] name + # @param [Hash] opts + def fetch_counter(name, opts = {}, &block) + define_metric(:counter, name, opts, &block) + end - @@_metrics_provider_mutex.synchronize do - @@_metric_provider_cached_#{name} ||= #{metric_fetching_code} - end - end + # DFetch and/or initialize gauge metric + # @param [Symbol] name + # @param [Hash] opts + def fetch_gauge(name, opts = {}, &block) + define_metric(:counter, name, opts, &block) + end - def reload_#{name}! - @@_metric_provider_cached_#{name} = nil - end - METRIC + # Fetch and/or initialize histogram metric + # @param [Symbol] name + # @param [Hash] opts + def fetch_histogram(name, opts = {}, &block) + define_metric(:histogram, name, opts, &block) + end - instance_eval(method_code, __FILE__, line) - module_eval(method_code, __FILE__, line) + # Fetch and/or initialize summary metric + # @param [Symbol] name + # @param [Hash] opts + def fetch_summary(name, opts = {}, &block) + define_metric(:summary, name, opts, &block) end - # Declare a Counter + # Define metric accessor method for a Counter # @param [Symbol] name - # @param [String] docstring - # @param [Hash] options - def counter(name, docstring, options = {}) - metrics_provider(:counter, name, docstring, options) + # @param [Hash] opts + def define_counter(name, opts = {}, &block) + define_metric(:counter, name, opts, &block) end - # Declare a Gauge + # Define metric accessor method for a Gauge # @param [Symbol] name - # @param [String] docstring - # @param [Hash] options - def gauge(name, docstring, options = {}) - metrics_provider(:counter, name, docstring, options) + # @param [Hash] opts + def define_gauge(name, opts = {}, &block) + define_metric(:counter, name, opts, &block) end - # Declare a Histograam + # Define metric accessor method for a Histogram # @param [Symbol] name - # @param [String] docstring - # @param [Hash] options - def histogram(name, docstring, options = {}) - metrics_provider(:histogram, name, docstring, options) + # @param [Hash] opts + def define_histogram(name, opts = {}, &block) + define_metric(:histogram, name, opts, &block) end - def summary(*args) - raise NotImplementedError, "summary metrics are not currently supported" + # Define metric accessor method for a Summary + # @param [Symbol] name + # @param [Hash] opts + def define_summary(name, opts = {}, &block) + define_metric(:summary, name, opts, &block) end end end diff --git a/lib/gitlab/metrics/concern/metric_options.rb b/lib/gitlab/metrics/concern/metric_options.rb new file mode 100644 index 00000000000..502805c135a --- /dev/null +++ b/lib/gitlab/metrics/concern/metric_options.rb @@ -0,0 +1,48 @@ +module Gitlab + module Metrics + module Concern + class MetricOptions + def initialize(options = {}) + @multiprocess_mode = options[:multiprocess_mode] || :all + @buckets = options[:buckets] || ::Prometheus::Client::Histogram::DEFAULT_BUCKETS + @base_labels = options[:base_labels] || {} + end + + def docs(docs = nil) + @docs = docs unless docs.nil? + + @docs + end + + def multiprocess_mode(mode) + @multiprocess_mode = mode unless @multiprocess_mode.nil? + + @multiprocess_mode + end + + def buckets(buckets) + @buckets = buckets unless @buckets.nil? + + @buckets + end + + def base_labels(base_labels) + @base_labels = base_labels unless @base_labels.nil? + + @base_labels + end + + def with_feature(name) + @feature_name = name unless @feature_name.nil? + + @feature_name + end + + def evaluate(&block) + instance_eval(&block) if block_given? + self + end + end + end + end +end |