class PrometheusAggregator::RackMiddleware

Public Class Methods

new(app, options = {}) click to toggle source
# File lib/prometheus_aggregator/rack_middleware.rb, line 7
def initialize(app, options = {})
  @app = app
  @client = options[:client]
  raise ArgumentError, ":client option is required" unless @client
end

Public Instance Methods

call(env) click to toggle source
# File lib/prometheus_aggregator/rack_middleware.rb, line 13
def call(env)
  start_time = Time.now
  response = @app.call(env)
  duration = Time.now - start_time

  begin
    @client.counter(
      name: "http_server_requests_total",
      help: "The total number of HTTP requests handled by the Rack app",
      value: 1,
      labels: labels(env).merge(code: response.first.to_s)
    )

    @client.histogram(
      name: "http_server_request_duration_seconds",
      help: "The HTTP response duration of the Rack application",
      value: duration,
      labels: labels(env)
    )
  rescue => err # rubocop:disable Style/RescueStandardError
    # Let's be ultra defensive. Metrics should never break the app.
    PrometheusAggregator.logger.error("RackMiddleware: #{err}")
  end

  response
end
clean_path(path) click to toggle source
# File lib/prometheus_aggregator/rack_middleware.rb, line 47
def clean_path(path)
  path.gsub(%r{/\d+/}, "/:id/").gsub(%r{/\d+$}, "/:id")
end
labels(env) click to toggle source
# File lib/prometheus_aggregator/rack_middleware.rb, line 40
def labels(env)
  {
    method: env["REQUEST_METHOD"].downcase,
    path: clean_path(env["PATH_INFO"])
  }
end