class Prometheus::FortyTwo::Collector

Collector is a Rack middleware that improves on the basic collector provided by the prometheus-client gem.

By default, the original collector will strip routes of their ids assuming they are either numeric or uuids. Set the `:specific_id_stripper` option to provide a specific method to strip ids from urls and replace them by a generic label. The lambda will receive the route as a string before the default stripper strips the ids from it, and should return the cleaned up route.

use(
  Prometheus::Client::FortyTwo::Middleware::Collector,
  specific_id_stripper: lambda { |path|
    path
      .gsub(%r{/users/[^/]*}, '/users/:name')
      .gsub(%r{/[en|es|fr]/}, '/:locale/')
  }
)

# '/en/users/albert/posts/10/articles'
# '/fr/users/julie/posts/223/articles'
# '/es/users/zoe/posts/68/articles'
# would be stripped as one route:
# '/:locale/users/:name/posts/:id/articles'

If the cleaner fails, the collector will not and only use the original strip function.

When your rails server serves static files, those requests are not necessarily very relevant to your stats. Set the `:static_files_path` option to make the middleware list those files on startup and ignore them. If the directory does not exist or an exception is raised when discovering it, the Collector will just ignore it and start anyways.

use(
  Prometheus::Client::FortyTwo::Middleware::Collector,
  static_files_path: File.join(File.dirname(__FILE__), 'public')
)

# all routes pointing to /public will be ignored

Some of your app routes might not be relevant to your stats either (ie. /metrics, or /assets/*/ paths). Set the `:irrelevant_paths` option to provide a method that will match paths you want to ignore.

use(
  Prometheus::Client::FortyTwo::Middleware::Collector,
  irrelevant_paths: labmda { |path|
    path == '/metrics' ||
    path =~ %r{\A/assets/}
  }
)

Public Class Methods

new(app, options = {}) click to toggle source
Calls superclass method
# File lib/prometheus/forty_two/collector.rb, line 65
def initialize(app, options = {})
  super

  @static_files = self.class.find_static_files(options[:static_files_path])
  @irrelevant_paths = options[:irrelevant_paths] || ->(_path) { false }
  @specific_id_stripper = options[:specific_id_stripper] || ->(path) { path }
end

Protected Class Methods

find_static_files(path) click to toggle source
# File lib/prometheus/forty_two/collector.rb, line 101
def find_static_files(path)
  find_static_files!(path)
rescue StandardError
  []
end
find_static_files!(path) click to toggle source
# File lib/prometheus/forty_two/collector.rb, line 107
def find_static_files!(path)
  return [] unless path

  path = path.gsub(%r{/+\z}, '')
  path_matcher = %r{\A#{Regexp.escape(path)}/}
  Find
    .find(path)
    .select { |f| File.file?(f) }
    .map { |f| f.gsub(path_matcher, '/') }
end

Public Instance Methods

call(env) click to toggle source
Calls superclass method
# File lib/prometheus/forty_two/collector.rb, line 73
def call(env)
  return @app.call(env) if ignore_path?(env['PATH_INFO'])

  super
end

Protected Instance Methods

ignore_path?(path) click to toggle source
# File lib/prometheus/forty_two/collector.rb, line 90
def ignore_path?(path)
  @static_files.include?(path) || irrelevant_path?(path)
end
irrelevant_path?(path) click to toggle source
# File lib/prometheus/forty_two/collector.rb, line 94
def irrelevant_path?(path)
  @irrelevant_paths.call(path)
rescue StandardError
  false
end
strip_ids_from_path(path) click to toggle source
Calls superclass method
# File lib/prometheus/forty_two/collector.rb, line 81
def strip_ids_from_path(path)
  stripped_path = super
  begin
    @specific_id_stripper.call(stripped_path)
  rescue StandardError
    stripped_path
  end
end