2017-08-23 20:46:03 +02:00
package metrics
import (
2018-11-14 10:18:03 +01:00
"context"
2017-08-23 20:46:03 +02:00
"time"
"github.com/containous/traefik/log"
"github.com/containous/traefik/safe"
"github.com/containous/traefik/types"
kitlog "github.com/go-kit/kit/log"
"github.com/go-kit/kit/metrics/dogstatsd"
)
var datadogClient = dogstatsd . New ( "traefik." , kitlog . LoggerFunc ( func ( keyvals ... interface { } ) error {
2018-11-14 10:18:03 +01:00
log . WithoutContext ( ) . WithField ( log . MetricsProviderName , "datadog" ) . Info ( keyvals )
2017-08-23 20:46:03 +02:00
return nil
} ) )
var datadogTicker * time . Ticker
// Metric names consistent with https://github.com/DataDog/integrations-extras/pull/64
const (
2018-02-21 03:04:03 -06:00
ddMetricsBackendReqsName = "backend.request.total"
ddMetricsBackendLatencyName = "backend.request.duration"
ddRetriesTotalName = "backend.retries.total"
ddConfigReloadsName = "config.reload.total"
ddConfigReloadsFailureTagName = "failure"
ddLastConfigReloadSuccessName = "config.reload.lastSuccessTimestamp"
ddLastConfigReloadFailureName = "config.reload.lastFailureTimestamp"
ddEntrypointReqsName = "entrypoint.request.total"
ddEntrypointReqDurationName = "entrypoint.request.duration"
ddEntrypointOpenConnsName = "entrypoint.connections.open"
ddOpenConnsName = "backend.connections.open"
ddServerUpName = "backend.server.up"
2017-08-23 20:46:03 +02:00
)
// RegisterDatadog registers the metrics pusher if this didn't happen yet and creates a datadog Registry instance.
2018-11-14 10:18:03 +01:00
func RegisterDatadog ( ctx context . Context , config * types . Datadog ) Registry {
2017-08-23 20:46:03 +02:00
if datadogTicker == nil {
2018-11-14 10:18:03 +01:00
datadogTicker = initDatadogClient ( ctx , config )
2017-08-23 20:46:03 +02:00
}
registry := & standardRegistry {
2018-02-21 03:04:03 -06:00
enabled : true ,
configReloadsCounter : datadogClient . NewCounter ( ddConfigReloadsName , 1.0 ) ,
configReloadsFailureCounter : datadogClient . NewCounter ( ddConfigReloadsName , 1.0 ) . With ( ddConfigReloadsFailureTagName , "true" ) ,
lastConfigReloadSuccessGauge : datadogClient . NewGauge ( ddLastConfigReloadSuccessName ) ,
lastConfigReloadFailureGauge : datadogClient . NewGauge ( ddLastConfigReloadFailureName ) ,
entrypointReqsCounter : datadogClient . NewCounter ( ddEntrypointReqsName , 1.0 ) ,
entrypointReqDurationHistogram : datadogClient . NewHistogram ( ddEntrypointReqDurationName , 1.0 ) ,
entrypointOpenConnsGauge : datadogClient . NewGauge ( ddEntrypointOpenConnsName ) ,
backendReqsCounter : datadogClient . NewCounter ( ddMetricsBackendReqsName , 1.0 ) ,
backendReqDurationHistogram : datadogClient . NewHistogram ( ddMetricsBackendLatencyName , 1.0 ) ,
backendRetriesCounter : datadogClient . NewCounter ( ddRetriesTotalName , 1.0 ) ,
backendOpenConnsGauge : datadogClient . NewGauge ( ddOpenConnsName ) ,
backendServerUpGauge : datadogClient . NewGauge ( ddServerUpName ) ,
2017-08-23 20:46:03 +02:00
}
return registry
}
2018-11-14 10:18:03 +01:00
func initDatadogClient ( ctx context . Context , config * types . Datadog ) * time . Ticker {
2017-08-23 20:46:03 +02:00
address := config . Address
if len ( address ) == 0 {
address = "localhost:8125"
}
pushInterval , err := time . ParseDuration ( config . PushInterval )
if err != nil {
2018-11-14 10:18:03 +01:00
log . FromContext ( ctx ) . Warnf ( "Unable to parse %s from config.PushInterval: using 10s as the default value" , config . PushInterval )
2017-08-23 20:46:03 +02:00
pushInterval = 10 * time . Second
}
report := time . NewTicker ( pushInterval )
safe . Go ( func ( ) {
datadogClient . SendLoop ( report . C , "udp" , address )
} )
return report
}
// StopDatadog stops internal datadogTicker which controls the pushing of metrics to DD Agent and resets it to `nil`.
func StopDatadog ( ) {
if datadogTicker != nil {
datadogTicker . Stop ( )
}
datadogTicker = nil
}