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)
Output:
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))) }
Output:
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.