lib/prometheus/client/rack/collector.rb in prometheus-client-0.2.0 vs lib/prometheus/client/rack/collector.rb in prometheus-client-0.3.0.pre.rc.1

- old
+ new

@@ -1,60 +1,80 @@ +# encoding: UTF-8 + require 'prometheus/client' module Prometheus module Client module Rack + # Collector is a Rack middleware that provides a sample implementation of + # a Prometheus HTTP client API. class Collector attr_reader :app, :registry - def initialize(app, options = {}) + def initialize(app, options = {}, &label_builder) @app = app @registry = options[:registry] || Client.registry + @label_builder = label_builder || proc do |env| + { + method: env['REQUEST_METHOD'].downcase, + path: env['PATH_INFO'].to_s, + } + end - init_metrics + init_request_metrics + init_exception_metrics end def call(env) # :nodoc: trace(env) { @app.call(env) } end - protected + protected - def init_metrics - @requests = @registry.counter(:http_requests_total, 'A counter of the total number of HTTP requests made') - @requests_duration = @registry.counter(:http_request_durations_total_microseconds, 'The total amount of time Rack has spent answering HTTP requests (microseconds).') - @durations = @registry.summary(:http_request_durations_microseconds, 'A histogram of the response latency for requests made (microseconds).') + def init_request_metrics + @requests = @registry.counter( + :http_requests_total, + 'A counter of the total number of HTTP requests made.',) + @requests_duration = @registry.counter( + :http_request_durations_total_microseconds, + 'The total amount of time spent answering HTTP requests ' \ + '(microseconds).',) + @durations = @registry.summary( + :http_request_durations_microseconds, + 'A histogram of the response latency (microseconds).',) end - def trace(env, &block) + def init_exception_metrics + @exceptions = @registry.counter( + :http_exceptions_total, + 'A counter of the total number of exceptions raised.',) + end + + def trace(env) start = Time.now - response = yield + yield.tap do |response| + duration = ((Time.now - start) * 1_000_000).to_i + record(labels(env, response), duration) + end rescue => exception + @exceptions.increment(exception: exception.class.name) raise - ensure - duration = ((Time.now - start) * 1_000_000).to_i - record(duration, env, response, exception) end - def record(duration, env, response, exception) - labels = { - :method => env['REQUEST_METHOD'].downcase, - :path => env['PATH_INFO'].to_s, - } - - if response + def labels(env, response) + @label_builder.call(env).tap do |labels| labels[:code] = response.first.to_s - else - labels[:exception] = exception.class.name end + end + def record(labels, duration) @requests.increment(labels) @requests_duration.increment(labels, duration) @durations.add(labels, duration) - rescue => error + rescue # TODO: log unexpected exception during request recording + nil end - end end end end