ginprom

package module
v1.8.1 Latest Latest
Warning

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

Go to latest
Published: Feb 21, 2024 License: MIT Imports: 9 Imported by: 49

README

Ginprom

Gin Prometheus metrics exporter

Sourcegraph Go Report Card Build Status codecov License godoc

Inspired by github.com/zsais/go-gin-prometheus

Install

Simply run: go get -u github.com/Depado/ginprom

Differences with go-gin-prometheus

  • No support for Prometheus' Push Gateway
  • Options on constructor
  • Adds a path label to get the matched route
  • Ability to ignore routes

Usage

package main

import (
	"github.com/Depado/ginprom"
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	p := ginprom.New(
		ginprom.Engine(r),
		ginprom.Subsystem("gin"),
		ginprom.Path("/metrics"),
	)
	r.Use(p.Instrument())

	r.GET("/hello/:id", func(c *gin.Context) {})
	r.GET("/world/:id", func(c *gin.Context) {})
	r.Run("127.0.0.1:8080")
}

Options

Custom counters

Add custom counters to add own values to the metrics

r := gin.New()
p := ginprom.New(
	ginprom.Engine(r),
)
p.AddCustomCounter("custom", "Some help text to provide", []string{"label"})
r.Use(p.Instrument())

Save p and use the following functions:

  • IncrementCounterValue
  • AddCounterValue

Custom gauges

Add custom gauges to add own values to the metrics

r := gin.New()
p := ginprom.New(
	ginprom.Engine(r),
)
p.AddCustomGauge("custom", "Some help text to provide", []string{"label"})
r.Use(p.Instrument())

Save p and use the following functions:

  • IncrementGaugeValue
  • DecrementGaugeValue
  • SetGaugeValue

Custom histograms

Add custom histograms to add own values to the metrics

r := gin.New()
p := ginprom.New(
  ginprom.Engine(r),
)
p.AddCustomHistogram("internal_request_latency", "Duration of internal HTTP requests", []string{"url", "method", "status"})
r.Use(p.Instrument())

Save p and use the following functions:

  • AddCustomHistogramValue

Path

Override the default path (/metrics) on which the metrics can be accessed:

r := gin.New()
p := ginprom.New(
	ginprom.Engine(r),
	ginprom.Path("/custom/metrics"),
)
r.Use(p.Instrument())

Namespace

Override the default namespace (gin):

r := gin.New()
p := ginprom.New(
	ginprom.Engine(r),
	ginprom.Namespace("custom_ns"),
)
r.Use(p.Instrument())

Subsystem

Override the default (gonic) subsystem:

r := gin.New()
p := ginprom.New(
	ginprom.Engine(r),
	ginprom.Subsystem("your_subsystem"),
)
r.Use(p.Instrument())

Engine

The preferred way to pass the router to ginprom:

r := gin.New()
p := ginprom.New(
	ginprom.Engine(r),
)
r.Use(p.Instrument())

The alternative being to call the Use method after initialization:

p := ginprom.New()
// ...
r := gin.New()
p.Use(r)
r.Use(p.Instrument())

Prometheus Registry

Use a custom prometheus.Registry instead of prometheus client's global registry. This option allows to use ginprom in multiple gin engines in the same process, or if you would like to integrate ginprom with your own prometheus Registry.

registry := prometheus.NewRegistry() // creates new prometheus metric registry
r := gin.New()
p := ginprom.New(
    ginprom.Registry(registry),
)
r.Use(p.Instrument())

HandlerNameFunc

Change the way the handler label is computed. By default, the (*gin.Context).HandlerName function is used. This option is useful when wanting to group different functions under the same handler label or when using gin with decorated handlers.

r := gin.Default()
p := ginprom.New(
	HandlerNameFunc(func (c *gin.Context) string {
		return "my handler"
	}),
)
r.Use(p.Instrument())

RequestPathFunc

Change how the path label is computed. By default, the (*gin.Context).FullPath function is used. This option is useful when wanting to group different requests under the same path label or when wanting to process unknown routes (the default (*gin.Context).FullPath returns an empty string for unregistered routes). Note that requests for which f returns the empty string are ignored.

To specifically ignore certain paths, see the Ignore option.

r := gin.Default()
p := ginprom.New(
	// record a metric for unregistered routes under the path label "<unknown>"
	RequestPathFunc(func (c *gin.Context) string {
		if fullpath := c.FullPath(); fullpath != "" {
			return fullpath
		}
		return "<unknown>"
	}),
)
r.Use(p.Instrument())

CustomCounterLabels

Add custom labels to the counter metric.

r := gin.Default()
p := ginprom.New(
  ginprom.CustomCounterLabels([]string{"client_id"}, func(c *gin.Context) map[string]string {
    client_id := c.GetHeader("x-client-id")
    if client_id == "" {
      client_id = "unknown"
    }
    return map[string]string{"client_id": client_id}
  }),
)
r.Use(p.Instrument())

Ignore

Ignore allows to completely ignore some routes. Even though you can apply the middleware to the only groups you're interested in, it is sometimes useful to have routes not instrumented.

r := gin.New()
p := ginprom.New(
	ginprom.Engine(r),
	ginprom.Ignore("/api/no/no/no", "/api/super/secret/route")
)
r.Use(p.Instrument())

Note that most of the time this can be solved by gin groups:

r := gin.New()
p := ginprom.New(ginprom.Engine(r))

// Add the routes that do not need instrumentation
g := r.Group("/api/")
g.Use(p.Instrument())
{
	// Instrumented routes
}

Token

Specify a secret token which Prometheus will use to access the endpoint. If the token is invalid, the endpoint will return an error.

r := gin.New()
p := ginprom.New(
	ginprom.Engine(r),
	ginprom.Token("supersecrettoken")
)
r.Use(p.Instrument())

Bucket size

Specify the bucket size for the request duration histogram according to your expected durations.

r := gin.New()
p := ginprom.New(
	ginprom.Engine(r),
	ginprom.BucketSize([]float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}),
)
r.Use(p.Instrument())

Troubleshooting

The instrumentation doesn't seem to work

Make sure you have set the gin.Engine in the ginprom middleware, either when initializing it using ginprom.New(ginprom.Engine(r)) or using the Use function after the initialization like this :

p := ginprom.New(
	ginprom.Namespace("gin"),
	ginprom.Subsystem("gonic"),
	ginprom.Path("/metrics"),
)
p.Use(r)
r.Use(p.Instrument())

By design, if the middleware was to panic, it would do so when a route is called. That's why it just silently fails when no engine has been set.

Documentation

Overview

Package ginprom is a library to instrument a gin server and expose a /metrics endpoint for Prometheus to scrape, keeping a low cardinality by preserving the path parameters name in the prometheus label

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrCustomCounter = errors.New("error finding custom counter")

ErrCustomCounter is returned when the custom counter can't be found.

View Source
var ErrCustomGauge = errors.New("error finding custom gauge")

ErrCustomGauge is returned when the custom gauge can't be found.

View Source
var ErrInvalidToken = errors.New("invalid or missing token")

ErrInvalidToken is returned when the provided token is invalid or missing.

Functions

This section is empty.

Types

type Prometheus

type Prometheus struct {
	MetricsPath     string
	Namespace       string
	Subsystem       string
	Token           string
	Ignored         pmapb
	Engine          *gin.Engine
	BucketsSize     []float64
	Registry        *prometheus.Registry
	HandlerNameFunc func(c *gin.Context) string
	RequestPathFunc func(c *gin.Context) string
	HandlerOpts     promhttp.HandlerOpts

	RequestCounterMetricName  string
	RequestDurationMetricName string
	RequestSizeMetricName     string
	ResponseSizeMetricName    string
	// contains filtered or unexported fields
}

Prometheus contains the metrics gathered by the instance and its path.

func New

func New(options ...PrometheusOption) *Prometheus

New will initialize a new Prometheus instance with the given options. If no options are passed, sane defaults are used. If a router is passed using the Engine() option, this instance will automatically bind to it.

func (*Prometheus) AddCounterValue added in v1.7.8

func (p *Prometheus) AddCounterValue(name string, labelValues []string, value float64) error

AddCounterValue adds value to custom counter.

func (*Prometheus) AddCustomCounter added in v1.7.8

func (p *Prometheus) AddCustomCounter(name, help string, labels []string)

AddCustomCounter adds a custom counter and registers it.

func (*Prometheus) AddCustomGauge added in v1.3.0

func (p *Prometheus) AddCustomGauge(name, help string, labels []string)

AddCustomGauge adds a custom gauge and registers it.

func (*Prometheus) AddCustomHistogram added in v1.8.1

func (p *Prometheus) AddCustomHistogram(name, help string, labels []string)

AddCustomCounter adds a custom counter and registers it.

func (*Prometheus) AddCustomHistogramValue added in v1.8.1

func (p *Prometheus) AddCustomHistogramValue(name string, labelValues []string, value float64) error

AddCustomHistogramValue adds value to custom counter.

func (*Prometheus) AddGaugeValue added in v1.7.2

func (p *Prometheus) AddGaugeValue(name string, labelValues []string, value float64) error

AddGaugeValue adds value to custom gauge.

func (*Prometheus) DecrementGaugeValue added in v1.3.0

func (p *Prometheus) DecrementGaugeValue(name string, labelValues []string) error

DecrementGaugeValue decrements a custom gauge.

func (*Prometheus) IncrementCounterValue added in v1.7.8

func (p *Prometheus) IncrementCounterValue(name string, labelValues []string) error

IncrementCounterValue increments a custom counter.

func (*Prometheus) IncrementGaugeValue added in v1.3.0

func (p *Prometheus) IncrementGaugeValue(name string, labelValues []string) error

IncrementGaugeValue increments a custom gauge.

func (*Prometheus) Instrument

func (p *Prometheus) Instrument() gin.HandlerFunc

Instrument is a gin middleware that can be used to generate metrics for a single handler

func (*Prometheus) SetGaugeValue added in v1.3.0

func (p *Prometheus) SetGaugeValue(name string, labelValues []string, value float64) error

SetGaugeValue sets gauge to value.

func (*Prometheus) SubGaugeValue added in v1.7.2

func (p *Prometheus) SubGaugeValue(name string, labelValues []string, value float64) error

SubGaugeValue adds gauge to value.

func (*Prometheus) Use

func (p *Prometheus) Use(e *gin.Engine)

Use is a method that should be used if the engine is set after middleware initialization.

type PrometheusOption added in v1.7.11

type PrometheusOption func(*Prometheus)

func BucketSize added in v1.4.0

func BucketSize(b []float64) PrometheusOption

BucketSize is used to define the default bucket size when initializing with New.

func CustomCounterLabels added in v1.8.0

func CustomCounterLabels(labels []string, f func(c *gin.Context) map[string]string) PrometheusOption

func Engine

func Engine(e *gin.Engine) PrometheusOption

Engine is an option allowing to set the gin engine when intializing with New. Example: r := gin.Default() p := ginprom.New(Engine(r))

func HandlerNameFunc added in v1.7.7

func HandlerNameFunc(f func(c *gin.Context) string) PrometheusOption

HandlerNameFunc is an option allowing to set the HandlerNameFunc with New. Use this option if you want to override the default behavior (i.e. using (*gin.Context).HandlerName). This is useful when wanting to group different functions under the same "handler" label or when using gin with decorated handlers Example: r := gin.Default() p := ginprom.New(HandlerNameFunc(func (c *gin.Context) string { return "my handler" }))

func HandlerOpts added in v1.8.0

func HandlerOpts(opts promhttp.HandlerOpts) PrometheusOption

HandlerOpts is an option allowing to set the promhttp.HandlerOpts. Use this option if you want to override the default zero value.

func Ignore

func Ignore(paths ...string) PrometheusOption

Ignore is used to disable instrumentation on some routes.

func Namespace added in v1.1.0

func Namespace(ns string) PrometheusOption

Namespace is an option allowing to set the namespace when initializing with New.

func Path

func Path(path string) PrometheusOption

Path is an option allowing to set the metrics path when initializing with New.

Example

Set the path (endpoint) where the metrics will be served

r := gin.New()
p := New(Engine(r), Path("/metrics"))
r.Use(p.Instrument())
Output:

func Registry added in v1.5.0

Registry is an option allowing to set a *prometheus.Registry with New. Use this option if you want to use a custom Registry instead of a global one that prometheus client uses by default Example: r := gin.Default() p := ginprom.New(Registry(r))

func RequestCounterMetricName added in v1.7.0

func RequestCounterMetricName(reqCntMetricName string) PrometheusOption

RequestCounterMetricName is an option allowing to set the request counter metric name.

func RequestDurationMetricName added in v1.7.0

func RequestDurationMetricName(reqDurMetricName string) PrometheusOption

RequestDurationMetricName is an option allowing to set the request duration metric name.

func RequestPathFunc added in v1.7.10

func RequestPathFunc(f func(c *gin.Context) string) PrometheusOption

RequestPathFunc is an option allowing to set the RequestPathFunc with New. Use this option if you want to override the default behavior (i.e. using (*gin.Context).FullPath). This is useful when wanting to group different requests under the same "path" label or when wanting to process unknown routes (the default (*gin.Context).FullPath return an empty string for unregistered routes). Note that requests for which f returns the empty string are ignored. To specifically ignore certain paths, see the Ignore option. Example:

r := gin.Default()
p := ginprom.New(RequestPathFunc(func (c *gin.Context) string {
	if fullpath := c.FullPath(); fullpath != "" {
		return fullpath
	}
	return "<unknown>"
}))

func RequestSizeMetricName added in v1.7.0

func RequestSizeMetricName(reqSzMetricName string) PrometheusOption

RequestSizeMetricName is an option allowing to set the request size metric name.

func ResponseSizeMetricName added in v1.7.0

func ResponseSizeMetricName(resDurMetricName string) PrometheusOption

ResponseSizeMetricName is an option allowing to set the response size metric name.

func Subsystem

func Subsystem(sub string) PrometheusOption

Subsystem is an option allowing to set the subsystem when initializing with New.

func Token added in v1.2.0

func Token(token string) PrometheusOption

Token is an option allowing to set the bearer token in prometheus with New. Example: ginprom.New(ginprom.Token("your_custom_token"))

Example

Set a secret token that is required to access the endpoint

r := gin.New()
p := New(Engine(r), Token("supersecrettoken"))
r.Use(p.Instrument())
Output:

Jump to

Keyboard shortcuts

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