Self-hosted service
prometheus/statsd_exporter avatar
prometheus/statsd_exporter

statsd_exporter: bridging StatsD traffic into Prometheus

StatsD to Prometheus metrics exporter

989 stars261 forksGoApache-2.0

At a glance

What is it?
statsd_exporter is a Prometheus exporter that receives StatsD style metrics and republishes them as Prometheus metrics, either through mapping rules or by parsing the tag dialects used by Librato, InfluxDB, DogStatsD and SignalFX. It is a bridge for a migration, and the project itself says to treat it as an intermediate step.
Who is it for?
statsd_exporter suits teams that already emit StatsD from applications they do not want to instrument again, especially where a sidecar can be added without touching application code. It does not suit a greenfield service, because the documentation tells you to move to native Prometheus instrumentation instead, and the repeater path loses the per-instance detail the sidecar path preserves.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A bridge for applications you cannot re-instrument

The problem is narrow and common. An organisation has applications that already report counters, timers and gauges over StatsD, usually through a client library that someone picked years ago. Meanwhile monitoring has moved to Prometheus, which scrapes an HTTP endpoint and expects labelled metrics. Rewriting every emitter is a large, boring project that competes with product work.

statsd_exporter sits between the two. It listens for StatsD style traffic, translates what it receives into Prometheus metrics, and exposes them for scraping. The project's own framing is that it is a drop-in replacement for StatsD, which means an existing StatsD server can be swapped for the exporter without the applications noticing, provided the ports and metric shapes line up.

There is an honest note in the documentation about how long this should be used. The project recommends treating the exporter as an intermediate solution and switching to native Prometheus instrumentation in the long term. Read that as a direction of travel, not as a disclaimer to be ignored. The exporter solves a migration problem, and it solves it well, but it does not become the endpoint state.

The deployment shape matters too. While it is common to run centralized StatsD servers, the documentation says the exporter works best as a sidecar, sitting next to the application instances it collects from.

The implementation is Go, the licence is Apache-2.0, and the module declares a go 1.26.0 toolchain.

Mapping rules rewrite dot separated names into labelled metrics

By default the exporter is not clever. A StatsD metric that matches no mapping rule is turned into a Prometheus metric with no labels, and every character that is not a letter or a digit replaced, periods included. That is enough for a counter called request.total, and wrong for anything that encodes structure in the name.

The configuration file fixes that. A mapping definition begins with a line matching the StatsD metric in question, where asterisks act as wildcards for each dot separated component. The lines that follow must each contain one label="value" pair, and they must at least define the metric name under the label name name. The Prometheus metric is then constructed from those labels.

References of the form $n inside a label value are replaced by the nth wildcard match from the matching line, counting from 1. Several matching definitions are separated by one or more empty lines, and the first rule that matches a StatsD metric wins. That first-match-wins rule is the detail to keep in mind when writing rules: a broad wildcard placed early will silently shadow a specific one below it.

The config file is reloaded on SIGHUP, so rule changes do not require a restart of the exporter.

Four tag dialects, and what happens when you mix them

StatsD never standardised tags, and the exporter supports four of the dialects that grew up independently, converting each into Prometheus labels. The Librato style appends tags to the metric name with a hash delimiter:

code
metric.name#tagName=val,tag2Name=val2:0|c

The InfluxDB style uses a comma instead:

code
metric.name,tagName=val,tag2Name=val2:0|c

DogStatsD puts the tags at the end of the metric in a section introduced by a pipe and a hash:

code
metric.name:0|c|#tagName:val,tag2Name:val2

And SignalFX dimensions use square brackets appended to the name:

code
metric.name[tagName=val,tag2Name=val2]:0|c

Two caveats come with this. Mixing tag styles, for example Librato tags on one metric and DogStatsD tags on another, is treated as an error and the behaviour is undefined, so a mixed estate has to pick one dialect or separate the exporters. Tags without a value, written as #some_tag, are not supported and are ignored.

All four parsers are on by default, and each can be turned off individually with a flag:

code
--no-statsd.parse-dogstatsd-tags
--no-statsd.parse-influxdb-tags
--no-statsd.parse-librato-tags
--no-statsd.parse-signalfx-tags

Disabling the parsers you do not use is worth doing on a shared ingress, since it turns an ambiguity into a rejection rather than a silent misparse.

Configured labels win over tags unless you set honor_labels

Label collisions are the second source of surprise. By default, a label written explicitly in the configuration file takes precedence over a label of the same name arriving from a tag on the StatsD event. In other words, if a mapping rule pins host="server-a" and the event also carries a host tag, the configured value is the one that ends up in the exported metric.

The documentation names the switch for the other behaviour: the honor_labels setting, which makes the label from the StatsD event tag win instead. This matters more than it sounds, because tags are per-event data while configuration labels are per-rule constants. A rule that hardcodes a hostname or a region will flatten all the per-instance detail your tags were carrying, and no error is raised.

The practical sequence for a first deployment is therefore: write the mapping rules, look at what the exporter produces, then decide per label whether the configured value or the tagged value is the one you want.

There is also a DogStatsD detail specific to aggregations. The exporter supports DogStatsD extended aggregations in combination with DogStatsD tags, but not with the other tagging styles.

Two migration shapes, sidecar relay and StatsD repeater

The documentation describes two ways to introduce the exporter, and the difference between them decides how much detail survives.

In the sidecar shape, the exporter runs next to the application instances and Prometheus scrapes it directly. To keep the old pipeline alive during the transition, the --statsd.relay.address flag forwards metrics to your existing StatsD UDP endpoint. Relaying forwards Statsd events unmodified, preserving the original metric name and tags in any format. In Kubernetes this means adding the exporter to the pod.

In the repeater shape, the flow is reversed. You configure StatsD's repeater backend to repeat all received metrics to a statsd_exporter process, and Prometheus then scrapes the exporter over /metrics. The documentation is blunt about the cost of this option: it allows trying the exporter out with minimal effort, but it does not provide the per-instance metrics of the sidecar pattern. Centralising through StatsD first flattens instance identity before Prometheus ever sees it.

There is also a third capability, the relay mode, which buffers incoming Statsd lines and relays them to a remote server. The stated purpose is to tee the data while migrating, and the buffer is flushed at least once per second so that delivery of metrics is not delayed.

Building the binary and the container image

The exporter is a Go program with a Makefile and a promu based build, and there is a Dockerfile in the repository along with a distroless variant and a .promu.yml configuration. The container image is built on the Prometheus busybox base for a given architecture and OS, copies the compiled binary to /bin/statsd_exporter, runs it as the non-root user 65534, and exposes three ports:

dockerfile
EXPOSE      9102 9125 9125/udp

That port set tells you the shape of the service. One port is the Prometheus scrape endpoint, and the pair with the udp suffix is the StatsD listener with its TCP counterpart alongside it, which matters for clients that prefer TCP or that send messages too large for a datagram.

Building from source is a Go toolchain operation, and the project documents the test run as:

code
$ go test

Flag handling has one historical quirk worth knowing. Version 0.7.0 switched to the kingpin flags library, and the behaviour is described as POSIX-ish: long flags take two dashes, boolean long flags are disabled by prefixing them with no, multiple short flags can be combined, and flag processing stops at the first --. The full list is available through --help.

There is an optional lifecycle API, disabled by default, that reloads or quits the exporter on request through a PUT or POST to the /-/reload or /-/quit endpoints. That gives you a clean way to apply a new config file without signalling the process, and a clean way to stop it in an orchestrated environment.

Editorial conclusion

statsd_exporter suits teams that already emit StatsD from applications they do not want to instrument again, especially where a sidecar can be added without touching application code. It does not suit a greenfield service, because the documentation tells you to move to native Prometheus instrumentation instead, and the repeater path loses the per-instance detail the sidecar path preserves. Before adopting it, decide which of the two deployment shapes you need, then check your StatsD flavour against the tag parsers and disable the ones you do not use with the no-statsd.parse flags.

Frequently asked questions

How do I install and run the Prometheus statsd_exporter?

It is a Go program built with a Makefile and promu, and the repository also contains a Dockerfile. The container exposes 9102 for scraping plus 9125 and 9125/udp for the StatsD listener, and the test suite runs with go test.

How do I map StatsD metric names to Prometheus labels in statsd_exporter?

Write a mapping rule whose first line matches the dot separated StatsD name with asterisks as wildcards, then give one label="value" pair per following line including the metric name label name. Use $n references to pull in wildcard matches, and the first matching rule wins.

Which StatsD tag formats does statsd_exporter understand?

Librato, InfluxDB, DogStatsD and SignalFX styles are all parsed by default and converted into Prometheus labels. Each parser can be turned off individually with flags such as --no-statsd.parse-dogstatsd-tags.

What is the difference between the sidecar and the StatsD repeater setup?

As a sidecar the exporter collects from application instances directly and Prometheus scrapes it, which preserves per-instance metrics. With the repeater setup StatsD forwards everything to the exporter, which is easier to try but does not provide the per-instance metrics of the sidecar pattern.

Can statsd_exporter reload its configuration without a restart?

Yes. The config file is reloaded on SIGHUP, and an optional lifecycle API, disabled by default, accepts a PUT or POST to the /-/reload endpoint to reload it and to /-/quit to stop the exporter.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. prometheus/statsd_exporter on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/prometheus-statsd-exporter.svg)](https://hysenlabs.com/projects/prometheus-statsd-exporter)

Was this useful?