statsd

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Feb 1, 2019 License: GPL-3.0 Imports: 6 Imported by: 0

README

StatsD Client (Go)

statsd is a simple yet powerful, futuristic StatsD client written in Go.

build status report card release

Features

  • Best suitable for netdata
  • Supports Counting, Sampling, Timing, Gauges, Sets and Histograms out of the box
  • Futuristic and Extendable: Ability to send custom metric values and types, yet unknown to the current client
  • It is blazing fast and it does not allocate unnecessary memory. Metrics are sent based on a customized packet size, manual Flushing of buffered metrics is also an option
  • Beautiful and easy to learn API
  • Easy for testing, the NewClient function accepts an io.WriteCloser, so you use it to test the sent metrics of your application on a development environment
  • Protocol-unawareness.

Installation

The only requirement is the Go Programming Language

$ go get -u github.com/netdata/statsd

Quick start

I know your time is valuable, so just bear with me another minute.

statsd is simple, it won't take more than 10 minutes of your time to read all of its documentation via godocs.

API
// NewClient returns a new StatsD client.
// The first input argument, "writeCloser", should be a value which completes the
// `io.WriteCloser` interface
// It can be a UDP connection or a string buffer or even the stdout for testing.
// The second input argument, "prefix" can be empty
// but it is usually the app's name and a single dot.
NewClient(writeCloser io.WriteCloser, prefix string) *Client
Client {
    SetMaxPackageSize(maxPacketSize int)
    SetFormatter(fmt func(metricName string) string)
    FlushEvery(dur time.Duration)

    IsClosed() bool
    Close() error

    WriteMetric(metricName, value, typ string, rate float32) error
    Flush(n int) error

    Count(metricName string, value int) error
    Increment(metricName string) error

    Gauge(metricName string, value int) error

    Unique(metricName string, value int) error

    Time(metricName string, value time.Duration) error
    Record(metricName string, rate float32) func() error
}
Metric Value helpers
Duration(v time.Duration) string
Int(v int) string
Int8(v int8) string
Int16(v int16) string
Int32(v int32) string
Int64(v int64) string
Uint(v uint) string
Uint8(v uint8) string
Uint16(v uint16) string
Uint32(v uint32) string
Uint64(v uint64) string
Float32(v float32) string
Float64(v float64) string
Metric Type constants
const (
    // Count is the "c" Counting statsd metric type.
    Count string = "c"
    // Gauge is the "g" Gauges statsd metric type.
    Gauge string = "g"
    // Unique is the "s" Sets statsd metric type.
    Unique string = "s"
    // Set is an alias for "Unique"
    Set = Unique
    // Time is the "ms" Timing statsd metric type.
    Time string = "ms"
    // Histogram is the "h" metric type,
    // difference from `Time` metric type is that `Time` writes milleseconds.
    // Read more at: https://docs.netdata.cloud/collectors/statsd.plugin/
    Histogram string = "h"
)

Read more at: https://github.com/etsy/statsd/blob/master/docs/metric_types.md

Example

Assuming that you have a statsd server running at :8125 (default port).

# assume the following codes in example.go file
$ cat example.go
package main

import (
	"fmt"
	"net/http"
	"strings"
	"time"

	"github.com/netdata/statsd"
)


// statusCodeReporter is a compatible `http.ResponseWriter`
// which stores the `statusCode` for further reporting.
type statusCodeReporter struct {
    http.ResponseWriter
    written    bool
    statusCode int
}

func (w *statusCodeReporter) WriteHeader(statusCode int) {
    if w.written {
        return
    }

    w.statusCode = statusCode
    w.ResponseWriter.WriteHeader(statusCode)
}

func (w *statusCodeReporter) Write(b []byte) (int, error) {
    w.written = true
    return w.ResponseWriter.Write(b)
}

func main() {
    statsWriter, err := statsd.UDP(":8125")
    if err != nil {
        panic(err)
    }

    statsD := statsd.NewClient(statsWriter, "prefix.")
    statsD.FlushEvery(5 * time.Second)

    statsDMiddleware := func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            path := r.URL.Path
            if len(path) == 1 {
                path = "index" // for root.
            } else if path == "/favicon.ico" {
                next.ServeHTTP(w, r)
                return
            } else {
                path = path[1:]
                path = strings.Replace(path, "/", ".", -1)
            }

            // HERE
            statsD.Increment(fmt.Sprintf("%s.request", path))
            
            newResponseWriter := &statusCodeReporter{ResponseWriter: w, statusCode: http.StatusOK}

            // HERE
            stop := statsD.Record(fmt.Sprintf("%s.time", path), 1)
            next.ServeHTTP(newResponseWriter, r)
            stop()

            // HERE
            statsD.Increment(fmt.Sprintf("%s.response.%d", path, newResponseWriter.statusCode))
        })
    }

    mux := http.DefaultServeMux

    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello from index")
    })

    mux.HandleFunc("/other", func(w http.ResponseWriter, r *http.Request) {
        // HERE
        statsD.Unique("other.unique", 1)

        fmt.Fprintln(w, "Hello from other page")
    })

    http.ListenAndServe(":8080", statsDMiddleware(mux))
}
# run example.go and visit http://localhost:8080/other
$ go run example.go

Navigate here to discover all available examples.

License

StatsD Go Client is licensed under the GNU GENERAL PUBLIC License.

Documentation

Overview

Package statsd implements is a client for https://github.com/etsy/statsd

Index

Constants

View Source
const (
	// Count is the "c" Counting statsd metric type.
	Count string = "c"
	// Gauge is the "g" Gauges statsd metric type.
	Gauge string = "g"
	// Unique is the "s" Sets statsd metric type.
	Unique string = "s"
	// Set is an alias for `Unique`.
	Set = Unique
	// Time is the "ms" Timing statsd metric type.
	Time string = "ms"
	// Histogram is the "h" metric type,
	// difference from `Time` metric type is that `Time` writes milleseconds.
	//
	// Read more at: https://docs.netdata.cloud/collectors/statsd.plugin/
	Histogram string = "h"
)

Types.

Variables

View Source
var (
	// Duration accepts a duration and returns a string of the duration's millesecond.
	Duration = func(v time.Duration) string { return Int(int(v / time.Millisecond)) }
	// Int accepts an int and returns its string form.
	Int = func(v int) string { return Int64(int64(v)) }
	// Int8 accepts an int8 and returns its string form.
	Int8 = func(v int8) string { return Int64(int64(v)) }
	// Int16 accepts an int16 and returns its string form.
	Int16 = func(v int16) string { return Int64(int64(v)) }
	// Int32 accepts an int32 and returns its string form.
	Int32 = func(v int32) string { return Int64(int64(v)) }
	// Int64 accepts an int64 and returns its string form.
	Int64 = func(v int64) string { return strconv.FormatInt(v, 10) }
	// Uint accepts an uint and returns its string form.
	Uint = func(v uint) string { return Uint64(uint64(v)) }
	// Uint8 accepts an uint8 and returns its string form.
	Uint8 = func(v uint8) string { return Uint64(uint64(v)) }
	// Uint16 accepts an uint16 and returns its string form.
	Uint16 = func(v uint16) string { return Uint64(uint64(v)) }
	// Uint32 accepts an uint32 and returns its string form.
	Uint32 = func(v uint32) string { return Uint64(uint64(v)) }
	// Uint64 accepts an uint64 and returns its string form.
	Uint64 = func(v uint64) string { return strconv.FormatUint(v, 10) }
	// Float32 accepts a float32 and returns its string form.
	Float32 = func(v float32) string { return Float64(float64(v)) }
	// Float64 accepts a float64 and returns its string form.
	Float64 = func(v float64) string { return strconv.FormatFloat(v, 'f', -1, 64) }
)

Values.

Functions

func UDP

func UDP(addr string) (io.WriteCloser, error)

UDP returns an `io.WriteCloser` from an `UDP` connection.

The "addr" should be the full UDP address of form: HOST:PORT. Usage: conn, _ := UDP(":8125") NewClient(conn, "my_prefix.")

Types

type Client

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

Client implements the StatsD Client. Look more at `WriteMetric`.

func NewClient

func NewClient(writeCloser io.WriteCloser, prefix string) *Client

NewClient returns a new StatsD client. The first input argument, "writeCloser", should be a value which completes the `io.WriteCloser` interface. It can be a UDP connection or a string buffer or even the stdout for testing.

The second input argument, "prefix" can be empty but it is usually the app's name + '.'.

Example: conn, err := UDP(":8125") if err != nil { panic(err) } client := NewClient(conn, "my_prefix.") defer client.Close() client.FlushEvery(4 *time.Second) [...] err := client.WriteMetric("my_metric", Int(1), Count, 0.5) ^ increment by one, sample rate at 0.5

Read more at: https://github.com/etsy/statsd/blob/master/docs/metric_types.md

func (*Client) Close

func (c *Client) Close() error

Close terminates the client, before closing it will try to write any pending metrics.

func (*Client) Count

func (c *Client) Count(metricName string, value int) error

Count is a shortcut of `Client#WriteMetric(metricName, statsd.Int(value), statsd.Count, 1)`.

func (*Client) Flush

func (c *Client) Flush(n int) error

Flush can be called manually, when `FlushEvery` is not configured, to flush the buffered metrics to the statsd server. Negative or zero "n" value will flush everything from the buffer. See `SetMaxPacketSize` too.

func (*Client) FlushEvery

func (c *Client) FlushEvery(dur time.Duration)

FlushEvery accepts a duration which is used to create a new ticker which will flush the buffered metrics on each tick.

func (*Client) Gauge

func (c *Client) Gauge(metricName string, value int) error

Gauge is a shortcut of `Client#WriteMetric(metricName, statsd.Int(value), statsd.Gauge, 1)`.

func (*Client) Histogram added in v0.0.2

func (c *Client) Histogram(metricName string, value int) error

Histogram writes a histogram metric value, difference from `Time` metric type is that `Time` writes milleseconds.

Histogram is a shortcut of `Client#WriteMetric(metricName, value, statsd.Histogram, 1)`.

Read more at: https://docs.netdata.cloud/collectors/statsd.plugin/

func (*Client) Increment

func (c *Client) Increment(metricName string) error

Increment is a shortcut of `Client#Count(metricName, 1)`.

func (*Client) IsClosed

func (c *Client) IsClosed() bool

IsClosed reports whether the client is closed or not.

func (*Client) Record

func (c *Client) Record(metricName string, rate float32) func() error

Record prepares a Timing metric which records a duration from now until the returned function is executed. For example: stop := client.Record("response.time."+ path, 1) next.ServeHTTP(w, r) stop() // This will write the metric of Timing with value of start time - stop time.

Extremely useful to capture http delays.

func (*Client) SetFormatter

func (c *Client) SetFormatter(fmt func(metricName string) string)

SetFormatter accepts a function which accepts the full metric name and returns a formatted string. Optionally, defaults to nil.

func (*Client) SetMaxPackageSize

func (c *Client) SetMaxPackageSize(maxPacketSize int)

SetMaxPackageSize sets the max buffer size, when exceeds it flushes the metrics to the statsd server.

Fast Ethernet (1432) - This is most likely for Intranets. Gigabit Ethernet (8932) - Jumbo frames can make use of this feature much more efficient. Commodity Internet (512) - If you are routing over the internet a value in this range will be reasonable. You might be able to go higher, but you are at the mercy of all the hops in your route.

Read more at: https://github.com/etsy/statsd/blob/master/docs/metric_types.md#multi-metric-packets Defaults to 1500. See `FlushEvery` and `Flush` too.

func (*Client) Time

func (c *Client) Time(metricName string, value time.Duration) error

Time is a shortcut of `Client#WriteMetric(metricName, statsd.Duration(value), statsd.Time, 1)`.

func (*Client) Unique

func (c *Client) Unique(metricName string, value int) error

Unique is a shortcut of `Client#WriteMetric(metricName, statsd.Int(value), statsd.Unique, 1)`.

Sampling rate is not supported on sets.

func (*Client) WriteMetric

func (c *Client) WriteMetric(metricName, value, typ string, rate float32) error

WriteMetric writes to the buffer a single metric. When metrics are "big" enough (see `SetMaxPacketSize`) then they will be flushed to the statsd server.

The "metricName" input argument is the metric name (prefix is setted automatically if any).

The "value" input argument is any string value, use the `Int`, `Int8`,`Int16`, `Int32`, `Int64` or `Uint`, `Uint8`, `Uint16`, `Uint32`, `Uint64` or `Float32`, `Float64` or `Duration` value helpers to convert a desired number to a string value. However if you are working on a custom statds server you may want to pass any supported value here.

The "typ" input argument is the type of the statsd, i.e "c"(statsd.Count),"ms"(statsd.Time),"g"(statsd.Gauge) and "s"(`statsd.Unique`)

The "rate" input argument is optional and defaults to 1. Use the `Client#Count`, `Client#Increment`, `Client#Gauge`, `Client#Unique`, `Client#Time`, `Client#Record` and `Client#Histogram` for common metrics instead.

Directories

Path Synopsis
_examples

Jump to

Keyboard shortcuts

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