-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit.go
98 lines (75 loc) · 2.37 KB
/
init.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package echoprometheus
import (
"github.com/labstack/echo/v4"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"strconv"
"time"
)
var defaultMetricPath = "/metrics"
// Prometheus contains the metrics gathered by the instance and its path
type Prometheus struct {
reqCnt *prometheus.CounterVec
reqDur *prometheus.HistogramVec
MetricsPath string
}
// NewPrometheus generates a new set of metrics with a certain subsystem name
func NewPrometheus(subsystem string) *Prometheus {
p := &Prometheus{
MetricsPath: defaultMetricPath,
}
p.registerMetrics(subsystem)
return p
}
func (p *Prometheus) registerMetrics(subsystem string) {
// p.reqCnt = prometheus.NewCounterVec(
// prometheus.CounterOpts{
// Subsystem: subsystem,
// Name: "requests_total",
// Help: "How many HTTP requests processed, partitioned by status code and HTTP path.",
// },
// []string{"code", "path"},
// )
// prometheus.MustRegister(p.reqCnt)
p.reqDur = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Subsystem: subsystem,
Name: "request_duration_seconds",
Help: "The HTTP request latencies in seconds.",
Buckets: []float64{.005, .01, .02, 0.04, .06, 0.08, .1, 0.15, .25, 0.4, .6, .8, 1, 1.5, 2, 3, 5},
},
[]string{"code", "path"},
)
prometheus.MustRegister(p.reqDur)
}
// Use adds the middleware to a echo enechoe.
func (p *Prometheus) Use(e *echo.Echo) {
e.Use(p.middlewareFunc())
e.GET(p.MetricsPath, prometheusHandler())
}
func (p *Prometheus) middlewareFunc() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) (err error) {
if c.Request().URL.String() == p.MetricsPath {
return next(c)
}
start := time.Now()
ctxPath := c.Path()
if err = next(c); err != nil {
c.Error(err)
ctxPath = "/404"
}
status := strconv.Itoa(c.Response().Status)
elapsed := float64(time.Since(start)) / float64(time.Second)
path := c.Request().Method + "_" + ctxPath
p.reqDur.WithLabelValues(status, path).Observe(elapsed)
//p.reqCnt.WithLabelValues(status, path).Inc()
c.Response().Header().Set("X-Response-Time", strconv.Itoa(int(elapsed*1000)))
return
}
}
}
func prometheusHandler() echo.HandlerFunc {
h := promhttp.HandlerFor(prometheus.DefaultGatherer, promhttp.HandlerOpts{})
return echo.WrapHandler(h)
}