gaugefuncvec

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 15, 2020 License: MIT Imports: 8 Imported by: 0

README

Gauge Function Vector for Prometheus (golang)

Build Status Coverage Status GoDoc

Summary

Like prometheus.GaugeFunc but with labels and one function per label.

Why?

Let's say you want to observer your mysql driver stats, setting up a prometheus.GaugeFunc gathering your db.Stats() works great, however if you have several connections the idiomatic way is to label them, but you can't with prometheus.GaugeFunc

How?

It works just as you'd expect to. gaugevecfunc.New() accepts the standard prometheus.GaugeOpts and respects them, additionally it accepts a slice of strings defining the labels your functions will have. It returns a *prometheus.GaugeVecFunc that is a prometheus.Collector, i.e., ready to be registered in the prometheus.Registerer.

The GaugeVecFunc provides two methods: Register(labels []string, function func() float64) error and MustRegister(labels []string, function func()). MustRegister invokes the Register and panics if an error was returned.

Register will validate the labels, which should not collide with const labels and should respect the ones defined when New() was called.

Example

See example_test for a runnable golang example.

	g := gaugefuncvec.New(
		prometheus.GaugeOpts{
			Namespace: "database",
			Name:      "connections",
			Help:      "Number of connections per database connection",
		},
		[]string{"connection_id"},
	)
	g.MustRegister(
		prometheus.Labels{"connection_id": "master"},
		func() float64 { return float64(db1.stats().conns) },
	)
	g.MustRegister(
		prometheus.Labels{"connection_id": "slave"},
		func() float64 { return float64(db2.stats().conns) },
	)

Decisions

New() may not respect the order of the given variable labels. Since Register isn't expected to be called frequently, it doesn't make sense to trade off readability of a prometheus.Labels for a performance of order-based labels.

There's no method to unregister. It's easy to implement, but there was no need when I wrote the library.

Different gather funcs could have been provided as constructor params to New() (as variadic options in a fancy way), however my usecase (instantiating db connections in separate places, when GaugeFuncVec is already instantiated and registered required a Register method, and I considered unnecesary to implement two ways of doing the same.

Documentation

Overview

Example
package main

import (
	"os"

	"github.com/colega/gaugefuncvec"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/expfmt"
)

func main() {
	g := gaugefuncvec.New(
		prometheus.GaugeOpts{
			Namespace: "database",
			Name:      "connections",
			Help:      "Number of connections per database connection",
		},
		[]string{"connection_id"},
	)

	db1 := &db{conns: 42}
	g.MustRegister(
		prometheus.Labels{"connection_id": "master"},
		func() float64 { return float64(db1.stats().conns) },
	)
	db2 := &db{conns: 288}
	g.MustRegister(
		prometheus.Labels{"connection_id": "slave"},
		func() float64 { return float64(db2.stats().conns) },
	)

	registry := prometheus.NewRegistry()
	registry.MustRegister(g)

	gatherAndPrintMetrics(registry)

}

func gatherAndPrintMetrics(gatherer prometheus.Gatherer) {
	metrics, _ := gatherer.Gather()
	enc := expfmt.NewEncoder(os.Stdout, expfmt.FmtText)
	for _, mf := range metrics {
		_ = enc.Encode(mf)
	}
}

type db struct{ conns int }

func (d db) stats() struct{ conns int } { return struct{ conns int }{d.conns} }
Output:

# HELP database_connections Number of connections per database connection
# TYPE database_connections gauge
database_connections{connection_id="master"} 42
database_connections{connection_id="slave"} 288

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type GaugeFuncVec

type GaugeFuncVec struct {
	// contains filtered or unexported fields
}

GaugeFuncVec is a prometheus.Collector that allows registering GaugeFunc's for different labels

func New

func New(opts prometheus.GaugeOpts, variableLabelNames []string) *GaugeFuncVec

New returns a GaugeFuncVec variableLabelNames should not include the ConstLabels defined in GaugeOpts, it will panic if they do

func (*GaugeFuncVec) Collect

func (g *GaugeFuncVec) Collect(metrics chan<- prometheus.Metric)

Collect implements prometheus.Collector

func (*GaugeFuncVec) Describe

func (g *GaugeFuncVec) Describe(desc chan<- *prometheus.Desc)

Describe implements prometheus.Collector

func (*GaugeFuncVec) MustRegister

func (g *GaugeFuncVec) MustRegister(labels prometheus.Labels, function func() float64)

MustRegister calls Register and panics if it returns an error

func (*GaugeFuncVec) Register

func (g *GaugeFuncVec) Register(labels prometheus.Labels, function func() float64) error

Register will register a function for the given set of labels Labels should respect the variable labels provided in New() and should not collide with const labels

Jump to

Keyboard shortcuts

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