diff --git a/docs/content/observability/metrics/statsd.md b/docs/content/observability/metrics/statsd.md index a777ae74f..d16714968 100644 --- a/docs/content/observability/metrics/statsd.md +++ b/docs/content/observability/metrics/statsd.md @@ -103,3 +103,25 @@ metrics: ```bash tab="CLI" --metrics.statsd.pushInterval=10s ``` + +#### `prefix` + +_Optional, Default="traefik"_ + +The prefix to use for metrics collection. + +```toml tab="File (TOML)" +[metrics] + [metrics.statsD] + prefix = "traefik" +``` + +```yaml tab="File (YAML)" +metrics: + statsD: + prefix: traefik +``` + +```bash tab="CLI" +--metrics.statsd.prefix="traefik" +``` \ No newline at end of file diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index ed6c70a6e..f0868656f 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -225,6 +225,9 @@ StatsD address. (Default: ```localhost:8125```) `--metrics.statsd.addserviceslabels`: Enable metrics on services. (Default: ```true```) +`--metrics.statsd.prefix`: +Prefix to use for metrics collection. (Default: ```traefik```) + `--metrics.statsd.pushinterval`: StatsD push interval. (Default: ```10```) diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index 115540ec6..b0a1ff489 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -225,6 +225,9 @@ StatsD address. (Default: ```localhost:8125```) `TRAEFIK_METRICS_STATSD_ADDSERVICESLABELS`: Enable metrics on services. (Default: ```true```) +`TRAEFIK_METRICS_STATSD_PREFIX`: +Prefix to use for metrics collection. (Default: ```traefik```) + `TRAEFIK_METRICS_STATSD_PUSHINTERVAL`: StatsD push interval. (Default: ```10```) diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index f409dffcb..ae6311f4d 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -151,6 +151,7 @@ pushInterval = "10s" addEntryPointsLabels = true addServicesLabels = true + prefix = "traefik" [metrics.influxDB] address = "foobar" protocol = "foobar" diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml index 23d813ac8..b6e9324e5 100644 --- a/docs/content/reference/static-configuration/file.yaml +++ b/docs/content/reference/static-configuration/file.yaml @@ -158,6 +158,7 @@ metrics: pushInterval: 42 addEntryPointsLabels: true addServicesLabels: true + prefix: traefik influxDB: address: foobar protocol: foobar diff --git a/pkg/metrics/statsd.go b/pkg/metrics/statsd.go index 8ebf6986e..eb08de8f4 100644 --- a/pkg/metrics/statsd.go +++ b/pkg/metrics/statsd.go @@ -11,11 +11,7 @@ import ( "github.com/go-kit/kit/metrics/statsd" ) -var statsdClient = statsd.New("traefik.", kitlog.LoggerFunc(func(keyvals ...interface{}) error { - log.WithoutContext().WithField(log.MetricsProviderName, "statsd").Info(keyvals) - return nil -})) - +var statsdClient *statsd.Statsd var statsdTicker *time.Ticker const ( @@ -35,6 +31,16 @@ const ( // RegisterStatsd registers the metrics pusher if this didn't happen yet and creates a statsd Registry instance. func RegisterStatsd(ctx context.Context, config *types.Statsd) Registry { + // just to be sure there is a prefix defined + if config.Prefix == "" { + config.Prefix = "traefik" + } + + statsdClient = statsd.New(config.Prefix+".", kitlog.LoggerFunc(func(keyvals ...interface{}) error { + log.WithoutContext().WithField(log.MetricsProviderName, "statsd").Info(keyvals) + return nil + })) + if statsdTicker == nil { statsdTicker = initStatsdTicker(ctx, config) } diff --git a/pkg/metrics/statsd_test.go b/pkg/metrics/statsd_test.go index 240685d67..11955a50a 100644 --- a/pkg/metrics/statsd_test.go +++ b/pkg/metrics/statsd_test.go @@ -49,3 +49,43 @@ func TestStatsD(t *testing.T) { statsdRegistry.ServiceServerUpGauge().With("service:test", "url", "http://127.0.0.1").Set(1) }) } + +func TestStatsDWithPrefix(t *testing.T) { + udp.SetAddr(":18125") + // This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond + udp.Timeout = 5 * time.Second + + statsdRegistry := RegisterStatsd(context.Background(), &types.Statsd{Address: ":18125", PushInterval: types.Duration(time.Second), AddEntryPointsLabels: true, AddServicesLabels: true, Prefix: "testPrefix"}) + defer StopStatsd() + + if !statsdRegistry.IsEpEnabled() || !statsdRegistry.IsSvcEnabled() { + t.Errorf("Statsd registry should return true for IsEnabled()") + } + + expected := []string{ + // We are only validating counts, as it is nearly impossible to validate latency, since it varies every run + "testPrefix.service.request.total:2.000000|c\n", + "testPrefix.service.retries.total:2.000000|c\n", + "testPrefix.service.request.duration:10000.000000|ms", + "testPrefix.config.reload.total:1.000000|c\n", + "testPrefix.config.reload.total:1.000000|c\n", + "testPrefix.entrypoint.request.total:1.000000|c\n", + "testPrefix.entrypoint.request.duration:10000.000000|ms", + "testPrefix.entrypoint.connections.open:1.000000|g\n", + "testPrefix.service.server.up:1.000000|g\n", + } + + udp.ShouldReceiveAll(t, expected, func() { + statsdRegistry.ServiceReqsCounter().With("service", "test", "code", string(http.StatusOK), "method", http.MethodGet).Add(1) + statsdRegistry.ServiceReqsCounter().With("service", "test", "code", string(http.StatusNotFound), "method", http.MethodGet).Add(1) + statsdRegistry.ServiceRetriesCounter().With("service", "test").Add(1) + statsdRegistry.ServiceRetriesCounter().With("service", "test").Add(1) + statsdRegistry.ServiceReqDurationHistogram().With("service", "test", "code", string(http.StatusOK)).Observe(10000) + statsdRegistry.ConfigReloadsCounter().Add(1) + statsdRegistry.ConfigReloadsFailureCounter().Add(1) + statsdRegistry.EntryPointReqsCounter().With("entrypoint", "test").Add(1) + statsdRegistry.EntryPointReqDurationHistogram().With("entrypoint", "test").Observe(10000) + statsdRegistry.EntryPointOpenConnsGauge().With("entrypoint", "test").Set(1) + statsdRegistry.ServiceServerUpGauge().With("service:test", "url", "http://127.0.0.1").Set(1) + }) +} diff --git a/pkg/types/metrics.go b/pkg/types/metrics.go index 4fcebf550..305284023 100644 --- a/pkg/types/metrics.go +++ b/pkg/types/metrics.go @@ -50,6 +50,7 @@ type Statsd struct { PushInterval Duration `description:"StatsD push interval." json:"pushInterval,omitempty" toml:"pushInterval,omitempty" yaml:"pushInterval,omitempty" export:"true"` AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"` AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"` + Prefix string `description:"Prefix to use for metrics collection." json:"prefix,omitempty" toml:"prefix,omitempty" yaml:"prefix,omitempty" export:"true"` } // SetDefaults sets the default values. @@ -58,6 +59,7 @@ func (s *Statsd) SetDefaults() { s.PushInterval = Duration(10 * time.Second) s.AddEntryPointsLabels = true s.AddServicesLabels = true + s.Prefix = "traefik" } // InfluxDB contains address, login and metrics pushing interval configuration.