Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

statsd - StatsD metrics client

Import with import "statsd.j" as statsd;. Emit metric:value|type lines to a StatsD / Datadog / Telegraf agent over UDP. This is the push counterpart to a pull-based scrape: it is fire-and-forget (UDP, no reply, no error when no agent is listening), so a metric costs one datagram and never blocks the program. Needs the default jennifer binary (net).

import "statsd.j" as statsd;

def c as statsd.Client init statsd.clientWith("127.0.0.1:8125", "web");
statsd.increment($c, "requests");        # web.requests:1|c
statsd.timing($c, "response", 42);       # web.response:42|ms
statsd.gauge($c, "queue.depth", 7);      # web.queue.depth:7|g
statsd.close($c);

Runnable: examples/modules/statsd_demo.j.

Client

def struct statsd.Client {
    socket as net.UDPSocket,   # the sending socket
    address as string,         # the agent "host:port"
    prefix as string           # a metric-name namespace ("" for none)
};

A Client bundles the sending socket, the agent address, and an optional metric-name prefix. Value-copies share the underlying socket (the usual handle carve-out to value semantics), so copying a Client is safe and cheap. The prefix is joined to every metric name with a . separator, so prefix web and metric hits send web.hits; an empty prefix sends the bare name.

CallReturns
statsd.client(host)Clientconnect to host:8125 (the default port), no prefix
statsd.clientWith(address, prefix)Clientconnect to a full host:port with a metric-name prefix
statsd.close(c)close the sending socket

Metrics

CallWire lineType
statsd.count(c, name, value)name:value|ccounter delta (value may be negative)
statsd.increment(c, name)name:1|ccounter +1
statsd.decrement(c, name)name:-1|ccounter -1
statsd.gauge(c, name, value)name:value|gabsolute gauge
statsd.timing(c, name, ms)name:ms|mstimer, milliseconds
statsd.set(c, name, value)name:value|sunique-member set (agent counts distinct values)

All six are fire-and-forget: they format one line, send one datagram, and return. count / increment / decrement adjust a counter; gauge sets an absolute value; timing records a duration the agent aggregates into percentiles; set records a distinct member (e.g. a user id) the agent counts uniquely. Counter and gauge values are integers in this version; set values are strings (any unique identifier).

Scope

  • Fire-and-forget only. UDP means a lost or unheard datagram is silent by design - there is no delivery confirmation and no error when the agent is down. Use it for metrics, not for data you must not lose.
  • No sample rates or tags in this version. The StatsD @rate sampling suffix and Datadog #tag:value tags are not emitted; every call sends its metric unconditionally with no tags. Both are candidate additions.
  • Integer counter / gauge values. Fractional gauges (e.g. a load average) would need a float-valued surface, not shipped here.
  • No batching. One datagram per metric. Aggregating several metrics into a single packet is a possible follow-on.

See also

  • net.md - the UDP surface (listenUDP / sendTo) the client is built on.
  • modules/index.md - the module catalog and import rules.