2017-01-12 13:34:54 +00:00
|
|
|
package middlewares
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
2017-04-18 06:22:06 +00:00
|
|
|
|
2017-08-23 18:46:03 +00:00
|
|
|
"github.com/containous/traefik/metrics"
|
|
|
|
gokitmetrics "github.com/go-kit/kit/metrics"
|
2017-01-12 13:34:54 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// MetricsWrapper is a Negroni compatible Handler which relies on a
|
2017-04-18 06:22:06 +00:00
|
|
|
// given Metrics implementation to expose and monitor Traefik Metrics.
|
2017-01-12 13:34:54 +00:00
|
|
|
type MetricsWrapper struct {
|
2017-08-23 18:46:03 +00:00
|
|
|
registry metrics.Registry
|
|
|
|
serviceName string
|
2017-01-12 13:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewMetricsWrapper return a MetricsWrapper struct with
|
|
|
|
// a given Metrics implementation e.g Prometheuss
|
2017-08-23 18:46:03 +00:00
|
|
|
func NewMetricsWrapper(registry metrics.Registry, service string) *MetricsWrapper {
|
2017-01-12 13:34:54 +00:00
|
|
|
var metricsWrapper = MetricsWrapper{
|
2017-08-23 18:46:03 +00:00
|
|
|
registry: registry,
|
|
|
|
serviceName: service,
|
2017-01-12 13:34:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &metricsWrapper
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *MetricsWrapper) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
|
|
|
start := time.Now()
|
|
|
|
prw := &responseRecorder{rw, http.StatusOK}
|
|
|
|
next(prw, r)
|
2017-06-15 14:06:02 +00:00
|
|
|
|
2017-08-23 18:46:03 +00:00
|
|
|
reqLabels := []string{"service", m.serviceName, "code", strconv.Itoa(prw.statusCode), "method", r.Method}
|
|
|
|
m.registry.ReqsCounter().With(reqLabels...).Add(1)
|
2017-06-15 14:06:02 +00:00
|
|
|
|
2017-08-23 18:46:03 +00:00
|
|
|
reqDurationLabels := []string{"service", m.serviceName, "code", strconv.Itoa(prw.statusCode)}
|
|
|
|
m.registry.ReqDurationHistogram().With(reqDurationLabels...).Observe(float64(time.Since(start).Seconds()))
|
|
|
|
}
|
|
|
|
|
|
|
|
type retryMetrics interface {
|
|
|
|
RetriesCounter() gokitmetrics.Counter
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewMetricsRetryListener instantiates a MetricsRetryListener with the given retryMetrics.
|
|
|
|
func NewMetricsRetryListener(retryMetrics retryMetrics, backendName string) RetryListener {
|
|
|
|
return &MetricsRetryListener{retryMetrics: retryMetrics, backendName: backendName}
|
2017-04-18 06:22:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// MetricsRetryListener is an implementation of the RetryListener interface to
|
2017-08-23 18:46:03 +00:00
|
|
|
// record RequestMetrics about retry attempts.
|
2017-04-18 06:22:06 +00:00
|
|
|
type MetricsRetryListener struct {
|
2017-08-23 18:46:03 +00:00
|
|
|
retryMetrics retryMetrics
|
|
|
|
backendName string
|
2017-01-12 13:34:54 +00:00
|
|
|
}
|
|
|
|
|
2017-08-23 18:46:03 +00:00
|
|
|
// Retried tracks the retry in the RequestMetrics implementation.
|
2017-08-28 10:50:02 +00:00
|
|
|
func (m *MetricsRetryListener) Retried(req *http.Request, attempt int) {
|
2017-08-23 18:46:03 +00:00
|
|
|
m.retryMetrics.RetriesCounter().With("backend", m.backendName).Add(1)
|
2017-01-12 13:34:54 +00:00
|
|
|
}
|