metrics

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Dec 24, 2023 License: BSD-3-Clause Imports: 16 Imported by: 1

README

Metrics

Two metrics packages for Go, based on ServiceWeaver's design.

Pure

The metrics package itself has no interesting dependencies. The otel package below it implements an OTEL Producer to use with an OTEL Reader. The OTEL Metric, MetricProvider and instrument types are unused.

Wrap

Wraps OTEL Instruments.

Documentation

Overview

Package metrics provides a way for programs to measure properties of themselves.

Instruments

Serving

Exporting

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExponentialBounds

func ExponentialBounds[N ~float64 | ~int64](base, first, max N) []N

ExponentialBounds creates a set of bounds that establish buckets whose size increases exponentially. The argument "first", which must not be negative, is the upper bound of the first bucket. The upper bound of each subsequent bucket is base times the upper bound of the previous. base must be greater than 1. The upper bound of the last bucket will not exceed max.

For example, ExponentialBounds[int64](10, 1, 100) returns

[]int64{1, 10, 100}

which results in buckets with ranges

(-infinity, 1]
(1, 10]
(10, 100]
(100, +infinity)

As a special case, if first is 0, the first bound will be 0 and the second will be 1.

func LinearBounds

func LinearBounds[N ~int64 | ~float64](size, min, max N) []N

LinearBounds creates a set of bounds that establish equal-sized buckets of the given size from min to max.

For example, LinearBounds[int64](5, 2, 12) returns

[]int64{2, 7, 12}

which results in buckets with ranges

(-infinity, 2]
(2, 7]
(7, 12]
(12, +infinity)

func NewHandler

func NewHandler(resource map[string]string, f func(name string) bool) http.Handler

NewHandler returns an http.Handler that serves the metrics for which f returns true.

By default, the handler serves the [JSON encoding] of [OTLP], the Open Telemetry metrics protocol. With the query parameter "format=prometheus", it serves the [prometheus protocol].

When serving OTLP, the resource argument populates that protocol's Resource message. It may be nil.

[JSON encoding]: https://opentelemetry.io/docs/specs/otlp/#json-protobuf-encoding [OTLP]: https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/metrics/v1/metrics.proto [prometheus protocol]: TODO

func Read

func Read(f func(name string) bool) []md.Metric

Read reads the metrics for which f returns true. / If f is nil, it reads all registered metrics.

func Register

func Register(r Reader)

Register records the reader in the set of metrics. It panics if any of the metric names were already registered.

func RegisterObservableGauge

func RegisterObservableGauge[N ~int64 | ~float64](name string, sum SumKind, observe func() N, desc string)

RegisterObservableGauge registers a new observable gauge that gets its value by calling the given function.

The corresponding metric has the given name, description and SumKind. It is not cumulative. If N is time.Duration, the unit will be "ns". If N has a method

Unit() string

then the unit will be the result of calling that method on a zero value of N. Otherwise, the unit will be the empty string.

func Reset

func Reset()

Reset metric system to initial state. Useful for testing.

func SetErrorHandler

func SetErrorHandler(f func(error)) func(error)

SetErrorHandler sets a function to be called when an error happens while recording a metric. It returns the previous value.

The default error handler prints the error to stderr.

Types

type Counter

type Counter[N ~int64 | ~float64] struct {
	// contains filtered or unexported fields
}

A Counter is a cumulative count that is always increasing.

Example
package main

import (
	"fmt"
	"io"
	"net/http/httptest"
	"strings"

	"github.com/jba/metrics"
)

func main() {
	c := metrics.NewCounter[int64]("metrics_test/reqs", "total reqs")
	c.Add(7)
	f := func(name string) bool {
		return strings.HasPrefix(name, "metrics_test/") ||
			name == "runtime/gc/heap/allocs"
	}
	h := metrics.NewHandler(nil, f)
	req := httptest.NewRequest("GET", "/", nil)
	w := httptest.NewRecorder()
	h.ServeHTTP(w, req)
	res := w.Result()
	body, err := io.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		panic(err)
	}
	fmt.Printf("%s\n", body)
}
Output:

func NewCounter

func NewCounter[N ~int64 | ~float64](name, desc string) *Counter[N]

NewCounter creates and registers a Counter.

The corresponding metric has the given name and description, and is cumulative and summable. If N is time.Duration, the unit will be "ns". If N has a method

Unit() string

then the unit will be the result of calling that method on a zero value of N. Otherwise, the unit will be the empty string.

func (*Counter[N]) Add

func (c *Counter[N]) Add(n N)

Add adds n to the value of the counter. If n is negative, NaN, or infinity, it is not added and the error handler is called with an appropriate error.

type Description

type Description struct {
	Name        string
	Description string
	Unit        string
	Cumulative  bool
	Sum         SumKind
}

Description describes a metric.

func All

func All() []Description

All returns descriptions for all registered metrics.

type Gauge

type Gauge[N ~int64 | ~float64] struct {
	// contains filtered or unexported fields
}

A Gauge records a value at a single point in time. The value of a Gauge may go up or down, and is not cumulative.

func NewGauge

func NewGauge[N ~int64 | ~float64](name string, sum SumKind, desc string) *Gauge[N]

NewGauge creates and registers a Gauge.

The corresponding metric has the given name, description and SumKind. It is not cumulative. If N is time.Duration, the unit will be "ns". If N has a method

Unit() string

then the unit will be the result of calling that method on a zero value of N. Otherwise, the unit will be the empty string.

func (*Gauge[N]) Set

func (g *Gauge[N]) Set(n N)

Set sets the value of the gauge to n. If n is NaN, or infinity, the gauge's value is left unchanged and the error handler is called with an appropriate error.

type Group

type Group[I any, Attrs comparable] struct {
	// contains filtered or unexported fields
}

A Group is a collection of instruments, each with a different value of Attrs. Attrs must be a struct.

func NewCounterGroup

func NewCounterGroup[N ~int64 | ~float64, A comparable](name, desc string) Group[*Counter[N], A]

NewCounterGroup creates a group of counters that differ in the values of the type A, which must be a struct. See NewCounter for details about the corresponding metric.

func NewGaugeGroup

func NewGaugeGroup[N ~int64 | ~float64, A comparable](name string, sum SumKind, desc string) Group[*Gauge[N], A]

NewGaugeGroup creates a group of gauges that differ in the values of the type A, which must be a struct. See NewGauge for details about the corresponding metric.

func NewHistogramGroup

func NewHistogramGroup[N ~int64 | ~float64, A comparable](name string, bounds []N, desc string) Group[*Histogram[N], A]

NewHistogram creates a group of Histograms, each with a different value of the type A. See NewHistogram for details about the corresponding metric.

func (Group[I, A]) At

func (g Group[I, A]) At(attrs A) I

At returns the instrument for the given attrs, creating one if it does not exist.

type Histogram

type Histogram[N ~int64 | ~float64] struct {
	// contains filtered or unexported fields
}

A Histogram represents a distribution of values.

func NewHistogram

func NewHistogram[N ~int64 | ~float64](name string, bounds []N, desc string) *Histogram[N]

NewHistogram creates and registers a histogram with the given bounds. For each i, bounds[i] is the upper bound of bucket i. There is one additional overflow bucket for values greater than the last bound. In other words, a value x belongs in bucket i if:

x <= bounds[i]               for i == 0
bounds[i-1] < x <= bounds[i] for 0 < i < len(bounds)
bounds[i-1] < x              for i == len(bounds)

The corresponding metric has the given name and description, and is cumulative and summable. If N is time.Duration, the unit will be "ns". If N has a method

Unit() string

then the unit will be the result of calling that method on a zero value of N. Otherwise, the unit will be the empty string.

func (*Histogram[N]) Record

func (h *Histogram[N]) Record(x N)

Record records a value in the histogram by incrementing the count of the bucket containing it.

type ObservableGaugeGroup

type ObservableGaugeGroup[N ~int64 | ~float64, A comparable] struct {
	// contains filtered or unexported fields
}

An ObservableGaugeGroup is a group of observable gauges.

func NewObservableGaugeGroup

func NewObservableGaugeGroup[N ~int64 | ~float64, A comparable](name string, sum SumKind, desc string) ObservableGaugeGroup[N, A]

NewObservableGaugeGroup creates an ObservableGaugeGroup. See RegisterObservableGauge for details about the corresponding metric.

func (ObservableGaugeGroup[N, A]) Register

func (g ObservableGaugeGroup[N, A]) Register(attrs A, observe func() N)

Register adds a new observable gauge to the group. If the value of attrs is already registered, the given value is ignored and the error handler is called.

type Reader

type Reader interface {
	// Descriptions returns a Description for each metric
	// that the Reader can read.
	Descriptions() []Description

	// Read returns the Metrics with the given names.
	//
	// The caller will populate the zero times of the returned metric data
	// points with the time of the call. A Reader may set a different time for
	// events known to have occurred earlier.
	Read(names []string) []md.Metric
}

A Reader reads values for one or more metrics.

type SumKind

type SumKind int

SumKind describes whether it makes sense to add metric values together. If a metric is Summable, then its values may be meaningfully added together. For example, a metric tracking the number of allocated bytes can be added across multiple processes or machines to produce a meaningful total.

A NonSummable metric cannot be meaningfully added. The percentage of CPU used by a process is one example of such a metric.

const (
	NonSummable SumKind = iota
	Summable
)

Directories

Path Synopsis
otel module
wrap module

Jump to

Keyboard shortcuts

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