2017-03-31 18:01:58 +02:00
|
|
|
# package metrics
|
|
|
|
|
|
|
|
`package metrics` provides a set of uniform interfaces for service instrumentation.
|
|
|
|
It has
|
|
|
|
[counters](http://prometheus.io/docs/concepts/metric_types/#counter),
|
|
|
|
[gauges](http://prometheus.io/docs/concepts/metric_types/#gauge), and
|
|
|
|
[histograms](http://prometheus.io/docs/concepts/metric_types/#histogram),
|
|
|
|
and provides adapters to popular metrics packages, like
|
|
|
|
[expvar](https://golang.org/pkg/expvar),
|
|
|
|
[StatsD](https://github.com/etsy/statsd), and
|
|
|
|
[Prometheus](https://prometheus.io).
|
|
|
|
|
|
|
|
## Rationale
|
|
|
|
|
|
|
|
Code instrumentation is absolutely essential to achieve
|
|
|
|
[observability](https://speakerdeck.com/mattheath/observability-in-micro-service-architectures)
|
|
|
|
into a distributed system.
|
|
|
|
Metrics and instrumentation tools have coalesced around a few well-defined idioms.
|
|
|
|
`package metrics` provides a common, minimal interface those idioms for service authors.
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
A simple counter, exported via expvar.
|
|
|
|
|
|
|
|
```go
|
|
|
|
import (
|
|
|
|
"github.com/go-kit/kit/metrics"
|
|
|
|
"github.com/go-kit/kit/metrics/expvar"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
var myCount metrics.Counter
|
|
|
|
myCount = expvar.NewCounter("my_count")
|
|
|
|
myCount.Add(1)
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
A histogram for request duration,
|
|
|
|
exported via a Prometheus summary with dynamically-computed quantiles.
|
|
|
|
|
|
|
|
```go
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
|
|
|
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
|
|
|
|
|
|
|
"github.com/go-kit/kit/metrics"
|
|
|
|
"github.com/go-kit/kit/metrics/prometheus"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
2017-05-18 18:54:23 +02:00
|
|
|
var dur metrics.Histogram = prometheus.NewSummary(stdprometheus.SummaryOpts{
|
2017-03-31 18:01:58 +02:00
|
|
|
Namespace: "myservice",
|
|
|
|
Subsystem: "api",
|
|
|
|
Name: "request_duration_seconds",
|
|
|
|
Help: "Total time spent serving requests.",
|
|
|
|
}, []string{})
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
|
|
|
|
func handleRequest(dur metrics.Histogram) {
|
|
|
|
defer func(begin time.Time) { dur.Observe(time.Since(begin).Seconds()) }(time.Now())
|
|
|
|
// handle request
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
A gauge for the number of goroutines currently running, exported via StatsD.
|
|
|
|
|
|
|
|
```go
|
|
|
|
import (
|
|
|
|
"net"
|
|
|
|
"os"
|
|
|
|
"runtime"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/go-kit/kit/metrics"
|
|
|
|
"github.com/go-kit/kit/metrics/statsd"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
statsd := statsd.New("foo_svc.", log.NewNopLogger())
|
|
|
|
report := time.NewTicker(5 * time.Second)
|
|
|
|
defer report.Stop()
|
|
|
|
go statsd.SendLoop(report.C, "tcp", "statsd.internal:8125")
|
|
|
|
goroutines := statsd.NewGauge("goroutine_count")
|
|
|
|
go exportGoroutines(goroutines)
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
|
|
|
|
func exportGoroutines(g metrics.Gauge) {
|
|
|
|
for range time.Tick(time.Second) {
|
|
|
|
g.Set(float64(runtime.NumGoroutine()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|