metrics

package module
v1.6.1 Latest Latest
Warning

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

Go to latest
Published: Jun 28, 2019 License: MIT Imports: 11 Imported by: 372

README

Build Status GoDoc Go Report codecov

metrics - lightweight package for exporting metrics in Prometheus format

Features
  • Lightweight. Has minimal number of third-party dependencies and all these deps are small. See this article for details.
  • Easy to use. See the API docs.
  • Fast.
  • Allows exporting distinct metric sets via distinct endpoints. See Set.
Limitations
Usage
import "github.com/VictoriaMetrics/metrics"

// Register various time series.
// Time series name may contain labels in Prometheus format - see below.
var (
	// Register counter without labels.
	requestsTotal = metrics.NewCounter("requests_total")

	// Register summary with a single label.
	requestDuration = metrics.NewSummary(`requests_duration_seconds{path="/foobar/baz"}`)

	// Register gauge with two labels.
	queueSize = metrics.NewGauge(`queue_size{queue="foobar",topic="baz"}`, func() float64 {
		return float64(foobarQueue.Len())
	})
)

// ...
func requestHandler() {
	// Increment requestTotal counter.
	requestsTotal.Inc()

	startTime := time.Now()
	processRequest()
	// Update requestDuration summary.
	requestDuration.UpdateDuration(startTime)
}

// Expose the registered metrics at `/metrics` path.
http.HandleFunc("/metrics", func(w http.ResponseWriter, req *http.Request) {
	metrics.WritePrometheus(w, true)
})

See docs for more info.

Users
FAQ
Why the metrics API isn't compatible with github.com/prometheus/client_golang?

Because the github.com/prometheus/client_golang is too complex and is hard to use.

Why the metrics.WritePrometheus doesn't expose documentation for each metric?

Because this documentation is ignored by Prometheus. The documentation is for users. Just add comments in the source code or in other suitable place explaining each metric exposed from your application.

How to implement CounterVec in metrics?

Just use GetOrCreateCounter instead of CounterVec.With. See this example for details.

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:

  1. Register the required metrics via New* functions.
  2. Expose them to `/metrics` page via WritePrometheus.
  3. Update the registered metrics during application lifetime.

The package has been extracted from https://victoriametrics.com/

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func WritePrometheus

func WritePrometheus(w io.Writer, exposeProcessMetrics bool)

WritePrometheus writes all the registered metrics in Prometheus format to w.

If exposeProcessMetrics is true, then various `go_*` 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/VictoriaMetrics/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/VictoriaMetrics/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/VictoriaMetrics/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 added in v1.2.0

func GetOrCreateCounter(name string) *Counter

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 lables. 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

func NewCounter(name string) *Counter

NewCounter registers and returns new counter with the given name.

name must be valid Prometheus-compatible metric with possible lables. For instance,

  • foo
  • foo{bar="baz"}
  • foo{bar="baz",aaa="b"}

The returned counter is safe to use from concurrent goroutines.

func (*Counter) Add

func (c *Counter) Add(n int)

Add adds n to c.

func (*Counter) Dec

func (c *Counter) Dec()

Dec decrements c.

func (*Counter) Get

func (c *Counter) Get() uint64

Get returns the current value for c.

func (*Counter) Inc

func (c *Counter) Inc()

Inc increments c.

func (*Counter) Set

func (c *Counter) Set(n uint64)

Set sets c value to n.

type Gauge added in v1.1.0

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/VictoriaMetrics/metrics"
)

func main() {
	// Define a gauge exporting the number of goroutines.
	var g = metrics.NewGauge(`goroutines_count`, func() float64 {
		return float64(runtime.NumGoroutine())
	})

	// Obtain gauge value.
	fmt.Println(g.Get())
}
Output:

Example (Vec)
package main

import (
	"fmt"

	"github.com/VictoriaMetrics/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)
		iLocal := i
		metrics.GetOrCreateGauge(name, func() float64 {
			return float64(iLocal + 1)
		})
	}

	// Read counter values.
	for i := 0; i < 3; i++ {
		name := fmt.Sprintf(`metric{label1=%q, label2="%d"}`, "value1", i)
		n := metrics.GetOrCreateGauge(name, func() float64 { return 0 }).Get()
		fmt.Println(n)
	}

}
Output:

1
2
3

func GetOrCreateGauge added in v1.4.0

func GetOrCreateGauge(name string, f func() float64) *Gauge

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 lables. 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

func NewGauge(name string, f func() float64) *Gauge

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.

func (*Gauge) Get added in v1.1.0

func (g *Gauge) Get() float64

Get returns the current value for g.

type Set added in v1.5.0

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/VictoriaMetrics/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 NewSet added in v1.5.0

func NewSet() *Set

NewSet creates new set of metrics.

func (*Set) GetOrCreateCounter added in v1.5.0

func (s *Set) GetOrCreateCounter(name string) *Counter

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 lables. 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) GetOrCreateGauge added in v1.5.0

func (s *Set) GetOrCreateGauge(name string, f func() float64) *Gauge

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 lables. 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) GetOrCreateSummary added in v1.5.0

func (s *Set) GetOrCreateSummary(name string) *Summary

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 lables. 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 added in v1.5.0

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 lables. 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 added in v1.5.0

func (s *Set) NewCounter(name string) *Counter

NewCounter registers and returns new counter with the given name in the s.

name must be valid Prometheus-compatible metric with possible lables. For instance,

  • foo
  • foo{bar="baz"}
  • foo{bar="baz",aaa="b"}

The returned counter is safe to use from concurrent goroutines.

func (*Set) NewGauge added in v1.5.0

func (s *Set) NewGauge(name string, f func() float64) *Gauge

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) NewSummary added in v1.5.0

func (s *Set) NewSummary(name string) *Summary

NewSummary creates and returns new summary with the given name in s.

name must be valid Prometheus-compatible metric with possible lables. For instance,

  • foo
  • foo{bar="baz"}
  • foo{bar="baz",aaa="b"}

The returned summary is safe to use from concurrent goroutines.

func (*Set) NewSummaryExt added in v1.5.0

func (s *Set) NewSummaryExt(name string, window time.Duration, quantiles []float64) *Summary

NewSummaryExt creates and returns new summary in s with the given name, window and quantiles.

name must be valid Prometheus-compatible metric with possible lables. For instance,

  • foo
  • foo{bar="baz"}
  • foo{bar="baz",aaa="b"}

The returned summary is safe to use from concurrent goroutines.

func (*Set) WritePrometheus added in v1.5.0

func (s *Set) WritePrometheus(w io.Writer)

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/VictoriaMetrics/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/VictoriaMetrics/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 added in v1.3.0

func GetOrCreateSummary(name string) *Summary

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 lables. 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 added in v1.3.0

func GetOrCreateSummaryExt(name string, window time.Duration, quantiles []float64) *Summary

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 lables. 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

func NewSummary(name string) *Summary

NewSummary creates and returns new summary with the given name.

name must be valid Prometheus-compatible metric with possible lables. For instance,

  • foo
  • foo{bar="baz"}
  • foo{bar="baz",aaa="b"}

The returned summary is safe to use from concurrent goroutines.

func NewSummaryExt

func NewSummaryExt(name string, window time.Duration, quantiles []float64) *Summary

NewSummaryExt creates and returns new summary with the given name, window and quantiles.

name must be valid Prometheus-compatible metric with possible lables. For instance,

  • foo
  • foo{bar="baz"}
  • foo{bar="baz",aaa="b"}

The returned summary is safe to use from concurrent goroutines.

func (*Summary) Update

func (sm *Summary) Update(v float64)

Update updates the summary.

func (*Summary) UpdateDuration

func (sm *Summary) UpdateDuration(startTime time.Time)

UpdateDuration updates request duration based on the given startTime.

Jump to

Keyboard shortcuts

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