Skip to main content

python-statsd

Metrics leave your application over UDP, statsd aggregates them, Graphite stores and graphs them

Test status CodeQL status Documentation Coverage, enforced in CI
PyPI version Supported Python versions Downloads BSD-3-Clause licence
Type checked by four checkers in CI Linted and formatted with ruff

python-statsd is a client for Etsy's statsd server, a front end and proxy for the Graphite stats collection and graphing server. It supports Python 3.10 and newer, and it has no dependencies.

pip install python-statsd
import statsd

counter = statsd.Counter('app')
counter += 1

with statsd.Timer('app').time('render'):
    pass  # the work you are measuring

Two metrics, two UDP packets, nothing blocking. A statsd server that is down costs you graphs rather than requests.

What goes on the wire

Every line under udp :8125 < in this recording is a packet the client sent, caught by a real listener on the other end:

A terminal session sending a counter, a gauge, a timer and a sampled counter, with each UDP payload printed as it arrives

Note the last one. At sample_rate=0.5 four increments produced a single packet, and it carries |@0.5 so the server knows to multiply back up.

The metric types

Type A burst of values becomes Reach for it when
Counter their sum you are counting events
Gauge the last one you are reporting a level
Timer mean, median, percentiles you are measuring duration
Average their mean the server should average samples
Raw stored as sent you already did the summarising
import statsd

counter = statsd.Counter('app')
counter.increment('requests')  # app.requests:1|c

gauge = statsd.Gauge('app')
gauge.send('queue_depth', 42)  # app.queue_depth:42|g

average = statsd.Average('app')
average.send('batch', 123)  # app.batch:123|a

raw = statsd.Raw('app')
raw.send('summary', 42, timestamp=1234567890)  # app.summary:42|r|1234567890

Timers come in three forms, and the context manager is the one to reach for, because it reports the block that raised as well as the block that did not:

import statsd

timer = statsd.Timer('app')

with timer.time('render'):
    pass  # the work you are measuring


@timer.decorate
def render_page():  # sends app.render_page
    pass

Names build themselves when you nest clients, which keeps the string formatting out of your call sites:

import statsd

app = statsd.Client('app')
queries = app.get_client('database').get_client('queries', statsd.Counter)

queries.increment()  # app.database.queries:1|c

See it working

The repository ships a compose file with statsd, Graphite and Grafana, so you can watch a metric arrive instead of taking anyone's word for it:

docker compose up -d
uv run python examples/send_metrics.py --seconds 120

Then open http://localhost:3000. Grafana comes up with the datasource configured and this dashboard loaded, no login in the way:

A Grafana dashboard showing request rate, render time percentiles, queue depth and packets received

That screenshot is the stack in this repository, fed by examples/send_metrics.py through this client. The local stack guide covers how statsd renames your metrics on the way through, and what to check when nothing shows up.

Configuration

Set the defaults once at startup and every client built afterwards follows:

import statsd

statsd.Connection.set_defaults(host='localhost', port=8125, sample_rate=1)

Or build connections yourself when one destination is not enough:

import statsd

connection = statsd.Connection(host='statsd-1', port=8125, sample_rate=0.1)
statsd.Counter('app.requests', connection).increment()

One trap worth knowing before it costs you an afternoon: a falsy argument means "use the default", so Connection(sample_rate=0) sends everything. Pass disabled=True to send nothing.

Documentation

Full documentation is at python-statsd.readthedocs.io.

  • Metrics: the five types, how to choose, and the exact bytes each one writes
  • Connections: destinations, sampling, disabling, failure behaviour, threads and forks
  • Patterns: naming, cardinality, client trees, WSGI and Celery integration
  • Local stack: docker compose, and how to debug a metric that never arrives

For Django, use django-statsd, the sister project built on this client. It times views and reports the queries per request without you writing any of it.

Note on the package name

This project is published on PyPI as python-statsd and installs a module called statsd. A different project, jsocol's client, is published as statsd and installs a module called statsd as well. Installing both in one environment leaves you with whichever was written last, so pick one.

Contributing

Bug reports and patches are welcome, and CONTRIBUTING.md covers the development setup: uv sync --all-extras, uv run pytest, and uv run tox -p auto to run everything CI runs. Every code sample in this README and in the documentation is executed by the test suite, so a change in behaviour tends to tell you which paragraph it just made wrong.

Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python_statsd-3.0.0.tar.gz (12.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

python_statsd-3.0.0-py3-none-any.whl (15.7 kB view details)

Uploaded Python 3

File details

Details for the file python_statsd-3.0.0.tar.gz.

File metadata

  • Download URL: python_statsd-3.0.0.tar.gz
  • Upload date:
  • Size: 12.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for python_statsd-3.0.0.tar.gz
Algorithm Hash digest
SHA256 f7f7957ddf6757a231e316ef2ca6bd47ce33a701c57b4049406308f811e9f76e
MD5 b33f05ea37fd30f6ee299fbc612098b2
BLAKE2b-256 01a5f881bb12332f80aa016998b6779aa5966bd8dc57f92c327a6f1fb8d3a1e7

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_statsd-3.0.0.tar.gz:

Publisher: publish.yml on wolph/python-statsd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file python_statsd-3.0.0-py3-none-any.whl.

File metadata

  • Download URL: python_statsd-3.0.0-py3-none-any.whl
  • Upload date:
  • Size: 15.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for python_statsd-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2ab8f8722f6725ecc39895b6ffe9f2a6752b6aa00786b77cc66058d06e06d320
MD5 5291776bc8f023d8e6ae321272d8e4a3
BLAKE2b-256 d727b9dabdcaf24c8a6e366deae5c22a5d9015dca9900451fdb8d3f834249f5e

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_statsd-3.0.0-py3-none-any.whl:

Publisher: publish.yml on wolph/python-statsd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

3.0.0 This release

2 files

2.1.0

2 files

2.0.0

2 files

1.7.2

1 file

1.7.1

1 file

1.7.0

1 file

1.6.4

1 file

1.6.3

1 file

1.6.2

1 file

1.6.1

1 file

1.6.0

1 file

1.5.8

1 file

1.5.7

1 file

1.5.6

1 file

1.5.5

1 file

1.5.4

1 file

1.5.3

1 file

1.5.2

1 file

1.5.1

1 file

1.4.3

1 file

1.4.2

2 files

1.4.1

1 file

1.4

3 files

1.3

2 files

1.2

2 files

1.1

2 files

1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page