statsd

package module
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 10, 2022 License: MIT Imports: 12 Imported by: 3

README

This is a backwards compatible fork of alexcesaro/statsd.

Note that this repository is versioned independently of the (unmaintained) upstream.

Changelog

  • 2022-01-11 - Add support for custom UDP writer + UDPConn impl. with re-resolve support

  • 2022-01-01 - Added support for relative gauges via Client.GaugeRelative, and fixed gauge handling of -0 floats

  • 2021-12-31 - Added support for disabling the initial ping/check for UDP connections via new UDPCheck option

  • 2020-11-13 - Added support for go modules

  • 2020-11-13 - Added the SafeConn write closer that checks if the connection is still up before attempting to write

  • 2020-08-27 - Fixed bug in Tags identified by https://github.com/alexcesaro/statsd/issues/41

  • 2019-05-22 - Added support for arbitrary output streams via new WriteCloser option

  • 2019-05-22 - Added support for simplified inline flush logic via new InlineFlush option

  • 2019-05-26 - Fixed bug causing trailing newlines to be removed for streaming (non-udp) connections

See also the upstream changelog.


statsd

Code Coverage Documentation

Introduction

Package statsd is a simple and efficient StatsD client.

See the benchmark for a comparison with other Go StatsD clients.

You may also be interested in this (old / historic) thread on golang-nuts.

Features

  • Supports all StatsD metrics: counter, gauge (absolute and relative), timing and set
  • Supports InfluxDB and Datadog tags
  • Fast and GC-friendly: all functions for sending metrics do not allocate
  • Efficient: metrics are buffered by default
  • Simple and clean API
  • 100% test coverage
  • Versioned API using gopkg.in

Documentation

https://pkg.go.dev/github.com/joeycumines/statsd#section-documentation

Download

go get github.com/joeycumines/statsd

Example

See the examples in the documentation.

License

MIT

Contribute

Do you have any question the documentation does not answer? Is there a use case that you feel is common and is not well-addressed by the current API?

If so you are more than welcome to ask questions, open an issue, or send a pull request here on GitHub.

Documentation

Overview

Package statsd is a simple and efficient StatsD client.

Options

Use options to configure the Client: target host/port, sampling rate, tags, etc.

Whenever you want to use different options (e.g. other tags, different sampling rate), you should use the Clone() method of the Client.

Because when cloning a Client, the same connection is reused so this is way cheaper and more efficient than creating another Client using New().

Internals

Client's methods buffer metrics. The buffer is flushed when either:

  • the background goroutine flushes the buffer (every 100ms by default)
  • the buffer is full (1440 bytes by default so that IP packets are not fragmented)

The background goroutine can be disabled using the FlushPeriod(0) option.

Buffering can be disabled using the MaxPacketSize(0) option.

StatsD homepage: https://github.com/etsy/statsd

Example
package main

import (
	"log"
	"runtime"

	"github.com/joeycumines/statsd"
)

func ping(url string) {}

func main() {
	c, err := statsd.New() // Connect to the UDP port 8125 by default.
	if err != nil {
		// If nothing is listening on the target port, an error is returned and
		// the returned client does nothing but is still usable. So we can
		// just log the error and go on.
		log.Print(err)
	}
	defer c.Close()

	// Increment a counter.
	c.Increment("foo.counter")

	// Gauge something.
	c.Gauge("num_goroutine", runtime.NumGoroutine())

	// Time something.
	t := c.NewTiming()
	ping("http://example.com/")
	t.Send("homepage.response_time")

	// It can also be used as a one-liner to easily time a function.
	pingHomepage := func() {
		defer c.NewTiming().Send("homepage.response_time")

		ping("http://example.com/")
	}
	pingHomepage()

	// Cloning a Client allows using different parameters while still using the
	// same connection.
	// This is way cheaper and more efficient than using New().
	stat := c.Clone(statsd.Prefix("http"), statsd.SampleRate(0.2))
	stat.Increment("view") // Increments http.view
}
Output:

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

A Client represents a StatsD client.

func New

func New(opts ...Option) (*Client, error)

New returns a new Client, which will always be non-nil, but will be muted (permanently inert / stubbed) if returned with an error, or if the Mute option was set.

func (*Client) Clone

func (c *Client) Clone(opts ...Option) *Client

Clone returns a clone of the Client. The cloned Client inherits its configuration from its parent.

All cloned Clients share the same connection, so cloning a Client is a cheap operation.

Example
package main

import (
	"log"

	"github.com/joeycumines/statsd"
)

func main() {
	c, err := statsd.New(statsd.Prefix("my_app"))
	if err != nil {
		log.Print(err)
	}

	httpStats := c.Clone(statsd.Prefix("http"))
	httpStats.Increment("foo.bar") // Increments: my_app.http.foo.bar
}
Output:

func (*Client) Close

func (c *Client) Close()

Close flushes the Client's buffer and releases the associated ressources. The Client and all the cloned Clients must not be used afterward.

func (*Client) Count

func (c *Client) Count(bucket string, n interface{})

Count adds n to bucket.

func (*Client) Flush

func (c *Client) Flush()

Flush flushes the Client's buffer.

func (*Client) Gauge

func (c *Client) Gauge(bucket string, value interface{})

Gauge records an absolute value for the given bucket.

func (*Client) GaugeRelative added in v1.2.0

func (c *Client) GaugeRelative(bucket string, value interface{})

GaugeRelative records a relative value for the given bucket.

func (*Client) Histogram

func (c *Client) Histogram(bucket string, value interface{})

Histogram sends a histogram value to a bucket.

func (*Client) Increment

func (c *Client) Increment(bucket string)

Increment increments the given bucket. It is equivalent to Count(bucket, 1).

func (*Client) NewTiming

func (c *Client) NewTiming() Timing

NewTiming creates a new Timing.

Example
package main

import (
	"github.com/joeycumines/statsd"
)

var c *statsd.Client

func ping(url string) {}

func main() {
	// Send a timing metric each time the function is run.
	defer c.NewTiming().Send("homepage.response_time")
	ping("http://example.com/")
}
Output:

func (*Client) Timing

func (c *Client) Timing(bucket string, value interface{})

Timing sends a timing value to a bucket.

func (*Client) Unique

func (c *Client) Unique(bucket string, value string)

Unique sends the given value to a set bucket.

type Option

type Option func(*config)

An Option represents an option for a Client. It must be used as an argument to New() or Client.Clone().

func Address

func Address(addr string) Option

Address sets the address of the StatsD daemon.

By default, ":8125" is used. This option is ignored in Client.Clone().

Example
package main

import (
	"github.com/joeycumines/statsd"
)

var (
	c   *statsd.Client
	err error
)

func main() {
	c, err = statsd.New(statsd.Address("192.168.0.5:8126"))
}
Output:

func ErrorHandler

func ErrorHandler(h func(error)) Option

ErrorHandler sets the function called when an error happens when sending metrics (e.g. the StatsD daemon is not listening anymore).

By default, these errors are ignored. This option is ignored in Client.Clone().

Example
package main

import (
	"log"

	"github.com/joeycumines/statsd"
)

var (
	c   *statsd.Client
	err error
)

func main() {
	c, err = statsd.New(statsd.ErrorHandler(func(err error) {
		log.Print(err)
	}))
}
Output:

func FlushPeriod

func FlushPeriod(p time.Duration) Option

FlushPeriod sets how often the Client's buffer is flushed. If p is 0, the goroutine that periodically flush the buffer is not launched and the buffer is only flushed when it is full.

By default, the flush period is 100 ms. This option is ignored in Client.Clone().

Example
package main

import (
	"time"

	"github.com/joeycumines/statsd"
)

var (
	c   *statsd.Client
	err error
)

func main() {
	c, err = statsd.New(statsd.FlushPeriod(10 * time.Millisecond))
}
Output:

func InlineFlush

func InlineFlush(enabled bool) Option

InlineFlush enables or disables (default disabled) forced flushing, inline with recording each stat. This option takes precedence over FlushPeriod, which would be redundant if always flushing after each write. Note that this DOES NOT guarantee exactly one line per write.

This option is ignored in Client.Clone().

func MaxPacketSize

func MaxPacketSize(n int) Option

MaxPacketSize sets the maximum packet size in bytes sent by the Client.

By default, it is 1440 to avoid IP fragmentation. This option is ignored in Client.Clone().

Example
package main

import (
	"github.com/joeycumines/statsd"
)

var (
	c   *statsd.Client
	err error
)

func main() {
	c, err = statsd.New(statsd.MaxPacketSize(512))
}
Output:

func Mute

func Mute(b bool) Option

Mute sets whether the Client is muted. All methods of a muted Client do nothing and return immediately.

This option can be used in Client.Clone() only if the parent Client is not muted. The clones of a muted Client are always muted.

Example
package main

import (
	"log"

	"github.com/joeycumines/statsd"
)

func main() {
	c, err := statsd.New(statsd.Mute(true))
	if err != nil {
		log.Print(err)
	}
	c.Increment("foo.bar") // Does nothing.
}
Output:

func Network

func Network(network string) Option

Network sets the network (udp, tcp, etc) used by the client. See the net.Dial documentation (https://golang.org/pkg/net/#Dial) for the available network options.

By default, network is udp. This option is ignored in Client.Clone().

Example
package main

import (
	"github.com/joeycumines/statsd"
)

var (
	c   *statsd.Client
	err error
)

func main() {
	// Send metrics using a TCP connection.
	c, err = statsd.New(statsd.Network("tcp"))
}
Output:

func Prefix

func Prefix(p string) Option

Prefix appends the prefix that will be used in every bucket name.

Note that when used in cloned, the prefix of the parent Client is not replaced but is prepended to the given prefix.

Example
package main

import (
	"log"

	"github.com/joeycumines/statsd"
)

func main() {
	c, err := statsd.New(statsd.Prefix("my_app"))
	if err != nil {
		log.Print(err)
	}
	c.Increment("foo.bar") // Increments: my_app.foo.bar
}
Output:

func SampleRate

func SampleRate(rate float32) Option

SampleRate sets the sample rate of the Client. It allows sending the metrics less often which can be useful for performance intensive code paths.

Example
package main

import (
	"github.com/joeycumines/statsd"
)

var (
	c   *statsd.Client
	err error
)

func main() {
	c, err = statsd.New(statsd.SampleRate(0.2)) // Send metrics 20% of the time.
}
Output:

func Tags

func Tags(tags ...string) Option

Tags appends the given tags to the tags sent with every metrics. If a tag already exists, it is replaced.

The tags must be set as key-value pairs. If the number of tags is not even, Tags panics.

If the format of tags have not been set using the TagsFormat option, the tags will be ignored.

Example
package main

import (
	"github.com/joeycumines/statsd"
)

var (
	c   *statsd.Client
	err error
)

func main() {
	c, err = statsd.New(
		statsd.TagsFormat(statsd.InfluxDB),
		statsd.Tags("region", "us", "app", "my_app"),
	)
}
Output:

func TagsFormat

func TagsFormat(tf TagFormat) Option

TagsFormat sets the format of tags.

Example
package main

import (
	"github.com/joeycumines/statsd"
)

var (
	c   *statsd.Client
	err error
)

func main() {
	c, err = statsd.New(statsd.TagsFormat(statsd.InfluxDB))
}
Output:

func TrimTrailingNewline added in v1.3.0

func TrimTrailingNewline(enabled bool) Option

TrimTrailingNewline may be used to strip the trailing newline from writes, and should be used when providing a UDP writer (i.e. net.Conn), to WriteCloser. This behavior will always be enabled for UDP connections that use the Address option.

This option is ignored in Client.Clone().

func UDPCheck added in v1.1.0

func UDPCheck(enabled bool) Option

UDPCheck enables or disables (default enabled) checking UDP connections, as part of New. This behavior is useful, as it makes it easier to quickly identify misconfigured services. Disabling this option removes the need to explicitly manage the connection state, at the cost of error visibility. Using an error handler may mitigate some of this cost. Explicitly setting this option to true will also enable this behavior for connections provided using the WriteCloser option (as part of New).

This option is ignored in Client.Clone().

func WriteCloser

func WriteCloser(writer io.WriteCloser) Option

WriteCloser sets the connection writer used by the client. If this option is present it will take precedence over the Network and Address options. If the client is muted then the writer will be closed before returning. The writer will be closed on Client.Close. Multiples of this option will cause the last writer to be used (if any), and previously provided writers to be closed.

This option is ignored in Client.Clone().

type SafeConn

type SafeConn struct {
	// contains filtered or unexported fields
}

SafeConn is an implementation of the io.WriteCloser that wraps a net.Conn type its purpose is to perform a guard as a part of each Write call to first check if the connection is still up by performing a small read. The use case of this is to protect against the case where a TCP connection comes disconnected and the Write continues to retry for up to 15 minutes before determining that the connection has been broken off. See also the WriteCloser option.

func NewSafeConn

func NewSafeConn(network, address string, connTimeout, readTimeout time.Duration) (*SafeConn, error)

func NewSafeConnWithDefaultTimeouts

func NewSafeConnWithDefaultTimeouts(network string, address string) (*SafeConn, error)

func (*SafeConn) Close

func (s *SafeConn) Close() error

func (*SafeConn) Write

func (s *SafeConn) Write(p []byte) (n int, err error)

type TagFormat

type TagFormat uint8

TagFormat represents the format of tags sent by a Client.

const (
	// InfluxDB tag format.
	// See https://influxdb.com/blog/2015/11/03/getting_started_with_influx_statsd.html
	InfluxDB TagFormat = iota + 1
	// Datadog tag format.
	// See http://docs.datadoghq.com/guides/metrics/#tags
	Datadog
)

type Timing

type Timing struct {
	// contains filtered or unexported fields
}

Timing is a helper object that eases sending timing values.

func (Timing) Duration

func (t Timing) Duration() time.Duration

Duration returns the time elapsed since the creation of the Timing.

func (Timing) Send

func (t Timing) Send(bucket string)

Send sends the time elapsed since the creation of the Timing.

type UDPConn added in v1.3.0

type UDPConn struct {
	// contains filtered or unexported fields
}

UDPConn is an implementation of an io.WriteCLoser, encapsulating a net.PacketConn, that supports DNS changes during operation. See also the WriteCloser, TrimTrailingNewline, and UDPCheck options.

func NewUDPConn added in v1.3.0

func NewUDPConn(network, address string, rate time.Duration) (*UDPConn, error)

func (*UDPConn) Close added in v1.3.0

func (x *UDPConn) Close() (err error)

func (*UDPConn) Write added in v1.3.0

func (x *UDPConn) Write(b []byte) (int, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL