Categorygithub.com/smira/go-statsd
modulepackage
1.3.4
Repository: https://github.com/smira/go-statsd.git
Documentation: pkg.go.dev

# README

Build Status Documentation Go Report Card codecov License FOSSA Status

Go statsd client library with zero allocation overhead, great performance and automatic reconnects.

Client has zero memory allocation per metric sent:

  • ring of buffers, each buffer is UDP packet
  • buffer is taken from the pool, filled with metrics, passed on to the network delivery and returned to the pool
  • buffer is flushed either when it is full or when flush period comes (e.g. every 100ms)
  • separate goroutines handle network operations: sending UDP packets and reconnecting UDP socket
  • when metric is serialized, zero allocation operations are used to avoid reflect and temporary buffers

Zero memory allocation

As metrics could be sent by the application at very high rate (e.g. hundreds of metrics per one request), it is important that sending metrics doesn't cause any additional GC or CPU pressure. go-statsd is using buffer pools and it tries to avoid allocations while building statsd packets.

Reconnecting to statsd

With modern container-based platforms with dynamic DNS statsd server might change its address when container gets rescheduled. As statsd packets are delivered over UDP, there's no easy way for the client to figure out that packets are going nowhere. go-statsd supports configurable reconnect interval which forces DNS resolution.

While client is reconnecting, metrics are still processed and buffered.

Dropping metrics

When buffer pool is exhausted, go-statsd starts dropping packets. Number of dropped packets is reported via Client.GetLostPackets() and every minute logged using log.Printf(). Usually packets should never be dropped, if that happens it's usually signal of enormous metric volume.

Stastd server

Any statsd-compatible server should work well with go-statsd, statsite works exceptionally well as it has great performance and low memory footprint even with huge number of metrics.

Usage

Initialize client instance with options, one client per application is usually enough:

client := statsd.NewClient("localhost:8125",
    statsd.MaxPacketSize(1400),
    statsd.MetricPrefix("web."))

Send metrics as events happen in the application, metrics will be packed together and delivered to statsd server:

start := time.Now()
client.Incr("requests.http", 1)
// ...
client.PrecisionTiming("requests.route.api.latency", time.Since(start))

Shutdown client during application shutdown to flush all the pending metrics:

client.Close()

Tagging

Metrics could be tagged to support aggregation on TSDB side. go-statsd supports tags in InfluxDB , Datadog and Graphite formats. Format and default tags (applied to every metric) are passed as options to the client initialization:

client := statsd.NewClient("localhost:8125",
    statsd.TagStyle(TagFormatDatadog),
    statsd.DefaultTags(statsd.StringTag("app", "billing")))

For every metric sent, tags could be added as the last argument(s) to the function call:

client.Incr("request", 1,
    statsd.StringTag("procotol", "http"), statsd.IntTag("port", 80))

Benchmark

Benchmark comparing several clients:

Benchmark results:

BenchmarkAlexcesaro-12    	 5000000	       333 ns/op	       0 B/op	       0 allocs/op
BenchmarkGoStatsd-12      	10000000	       230 ns/op	      23 B/op	       0 allocs/op
BenchmarkCactus-12        	 3000000	       604 ns/op	       5 B/op	       0 allocs/op
BenchmarkG2s-12           	  200000	      7499 ns/op	     576 B/op	      21 allocs/op
BenchmarkQuipo-12         	 1000000	      1048 ns/op	     384 B/op	       7 allocs/op
BenchmarkUnix4ever-12        1000000	      1695 ns/op	     408 B/op	      18 allocs/op

Origins

Ideas were borrowed from the following stastd clients:

Talks

I gave a talk about design and optimizations which went into go-statsd at Gophercon Russia 2018: slides, source.

License

License is MIT License.

FOSSA Status

# Functions

BufPoolCapacity controls size of pre-allocated buffer cache Each buffer is MaxPacketSize.
DefaultTags defines a list of tags to be applied to every metric.
FlushInterval controls flushing incomplete UDP packets which makes sure metric is not delayed longer than FlushInterval Default value is 100ms, setting FlushInterval to zero disables flushing.
Int64Tag creates Tag with integer value.
IntTag creates Tag with integer value.
Logger is used by statsd client to report errors and lost packets If not set, default logger to stderr with metricPrefix `[STATSD] ` is being used.
MaxPacketSize control maximum UDP packet size Default value is DefaultMaxPacketSize.
MetricPrefix is metricPrefix to prepend to every metric being sent Usually metrics are prefixed with app name, e.g.
Network sets the network to use Dialing the statsd server.
NewClient creates new statsd client and starts background processing Client connects to statsd server at addr ("host:port") Client settings could be controlled via functions of type Option.
ReconnectInterval controls UDP socket reconnects Reconnecting is important to follow DNS changes, e.g.
ReportInterval instructs client to report number of packets lost each interval via Logger By default lost packets are reported every minute, setting to zero disables reporting.
RetryTimeout controls how often client should attempt reconnecting to statsd server on failure Default value is 5 seconds.
SendLoopCount controls number of goroutines sending UDP packets Default value is 1, so packets are sent from single goroutine, this value might need to be bumped under high load.
SendQueueCapacity controls length of the queue of packet ready to be sent Packets might stay in the queue during short load bursts or while client is reconnecting to statsd Default value is DefaultSendQueueCapacity.
StringTag creates Tag with string value.
TagStyle controls formatting of StatsD tags There are two predefined formats: for InfluxDB and Datadog, default format is InfluxDB tag format.

# Constants

Default settings.
Default settings.
Default settings.
Default settings.
Default settings.
Default settings.
Default settings.
Default settings.
Default settings.
Default settings.
Default settings.
Tag placement constants.
Tag placement constants.

# Variables

TagFormatDatadog is format for DogStatsD (Datadog Agent) Docs: https://docs.datadoghq.com/developers/dogstatsd/#datagram-format.
TagFormatGraphite is format for Graphite Docs: https://graphite.readthedocs.io/en/latest/tags.html.
TagFormatInfluxDB is format for InfluxDB StatsD telegraf plugin Docs: https://github.com/influxdata/telegraf/tree/master/plugins/inputs/statsd.
TagFormatOkmeter is format for Okmeter agent Docs: https://okmeter.io/misc/docs#statsd-plugin-config.

# Structs

Client implements statsd client.
ClientOptions are statsd client settings.
Tag is metric-specific tag.
TagFormat controls tag formatting style.

# Interfaces

SomeLogger defines logging interface that allows using 3rd party loggers (e.g.

# Type aliases

Option is type for option transport.