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