class Prometheus::Middleware::Exporter

Exporter is a Rack middleware that provides a sample implementation of a Prometheus HTTP exposition endpoint.

By default it will export the state of the global registry and expose it under `/metrics`. Use the `:registry` and `:path` options to change the defaults.

Constants

FALLBACK
FORMATS

Attributes

app[R]
path[R]
registry[R]

Public Class Methods

new(app, options = {}) click to toggle source
# File lib/prometheus/middleware/exporter.rb, line 20
def initialize(app, options = {})
  @app = app
  @registry = options[:registry] || Client.registry
  @path = options[:path] || '/metrics'
  @acceptable = build_dictionary(FORMATS, FALLBACK)
end

Public Instance Methods

call(env) click to toggle source
# File lib/prometheus/middleware/exporter.rb, line 27
def call(env)
  if env['PATH_INFO'] == @path
    format = negotiate(env, @acceptable)
    format ? respond_with(format) : not_acceptable(FORMATS)
  else
    @app.call(env)
  end
end

Private Instance Methods

build_dictionary(formats, fallback) click to toggle source
# File lib/prometheus/middleware/exporter.rb, line 83
def build_dictionary(formats, fallback)
  formats.each_with_object('*/*' => fallback) do |format, memo|
    memo[format::CONTENT_TYPE] = format
    memo[format::MEDIA_TYPE] = format
  end
end
extract_quality(attributes, default = 1.0) click to toggle source
# File lib/prometheus/middleware/exporter.rb, line 55
def extract_quality(attributes, default = 1.0)
  quality = default

  attributes.delete_if do |attr|
    quality = attr.split('q=').last.to_f if attr.start_with?('q=')
  end

  quality
end
negotiate(env, formats) click to toggle source
# File lib/prometheus/middleware/exporter.rb, line 38
def negotiate(env, formats)
  parse(env.fetch('HTTP_ACCEPT', '*/*')).each do |content_type, _|
    return formats[content_type] if formats.key?(content_type)
  end

  nil
end
not_acceptable(formats) click to toggle source
# File lib/prometheus/middleware/exporter.rb, line 73
def not_acceptable(formats)
  types = formats.map { |format| format::MEDIA_TYPE }

  [
    406,
    { 'Content-Type' => 'text/plain' },
    ["Supported media types: #{types.join(', ')}"],
  ]
end
parse(header) click to toggle source
# File lib/prometheus/middleware/exporter.rb, line 46
def parse(header)
  header.split(/\s*,\s*/).map do |type|
    attributes = type.split(/\s*;\s*/)
    quality = extract_quality(attributes)

    [attributes.join('; '), quality]
  end.sort_by(&:last).reverse
end
respond_with(format) click to toggle source
# File lib/prometheus/middleware/exporter.rb, line 65
def respond_with(format)
  [
    200,
    { 'Content-Type' => format::CONTENT_TYPE },
    [format.marshal(@registry)],
  ]
end