class Prometheus::Client::Rack::Exporter

Exporter is a Rack middleware that provides a sample implementation of a Prometheus HTTP client API.

Constants

FALLBACK
FORMATS

Attributes

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

Public Class Methods

new(app, options = {}) click to toggle source
# File lib/prometheus/client/rack/exporter.rb, line 16
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/client/rack/exporter.rb, line 23
def call(env)
  if env['PATH_INFO'] == @path
    format = negotiate(env['HTTP_ACCEPT'], @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/client/rack/exporter.rb, line 86
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/client/rack/exporter.rb, line 53
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(accept, formats) click to toggle source
# File lib/prometheus/client/rack/exporter.rb, line 34
def negotiate(accept, formats)
  accept = '*/*' if accept.to_s.empty?

  parse(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/client/rack/exporter.rb, line 76
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/client/rack/exporter.rb, line 44
def parse(header)
  header.to_s.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/client/rack/exporter.rb, line 63
def respond_with(format)
  response = if Prometheus::Client.configuration.value_class.multiprocess
               format.marshal_multiprocess
             else
               format.marshal
             end
  [
    200,
    { 'Content-Type' => format::CONTENT_TYPE },
    [response],
  ]
end