Add DogStatsD metrics exporter alongside Graphite#11
Merged
Conversation
Implements the Metrics interface alongside graphiteMetrics and
extensibleMetrics. Emits two packets per command invocation over
UDP:
<prefix>duration:<ms>|ms|#launcher=,repo=,pkg=,cmd=,subcmd=,partition=,status=
<prefix>count:1|c|#<same tags>
Dimensions live in DogStatsD tags rather than the metric name, so
the same emit code reaches the Datadog agent, prometheus
statsd_exporter, the OTel collector, Telegraf, Vector, or a custom
receiver — the receiver decides how to roll up.
Off by default: an empty host returns a no-op collector that never
opens a socket. Mirrors how Graphite is wired in today.
No external dep. Single net.Dial("udp", ...) per Send; UDP
fire-and-forget so the CLI doesn't block on a downed receiver.
Tests cover format generation, tag sanitisation, end-to-end UDP
loopback, and the exit-code → status mapping. Wired into the
composite collector in a follow-up commit so this lands as a pure
addition.
Three new keys, all opt-in: METRIC_STATSD_HOST "" — set to enable; "" leaves the exporter disabled METRIC_STATSD_PORT 8125 — de-facto StatsD/DogStatsD port METRIC_STATSD_PREFIX "launcher." — namespace prefix for emitted metric names Adds a small setIntConfig helper for the port; uses existing string/duration helpers for the rest. Same disabled-by-default posture as Graphite — both exporters can be set independently and either, both, or neither will emit.
Add the StatsD collector alongside Graphite + extensible in the composite. Passes the launcher's runtime app name as the launcher tag so the exporter doesn't need to reach into the context itself. No behaviour change at default config: METRIC_STATSD_HOST is empty by default, so the constructor returns a no-op. Setting the host activates the exporter without touching Graphite — both run side by side, emitting to whatever receivers you point them at.
Tightens whitespace in two places gofmt flagged after the initial commits: a double-space in the noopMetrics.Send signature, and struct-field column alignment in TestStatsd_StatusReflectsExitCode. No behaviour change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a third metrics exporter — DogStatsD over UDP — that runs alongside the existing Graphite and extensible exporters. Strictly additive: Graphite stays untouched, no existing config keys change, no new dependencies.
Why DogStatsD specifically: the dimension-as-tag model means receivers (Prometheus via
statsd_exporter, the Datadog agent, OTel collector, Telegraf, Vector, or a hand-rolled receiver) can slice on any combination of dimensions without sender-side templating. The same on-wire packets work everywhere — no need to decide at code-write time which dimensions belong in a prefix.Commits
fc793fecmd/metrics/statsd.go+ tests. Two packets per invocation (<prefix>duration|ms,<prefix>count|c) with tagslauncher,repo,pkg,cmd,subcmd,partition,status. Off by default — an empty host returns a no-op collector that never opens a socket. Stdlibnetonly, no external dep. Tests cover format generation, tag sanitisation, end-to-end UDP loopback, and exit-code → status mapping.a7fdb93METRIC_STATSD_HOST(empty default — disables),METRIC_STATSD_PORT(8125 default),METRIC_STATSD_PREFIX("launcher."default). Adds a tinysetIntConfighelper for the port.1bdcfdecmd/root.goto add the StatsD collector to the existing composite alongside Graphite + extensible.8d92670What changes on the wire
Nothing for existing users. Graphite still emits the same dotted-prefix metrics on its existing UDP port. Setting
METRIC_STATSD_HOSTto a real host activates the new exporter in parallel.What gets collected (in case anyone asks)
Same shape as Graphite: command identity (repo, pkg, cmd, subcmd), partition, duration, count, success/failure. Plus the launcher's own name as a tag (Graphite hardcoded
\"cdt\"in the prefix; we put it in a tag). No arguments, no env vars, no stdout, no user identity.End-to-end verification
Built fresh from this branch, ran against
prom/statsd-exporterin Docker. Sample output after onecola bonjourand onecola exit1:All seven tags came through, both metric types parsed cleanly by
statsd_exporterwith no custom mapping rules.Test plan
go build ./...cleango vet ./...cleango test -race -count=1 ./...all packages pass./test/integration.sh19/19 suites passgovulncheck ./...no vulnerabilities