Documentation
¶
Overview ¶
Package metrics implements Prometheus-compatible metrics for applications.
This package is lightweight alternative to https://github.com/prometheus/client_golang with simpler API and smaller dependencies.
Usage:
- Register the required metrics via New* functions.
- Expose them to `/metrics` page via WritePrometheus.
- Update the registered metrics during application lifetime.
The package has been extracted from https://victoriametrics.com/
Index ¶
- func SetTTL(ttl time.Duration)
- func WritePrometheus(w io.Writer, exposeProcessMetrics bool)
- type Counter
- type FloatCounter
- type Gauge
- type Histogram
- type Set
- func (s *Set) GetOrCreateCounter(name string) *Counter
- func (s *Set) GetOrCreateFloatCounter(name string) *FloatCounter
- func (s *Set) GetOrCreateGauge(name string) *Gauge
- func (s *Set) GetOrCreateHistogram(name string) *Histogram
- func (s *Set) GetOrCreateSummary(name string) *Summary
- func (s *Set) GetOrCreateSummaryExt(name string, window time.Duration, quantiles []float64) *Summary
- func (s *Set) NewCounter(name string) *Counter
- func (s *Set) NewFloatCounter(name string) *FloatCounter
- func (s *Set) NewGauge(name string) *Gauge
- func (s *Set) NewHistogram(name string) *Histogram
- func (s *Set) NewSummary(name string) *Summary
- func (s *Set) NewSummaryExt(name string, window time.Duration, quantiles []float64) *Summary
- func (s *Set) SetTTL(ttl time.Duration)
- func (s *Set) WritePrometheus(w io.Writer)
- type Summary
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func WritePrometheus ¶
WritePrometheus writes all the registered metrics in Prometheus format to w.
If exposeProcessMetrics is true, then various `go_*` and `process_*` metrics are exposed for the current process.
The WritePrometheus func is usually called inside "/metrics" handler:
http.HandleFunc("/metrics", func(w http.ResponseWriter, req *http.Request) {
metrics.WritePrometheus(w, true)
})
Example ¶
package main
import (
"net/http"
"github.com/faceair/metrics"
)
func main() {
// Export all the registered metrics in Prometheus format at `/metrics` http path.
http.HandleFunc("/metrics", func(w http.ResponseWriter, req *http.Request) {
metrics.WritePrometheus(w, true)
})
}
Output:
Types ¶
type Counter ¶
type Counter struct {
// contains filtered or unexported fields
}
Counter is a counter.
It may be used as a gauge if Dec and Set are called.
Example ¶
package main
import (
"fmt"
"github.com/faceair/metrics"
)
func main() {
// Define a counter in global scope.
var c = metrics.NewCounter(`metric_total{label1="value1", label2="value2"}`)
// Increment the counter when needed.
for i := 0; i < 10; i++ {
c.Inc()
}
n := c.Get()
fmt.Println(n)
}
Output: 10
Example (Vec) ¶
package main
import (
"fmt"
"github.com/faceair/metrics"
)
func main() {
for i := 0; i < 3; i++ {
// Dynamically construct metric name and pass it to GetOrCreateCounter.
name := fmt.Sprintf(`metric_total{label1=%q, label2="%d"}`, "value1", i)
metrics.GetOrCreateCounter(name).Add(i + 1)
}
// Read counter values.
for i := 0; i < 3; i++ {
name := fmt.Sprintf(`metric_total{label1=%q, label2="%d"}`, "value1", i)
n := metrics.GetOrCreateCounter(name).Get()
fmt.Println(n)
}
}
Output: 1 2 3
func GetOrCreateCounter ¶
GetOrCreateCounter returns registered counter with the given name or creates new counter if the registry doesn't contain counter with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned counter is safe to use from concurrent goroutines.
Performance tip: prefer NewCounter instead of GetOrCreateCounter.
func NewCounter ¶
NewCounter registers and returns new counter with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned counter is safe to use from concurrent goroutines.
type FloatCounter ¶
type FloatCounter struct {
// contains filtered or unexported fields
}
FloatCounter is a float64 counter guarded by RWmutex.
It may be used as a gauge if Add and Sub are called.
Example ¶
package main
import (
"fmt"
"github.com/faceair/metrics"
)
func main() {
// Define a float64 counter in global scope.
var fc = metrics.NewFloatCounter(`float_metric_total{label1="value1", label2="value2"}`)
// Add to the counter when needed.
for i := 0; i < 10; i++ {
fc.Add(1.01)
}
n := fc.Get()
fmt.Println(n)
}
Output: 10.1
Example (Vec) ¶
package main
import (
"fmt"
"github.com/faceair/metrics"
)
func main() {
for i := 0; i < 3; i++ {
// Dynamically construct metric name and pass it to GetOrCreateFloatCounter.
name := fmt.Sprintf(`float_metric_total{label1=%q, label2="%d"}`, "value1", i)
metrics.GetOrCreateFloatCounter(name).Add(float64(i) + 1.01)
}
// Read counter values.
for i := 0; i < 3; i++ {
name := fmt.Sprintf(`float_metric_total{label1=%q, label2="%d"}`, "value1", i)
n := metrics.GetOrCreateFloatCounter(name).Get()
fmt.Println(n)
}
}
Output: 1.01 2.01 3.01
func GetOrCreateFloatCounter ¶
func GetOrCreateFloatCounter(name string) *FloatCounter
GetOrCreateFloatCounter returns registered FloatCounter with the given name or creates new FloatCounter if the registry doesn't contain FloatCounter with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned FloatCounter is safe to use from concurrent goroutines.
Performance tip: prefer NewFloatCounter instead of GetOrCreateFloatCounter.
func NewFloatCounter ¶
func NewFloatCounter(name string) *FloatCounter
NewFloatCounter registers and returns new counter of float64 type with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned counter is safe to use from concurrent goroutines.
func (*FloatCounter) Get ¶
func (fc *FloatCounter) Get() float64
Get returns the current value for fc.
type Gauge ¶
type Gauge struct {
// contains filtered or unexported fields
}
Gauge is a float64 gauge.
See also Counter, which could be used as a gauge with Set and Dec calls.
Example ¶
package main
import (
"fmt"
"runtime"
"github.com/faceair/metrics"
)
func main() {
// Define a gauge exporting the number of goroutines.
var g = metrics.NewGauge(`goroutines_count`)
g.Set(float64(runtime.NumGoroutine()))
// Obtain gauge value.
fmt.Println(g.Get())
}
Output:
Example (Vec) ¶
package main
import (
"fmt"
"github.com/faceair/metrics"
)
func main() {
for i := 0; i < 3; i++ {
// Dynamically construct metric name and pass it to GetOrCreateGauge.
name := fmt.Sprintf(`metric{label1=%q, label2="%d"}`, "value1", i)
gauge := metrics.GetOrCreateGauge(name)
gauge.Set(float64(i))
}
// Read counter values.
for i := 0; i < 3; i++ {
name := fmt.Sprintf(`metric{label1=%q, label2="%d"}`, "value1", i)
n := metrics.GetOrCreateGauge(name).Get()
fmt.Println(n)
}
}
Output: 0 1 2
func GetOrCreateGauge ¶
GetOrCreateGauge returns registered gauge with the given name or creates new gauge if the registry doesn't contain gauge with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned gauge is safe to use from concurrent goroutines.
Performance tip: prefer NewGauge instead of GetOrCreateGauge.
func NewGauge ¶
NewGauge registers and returns gauge with the given name, which calls f to obtain gauge value.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
f must be safe for concurrent calls.
The returned gauge is safe to use from concurrent goroutines.
type Histogram ¶
type Histogram struct {
// contains filtered or unexported fields
}
Histogram is a histogram for non-negative values with automatically created buckets.
See https://medium.com/@valyala/improving-histogram-usability-for-prometheus-and-grafana-bc7e5df0e350
Each bucket contains a counter for values in the given range. Each non-empty bucket is exposed via the following metric:
<metric_name>_bucket{<optional_tags>,vmrange="<start>...<end>"} <counter>
Where:
- <metric_name> is the metric name passed to NewHistogram
- <optional_tags> is optional tags for the <metric_name>, which are passed to NewHistogram
- <start> and <end> - start and end values for the given bucket
- <counter> - the number of hits to the given bucket during Update* calls
Histogram buckets can be converted to Prometheus-like buckets with `le` labels with `prometheus_buckets(<metric_name>_bucket)` function from PromQL extensions in VictoriaMetrics. (see https://github.com/VictoriaMetrics/VictoriaMetrics/wiki/ExtendedPromQL ):
prometheus_buckets(request_duration_bucket)
Time series produced by the Histogram have better compression ratio comparing to Prometheus histogram buckets with `le` labels, since they don't include counters for all the previous buckets.
Zero histogram is usable.
Example ¶
// Define a histogram in global scope.
var h = metrics.NewHistogram(`request_duration_seconds{path="/foo/bar"}`)
// Update the histogram with the duration of processRequest call.
startTime := time.Now()
processRequest()
h.UpdateDuration(startTime)
Example (Vec) ¶
for i := 0; i < 3; i++ {
// Dynamically construct metric name and pass it to GetOrCreateHistogram.
name := fmt.Sprintf(`response_size_bytes{path=%q}`, "/foo/bar")
response := processRequest()
metrics.GetOrCreateHistogram(name).Update(float64(len(response)))
}
func GetOrCreateHistogram ¶
GetOrCreateHistogram returns registered histogram with the given name or creates new histogram if the registry doesn't contain histogram with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned histogram is safe to use from concurrent goroutines.
Performance tip: prefer NewHistogram instead of GetOrCreateHistogram.
func NewHistogram ¶
NewHistogram creates and returns new histogram with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned histogram is safe to use from concurrent goroutines.
func (*Histogram) UpdateDuration ¶
UpdateDuration updates request duration based on the given startTime.
func (*Histogram) VisitNonZeroBuckets ¶
VisitNonZeroBuckets calls f for all buckets with non-zero counters.
vmrange contains "<start>...<end>" string with bucket bounds. The lower bound isn't included in the bucket, while the upper bound is included. This is required to be compatible with Prometheus-style histogram buckets with `le` (less or equal) labels.
type Set ¶
type Set struct {
// contains filtered or unexported fields
}
Set is a set of metrics.
Metrics belonging to a set are exported separately from global metrics.
Set.WritePrometheus must be called for exporting metrics from the set.
Example ¶
package main
import (
"bytes"
"fmt"
"github.com/faceair/metrics"
)
func main() {
// Create a set with a counter
s := metrics.NewSet()
sc := s.NewCounter("set_counter")
sc.Inc()
s.NewGauge(`set_gauge{foo="bar"}`, func() float64 { return 42 })
// Dump metrics from s.
var bb bytes.Buffer
s.WritePrometheus(&bb)
fmt.Printf("set metrics:\n%s\n", bb.String())
}
Output: set metrics: set_counter 1 set_gauge{foo="bar"} 42
func (*Set) GetOrCreateCounter ¶
GetOrCreateCounter returns registered counter in s with the given name or creates new counter if s doesn't contain counter with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned counter is safe to use from concurrent goroutines.
Performance tip: prefer NewCounter instead of GetOrCreateCounter.
func (*Set) GetOrCreateFloatCounter ¶
func (s *Set) GetOrCreateFloatCounter(name string) *FloatCounter
GetOrCreateFloatCounter returns registered FloatCounter in s with the given name or creates new FloatCounter if s doesn't contain FloatCounter with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned FloatCounter is safe to use from concurrent goroutines.
Performance tip: prefer NewFloatCounter instead of GetOrCreateFloatCounter.
func (*Set) GetOrCreateGauge ¶
GetOrCreateGauge returns registered gauge with the given name in s or creates new gauge if s doesn't contain gauge with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned gauge is safe to use from concurrent goroutines.
Performance tip: prefer NewGauge instead of GetOrCreateGauge.
func (*Set) GetOrCreateHistogram ¶
GetOrCreateHistogram returns registered histogram in s with the given name or creates new histogram if s doesn't contain histogram with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned histogram is safe to use from concurrent goroutines.
Performance tip: prefer NewHistogram instead of GetOrCreateHistogram.
func (*Set) GetOrCreateSummary ¶
GetOrCreateSummary returns registered summary with the given name in s or creates new summary if s doesn't contain summary with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned summary is safe to use from concurrent goroutines.
Performance tip: prefer NewSummary instead of GetOrCreateSummary.
func (*Set) GetOrCreateSummaryExt ¶
func (s *Set) GetOrCreateSummaryExt(name string, window time.Duration, quantiles []float64) *Summary
GetOrCreateSummaryExt returns registered summary with the given name, window and quantiles in s or creates new summary if s doesn't contain summary with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned summary is safe to use from concurrent goroutines.
Performance tip: prefer NewSummaryExt instead of GetOrCreateSummaryExt.
func (*Set) NewCounter ¶
NewCounter registers and returns new counter with the given name in the s.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned counter is safe to use from concurrent goroutines.
func (*Set) NewFloatCounter ¶
func (s *Set) NewFloatCounter(name string) *FloatCounter
NewFloatCounter registers and returns new FloatCounter with the given name in the s.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned FloatCounter is safe to use from concurrent goroutines.
func (*Set) NewGauge ¶
NewGauge registers and returns gauge with the given name in s, which calls f to obtain gauge value.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
f must be safe for concurrent calls.
The returned gauge is safe to use from concurrent goroutines.
func (*Set) NewHistogram ¶
NewHistogram creates and returns new histogram in s with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned histogram is safe to use from concurrent goroutines.
func (*Set) NewSummary ¶
NewSummary creates and returns new summary with the given name in s.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned summary is safe to use from concurrent goroutines.
func (*Set) NewSummaryExt ¶
NewSummaryExt creates and returns new summary in s with the given name, window and quantiles.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned summary is safe to use from concurrent goroutines.
func (*Set) WritePrometheus ¶
WritePrometheus writes all the metrics from s to w in Prometheus format.
type Summary ¶
type Summary struct {
// contains filtered or unexported fields
}
Summary implements summary.
Example ¶
package main
import (
"time"
"github.com/faceair/metrics"
)
func main() {
// Define a summary in global scope.
var s = metrics.NewSummary(`request_duration_seconds{path="/foo/bar"}`)
// Update the summary with the duration of processRequest call.
startTime := time.Now()
processRequest()
s.UpdateDuration(startTime)
}
func processRequest() string {
return "foobar"
}
Output:
Example (Vec) ¶
package main
import (
"fmt"
"github.com/faceair/metrics"
)
func main() {
for i := 0; i < 3; i++ {
// Dynamically construct metric name and pass it to GetOrCreateSummary.
name := fmt.Sprintf(`response_size_bytes{path=%q}`, "/foo/bar")
response := processRequest()
metrics.GetOrCreateSummary(name).Update(float64(len(response)))
}
}
func processRequest() string {
return "foobar"
}
Output:
func GetOrCreateSummary ¶
GetOrCreateSummary returns registered summary with the given name or creates new summary if the registry doesn't contain summary with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned summary is safe to use from concurrent goroutines.
Performance tip: prefer NewSummary instead of GetOrCreateSummary.
func GetOrCreateSummaryExt ¶
GetOrCreateSummaryExt returns registered summary with the given name, window and quantiles or creates new summary if the registry doesn't contain summary with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned summary is safe to use from concurrent goroutines.
Performance tip: prefer NewSummaryExt instead of GetOrCreateSummaryExt.
func NewSummary ¶
NewSummary creates and returns new summary with the given name.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned summary is safe to use from concurrent goroutines.
func NewSummaryExt ¶
NewSummaryExt creates and returns new summary with the given name, window and quantiles.
name must be valid Prometheus-compatible metric with possible labels. For instance,
- foo
- foo{bar="baz"}
- foo{bar="baz",aaa="b"}
The returned summary is safe to use from concurrent goroutines.
func (*Summary) UpdateDuration ¶
UpdateDuration updates request duration based on the given startTime.