项目作者: Depado

项目描述 :
Gin Prometheus metrics exporter inspired by https://github.com/zsais/go-gin-prometheus
高级语言: Go
项目地址: git://github.com/Depado/ginprom.git
创建时间: 2017-10-09T09:23:22Z
项目社区:https://github.com/Depado/ginprom

开源协议:MIT License

下载


Ginprom

Gin Prometheus metrics exporter

Sourcegraph
Go Report Card
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

  1. package main
  2. import (
  3. "github.com/Depado/ginprom"
  4. "github.com/gin-gonic/gin"
  5. )
  6. func main() {
  7. r := gin.Default()
  8. p := ginprom.New(
  9. ginprom.Engine(r),
  10. ginprom.Subsystem("gin"),
  11. ginprom.Path("/metrics"),
  12. )
  13. r.Use(p.Instrument())
  14. r.GET("/hello/:id", func(c *gin.Context) {})
  15. r.GET("/world/:id", func(c *gin.Context) {})
  16. r.Run("127.0.0.1:8080")
  17. }

Options

Custom counters

Add custom counters to add own values to the metrics

  1. r := gin.New()
  2. p := ginprom.New(
  3. ginprom.Engine(r),
  4. )
  5. p.AddCustomCounter("custom", "Some help text to provide", []string{"label"})
  6. 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

  1. r := gin.New()
  2. p := ginprom.New(
  3. ginprom.Engine(r),
  4. )
  5. p.AddCustomGauge("custom", "Some help text to provide", []string{"label"})
  6. 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

  1. r := gin.New()
  2. p := ginprom.New(
  3. ginprom.Engine(r),
  4. )
  5. p.AddCustomHistogram("internal_request_latency", "Duration of internal HTTP requests", []string{"url", "method", "status"})
  6. 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:

  1. r := gin.New()
  2. p := ginprom.New(
  3. ginprom.Engine(r),
  4. ginprom.Path("/custom/metrics"),
  5. )
  6. r.Use(p.Instrument())

Namespace

Override the default namespace (gin):

  1. r := gin.New()
  2. p := ginprom.New(
  3. ginprom.Engine(r),
  4. ginprom.Namespace("custom_ns"),
  5. )
  6. r.Use(p.Instrument())

Subsystem

Override the default (gonic) subsystem:

  1. r := gin.New()
  2. p := ginprom.New(
  3. ginprom.Engine(r),
  4. ginprom.Subsystem("your_subsystem"),
  5. )
  6. r.Use(p.Instrument())

Engine

The preferred way to pass the router to ginprom:

  1. r := gin.New()
  2. p := ginprom.New(
  3. ginprom.Engine(r),
  4. )
  5. r.Use(p.Instrument())

The alternative being to call the Use method after initialization:

  1. p := ginprom.New()
  2. // ...
  3. r := gin.New()
  4. p.Use(r)
  5. 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.

  1. registry := prometheus.NewRegistry() // creates new prometheus metric registry
  2. r := gin.New()
  3. p := ginprom.New(
  4. ginprom.Registry(registry),
  5. )
  6. 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.

  1. r := gin.Default()
  2. p := ginprom.New(
  3. HandlerNameFunc(func (c *gin.Context) string {
  4. return "my handler"
  5. }),
  6. )
  7. 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.

  1. r := gin.Default()
  2. p := ginprom.New(
  3. // record a metric for unregistered routes under the path label "<unknown>"
  4. RequestPathFunc(func (c *gin.Context) string {
  5. if fullpath := c.FullPath(); fullpath != "" {
  6. return fullpath
  7. }
  8. return "<unknown>"
  9. }),
  10. )
  11. r.Use(p.Instrument())

CustomCounterLabels

Add custom labels to the counter metric.

  1. r := gin.Default()
  2. p := ginprom.New(
  3. ginprom.CustomCounterLabels([]string{"client_id"}, func(c *gin.Context) map[string]string {
  4. client_id := c.GetHeader("x-client-id")
  5. if client_id == "" {
  6. client_id = "unknown"
  7. }
  8. return map[string]string{"client_id": client_id}
  9. }),
  10. )
  11. 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.

  1. r := gin.New()
  2. p := ginprom.New(
  3. ginprom.Engine(r),
  4. ginprom.Ignore("/api/no/no/no", "/api/super/secret/route")
  5. )
  6. r.Use(p.Instrument())

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

  1. r := gin.New()
  2. p := ginprom.New(ginprom.Engine(r))
  3. // Add the routes that do not need instrumentation
  4. g := r.Group("/api/")
  5. g.Use(p.Instrument())
  6. {
  7. // Instrumented routes
  8. }

Token

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

  1. r := gin.New()
  2. p := ginprom.New(
  3. ginprom.Engine(r),
  4. ginprom.Token("supersecrettoken")
  5. )
  6. r.Use(p.Instrument())

Bucket size

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

  1. r := gin.New()
  2. p := ginprom.New(
  3. ginprom.Engine(r),
  4. ginprom.BucketSize([]float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}),
  5. )
  6. 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 :

  1. p := ginprom.New(
  2. ginprom.Namespace("gin"),
  3. ginprom.Subsystem("gonic"),
  4. ginprom.Path("/metrics"),
  5. )
  6. p.Use(r)
  7. 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.