zsais / go-gin-prometheus Goto Github PK
View Code? Open in Web Editor NEWGin Web Framework Prometheus metrics exporter
License: MIT License
Gin Web Framework Prometheus metrics exporter
License: MIT License
Hi, i read sourse code and could not understand how to use custom metrics? Does exist way do it, or i should rewrite this library?
Hi,
I saw you fix some bug in master, please add a tag from the newest master.
We used v0.1.0 and met OOM issue, after we looked up the issues, we found you fix it in #35.
Thank you.
url
label contains the url of every request that was ever made against gin webserver. This can cause very high memory usage for prometheus server. What's worse this is out of control for the operator of a service running go-gin-prometheus and someone sending a high number of requests with random url can easily cause prometheus server scraping that webserver to run out of memory. This is a common misuse of prometheus metrics and there's even a tool written to detect and mitigate the most serious cases of cardinality explosion - https://blog.freshtracks.io/bomb-squad-automatic-detection-and-suppression-of-prometheus-cardinality-explosions-62ca8e02fa32
This is very easy to reproduce with curl:
for i in {1..1000} ; do curl -so /dev/null "localhost:8080/xxx$i" ; done```
Resulting in:
[...]
gin_requests_total{code="404",handler="main.notFound",host="localhost:8080",method="GET",url="/xxx100"} 1
gin_requests_total{code="404",handler="main.notFound",host="localhost:8080",method="GET",url="/xxx10"} 1
gin_requests_total{code="404",handler="main.notFound",host="localhost:8080",method="GET",url="/xxx1"} 1
gin_requests_total{code="404",handler="main.notFound",host="localhost:8080",method="GET",url="/xxx11"} 1
gin_requests_total{code="404",handler="main.notFound",host="localhost:8080",method="GET",url="/xxx12"} 1
gin_requests_total{code="404",handler="main.notFound",host="localhost:8080",method="GET",url="/xxx13"} 1
[...]
This was already reported in #34 and partially fixed in #35 but those changes are not enough.
All metrics already have the handler
label that points to the request handler method that the request was routed to, this is enough to identify requests for any debugging / performance tracking.
Please remove the url
label from metrics.
The middleware pulls in this function: computeApproximateRequestSize
from
https://github.com/DanielHeckrath/gin-prometheus
which inherits this bug:
DanielHeckrath/gin-prometheus#1
./main.go:12:7: cannot use r (type *"gitlab.lojasrenner.com.br/bd-api-gateway-2/vendor/github.com/gin-gonic/gin".Engine) as type *"github.com/zsais/go-gin-prometheus/vendor/github.com/gin-gonic/gin".Engine in argument to p.Use
package main
import (
"github.com/gin-gonic/gin"
"github.com/zsais/go-gin-prometheus"
)
func main() {
r := gin.New()
p := ginprometheus.NewPrometheus("gin")
p.Use(r)
r.GET("/", func(c *gin.Context) {
c.JSON(200, "Hello world!")
})
r.Run(":29090")
}
How to use custom metrics ? i want to integrate with my personal apps
Hi, i have a problem with the status code metrics, all the other metrics works except these:
promhttp_metric_handler_requests_total{code="200"} 0
promhttp_metric_handler_requests_total{code="500"} 0
promhttp_metric_handler_requests_total{code="503"} 0
Any idea?
This problem cause too many labels in metrics requests_total.
myname_requests_total{code="200",handler="myname",host="127.0.0.1:3000",method="GET",url="/handshake?token=1"} 1
myname_requests_total{code="200",handler="myname",host="127.0.0.1:3000",method="GET",url="/handshake?token=2"} 1
myname_requests_total{code="200",handler="myname",host="127.0.0.1:3000",method="GET",url="/handshake?token=3"} 1
myname_requests_total{code="200",handler="myname",host="127.0.0.1:3000",method="GET",url="/handshake?token=4"} 1
myname_requests_total{code="200",handler="myname",host="127.0.0.1:3000",method="GET",url="/handshake?token=5"} 1
myname_requests_total{code="200",handler="myname",host="127.0.0.1:3000",method="GET",url="/handshake?token=6"} 1
The SetListenAddress
/ SetListenAddressWithRouter
is really nice, but unfortunately it only supports the "ADDRESS:PORT" scheme.
Do you can think of a good way to support also the other run functions like RunUnix
?
It crashes complaining about
case-insensitive import collision: "github.com/Sirupsen/logrus" and "github.com/sirupsen/logrus"
I am using go-gin-prometheus as a middleware with the default metrics and a couple of custom metrics that I registered but when I look at the metrics in my /metrics endpoint, I do not see a requests_total
metric in there. Should I be implementing this like a custom metrics?
func Use(engine *gin.Engine, port string) {
prometheus.MustRegister(commonMetrics.ComponentProcessingTime)
prometheus.MustRegister(commonMetrics.ComponentConsumerFailures)
ginCol := ginprometheus.NewPrometheus("gin")
ginCol.SetListenAddress(":" + port)
ginCol.Use(engine)
}
Hi,
In case and you try to use this package along with an existing Gin router that have Gzip middleware, /metrics
will get Gzipped twice and won't be readable.
For example:
import (
"github.com/gin-gonic/gin"
"github.com/zsais/go-gin-prometheus"
)
ginRouter := gin.New()
ginRouter.Use(gzip.Gzip(gzip.BestCompression))
// Add Prometheus
p := ginprometheus.NewPrometheus("gin")
p.Use(ginRouter)
// Add custom route
ginRouter.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
// Run
ginRouter.Run(":8080")
Now browse:
http://localhost:8080/ping
- {"message": "pong"}
http://localhost:8080/metrics
- gibberish
Suggestion:
Please export hidden functionality to allow uses to have more control over this package.
hi, the metrics data can be get from http://host/metrics, but it's text, can you please visualize it?
Parameter in SetPushGateway
No longer relevant.
This metic default label ‘url’ will set url param,
if url param contain uuid or ramdon number.
label array give rise to oom.
Hi peeps, according to Prometheus best practices docs, labels should have the http_
prefix upfront, is it possible to have it by any chance? Thank you
At the moment because the default registry is used this is not possible. For example if you have an application with two Gin servers the second gin-prometheus handler will fail with an error like:
time="2021-03-09T17:43:51Z" level=error msg="requests_total could not be registered in Prometheus" error="duplicate metrics collector registration attempted"
time="2021-03-09T17:43:51Z" level=error msg="request_duration_seconds could not be registered in Prometheus" error="duplicate metrics collector registration attempted"
time="2021-03-09T17:43:51Z" level=error msg="response_size_bytes could not be registered in Prometheus" error="duplicate metrics collector registration attempted"
time="2021-03-09T17:43:51Z" level=error msg="request_size_bytes could not be registered in Prometheus" error="duplicate metrics collector registration attempted"
Cheers!
I have a server which listens for http (80) and https (443), with a gin instance for each. I'm trying to figure out how I should handle that setup with this package-- what is the best practice?
What I think I want is a single Prometheus /metrics endpoint on a separate port (let's say 3000) which exports metrics for both http and https endpoints, ideally as separate metrics sets, but merged would be OK. Is this possible? I couldn't find a way to get this to work, nor any examples which got to this level of detail.
The closest I got was something like this:
package main
import (
"github.com/gin-gonic/gin"
"github.com/zsais/go-gin-prometheus"
)
func main() {
metrics := gin.New()
r1 := gin.New()
r2 := gin.New()
p := ginprometheus.NewPrometheus("gin")
p.SetListenAddressWithRouter(":3000", metrics)
p.Use(r1)
p.Use(r2)
r1.GET("/", func(c *gin.Context) {
c.JSON(200, "Hello world!")
})
r2.GET("/", func(c *gin.Context) {
c.JSON(200, "Goodbye world!")
})
go r1.Run(":29090")
go r2.Run(":29091")
go metrics.Run(":3000")
}
Which panics as follows:
[GIN-debug] GET /metrics --> github.com/zsais/go-gin-prometheus.prometheusHandler.func1 (3 handlers)
[GIN-debug] GET /metrics --> github.com/zsais/go-gin-prometheus.prometheusHandler.func1 (3 handlers)
[GIN-debug] Listening and serving HTTP on :3000
panic: handlers are already registered for path '/metrics'
goroutine 1 [running]:
github.com/gin-gonic/gin.(*node).addRoute(0xc420070780, 0xc420024810, 0x8, 0xc42000d2c0, 0x3, 0x3)
/home/dp/go/src/github.com/gin-gonic/gin/tree.go:235 +0x9c6
github.com/gin-gonic/gin.(*Engine).addRoute(0xc42022e480, 0xae34e2, 0x3, 0xc420024810, 0x8, 0xc42000d2c0, 0x3, 0x3)
/home/dp/go/src/github.com/gin-gonic/gin/gin.go:252 +0x19e
github.com/gin-gonic/gin.(*RouterGroup).handle(0xc42022e480, 0xae34e2, 0x3, 0xae6ee0, 0x8, 0xc42000e188, 0x1, 0x1, 0xb68601, 0xc42000e188)
/home/dp/go/src/github.com/gin-gonic/gin/routergroup.go:71 +0xe7
github.com/gin-gonic/gin.(*RouterGroup).GET(0xc42022e480, 0xae6ee0, 0x8, 0xc42000e188, 0x1, 0x1, 0x1, 0xb70f40)
/home/dp/go/src/github.com/gin-gonic/gin/routergroup.go:99 +0x7c
github.com/zsais/go-gin-prometheus.(*Prometheus).setMetricsPath(0xc42023e180, 0xc42022e360)
/home/dp/go/src/github.com/zsais/go-gin-prometheus/middleware.go:181 +0xab
github.com/zsais/go-gin-prometheus.(*Prometheus).Use(0xc42023e180, 0xc42022e360)
/home/dp/go/src/github.com/zsais/go-gin-prometheus/middleware.go:339 +0x80
main.main()
/home/dp/example1/main.go:16 +0xbf
Thanks for any ideas you might have.
I'm trying to use this package and I need the reqDur to be HistogramVec but in the current release(v0.1.0), it is a Summary. Can you fast track the next release?
My point being versions should be moving. The first and last version came two years back..
# gitlab.lojasrenner.com.br/bd-api-gateway-2/vendor/github.com/prometheus/client_model/go
vendor/github.com/prometheus/client_model/go/metrics.pb.go:96:31: undefined: proto.InternalMessageInfo
vendor/github.com/prometheus/client_model/go/metrics.pb.go:141:27: undefined: proto.InternalMessageInfo
vendor/github.com/prometheus/client_model/go/metrics.pb.go:179:29: undefined: proto.InternalMessageInfo
vendor/github.com/prometheus/client_model/go/metrics.pb.go:218:30: undefined: proto.InternalMessageInfo
vendor/github.com/prometheus/client_model/go/metrics.pb.go:265:29: undefined: proto.InternalMessageInfo
vendor/github.com/prometheus/client_model/go/metrics.pb.go:317:29: undefined: proto.InternalMessageInfo
vendor/github.com/prometheus/client_model/go/metrics.pb.go:357:31: undefined: proto.InternalMessageInfo
vendor/github.com/prometheus/client_model/go/metrics.pb.go:410:28: undefined: proto.InternalMessageInfo
vendor/github.com/prometheus/client_model/go/metrics.pb.go:461:28: undefined: proto.InternalMessageInfo
vendor/github.com/prometheus/client_model/go/metrics.pb.go:544:34: undefined: proto.InternalMessageInfo
vendor/github.com/prometheus/client_model/go/metrics.pb.go:544:34: too many errors
package main
import (
"github.com/gin-contrib/gzip"
"github.com/gin-gonic/gin"
"github.com/zsais/go-gin-prometheus"
)
func main() {
r := gin.New()
r.Use(gzip.Gzip(gzip.DefaultCompression))
p := ginprometheus.NewPrometheus("gin")
p.Use(r)
r.GET("/", func(c *gin.Context) {
c.JSON(200, "Hello world!")
})
r.Run(":29090")
}
ok.. so im a bit stumped here.
i have the custom metrics implemented (so i can see them show up when i have my server running):
However, even with looking with the answer provided to nizarayari, i dont see how to apply the .Inc() method to the custom metric.
I have tried as well looking at the other example, however the prometheus.Register(numErrors) example never ends up showing up in the gin metrics list (as the test ones outlined above are).
any pointers would be wonderful!
D
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.