Flexible StatsD instrumentation for Rails, Rack, Grape and more
Ruby HTML CSS JavaScript Other
Latest commit 6248acc Apr 26, 2017 @guyisra guyisra committed on GitHub Merge pull request #16 from meh-meh-k/support-grape-0-18-route_xxx-me…

Support new Grape route methods syntax
Failed to load latest commit information.
bin start over Mar 20, 2016
integration fix multiverse tests, part 2 Apr 3, 2016
lib Support new Grape route methods syntax Apr 26, 2017
spec handle #14 (#15) Dec 15, 2016
.gitignore more testing, better rack compatibility Mar 23, 2016
Guardfile start over Mar 20, 2016
README.md Merge pull request #9 from guyisra/no_host_format Oct 15, 2016



Build Status Coverage Status

Vitals is your one stop shop for metrics in Ruby and Ruby Web and API frameworks. It currently support Rails, Rack (Sinatra and any Rack-supported frameworks), and Grape.


Add this line to your application's Gemfile:

gem 'vitals'

And then execute:

$ bundle

Or install it yourself as:

$ gem install vitals


Rails or Grape

Make an initializers/vitals.rb initializer, and configure Vitals as you'd like:

require 'vitals'
Vitals.configure! do |c|
  c.facility = 'my_service'
  c.reporter = Vitals::Reporters::StatsdReporter.new(host: 'statsd-host', port: 8125)

# Rails
require 'vitals/integrations/notifications/action_controller'

# if you also want ActiveJob metrics
require 'vitals/integrations/notifications/action_job'

# Grape
require 'vitals/integrations/notifications/grape'

You can shortcircuit the notifications configuration by using subscribe! right after configuring:

require 'vitals'
Vitals.configure! do |c|
  c.facility = 'my_service'
  c.reporter = Vitals::Reporters::StatsdReporter.new(host: 'statsd-host', port: 8125)
# Subscribe to Rails' controllers, background jobs, and grape's API controllers
Vitals.subscribe!(:action_controller, :active_job, :grape)


You can use the Requests middleware for pure Rack apps or Sinatra, Rails, and Grape instead of, or in addition to, using the notification based instrumentation. Here is a sample Sinatra app:

require 'vitals'
require 'vitals/integrations/rack/requests'

class SinatraTestAPI < Sinatra::Base
  use Vitals::Integrations::Rack::Requests

  get '/foo/bar/baz' do
    sleep 0.1
    "hello get"

  post '/foo/bar/:name' do
    sleep 0.1
    "hello post"


You can emit metrics from anywhere:


Vitals.count('my_metric', 17)

Vitals.gauge('my_metric', 42)

Vitals.timing('my_metric', 500) # milliseconds

 # so something slow

# Use a dot to logically separate segments

Vitals.timing('category.my_metric', 500) # milliseconds

Configuration Options

The Vitals API is extensible. It should resemble the standard Logger look and feel, and it revolves around 3 concepts:

  1. Reporter - the thing that takes your metrics and flushes them to a metrics agent. Use StatsdReporter in production and ConsoleReporter in development. ConsoleReporter will spit out metrics to stdout as they come. You can also wire them both with MultiReporter. Check the specs for how to do that.
  2. Format - takes the contextual information (host, service, environment) and your metric, and formats them in an order that makes sense for working with Graphite. You have the ProductionFormat, HostLastFormat and NoHostFormat.
  3. Integrations - integrations hook things that we're able to instrument with Vitals. Check integrations for more.

Here's what's available to you at configuration time:

Vitals.configure! do |c|
  # Set your service name (default: 'default')
  c.facility = 'my_service'

  # Set environment (default: taken from RACK_ENV)
  # c.environment = 'env'

  # Set a host (default: taken from hostname)
  # c.host = 'foohost'

  # Use a specific reporter (default: InmemReporter)
  # c.reporter = Vitals::Reporters::ConsoleReporter.new

  # Use a different format perhaps? (default: ProductionFormat)
  # c.format = Vitals::Formats::HostLastFormat

  # Use a different metric path separator, control how hierarcies are generated (default: '.')
  # c.path_sep = '__'

Metric Hierarchies

If you leave the default metric path separator, it will be a dot. This means Graphite will parse this and generate a branch in the tree when ever it sees a new segment, so:


Will be created from a GET /api/status/registration

On the other hand, if you choose a non-dot separator, like underscore, then:


Will be generated from a GET /api/status/registration.

You can pick either of those and the trade-offs are:

  • Nested hierarchy (using a dot): fine-grained control over grouping your metrics efficiently. If you want to pick and choose a metric, and be able to group based on topics efficiently. You cannot group cross-segments of a path in graphite.

  • Flat hierarchy (using anything other than a dot, like an underscore): grouping over segments can be glob-like, so quick wins like "graph all errors" can be had like this: api.*.500.*. However, every time you want to group metrics, you will need to find the appropriate glob pattern, which will taxi Graphite for a huge amounts of metrics.

The default separator is a dot, which makes everything hierarchical.


Tests and benchmarks should be run with at least Ruby 2.1 (because of memory profiling API)

$ bundle install && rake spec && rake bench

You can use the following to test various web frameworks using their own integration testing stacks:

$ rake multiverse


Fork, implement, add tests, pull request, get my everlasting thanks and a respectable place here :).


Copyright (c) 2011-2016 Dotan Nahum @jondot. See LICENSE for further details.