2019-01-25 17:27:27 +03:00
|
|
|
package prometheus
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2019-01-26 12:33:51 +03:00
|
|
|
"fmt"
|
|
|
|
|
2019-01-25 17:27:27 +03:00
|
|
|
"github.com/micro/go-micro/server"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
|
)
|
|
|
|
|
2019-01-26 12:33:51 +03:00
|
|
|
var (
|
|
|
|
defaultMetricPrefix = "micro"
|
|
|
|
)
|
|
|
|
|
|
|
|
func NewHandlerWrapper(opts ...server.Option) server.HandlerWrapper {
|
|
|
|
md := make(map[string]string)
|
|
|
|
sopts := server.Options{}
|
|
|
|
|
|
|
|
for _, opt := range opts {
|
|
|
|
opt(&sopts)
|
|
|
|
}
|
|
|
|
|
|
|
|
for k, v := range sopts.Metadata {
|
|
|
|
md[fmt.Sprintf("%s_%s", defaultMetricPrefix, k)] = v
|
|
|
|
}
|
|
|
|
if len(sopts.Name) > 0 {
|
|
|
|
md[fmt.Sprintf("%s_%s", defaultMetricPrefix, "name")] = sopts.Name
|
|
|
|
}
|
|
|
|
if len(sopts.Id) > 0 {
|
|
|
|
md[fmt.Sprintf("%s_%s", defaultMetricPrefix, "id")] = sopts.Id
|
|
|
|
}
|
|
|
|
if len(sopts.Version) > 0 {
|
|
|
|
md[fmt.Sprintf("%s_%s", defaultMetricPrefix, "version")] = sopts.Version
|
|
|
|
}
|
|
|
|
|
2019-01-25 17:27:27 +03:00
|
|
|
opsCounter := prometheus.NewCounterVec(
|
|
|
|
prometheus.CounterOpts{
|
2019-03-09 00:24:35 +03:00
|
|
|
Namespace: "micro",
|
|
|
|
Name: "request_total",
|
|
|
|
Help: "How many go-micro requests processed, partitioned by method and status",
|
2019-01-25 17:27:27 +03:00
|
|
|
},
|
|
|
|
[]string{"method", "status"},
|
|
|
|
)
|
|
|
|
|
2019-01-28 17:47:32 +03:00
|
|
|
timeCounterSummary := prometheus.NewSummaryVec(
|
2019-01-25 17:27:27 +03:00
|
|
|
prometheus.SummaryOpts{
|
2019-03-09 00:24:35 +03:00
|
|
|
Namespace: "micro",
|
|
|
|
Name: "upstream_latency_microseconds",
|
|
|
|
Help: "Service backend method request latencies in microseconds",
|
2019-01-28 17:47:32 +03:00
|
|
|
},
|
|
|
|
[]string{"method"},
|
|
|
|
)
|
|
|
|
|
|
|
|
timeCounterHistogram := prometheus.NewHistogramVec(
|
|
|
|
prometheus.HistogramOpts{
|
2019-03-09 00:24:35 +03:00
|
|
|
Namespace: "micro",
|
|
|
|
Name: "request_duration_seconds",
|
|
|
|
Help: "Service method request time in seconds",
|
2019-01-25 17:27:27 +03:00
|
|
|
},
|
|
|
|
[]string{"method"},
|
|
|
|
)
|
|
|
|
|
2019-02-04 01:26:31 +03:00
|
|
|
reg := prometheus.NewRegistry()
|
|
|
|
wrapreg := prometheus.WrapRegistererWith(md, reg)
|
|
|
|
wrapreg.MustRegister(
|
|
|
|
prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}),
|
|
|
|
prometheus.NewGoCollector(),
|
|
|
|
opsCounter,
|
|
|
|
timeCounterSummary,
|
|
|
|
timeCounterHistogram,
|
|
|
|
)
|
|
|
|
|
|
|
|
prometheus.DefaultGatherer = reg
|
|
|
|
prometheus.DefaultRegisterer = wrapreg
|
2019-01-25 17:27:27 +03:00
|
|
|
|
|
|
|
return func(fn server.HandlerFunc) server.HandlerFunc {
|
|
|
|
return func(ctx context.Context, req server.Request, rsp interface{}) error {
|
|
|
|
name := req.Endpoint()
|
|
|
|
|
|
|
|
timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
|
|
|
|
us := v * 1000000 // make microseconds
|
2019-01-28 17:47:32 +03:00
|
|
|
timeCounterSummary.WithLabelValues(name).Observe(us)
|
|
|
|
timeCounterHistogram.WithLabelValues(name).Observe(v)
|
2019-01-25 17:27:27 +03:00
|
|
|
}))
|
|
|
|
defer timer.ObserveDuration()
|
|
|
|
|
|
|
|
err := fn(ctx, req, rsp)
|
|
|
|
if err == nil {
|
|
|
|
opsCounter.WithLabelValues(name, "success").Inc()
|
|
|
|
} else {
|
|
|
|
opsCounter.WithLabelValues(name, "fail").Inc()
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|