跳转到内容

Prometheus

Echo Prometheus 中间件会为 HTTP 请求生成 Prometheus metrics。

添加所需 module:

Terminal window
go get github.com/labstack/echo-prometheus

添加 Prometheus 中间件和用于提供已收集 metrics 的路由:

e := echo.New()
e.Use(echoprometheus.NewMiddleware("myapp")) // adds middleware to gather metrics
e.GET("/metrics", echoprometheus.NewHandler()) // adds route to serve gathered metrics

从收集 metrics 的同一服务器提供 metrics:

package main
import (
"net/http"
echoprometheus "github.com/labstack/echo-prometheus"
"github.com/labstack/echo/v5"
)
func main() {
e := echo.New()
e.Use(echoprometheus.NewMiddleware("myapp")) // adds middleware to gather metrics
e.GET("/metrics", echoprometheus.NewHandler()) // adds route to serve gathered metrics
e.GET("/hello", func(c *echo.Context) error {
return c.String(http.StatusOK, "hello")
})
if err := e.Start(":8080"); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}

在单独端口上提供 metrics:

func main() {
e := echo.New() // this Echo instance will serve routes on port 8080
e.Use(echoprometheus.NewMiddleware("myapp")) // adds middleware to gather metrics
go func() {
metrics := echo.New() // this Echo will run on separate port 8081
metrics.GET("/metrics", echoprometheus.NewHandler()) // adds route to serve gathered metrics
if err := metrics.Start(":8081"); err != nil {
e.Logger.Error("failed to start metrics server", "error", err)
}
}()
e.GET("/hello", func(c *echo.Context) error {
return c.String(http.StatusOK, "hello")
})
if err := e.Start(":8080"); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}

示例输出(第一个示例):

Terminal window
curl http://localhost:8080/metrics
# HELP echo_request_duration_seconds The HTTP request latencies in seconds.
# TYPE echo_request_duration_seconds summary
echo_request_duration_seconds_sum 0.41086482
echo_request_duration_seconds_count 1
# HELP echo_request_size_bytes The HTTP request sizes in bytes.
# TYPE echo_request_size_bytes summary
echo_request_size_bytes_sum 56
echo_request_size_bytes_count 1
# HELP echo_requests_total How many HTTP requests processed, partitioned by status code and HTTP method.
# TYPE echo_requests_total counter
echo_requests_total{code="200",host="localhost:8080",method="GET",url="/"} 1
# HELP echo_response_size_bytes The HTTP response sizes in bytes.
# TYPE echo_response_size_bytes summary
echo_response_size_bytes_sum 61
echo_response_size_bytes_count 1
...

使用 Prometheus 默认 registry 的自定义 metrics:

package main
import (
"log"
echoprometheus "github.com/labstack/echo-prometheus"
"github.com/labstack/echo/v5"
"github.com/prometheus/client_golang/prometheus"
)
func main() {
e := echo.New() // this Echo instance will serve routes on port 8080
customCounter := prometheus.NewCounter( // create a new counter metric
prometheus.CounterOpts{
Name: "custom_requests_total",
Help: "How many HTTP requests processed, partitioned by status code and HTTP method.",
},
)
if err := prometheus.Register(customCounter); err != nil { // register the counter with the default registry
log.Fatal(err)
}
e.Use(echoprometheus.NewMiddlewareWithConfig(echoprometheus.MiddlewareConfig{
AfterNext: func(c *echo.Context, err error) {
customCounter.Inc() // increment the counter after every request
},
}))
e.GET("/metrics", echoprometheus.NewHandler()) // register a route to serve gathered metrics
if err := e.Start(":8080"); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}

或者创建你自己的 registry,并向其中注册自定义 metrics:

package main
import (
"log"
echoprometheus "github.com/labstack/echo-prometheus"
"github.com/labstack/echo/v5"
"github.com/prometheus/client_golang/prometheus"
)
func main() {
e := echo.New() // this Echo instance will serve routes on port 8080
customRegistry := prometheus.NewRegistry() // create a custom registry for your custom metrics
customCounter := prometheus.NewCounter( // create a new counter metric
prometheus.CounterOpts{
Name: "custom_requests_total",
Help: "How many HTTP requests processed, partitioned by status code and HTTP method.",
},
)
if err := customRegistry.Register(customCounter); err != nil { // register the counter with the custom registry
log.Fatal(err)
}
e.Use(echoprometheus.NewMiddlewareWithConfig(echoprometheus.MiddlewareConfig{
AfterNext: func(c *echo.Context, err error) {
customCounter.Inc() // increment the counter after every request
},
Registerer: customRegistry, // use the custom registry instead of the default Prometheus registry
}))
e.GET("/metrics", echoprometheus.NewHandlerWithConfig(echoprometheus.HandlerConfig{Gatherer: customRegistry})) // serve metrics from the custom registry
if err := e.Start(":8080"); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}

可以传入 skipper,避免为某些 URL 生成 metrics:

package main
import (
"net/http"
"strings"
echoprometheus "github.com/labstack/echo-prometheus"
"github.com/labstack/echo/v5"
)
func main() {
e := echo.New() // this Echo instance will serve routes on port 8080
mwConfig := echoprometheus.MiddlewareConfig{
Skipper: func(c *echo.Context) bool {
return strings.HasPrefix(c.Path(), "/testurl")
}, // does not gather metrics on routes starting with `/testurl`
}
e.Use(echoprometheus.NewMiddlewareWithConfig(mwConfig)) // adds middleware to gather metrics
e.GET("/metrics", echoprometheus.NewHandler()) // adds route to serve gathered metrics
e.GET("/", func(c *echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
if err := e.Start(":8080"); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}

修改默认的 echoprometheus metric 定义:

package main
import (
"net/http"
echoprometheus "github.com/labstack/echo-prometheus"
"github.com/labstack/echo/v5"
"github.com/prometheus/client_golang/prometheus"
)
func main() {
e := echo.New() // this Echo instance will serve routes on port 8080
e.Use(echoprometheus.NewMiddlewareWithConfig(echoprometheus.MiddlewareConfig{
// Labels of default metrics can be modified or added with the `LabelFuncs` function.
LabelFuncs: map[string]echoprometheus.LabelValueFunc{
"scheme": func(c *echo.Context, err error) string { // additional custom label
return c.Scheme()
},
"host": func(c *echo.Context, err error) string { // overrides the default 'host' label value
return "y_" + c.Request().Host
},
},
// The `echoprometheus` middleware registers the following metrics by default:
// - Histogram: request_duration_seconds
// - Histogram: response_size_bytes
// - Histogram: request_size_bytes
// - Counter: requests_total
// which can be modified with the `HistogramOptsFunc` and `CounterOptsFunc` functions.
HistogramOptsFunc: func(opts prometheus.HistogramOpts) prometheus.HistogramOpts {
if opts.Name == "request_duration_seconds" {
opts.Buckets = []float64{1000.0, 10_000.0, 100_000.0, 1_000_000.0} // 1KB, 10KB, 100KB, 1MB
}
return opts
},
CounterOptsFunc: func(opts prometheus.CounterOpts) prometheus.CounterOpts {
if opts.Name == "requests_total" {
opts.ConstLabels = prometheus.Labels{"my_const": "123"}
}
return opts
},
})) // adds middleware to gather metrics
e.GET("/metrics", echoprometheus.NewHandler()) // adds route to serve gathered metrics
e.GET("/hello", func(c *echo.Context) error {
return c.String(http.StatusOK, "hello")
})
if err := e.Start(":8080"); err != nil {
e.Logger.Error("failed to start server", "error", err)
}
}

MiddlewareConfig · github.com/labstack/[email protected]

字段说明由英文源码注释生成。

包源码中的字段
字段类型说明源码
Skipper middleware.Skipper Skipper defines a function to skip middleware. L44
Namespace string Namespace is components of the fully-qualified name of the Metric (created by joining Namespace,Subsystem and Name components with "_") Optional L48
Subsystem string Subsystem is components of the fully-qualified name of the Metric (created by joining Namespace,Subsystem and Name components with "_") Defaults to: "echo" L52
LabelFuncs map[string]LabelValueFunc LabelFuncs allows adding custom labels in addition to default labels. When key has same name with default label it replaces default one. L56
HistogramOptsFunc func(opts prometheus.HistogramOpts) prometheus.HistogramOpts HistogramOptsFunc allows to change options for metrics of type histogram before metric is registered to Registerer L59
CounterOptsFunc func(opts prometheus.CounterOpts) prometheus.CounterOpts CounterOptsFunc allows to change options for metrics of type counter before metric is registered to Registerer L62
Registerer prometheus.Registerer Registerer sets the prometheus.Registerer instance the middleware will register these metrics with. Defaults to: prometheus.DefaultRegisterer L66
BeforeNext func(c *echo.Context) BeforeNext is callback that is executed before next middleware/handler is called. Useful for case when you have own metrics that need data to be stored for AfterNext. L70
AfterNext func(c *echo.Context, err error) AfterNext is callback that is executed after next middleware/handler returns. Useful for case when you have own metrics that need incremented/observed. L74
DoNotUseRequestPathFor404 bool If DoNotUseRequestPathFor404 is true, all 404 responses (due to non-matching route) will have the same `url` label and thus won't generate new metrics. L80
包源码中的函数
类型源码
func NewMiddleware(subsystem string) echo.MiddlewareFunc L137
func NewMiddlewareWithConfig(config MiddlewareConfig) echo.MiddlewareFunc L142

HandlerConfig · github.com/labstack/[email protected]

字段说明由英文源码注释生成。

包源码中的字段
字段类型说明源码
Gatherer prometheus.Gatherer Gatherer sets the prometheus.Gatherer instance the middleware will use when generating the metric endpoint handler. Defaults to: prometheus.DefaultGatherer L90
包源码中的函数
类型源码
func NewHandler() echo.HandlerFunc L115
func NewHandlerWithConfig(config HandlerConfig) echo.HandlerFunc L120

PushGatewayConfig · github.com/labstack/[email protected]

字段说明由英文源码注释生成。

包源码中的字段
字段类型说明源码
PushGatewayURL string PushGatewayURL is push gateway URL in format http://domain:port L96
PushInterval time.Duration PushInterval in ticker interval for pushing gathered metrics to the Gateway Defaults to: 1 minute L100
Gatherer prometheus.Gatherer Gatherer sets the prometheus.Gatherer instance the middleware will use when generating the metric endpoint handler. Defaults to: prometheus.DefaultGatherer L104
ErrorHandler func(err error) error ErrorHandler is function that is called when errors occur. When callback returns error StartPushGateway also returns. L107
ClientTransport http.RoundTripper ClientTransport specifies the mechanism by which individual HTTP POST requests are made. Defaults to: http.DefaultTransport L111
包源码中的函数
类型源码
func RunPushGatewayGatherer(ctx context.Context, config PushGatewayConfig) error L382