Go port of Coda Hale's Metrics library

go-metrics

travis build status

Go port of Coda Hale's Metrics library: https://github.com/dropwizard/metrics.

Documentation: http://godoc.org/github.com/rcrowley/go-metrics.

Usage

Create and update metrics:

c := metrics.NewCounter()
metrics.Register("foo", c)
c.Inc(47)

g := metrics.NewGauge()
metrics.Register("bar", g)
g.Update(47)

r := NewRegistry()
g := metrics.NewRegisteredFunctionalGauge("cache-evictions", r, func() int64 { return cache.getEvictionsCount() })

s := metrics.NewExpDecaySample(1028, 0.015) // or metrics.NewUniformSample(1028)
h := metrics.NewHistogram(s)
metrics.Register("baz", h)
h.Update(47)

m := metrics.NewMeter()
metrics.Register("quux", m)
m.Mark(47)

t := metrics.NewTimer()
metrics.Register("bang", t)
t.Time(func() {})
t.Update(47)

Register() is not threadsafe. For threadsafe metric registration use GetOrRegister:

t := metrics.GetOrRegisterTimer("account.create.latency", nil)
t.Time(func() {})
t.Update(47)

NOTE: Be sure to unregister short-lived meters and timers otherwise they will leak memory:

// Will call Stop() on the Meter to allow for garbage collection
metrics.Unregister("quux")
// Or similarly for a Timer that embeds a Meter
metrics.Unregister("bang")

Periodically log every metric in human-readable form to standard error:

go metrics.Log(metrics.DefaultRegistry, 5 * time.Second, log.New(os.Stderr, "metrics: ", log.Lmicroseconds))

Periodically log every metric in slightly-more-parseable form to syslog:

w, _ := syslog.Dial("unixgram", "/dev/log", syslog.LOG_INFO, "metrics")
go metrics.Syslog(metrics.DefaultRegistry, 60e9, w)

Periodically emit every metric to Graphite using the Graphite client:

import "github.com/cyberdelia/go-metrics-graphite"

addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:2003")
go graphite.Graphite(metrics.DefaultRegistry, 10e9, "metrics", addr)

Periodically emit every metric into InfluxDB:

NOTE: this has been pulled out of the library due to constant fluctuations in the InfluxDB API. In fact, all client libraries are on their way out. see issues #121 and #124 for progress and details.

import "github.com/vrischmann/go-metrics-influxdb"

go influxdb.InfluxDB(metrics.DefaultRegistry,
  10e9, 
  "127.0.0.1:8086", 
  "database-name", 
  "username", 
  "password"
)

Periodically upload every metric to Librato using the Librato client:

Note: the client included with this repository under the librato package has been deprecated and moved to the repository linked above.

import "github.com/mihasya/go-metrics-librato"

go librato.Librato(metrics.DefaultRegistry,
    10e9,                  // interval
    "[email protected]", // account owner email address
    "token",               // Librato API token
    "hostname",            // source
    []float64{0.95},       // percentiles to send
    time.Millisecond,      // time unit
)

Periodically emit every metric to StatHat:

import "github.com/rcrowley/go-metrics/stathat"

go stathat.Stathat(metrics.DefaultRegistry, 10e9, "[email protected]")

Maintain all metrics along with expvars at /debug/metrics:

This uses the same mechanism as the official expvar but exposed under /debug/metrics, which shows a json representation of all your usual expvars as well as all your go-metrics.

import "github.com/rcrowley/go-metrics/exp"

exp.Exp(metrics.DefaultRegistry)

Installation

go get github.com/rcrowley/go-metrics

StatHat support additionally requires their Go client:

go get github.com/stathat/go

Publishing Metrics

Clients are available for the following destinations:

Comments
  • add riemann package to report metrics to riemann

    add riemann package to report metrics to riemann

    hi,

    We use riemann and so have added a package to report events to there. The code can't be immediately pulled in without changing the import to reference rcrowley/go-metrics rather than pingles/go-metrics but that should be it.

    Hope it's useful, Paul @ uSwitch

  • Reduces lock-contention in high-performance usage of go-metrics.

    Reduces lock-contention in high-performance usage of go-metrics.

    Remove lock contention in go-metrics in a few key places. For all of these changes there is expectation around CPU performance gain but the real benefit is reduced lock contention which shows up as significant bottlenecks in both Go 1.9 and Go 1.10 for high performance services.

    1. gauge_float64.go
    • Removes the mutex lock around the internal value field in favor of atomic ops.
    • Changes the value field to be an uint64 (no precision is lost) and does conversions
    • Utilizes atomic.Load/atomic.Store to reduce lock contention
    • Adds a parallel benchmark
    BEFORE:
    BenchmarkGuageFloat64Parallel-8   	20000000	        88.1 ns/op	       0 B/op	       0 allocs/op
    AFTER:
    BenchmarkGuageFloat64Parallel-8   	50000000	        28.8 ns/op	       0 B/op	       0 allocs/op
    
    1. ewma.go
    • Removes lock contention around a few fields in favor of atomic ops.
    • For the mutex lock in place this lock is only taken on the first Tick() operation only
    • Adds a parallel benchmark
    BEFORE:
    BenchmarkEWMAParallel-8   	20000000	        99.4 ns/op	       0 B/op	       0 allocs/op
    AFTER:
    BenchmarkEWMAParallel-8   	20000000	        74.5 ns/op	       0 B/op	       0 allocs/op
    
    1. meter.go
    • Removes lock contention around multiple fields in favor of atomic ops.
    • Mutex locking is left in places where there is not high concurrency such as tickMeters and Stop.
    • Adds a parallel benchmark
    BEFORE:
    BenchmarkMeterParallel-8   	 3000000	       467 ns/op	       0 B/op	       0 allocs/op
    AFTER:
    BenchmarkMeterParallel-8   	10000000	       169 ns/op	       0 B/op	       0 allocs/op
    
  • speed up registry Each method

    speed up registry Each method

    Creating a map entry with a string type as key leads to a copy of that string in Go. Iterating via Each creates a lot of these entries, especially while reporting lots of values to a remote metrics system.

    Our use case is modelled with HugeRegistry and the below benchmarks show improvements there to to the removed memory allocation.

    name                  old time/op    new time/op    delta
    Counter-4               9.83ns ± 0%   10.03ns ± 1%   +2.03%          (p=0.016 n=4+5)
    GuageFloat64-4          62.7ns ± 4%    60.6ns ± 1%   -3.38%          (p=0.008 n=5+5)
    Histogram-4              117ns ± 3%     129ns ± 4%  +10.26%          (p=0.008 n=5+5)
    Registry-4               760ns ± 2%     232ns ± 2%  -69.52%          (p=0.008 n=5+5)
    HugeRegistry-4          2.58ms ± 3%    0.82ms ± 1%  -68.10%          (p=0.008 n=5+5)
    UniformSample257-4       108ns ± 2%     123ns ± 5%  +13.10%          (p=0.008 n=5+5)
    UniformSample514-4       106ns ± 2%     118ns ± 5%  +10.90%          (p=0.008 n=5+5)
    UniformSample1028-4      106ns ± 1%     119ns ± 2%  +12.43%          (p=0.008 n=5+5)
    
    name                  old alloc/op   new alloc/op   delta
    Registry-4                336B ± 0%       32B ± 0%  -90.48%          (p=0.008 n=5+5)
    HugeRegistry-4           598kB ± 0%     328kB ± 0%     ~             (p=0.079 n=4+5)
    
    name                  old allocs/op  new allocs/op  delta
    Registry-4                2.00 ± 0%      1.00 ± 0%  -50.00%          (p=0.008 n=5+5)
    HugeRegistry-4            5.00 ± 0%      3.00 ± 0%  -40.00%          (p=0.008 n=5+5)
    
  • consider merging with armon's go-metrics

    consider merging with armon's go-metrics

    @armon is a maintainer of serf and statsite. He also has a project with the same name and goal as yours: https://github.com/armon/go-metrics

    Perhaps you might consider combining effort?

  • Implementing gauge as a callback

    Implementing gauge as a callback

    In the spirit of how gauge is implemented in the original codahale metrics shouldn't the gauge type "pull values"? Maybe by accepting a function pointer and starting a goroutine to call the function on a fixed interval to retrieve value. It can also use a task manager to avoid spawning too many goroutines.

  • Histogram's Max() and probably others

    Histogram's Max() and probably others

    Histogram's Max() (and probably other, similar functions) are wrong and store values independently of the Sample being used. This means that Max() on a Histogram backed by an ExpDecaySample doesn't return the sample's current Max.

    I read through the related @codahale's metrics implementation and they solve this by taking a snapshot of the sample (there it's called a Reservoir) during reporting. The snapshot is what has functions like Max() on it.

    This is a nice abstraction, allowing the different Sample implementation deal with handling values, letting the snapshot tell you about the values of a sample at a given time, etc.

    Would you consider a patch that re-organizes things and inserts Snapshots in between Samples and Histograms?

  • ChildRegistry should filter by prefix

    ChildRegistry should filter by prefix

    This commit changes the behavior of PrefixedChildRegistry to only apply the Each function to registered metrics that have the the appropriate prefix.

    This commit contains two changes: 1: An originally failing test showing the behavior 2: A wrapper func around the passed in function for Each that applies the required filter

    The behavior that this addresses was quite unexpected, but happy to discuss if this was the intended behavior.

  • Expose stable copies of a Histogram's Sample with statistics methods

    Expose stable copies of a Histogram's Sample with statistics methods

    Here's my proposal for addressing #26 and #31.

    I still have to tackle how to expose the Sample-based Count, Max, Mean, and Min to the various reporters. Ideas are welcome.

  • Influx dependency broken

    Influx dependency broken

    Influxdb's client package broke their public API. I'll try to create a snapshot from the last valid version and PR with a new import path for go-metrics.

  • Unable to use non-integer metrics for gauge and meter.

    Unable to use non-integer metrics for gauge and meter.

    The code does not allow for non-integer metrics for gauge and meter. This was not the case in the original codahale metrics and I would like to understand the reasoning behind this limitation.

  • Increment and Decrement methods on Gauge

    Increment and Decrement methods on Gauge

    How would you feel about supporting Inc() and Dec() methods on the gauge type? A motivating use case that's come up for me is wanting to track the number of things that are currently in some undesirable state but may leave that state later.

    For example, to track the number of requests that have been waiting on a response for more than a minute -- we'd increment the gauge once a request had been waiting for at least a minute, and decrement the gauge once the request completes. Doing this with a gauge gives more information than with a counter, since we can decrement it once the request is done.

    Adding these methods would add incredibly little code to the repo. If this sounds alright, I'll send a quick PR for it. What do you think?

    @mihasya

  • Do we expect `StandardEWMA.Tick` to be called concurrently?

    Do we expect `StandardEWMA.Tick` to be called concurrently?

    Do we expect StandardEWMA.Tick to be called concurrently?

    If not, then there's no need to use a mutex and atomic operations on a.init, just below code is fine:

        if a.init == 0 {
            atomic.StoreUint64(&a.rate, math.Float64bits(a.fetchInstantRate())) 
            a.init = 1
        } else {
             a.updateRate(a.fetchInstantRate()) 
        }
    

    if yes, then the current implementation is incorrect, because, after the current goroutine executed L115, other goroutines could execute L103, which creates a race condition with L116 of the current goroutine, and L103 itself could create race conditions between concurrent goroutines.

    https://github.com/rcrowley/go-metrics/blob/cf1acfcdf4751e0554ffa765d03e479ec491cad6/ewma.go#L100-L120

  • [Question] Count by range of timer metrics?

    [Question] Count by range of timer metrics?

    Hi, is there any way that I can the ranges with their counts for a timer metric? Something like this:

    0-10ms: 9123 requests
    10-50ms: 234 requests
    50-100ms: 67 requests
    100-200ms: 89 requests
    200-500ms: 4 requests
    500-1000ms: 3 requests
    1000ms+: 7 requests
    

    I'm sorry if this is a duplicate question. I searched for anything like this, but couldn't find any issue about it.

Type-safe Prometheus metrics builder library for golang

gotoprom A Prometheus metrics builder gotoprom offers an easy to use declarative API with type-safe labels for building and using Prometheus metrics.

Dec 5, 2022
Go binding to libserialport for serial port functionality.

Go Serial Package serial provides a binding to libserialport for serial port functionality. Serial ports are commonly used with embedded systems, such

Nov 1, 2022
Lima launches Linux virtual machines on macOS, with automatic file sharing, port forwarding, and containerd.

Lima: Linux-on-Mac ("macOS subsystem for Linux", "containerd for Mac")

Jan 8, 2023
Entitas-Go is a fast Entity Component System Framework (ECS) Go 1.17 port of Entitas v1.13.0 for C# and Unity.

Entitas-Go Entitas-GO is a fast Entity Component System Framework (ECS) Go 1.17 port of Entitas v1.13.0 for C# and Unity. Code Generator Install the l

Dec 26, 2022
Minecraft Port Knock With Golang

Minecraft Port Knock A simple program that performs two duties: Monitor a Minecraft server and stop it after it has been empty for some amount of time

Jan 11, 2022
A simple tool to send binary data over a serial port. Designed for use with my retro computer systems.

Colin's Transfer Tool This is a really basic tool to transfer firmware files to my retro computer systems over a serial port. This removes the need fo

Dec 21, 2021
A Go package to allow you to read and write from the serial port as a stream of bytes.

Serial A Go package to allow you to read and write from the serial port as a stream of bytes. Details It aims to have the same API on all platforms, i

Jan 6, 2023
A tool to run queries in defined frequency and expose the count as prometheus metrics.
A tool to run queries in defined frequency and expose the count as prometheus metrics.

A tool to run queries in defined frequency and expose the count as prometheus metrics. Supports MongoDB and SQL

Jul 1, 2022
Prometheus support for go-metrics

go-metrics-prometheus This is a reporter for the go-metrics library which will post the metrics to the prometheus client registry . It just updates th

Nov 13, 2022
a tool for getting metrics in containers

read metrics in container if environment is container, the cpu ,memory is relative to container, else the metrics is relative to host. juejing link :

Oct 13, 2022
Collect and visualize metrics from Brigade 2

Brigade Metrics: Monitoring for Brigade 2 Brigade Metrics adds monitoring capabilities to a Brigade 2 installation. It utilizes Brigade APIs to export

Sep 8, 2022
Count Dracula is a fast metrics server that counts entries while automatically expiring old ones

In-Memory Expirable Key Counter This is a fast metrics server, ideal for tracking throttling. Put values to the server, and then count them. Values ex

Jun 17, 2022
rsync wrapper (or output parser) that pushes metrics to prometheus

rsync-prom An rsync wrapper (or output parser) that pushes metrics to prometheus. This allows you to then build dashboards and alerting for your rsync

Dec 11, 2022
Service for firewalling graphite metrics

hadrianus Block incoming graphite metrics if they come in too fast for downstream carbon-relay/carbon-cache to handle. Building Hadrianus is written i

Apr 28, 2022
mackerel-agent is an agent program to post your hosts' metrics to mackerel.io.
mackerel-agent is an agent program to post your hosts' metrics to mackerel.io.

mackerel-agent mackerel-agent is a client software for Mackerel. Mackerel is an online visualization and monitoring service for servers. Once mackerel

Jan 7, 2023
Library to work with MimeHeaders and another mime types. Library support wildcards and parameters.

Mime header Motivation This library created to help people to parse media type data, like headers, and store and match it. The main features of the li

Nov 9, 2022
Evolutionary optimization library for Go (genetic algorithm, partical swarm optimization, differential evolution)
Evolutionary optimization library for Go (genetic algorithm, partical swarm optimization, differential evolution)

eaopt is an evolutionary optimization library Table of Contents Changelog Example Background Features Usage General advice Genetic algorithms Overview

Dec 30, 2022
cross-platform, normalized battery information library

battery Cross-platform, normalized battery information library. Gives access to a system independent, typed battery state, capacity, charge and voltag

Dec 22, 2022
GoLang Library for Browser Capabilities Project

Browser Capabilities GoLang Project PHP has get_browser() function which tells what the user's browser is capable of. You can check original documenta

Sep 27, 2022