Gin Prometheus metrics exporter inspired by github.com/zsais/go-gin-prometheus
Simply run:
go get -u github.com/Depado/ginprom
- No support for Prometheus' Push Gateway
- Options on constructor
- Adds a
path
label to get the matched route - Ability to ignore routes
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")
}
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
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())
Override the default namespace (gin
):
r := gin.New()
p := ginprom.New(
ginprom.Engine(r),
ginprom.Namespace("custom_ns"),
)
r.Use(p.Instrument())
Override the default (gonic
) subsystem:
r := gin.New()
p := ginprom.New(
ginprom.Engine(r),
ginprom.Subsystem("your_subsystem"),
)
r.Use(p.Instrument())
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())
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())
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
}
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())
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())
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.