A long-lived project that still receives updates
Send puma metrics to statsd via a background thread
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 5.0
>= 0
>= 0

Runtime

>= 5.0, < 7
 Project Readme

Puma Statsd Plugin

Puma integration with statsd for easy tracking of key metrics that puma can provide:

Gauges:

  • puma.workers - The number of distinct process running. In single mode this will be 1, in cluster mode the number of worker processes
  • puma.old_workers - The number of worker processes that are about to be shut down as part of a phased restart. Will normally be 0
  • puma.booted_workers - The number of worker processes that are in a booted state
  • puma.running - The number of worker threads currently running. In quiet times, idle threads may be shutdown, but they'll start back up again when traffic arrives
  • puma.backlog - The number of requests that have made it to a worker but are yet to be processed. This will normally be zero, as requests queue on the tcp/unix socket in front of the master puma process, not in the worker thread pool
  • puma.pool_capacity - The number of idle and unused worker threads. When this is low/zero, puma is running at full capacity and might need scaling up
  • puma.max_threads - The maximum number of worker threads that might run at one time
  • puma.percent_busy - The percentage of busy threads calculated as pool capacity relative to max threads
  • puma.requests_count - Total number of requests served by this puma since it started

Counters:

  • puma.requests - The number of requests served since the previous report

Installation

Add this gem to your Gemfile with puma and then bundle:

gem "puma"
gem "puma-plugin-statsd"

Add it to your puma config:

# config/puma.rb

bind "http://127.0.0.1:9292"

workers 1
threads 8, 16

plugin :statsd

Configuration

Statsd Connection

By default the plugin assumes statsd is available at 127.0.0.1. If that's true in your environment, just start puma like normal:

bundle exec puma

If statsd isn't on 127.0.0.1 or the UDP port is non-standard, you can configure them using optional environment variables:

STATSD_HOST=127.0.0.1 STATSD_PORT=9125 bundle exec puma

Some setups have statsd listening on a Unix socket rather than UDP. In that case, specify the socket path:

STATSD_SOCKET_PATH=/tmp/statsd.socket bundle exec puma

Interval

By default values will be reported to statsd every 2 seconds. To customise that internal, set the STATSD_INTERVAL_SECONDS environment variable.

STATSD_INTERVAL_SECONDS=1 bundle exec puma

Fractional seconds are supported. Here's how you'd opt into 500ms:

STATSD_INTERVAL_SECONDS="0.5" bundle exec puma

Prefix

In some environments you may want to prefix the metric names. To report foo.puma.pool_capacity instead of puma.pool_capacity:

STATSD_METRIC_PREFIX=foo bundle exec puma

Datadog Integration

metric tags are a non-standard addition to the statsd protocol, supported by the datadog "dogstatsd" server.

Should you be reporting the puma metrics to a dogstatsd server, you can set tags via the following environment variables.

DD_TAGS

DD_TAGS: Set this to a space-separated list of tags, using the datadog agent standard format.

For example, you could set this environment variable to set three datadog tags, and then you can filter by in the datadog interface:

DD_TAGS="env:test simple-tag-0 tag-key-1:tag-value-1" bundle exec puma

DD_ENV, DD_SERVICE, DD_VERSION, DD_ENTITY_ID

The env, service, version and dd.internal.entity_id tags have special meaning to datadog, and they can be set using the above environment variables. These are the conventional environment variables recommended by datadog, so they're likely to be set in many deployments.

MY_POD_NAME

MY_POD_NAME: Set a pod_name tag to the metrics. The MY_POD_NAME environment variable is recommended in the datadog kubernetes setup documentation, and for puma apps deployed to kubernetes it's very helpful to have the option to report on specific pods.

You can set it on your pods like this:

env:
  - name: MY_POD_NAME
    valueFrom:
      fieldRef:
        fieldPath: metadata.name

STATSD_GROUPING

STATSD_GROUPING: add a grouping tag to the metrics, with a value equal to the environment variable value. This is particularly helpful in a kubernetes deployment where each pod has a unique name but you want the option to group metrics across all pods in a deployment. Setting this on the pods in a deployment might look something like:

env:
  - name: STATSD_GROUPING
    value: deployment-foo

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/yob/puma-plugin-statsd.

Testing the data being sent to statsd

Start a pretend statsd server that listens for UDP packets on port 8125.

If you've installed the gem in your app:

# only need to install the binstub once
bundle binstubs puma-plugin-statsd
./bin/statsd-to-stdout

If you are developing/testing this gem locally:

./bin/statsd-to-stdout

Start puma:

STATSD_HOST=127.0.0.1 bundle exec puma devtools/config.ru --config devtools/puma-config.rb

Throw some traffic at it, either with curl or a tool like ab:

curl http://127.0.0.1:9292/
ab -n 10000 -c 20 http://127.0.0.1:9292/

Watch the output of the UDP server process - you should see statsd data printed to stdout.

Acknowledgements

This gem is a fork of the excellent puma-plugin-systemd by Samuel Cochran.

Other puma plugins that were helpful references:

The puma docs were also helpful.

License

The gem is available as open source under the terms of the MIT License.