Support InfluxDB v2 metrics backend
This commit is contained in:
parent
5780dc2b15
commit
ca55dfe1c6
16 changed files with 681 additions and 49 deletions
|
@ -448,6 +448,16 @@ func registerMetricClients(metricsConfig *types.Metrics) []metrics.Registry {
|
||||||
metricsConfig.InfluxDB.Address, metricsConfig.InfluxDB.PushInterval)
|
metricsConfig.InfluxDB.Address, metricsConfig.InfluxDB.PushInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if metricsConfig.InfluxDB2 != nil {
|
||||||
|
ctx := log.With(context.Background(), log.Str(log.MetricsProviderName, "influxdb2"))
|
||||||
|
influxDB2Register := metrics.RegisterInfluxDB2(ctx, metricsConfig.InfluxDB2)
|
||||||
|
if influxDB2Register != nil {
|
||||||
|
registries = append(registries, influxDB2Register)
|
||||||
|
log.FromContext(ctx).Debugf("Configured InfluxDB v2 metrics: pushing to %s (%s org/%s bucket) once every %s",
|
||||||
|
metricsConfig.InfluxDB2.Address, metricsConfig.InfluxDB2.Org, metricsConfig.InfluxDB2.Bucket, metricsConfig.InfluxDB2.PushInterval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return registries
|
return registries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
219
docs/content/observability/metrics/influxdb2.md
Normal file
219
docs/content/observability/metrics/influxdb2.md
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
# InfluxDB v2
|
||||||
|
|
||||||
|
To enable the InfluxDB2:
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
influxDB2: {}
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.influxDB2]
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.influxdb2=true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `address`
|
||||||
|
|
||||||
|
_Required, Default="http://localhost:8086"_
|
||||||
|
|
||||||
|
Address of the InfluxDB v2 instance.
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
influxDB2:
|
||||||
|
address: http://localhost:8086
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.influxDB2]
|
||||||
|
address = "http://localhost:8086"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.influxdb2.address=http://localhost:8086
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `token`
|
||||||
|
|
||||||
|
_Required, Default=""_
|
||||||
|
|
||||||
|
Token with which to connect to InfluxDB v2.
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
influxDB2:
|
||||||
|
token: secret
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.influxDB2]
|
||||||
|
token = "secret"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.influxdb2.token=secret
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `org`
|
||||||
|
|
||||||
|
_Required, Default=""_
|
||||||
|
|
||||||
|
Organisation where metrics will be stored.
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
influxDB2:
|
||||||
|
org: my-org
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.influxDB2]
|
||||||
|
org = "my-org"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.influxdb2.org=my-org
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `bucket`
|
||||||
|
|
||||||
|
_Required, Default=""_
|
||||||
|
|
||||||
|
Bucket where metrics will be stored.
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
influxDB2:
|
||||||
|
bucket: my-bucket
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.influxDB2]
|
||||||
|
bucket = "my-bucket"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.influxdb2.bucket=my-bucket
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `addEntryPointsLabels`
|
||||||
|
|
||||||
|
_Optional, Default=true_
|
||||||
|
|
||||||
|
Enable metrics on entry points.
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
influxDB2:
|
||||||
|
addEntryPointsLabels: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.influxDB2]
|
||||||
|
addEntryPointsLabels = true
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.influxdb2.addEntryPointsLabels=true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `addRoutersLabels`
|
||||||
|
|
||||||
|
_Optional, Default=false_
|
||||||
|
|
||||||
|
Enable metrics on routers.
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
influxDB2:
|
||||||
|
addRoutersLabels: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.influxDB2]
|
||||||
|
addRoutersLabels = true
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.influxdb2.addrouterslabels=true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `addServicesLabels`
|
||||||
|
|
||||||
|
_Optional, Default=true_
|
||||||
|
|
||||||
|
Enable metrics on services.
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
influxDB2:
|
||||||
|
addServicesLabels: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.influxDB2]
|
||||||
|
addServicesLabels = true
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.influxdb2.addServicesLabels=true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `pushInterval`
|
||||||
|
|
||||||
|
_Optional, Default=10s_
|
||||||
|
|
||||||
|
The interval used by the exporter to push metrics to InfluxDB server.
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
influxDB2:
|
||||||
|
pushInterval: 10s
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.influxDB2]
|
||||||
|
pushInterval = "10s"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.influxdb2.pushInterval=10s
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `additionalLabels`
|
||||||
|
|
||||||
|
_Optional, Default={}_
|
||||||
|
|
||||||
|
Additional labels (InfluxDB tags) on all metrics.
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
metrics:
|
||||||
|
influxDB2:
|
||||||
|
additionalLabels:
|
||||||
|
host: example.com
|
||||||
|
environment: production
|
||||||
|
```
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[metrics]
|
||||||
|
[metrics.influxDB2]
|
||||||
|
[metrics.influxDB2.additionalLabels]
|
||||||
|
host = "example.com"
|
||||||
|
environment = "production"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--metrics.influxdb2.additionallabels.host=example.com --metrics.influxdb2.additionallabels.environment=production
|
||||||
|
```
|
|
@ -4,13 +4,14 @@ Traefik supports 4 metrics backends:
|
||||||
|
|
||||||
- [Datadog](./datadog.md)
|
- [Datadog](./datadog.md)
|
||||||
- [InfluxDB](./influxdb.md)
|
- [InfluxDB](./influxdb.md)
|
||||||
|
- [InfluxDB2](./influxdb2.md)
|
||||||
- [Prometheus](./prometheus.md)
|
- [Prometheus](./prometheus.md)
|
||||||
- [StatsD](./statsd.md)
|
- [StatsD](./statsd.md)
|
||||||
|
|
||||||
## Global Metrics
|
## Global Metrics
|
||||||
|
|
||||||
| Metric | DataDog | InfluxDB | Prometheus | StatsD |
|
| Metric | DataDog | InfluxDB / InfluxDB2 | Prometheus | StatsD |
|
||||||
|-------------------------------------------------------------------------|---------|----------|------------|--------|
|
|-------------------------------------------------------------------------|---------|----------------------|------------|--------|
|
||||||
| [Configuration reloads](#configuration-reloads) | ✓ | ✓ | ✓ | ✓ |
|
| [Configuration reloads](#configuration-reloads) | ✓ | ✓ | ✓ | ✓ |
|
||||||
| [Last Configuration Reload Success](#last-configuration-reload-success) | ✓ | ✓ | ✓ | ✓ |
|
| [Last Configuration Reload Success](#last-configuration-reload-success) | ✓ | ✓ | ✓ | ✓ |
|
||||||
| [TLS certificates expiration](#tls-certificates-expiration) | ✓ | ✓ | ✓ | ✓ |
|
| [TLS certificates expiration](#tls-certificates-expiration) | ✓ | ✓ | ✓ | ✓ |
|
||||||
|
@ -23,7 +24,7 @@ The total count of configuration reloads.
|
||||||
config.reload.total
|
config.reload.total
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.config.reload.total
|
traefik.config.reload.total
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ The timestamp of the last configuration reload success.
|
||||||
config.reload.lastSuccessTimestamp
|
config.reload.lastSuccessTimestamp
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.config.reload.lastSuccessTimestamp
|
traefik.config.reload.lastSuccessTimestamp
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ Available labels: `cn`, `sans`, `serial`.
|
||||||
tls.certs.notAfterTimestamp
|
tls.certs.notAfterTimestamp
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.tls.certs.notAfterTimestamp
|
traefik.tls.certs.notAfterTimestamp
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -82,8 +83,8 @@ traefik_tls_certs_not_after
|
||||||
|
|
||||||
## EntryPoint Metrics
|
## EntryPoint Metrics
|
||||||
|
|
||||||
| Metric | DataDog | InfluxDB | Prometheus | StatsD |
|
| Metric | DataDog | InfluxDB / InfluxDB2 | Prometheus | StatsD |
|
||||||
|-----------------------------------------------------------|---------|----------|------------|--------|
|
|-----------------------------------------------------------|---------|----------------------|------------|--------|
|
||||||
| [HTTP Requests Count](#http-requests-count) | ✓ | ✓ | ✓ | ✓ |
|
| [HTTP Requests Count](#http-requests-count) | ✓ | ✓ | ✓ | ✓ |
|
||||||
| [HTTPS Requests Count](#https-requests-count) | ✓ | ✓ | ✓ | ✓ |
|
| [HTTPS Requests Count](#https-requests-count) | ✓ | ✓ | ✓ | ✓ |
|
||||||
| [Request Duration Histogram](#request-duration-histogram) | ✓ | ✓ | ✓ | ✓ |
|
| [Request Duration Histogram](#request-duration-histogram) | ✓ | ✓ | ✓ | ✓ |
|
||||||
|
@ -99,7 +100,7 @@ Available labels: `code`, `method`, `protocol`, `entrypoint`.
|
||||||
entrypoint.request.total
|
entrypoint.request.total
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.entrypoint.requests.total
|
traefik.entrypoint.requests.total
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ Available labels: `tls_version`, `tls_cipher`, `entrypoint`.
|
||||||
entrypoint.request.tls.total
|
entrypoint.request.tls.total
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.entrypoint.requests.tls.total
|
traefik.entrypoint.requests.tls.total
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -145,7 +146,7 @@ Available labels: `code`, `method`, `protocol`, `entrypoint`.
|
||||||
entrypoint.request.duration
|
entrypoint.request.duration
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.entrypoint.request.duration
|
traefik.entrypoint.request.duration
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -168,7 +169,7 @@ Available labels: `method`, `protocol`, `entrypoint`.
|
||||||
entrypoint.connections.open
|
entrypoint.connections.open
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.entrypoint.connections.open
|
traefik.entrypoint.connections.open
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -183,8 +184,8 @@ traefik_entrypoint_open_connections
|
||||||
|
|
||||||
## Router Metrics
|
## Router Metrics
|
||||||
|
|
||||||
| Metric | DataDog | InfluxDB | Prometheus | StatsD |
|
| Metric | DataDog | InfluxDB / InfluxDB2 | Prometheus | StatsD |
|
||||||
|-------------------------------------------------------------|---------|----------|------------|--------|
|
|-------------------------------------------------------------|---------|----------------------|------------|--------|
|
||||||
| [HTTP Requests Count](#http-requests-count_1) | ✓ | ✓ | ✓ | ✓ |
|
| [HTTP Requests Count](#http-requests-count_1) | ✓ | ✓ | ✓ | ✓ |
|
||||||
| [HTTPS Requests Count](#https-requests-count_1) | ✓ | ✓ | ✓ | ✓ |
|
| [HTTPS Requests Count](#https-requests-count_1) | ✓ | ✓ | ✓ | ✓ |
|
||||||
| [Request Duration Histogram](#request-duration-histogram_1) | ✓ | ✓ | ✓ | ✓ |
|
| [Request Duration Histogram](#request-duration-histogram_1) | ✓ | ✓ | ✓ | ✓ |
|
||||||
|
@ -200,7 +201,7 @@ Available labels: `code`, `method`, `protocol`, `router`, `service`.
|
||||||
router.request.total
|
router.request.total
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.router.requests.total
|
traefik.router.requests.total
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -223,7 +224,7 @@ Available labels: `tls_version`, `tls_cipher`, `router`, `service`.
|
||||||
router.request.tls.total
|
router.request.tls.total
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.router.requests.tls.total
|
traefik.router.requests.tls.total
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -246,7 +247,7 @@ Available labels: `code`, `method`, `protocol`, `router`, `service`.
|
||||||
router.request.duration
|
router.request.duration
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.router.request.duration
|
traefik.router.request.duration
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -269,7 +270,7 @@ Available labels: `method`, `protocol`, `router`, `service`.
|
||||||
router.connections.open
|
router.connections.open
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.router.connections.open
|
traefik.router.connections.open
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -284,8 +285,8 @@ traefik_router_open_connections
|
||||||
|
|
||||||
## Service Metrics
|
## Service Metrics
|
||||||
|
|
||||||
| Metric | DataDog | InfluxDB | Prometheus | StatsD |
|
| Metric | DataDog | InfluxDB / InfluxDB2 | Prometheus | StatsD |
|
||||||
|-------------------------------------------------------------|---------|----------|------------|--------|
|
|-------------------------------------------------------------|---------|----------------------|------------|--------|
|
||||||
| [HTTP Requests Count](#http-requests-count_2) | ✓ | ✓ | ✓ | ✓ |
|
| [HTTP Requests Count](#http-requests-count_2) | ✓ | ✓ | ✓ | ✓ |
|
||||||
| [HTTPS Requests Count](#https-requests-count_2) | ✓ | ✓ | ✓ | ✓ |
|
| [HTTPS Requests Count](#https-requests-count_2) | ✓ | ✓ | ✓ | ✓ |
|
||||||
| [Request Duration Histogram](#request-duration-histogram_2) | ✓ | ✓ | ✓ | ✓ |
|
| [Request Duration Histogram](#request-duration-histogram_2) | ✓ | ✓ | ✓ | ✓ |
|
||||||
|
@ -303,7 +304,7 @@ Available labels: `code`, `method`, `protocol`, `service`.
|
||||||
service.request.total
|
service.request.total
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.service.requests.total
|
traefik.service.requests.total
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -326,7 +327,7 @@ Available labels: `tls_version`, `tls_cipher`, `service`.
|
||||||
router.service.tls.total
|
router.service.tls.total
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.service.requests.tls.total
|
traefik.service.requests.tls.total
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -349,7 +350,7 @@ Available labels: `code`, `method`, `protocol`, `service`.
|
||||||
service.request.duration
|
service.request.duration
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.service.request.duration
|
traefik.service.request.duration
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -372,7 +373,7 @@ Available labels: `method`, `protocol`, `service`.
|
||||||
service.connections.open
|
service.connections.open
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.service.connections.open
|
traefik.service.connections.open
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -395,7 +396,7 @@ Available labels: `service`.
|
||||||
service.retries.total
|
service.retries.total
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.service.retries.total
|
traefik.service.retries.total
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -418,7 +419,7 @@ Available labels: `service`, `url`.
|
||||||
service.server.up
|
service.server.up
|
||||||
```
|
```
|
||||||
|
|
||||||
```influxdb tab="InfluxDB"
|
```influxdb tab="InfluxDB / InfluxDB2"
|
||||||
traefik.service.server.up
|
traefik.service.server.up
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -285,6 +285,36 @@ InfluxDB retention policy used when protocol is http.
|
||||||
`--metrics.influxdb.username`:
|
`--metrics.influxdb.username`:
|
||||||
InfluxDB username (only with http).
|
InfluxDB username (only with http).
|
||||||
|
|
||||||
|
`--metrics.influxdb2`:
|
||||||
|
InfluxDB v2 metrics exporter type. (Default: ```false```)
|
||||||
|
|
||||||
|
`--metrics.influxdb2.addentrypointslabels`:
|
||||||
|
Enable metrics on entry points. (Default: ```true```)
|
||||||
|
|
||||||
|
`--metrics.influxdb2.additionallabels.<name>`:
|
||||||
|
Additional labels (influxdb tags) on all metrics
|
||||||
|
|
||||||
|
`--metrics.influxdb2.address`:
|
||||||
|
InfluxDB v2 address. (Default: ```http://localhost:8086```)
|
||||||
|
|
||||||
|
`--metrics.influxdb2.addrouterslabels`:
|
||||||
|
Enable metrics on routers. (Default: ```false```)
|
||||||
|
|
||||||
|
`--metrics.influxdb2.addserviceslabels`:
|
||||||
|
Enable metrics on services. (Default: ```true```)
|
||||||
|
|
||||||
|
`--metrics.influxdb2.bucket`:
|
||||||
|
InfluxDB v2 bucket ID.
|
||||||
|
|
||||||
|
`--metrics.influxdb2.org`:
|
||||||
|
InfluxDB v2 org ID.
|
||||||
|
|
||||||
|
`--metrics.influxdb2.pushinterval`:
|
||||||
|
InfluxDB v2 push interval. (Default: ```10```)
|
||||||
|
|
||||||
|
`--metrics.influxdb2.token`:
|
||||||
|
InfluxDB v2 access token.
|
||||||
|
|
||||||
`--metrics.prometheus`:
|
`--metrics.prometheus`:
|
||||||
Prometheus metrics exporter type. (Default: ```false```)
|
Prometheus metrics exporter type. (Default: ```false```)
|
||||||
|
|
||||||
|
|
|
@ -252,6 +252,36 @@ Datadog push interval. (Default: ```10```)
|
||||||
`TRAEFIK_METRICS_INFLUXDB`:
|
`TRAEFIK_METRICS_INFLUXDB`:
|
||||||
InfluxDB metrics exporter type. (Default: ```false```)
|
InfluxDB metrics exporter type. (Default: ```false```)
|
||||||
|
|
||||||
|
`TRAEFIK_METRICS_INFLUXDB2`:
|
||||||
|
InfluxDB v2 metrics exporter type. (Default: ```false```)
|
||||||
|
|
||||||
|
`TRAEFIK_METRICS_INFLUXDB2_ADDENTRYPOINTSLABELS`:
|
||||||
|
Enable metrics on entry points. (Default: ```true```)
|
||||||
|
|
||||||
|
`TRAEFIK_METRICS_INFLUXDB2_ADDITIONALLABELS_<NAME>`:
|
||||||
|
Additional labels (influxdb tags) on all metrics
|
||||||
|
|
||||||
|
`TRAEFIK_METRICS_INFLUXDB2_ADDRESS`:
|
||||||
|
InfluxDB v2 address. (Default: ```http://localhost:8086```)
|
||||||
|
|
||||||
|
`TRAEFIK_METRICS_INFLUXDB2_ADDROUTERSLABELS`:
|
||||||
|
Enable metrics on routers. (Default: ```false```)
|
||||||
|
|
||||||
|
`TRAEFIK_METRICS_INFLUXDB2_ADDSERVICESLABELS`:
|
||||||
|
Enable metrics on services. (Default: ```true```)
|
||||||
|
|
||||||
|
`TRAEFIK_METRICS_INFLUXDB2_BUCKET`:
|
||||||
|
InfluxDB v2 bucket ID.
|
||||||
|
|
||||||
|
`TRAEFIK_METRICS_INFLUXDB2_ORG`:
|
||||||
|
InfluxDB v2 org ID.
|
||||||
|
|
||||||
|
`TRAEFIK_METRICS_INFLUXDB2_PUSHINTERVAL`:
|
||||||
|
InfluxDB v2 push interval. (Default: ```10```)
|
||||||
|
|
||||||
|
`TRAEFIK_METRICS_INFLUXDB2_TOKEN`:
|
||||||
|
InfluxDB v2 access token.
|
||||||
|
|
||||||
`TRAEFIK_METRICS_INFLUXDB_ADDENTRYPOINTSLABELS`:
|
`TRAEFIK_METRICS_INFLUXDB_ADDENTRYPOINTSLABELS`:
|
||||||
Enable metrics on entry points. (Default: ```true```)
|
Enable metrics on entry points. (Default: ```true```)
|
||||||
|
|
||||||
|
|
|
@ -281,6 +281,17 @@
|
||||||
addServicesLabels = true
|
addServicesLabels = true
|
||||||
[metrics.influxDB.additionalLabels]
|
[metrics.influxDB.additionalLabels]
|
||||||
foobar = "foobar"
|
foobar = "foobar"
|
||||||
|
[metrics.influxDB2]
|
||||||
|
address = "foobar"
|
||||||
|
token = "foobar"
|
||||||
|
pushInterval = "42s"
|
||||||
|
org = "foobar"
|
||||||
|
bucket = "foobar"
|
||||||
|
addEntryPointsLabels = true
|
||||||
|
addRoutersLabels = true
|
||||||
|
addServicesLabels = true
|
||||||
|
[metrics.influxDB2.additionalLabels]
|
||||||
|
foobar = "foobar"
|
||||||
|
|
||||||
[ping]
|
[ping]
|
||||||
entryPoint = "foobar"
|
entryPoint = "foobar"
|
||||||
|
|
|
@ -303,6 +303,18 @@ metrics:
|
||||||
addServicesLabels: true
|
addServicesLabels: true
|
||||||
additionalLabels:
|
additionalLabels:
|
||||||
foobar: foobar
|
foobar: foobar
|
||||||
|
influxDB2:
|
||||||
|
address: foobar
|
||||||
|
token: foobar
|
||||||
|
pushInterval: 42s
|
||||||
|
org: foobar
|
||||||
|
bucket: foobar
|
||||||
|
addEntryPointsLabels: true
|
||||||
|
addRoutersLabels: true
|
||||||
|
addServicesLabels: true
|
||||||
|
additionalLabels:
|
||||||
|
foobar: foobar
|
||||||
|
|
||||||
ping:
|
ping:
|
||||||
entryPoint: foobar
|
entryPoint: foobar
|
||||||
manualRouting: true
|
manualRouting: true
|
||||||
|
|
|
@ -147,6 +147,7 @@ nav:
|
||||||
- 'Overview': 'observability/metrics/overview.md'
|
- 'Overview': 'observability/metrics/overview.md'
|
||||||
- 'Datadog': 'observability/metrics/datadog.md'
|
- 'Datadog': 'observability/metrics/datadog.md'
|
||||||
- 'InfluxDB': 'observability/metrics/influxdb.md'
|
- 'InfluxDB': 'observability/metrics/influxdb.md'
|
||||||
|
- 'InfluxDB2': 'observability/metrics/influxdb2.md'
|
||||||
- 'Prometheus': 'observability/metrics/prometheus.md'
|
- 'Prometheus': 'observability/metrics/prometheus.md'
|
||||||
- 'StatsD': 'observability/metrics/statsd.md'
|
- 'StatsD': 'observability/metrics/statsd.md'
|
||||||
- 'Tracing':
|
- 'Tracing':
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -35,6 +35,7 @@ require (
|
||||||
github.com/hashicorp/go-hclog v0.16.1
|
github.com/hashicorp/go-hclog v0.16.1
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
github.com/hashicorp/go-version v1.3.0
|
github.com/hashicorp/go-version v1.3.0
|
||||||
|
github.com/influxdata/influxdb-client-go/v2 v2.7.0
|
||||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d
|
||||||
github.com/instana/go-sensor v1.38.3
|
github.com/instana/go-sensor v1.38.3
|
||||||
github.com/klauspost/compress v1.13.0
|
github.com/klauspost/compress v1.13.0
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -473,8 +473,9 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/deepmap/oapi-codegen v1.6.1 h1:2BvsmRb6pogGNtr8Ann+esAbSKFXx2CZN18VpAMecnw=
|
|
||||||
github.com/deepmap/oapi-codegen v1.6.1/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
|
github.com/deepmap/oapi-codegen v1.6.1/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
|
||||||
|
github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU=
|
||||||
|
github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20190315220205-a8ed825ac853/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
|
github.com/denisenkom/go-mssqldb v0.0.0-20190315220205-a8ed825ac853/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
||||||
github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||||
|
@ -615,6 +616,7 @@ github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 h1:df6OFl8WNX
|
||||||
github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2/go.mod h1:GLyXJD41gBO/NPKVPGQbhyyC06eugGy15QEZyUkE2/s=
|
github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2/go.mod h1:GLyXJD41gBO/NPKVPGQbhyyC06eugGy15QEZyUkE2/s=
|
||||||
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||||
github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
||||||
|
github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
||||||
github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
@ -988,8 +990,12 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/influxdata/influxdb-client-go/v2 v2.7.0 h1:QgP5mlBE9sGnzplpnf96pr+p7uqlIlL4W2GAP3n+XZg=
|
||||||
|
github.com/influxdata/influxdb-client-go/v2 v2.7.0/go.mod h1:Y/0W1+TZir7ypoQZYd2IrnVOKB3Tq6oegAQeSVN/+EU=
|
||||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZQPMZNsjZ7IlCpsLGdQBINg5bxKQ1K1sh6awxLtkA=
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZQPMZNsjZ7IlCpsLGdQBINg5bxKQ1K1sh6awxLtkA=
|
||||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
|
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU=
|
||||||
|
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
|
||||||
github.com/infobloxopen/infoblox-go-client v1.1.1 h1:728A6LbLjptj/7kZjHyIxQnm768PWHfGFm0HH8FnbtU=
|
github.com/infobloxopen/infoblox-go-client v1.1.1 h1:728A6LbLjptj/7kZjHyIxQnm768PWHfGFm0HH8FnbtU=
|
||||||
github.com/infobloxopen/infoblox-go-client v1.1.1/go.mod h1:BXiw7S2b9qJoM8MS40vfgCNB2NLHGusk1DtO16BD9zI=
|
github.com/infobloxopen/infoblox-go-client v1.1.1/go.mod h1:BXiw7S2b9qJoM8MS40vfgCNB2NLHGusk1DtO16BD9zI=
|
||||||
github.com/instana/go-sensor v1.38.3 h1:/PdHEDveLmUCvK+O6REvSv8kKljX8vaj9JMjMeCHAWk=
|
github.com/instana/go-sensor v1.38.3 h1:/PdHEDveLmUCvK+O6REvSv8kKljX8vaj9JMjMeCHAWk=
|
||||||
|
|
|
@ -98,7 +98,7 @@ func RegisterInfluxDB(ctx context.Context, config *types.InfluxDB) Registry {
|
||||||
return registry
|
return registry
|
||||||
}
|
}
|
||||||
|
|
||||||
// initInfluxDBTicker creates a influxDBClient.
|
// initInfluxDBClient creates a influxDBClient.
|
||||||
func initInfluxDBClient(ctx context.Context, config *types.InfluxDB) *influx.Influx {
|
func initInfluxDBClient(ctx context.Context, config *types.InfluxDB) *influx.Influx {
|
||||||
logger := log.FromContext(ctx)
|
logger := log.FromContext(ctx)
|
||||||
|
|
||||||
|
|
144
pkg/metrics/influxdb2.go
Normal file
144
pkg/metrics/influxdb2.go
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
package metrics
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
kitlog "github.com/go-kit/kit/log"
|
||||||
|
"github.com/go-kit/kit/metrics/influx"
|
||||||
|
influxdb2 "github.com/influxdata/influxdb-client-go/v2"
|
||||||
|
influxdb2api "github.com/influxdata/influxdb-client-go/v2/api"
|
||||||
|
"github.com/influxdata/influxdb-client-go/v2/api/write"
|
||||||
|
influxdb2log "github.com/influxdata/influxdb-client-go/v2/log"
|
||||||
|
influxdb "github.com/influxdata/influxdb1-client/v2"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/log"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/safe"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
influxDB2Ticker *time.Ticker
|
||||||
|
influxDB2Store *influx.Influx
|
||||||
|
influxDB2Client influxdb2.Client
|
||||||
|
)
|
||||||
|
|
||||||
|
// RegisterInfluxDB2 creates metrics exporter for InfluxDB2.
|
||||||
|
func RegisterInfluxDB2(ctx context.Context, config *types.InfluxDB2) Registry {
|
||||||
|
if influxDB2Client == nil {
|
||||||
|
var err error
|
||||||
|
if influxDB2Client, err = newInfluxDB2Client(config); err != nil {
|
||||||
|
log.FromContext(ctx).Error(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if influxDB2Store == nil {
|
||||||
|
influxDB2Store = influx.New(
|
||||||
|
config.AdditionalLabels,
|
||||||
|
influxdb.BatchPointsConfig{},
|
||||||
|
kitlog.LoggerFunc(func(kv ...interface{}) error {
|
||||||
|
log.FromContext(ctx).Error(kv)
|
||||||
|
return nil
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
influxDB2Ticker = time.NewTicker(time.Duration(config.PushInterval))
|
||||||
|
|
||||||
|
safe.Go(func() {
|
||||||
|
wc := influxDB2Client.WriteAPIBlocking(config.Org, config.Bucket)
|
||||||
|
influxDB2Store.WriteLoop(ctx, influxDB2Ticker.C, influxDB2Writer{wc: wc})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
registry := &standardRegistry{
|
||||||
|
configReloadsCounter: influxDB2Store.NewCounter(influxDBConfigReloadsName),
|
||||||
|
configReloadsFailureCounter: influxDB2Store.NewCounter(influxDBConfigReloadsFailureName),
|
||||||
|
lastConfigReloadSuccessGauge: influxDB2Store.NewGauge(influxDBLastConfigReloadSuccessName),
|
||||||
|
lastConfigReloadFailureGauge: influxDB2Store.NewGauge(influxDBLastConfigReloadFailureName),
|
||||||
|
tlsCertsNotAfterTimestampGauge: influxDB2Store.NewGauge(influxDBTLSCertsNotAfterTimestampName),
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.AddEntryPointsLabels {
|
||||||
|
registry.epEnabled = config.AddEntryPointsLabels
|
||||||
|
registry.entryPointReqsCounter = influxDB2Store.NewCounter(influxDBEntryPointReqsName)
|
||||||
|
registry.entryPointReqsTLSCounter = influxDB2Store.NewCounter(influxDBEntryPointReqsTLSName)
|
||||||
|
registry.entryPointReqDurationHistogram, _ = NewHistogramWithScale(influxDB2Store.NewHistogram(influxDBEntryPointReqDurationName), time.Second)
|
||||||
|
registry.entryPointOpenConnsGauge = influxDB2Store.NewGauge(influxDBEntryPointOpenConnsName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.AddRoutersLabels {
|
||||||
|
registry.routerEnabled = config.AddRoutersLabels
|
||||||
|
registry.routerReqsCounter = influxDB2Store.NewCounter(influxDBRouterReqsName)
|
||||||
|
registry.routerReqsTLSCounter = influxDB2Store.NewCounter(influxDBRouterReqsTLSName)
|
||||||
|
registry.routerReqDurationHistogram, _ = NewHistogramWithScale(influxDB2Store.NewHistogram(influxDBRouterReqsDurationName), time.Second)
|
||||||
|
registry.routerOpenConnsGauge = influxDB2Store.NewGauge(influxDBORouterOpenConnsName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.AddServicesLabels {
|
||||||
|
registry.svcEnabled = config.AddServicesLabels
|
||||||
|
registry.serviceReqsCounter = influxDB2Store.NewCounter(influxDBServiceReqsName)
|
||||||
|
registry.serviceReqsTLSCounter = influxDB2Store.NewCounter(influxDBServiceReqsTLSName)
|
||||||
|
registry.serviceReqDurationHistogram, _ = NewHistogramWithScale(influxDB2Store.NewHistogram(influxDBServiceReqsDurationName), time.Second)
|
||||||
|
registry.serviceRetriesCounter = influxDB2Store.NewCounter(influxDBServiceRetriesTotalName)
|
||||||
|
registry.serviceOpenConnsGauge = influxDB2Store.NewGauge(influxDBServiceOpenConnsName)
|
||||||
|
registry.serviceServerUpGauge = influxDB2Store.NewGauge(influxDBServiceServerUpName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return registry
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopInfluxDB2 stops and resets InfluxDB2 client, ticker and store.
|
||||||
|
func StopInfluxDB2() {
|
||||||
|
if influxDB2Client != nil {
|
||||||
|
influxDB2Client.Close()
|
||||||
|
}
|
||||||
|
influxDB2Client = nil
|
||||||
|
|
||||||
|
if influxDB2Ticker != nil {
|
||||||
|
influxDB2Ticker.Stop()
|
||||||
|
}
|
||||||
|
influxDB2Ticker = nil
|
||||||
|
|
||||||
|
influxDB2Store = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newInfluxDB2Client creates an influxdb2.Client.
|
||||||
|
func newInfluxDB2Client(config *types.InfluxDB2) (influxdb2.Client, error) {
|
||||||
|
if config.Token == "" || config.Org == "" || config.Bucket == "" {
|
||||||
|
return nil, errors.New("token, org or bucket property is missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable InfluxDB2 logs.
|
||||||
|
// See https://github.com/influxdata/influxdb-client-go/blob/v2.7.0/options.go#L128
|
||||||
|
influxdb2log.Log = nil
|
||||||
|
|
||||||
|
return influxdb2.NewClient(config.Address, config.Token), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type influxDB2Writer struct {
|
||||||
|
wc influxdb2api.WriteAPIBlocking
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w influxDB2Writer) Write(bp influxdb.BatchPoints) error {
|
||||||
|
ctx := log.With(context.Background(), log.Str(log.MetricsProviderName, "influxdb2"))
|
||||||
|
logger := log.FromContext(ctx)
|
||||||
|
|
||||||
|
wps := make([]*write.Point, 0, len(bp.Points()))
|
||||||
|
for _, p := range bp.Points() {
|
||||||
|
fields, err := p.Fields()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Error while getting %s point fields: %s", p.Name(), err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
wps = append(wps, influxdb2.NewPoint(
|
||||||
|
p.Name(),
|
||||||
|
p.Tags(),
|
||||||
|
fields,
|
||||||
|
p.Time(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return w.wc.WritePoint(ctx, wps...)
|
||||||
|
}
|
145
pkg/metrics/influxdb2_test.go
Normal file
145
pkg/metrics/influxdb2_test.go
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
package metrics
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
ptypes "github.com/traefik/paerser/types"
|
||||||
|
"github.com/traefik/traefik/v2/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInfluxDB2(t *testing.T) {
|
||||||
|
c := make(chan *string)
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
body, err := io.ReadAll(r.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
bodyStr := string(body)
|
||||||
|
c <- &bodyStr
|
||||||
|
_, _ = fmt.Fprintln(w, "ok")
|
||||||
|
}))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
influxDB2Registry := RegisterInfluxDB2(context.Background(),
|
||||||
|
&types.InfluxDB2{
|
||||||
|
Address: ts.URL,
|
||||||
|
Token: "test-token",
|
||||||
|
PushInterval: ptypes.Duration(10 * time.Millisecond),
|
||||||
|
Org: "test-org",
|
||||||
|
Bucket: "test-bucket",
|
||||||
|
AddEntryPointsLabels: true,
|
||||||
|
AddRoutersLabels: true,
|
||||||
|
AddServicesLabels: true,
|
||||||
|
})
|
||||||
|
defer StopInfluxDB2()
|
||||||
|
|
||||||
|
if !influxDB2Registry.IsEpEnabled() || !influxDB2Registry.IsRouterEnabled() || !influxDB2Registry.IsSvcEnabled() {
|
||||||
|
t.Fatalf("InfluxDB2Registry should return true for IsEnabled(), IsRouterEnabled() and IsSvcEnabled()")
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedServer := []string{
|
||||||
|
`(traefik\.config\.reload\.total count=1) [\d]{19}`,
|
||||||
|
`(traefik\.config\.reload\.total\.failure count=1) [\d]{19}`,
|
||||||
|
`(traefik\.config\.reload\.lastSuccessTimestamp value=1) [\d]{19}`,
|
||||||
|
`(traefik\.config\.reload\.lastFailureTimestamp value=1) [\d]{19}`,
|
||||||
|
}
|
||||||
|
|
||||||
|
influxDB2Registry.ConfigReloadsCounter().Add(1)
|
||||||
|
influxDB2Registry.ConfigReloadsFailureCounter().Add(1)
|
||||||
|
influxDB2Registry.LastConfigReloadSuccessGauge().Set(1)
|
||||||
|
influxDB2Registry.LastConfigReloadFailureGauge().Set(1)
|
||||||
|
msgServer := <-c
|
||||||
|
|
||||||
|
assertMessage(t, *msgServer, expectedServer)
|
||||||
|
|
||||||
|
expectedTLS := []string{
|
||||||
|
`(traefik\.tls\.certs\.notAfterTimestamp,key=value value=1) [\d]{19}`,
|
||||||
|
}
|
||||||
|
|
||||||
|
influxDB2Registry.TLSCertsNotAfterTimestampGauge().With("key", "value").Set(1)
|
||||||
|
msgTLS := <-c
|
||||||
|
|
||||||
|
assertMessage(t, *msgTLS, expectedTLS)
|
||||||
|
|
||||||
|
expectedEntrypoint := []string{
|
||||||
|
`(traefik\.entrypoint\.requests\.total,code=200,entrypoint=test,method=GET count=1) [\d]{19}`,
|
||||||
|
`(traefik\.entrypoint\.requests\.tls\.total,entrypoint=test,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`,
|
||||||
|
`(traefik\.entrypoint\.request\.duration(?:,code=[\d]{3})?,entrypoint=test p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`,
|
||||||
|
`(traefik\.entrypoint\.connections\.open,entrypoint=test value=1) [\d]{19}`,
|
||||||
|
}
|
||||||
|
|
||||||
|
influxDB2Registry.EntryPointReqsCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1)
|
||||||
|
influxDB2Registry.EntryPointReqsTLSCounter().With("entrypoint", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1)
|
||||||
|
influxDB2Registry.EntryPointReqDurationHistogram().With("entrypoint", "test").Observe(10000)
|
||||||
|
influxDB2Registry.EntryPointOpenConnsGauge().With("entrypoint", "test").Set(1)
|
||||||
|
msgEntrypoint := <-c
|
||||||
|
|
||||||
|
assertMessage(t, *msgEntrypoint, expectedEntrypoint)
|
||||||
|
|
||||||
|
expectedRouter := []string{
|
||||||
|
`(traefik\.router\.requests\.total,code=200,method=GET,router=demo,service=test count=1) [\d]{19}`,
|
||||||
|
`(traefik\.router\.requests\.total,code=404,method=GET,router=demo,service=test count=1) [\d]{19}`,
|
||||||
|
`(traefik\.router\.requests\.tls\.total,router=demo,service=test,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`,
|
||||||
|
`(traefik\.router\.request\.duration,code=200,router=demo,service=test p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`,
|
||||||
|
`(traefik\.router\.connections\.open,router=demo,service=test value=1) [\d]{19}`,
|
||||||
|
}
|
||||||
|
|
||||||
|
influxDB2Registry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1)
|
||||||
|
influxDB2Registry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1)
|
||||||
|
influxDB2Registry.RouterReqsTLSCounter().With("router", "demo", "service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1)
|
||||||
|
influxDB2Registry.RouterReqDurationHistogram().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000)
|
||||||
|
influxDB2Registry.RouterOpenConnsGauge().With("router", "demo", "service", "test").Set(1)
|
||||||
|
msgRouter := <-c
|
||||||
|
|
||||||
|
assertMessage(t, *msgRouter, expectedRouter)
|
||||||
|
|
||||||
|
expectedService := []string{
|
||||||
|
`(traefik\.service\.requests\.total,code=200,method=GET,service=test count=1) [\d]{19}`,
|
||||||
|
`(traefik\.service\.requests\.total,code=404,method=GET,service=test count=1) [\d]{19}`,
|
||||||
|
`(traefik\.service\.requests\.tls\.total,service=test,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`,
|
||||||
|
`(traefik\.service\.request\.duration,code=200,service=test p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`,
|
||||||
|
`(traefik\.service\.server\.up,service=test,url=http://127.0.0.1 value=1) [\d]{19}`,
|
||||||
|
}
|
||||||
|
|
||||||
|
influxDB2Registry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1)
|
||||||
|
influxDB2Registry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1)
|
||||||
|
influxDB2Registry.ServiceReqsTLSCounter().With("service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1)
|
||||||
|
influxDB2Registry.ServiceReqDurationHistogram().With("service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000)
|
||||||
|
influxDB2Registry.ServiceServerUpGauge().With("service", "test", "url", "http://127.0.0.1").Set(1)
|
||||||
|
msgService := <-c
|
||||||
|
|
||||||
|
assertMessage(t, *msgService, expectedService)
|
||||||
|
|
||||||
|
expectedServiceRetries := []string{
|
||||||
|
`(traefik\.service\.retries\.total,service=test count=2) [\d]{19}`,
|
||||||
|
`(traefik\.service\.retries\.total,service=foobar count=1) [\d]{19}`,
|
||||||
|
}
|
||||||
|
|
||||||
|
influxDB2Registry.ServiceRetriesCounter().With("service", "test").Add(1)
|
||||||
|
influxDB2Registry.ServiceRetriesCounter().With("service", "test").Add(1)
|
||||||
|
influxDB2Registry.ServiceRetriesCounter().With("service", "foobar").Add(1)
|
||||||
|
|
||||||
|
msgServiceRetries := <-c
|
||||||
|
|
||||||
|
assertMessage(t, *msgServiceRetries, expectedServiceRetries)
|
||||||
|
|
||||||
|
expectedServiceOpenConns := []string{
|
||||||
|
`(traefik\.service\.connections\.open,service=test value=2) [\d]{19}`,
|
||||||
|
`(traefik\.service\.connections\.open,service=foobar value=1) [\d]{19}`,
|
||||||
|
}
|
||||||
|
|
||||||
|
influxDB2Registry.ServiceOpenConnsGauge().With("service", "test").Add(1)
|
||||||
|
influxDB2Registry.ServiceOpenConnsGauge().With("service", "test").Add(1)
|
||||||
|
influxDB2Registry.ServiceOpenConnsGauge().With("service", "foobar").Add(1)
|
||||||
|
|
||||||
|
msgServiceOpenConns := <-c
|
||||||
|
|
||||||
|
assertMessage(t, *msgServiceOpenConns, expectedServiceOpenConns)
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/stvp/go-udp-testing"
|
"github.com/stvp/go-udp-testing"
|
||||||
ptypes "github.com/traefik/paerser/types"
|
ptypes "github.com/traefik/paerser/types"
|
||||||
"github.com/traefik/traefik/v2/pkg/types"
|
"github.com/traefik/traefik/v2/pkg/types"
|
||||||
|
@ -125,10 +126,8 @@ func TestInfluxDBHTTP(t *testing.T) {
|
||||||
c := make(chan *string)
|
c := make(chan *string)
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
body, err := io.ReadAll(r.Body)
|
body, err := io.ReadAll(r.Body)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
http.Error(w, "can't read body "+err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bodyStr := string(body)
|
bodyStr := string(body)
|
||||||
c <- &bodyStr
|
c <- &bodyStr
|
||||||
_, _ = fmt.Fprintln(w, "ok")
|
_, _ = fmt.Fprintln(w, "ok")
|
||||||
|
@ -140,7 +139,7 @@ func TestInfluxDBHTTP(t *testing.T) {
|
||||||
&types.InfluxDB{
|
&types.InfluxDB{
|
||||||
Address: ts.URL,
|
Address: ts.URL,
|
||||||
Protocol: "http",
|
Protocol: "http",
|
||||||
PushInterval: ptypes.Duration(time.Second),
|
PushInterval: ptypes.Duration(10 * time.Millisecond),
|
||||||
Database: "test",
|
Database: "test",
|
||||||
RetentionPolicy: "autogen",
|
RetentionPolicy: "autogen",
|
||||||
AddEntryPointsLabels: true,
|
AddEntryPointsLabels: true,
|
||||||
|
|
|
@ -111,4 +111,5 @@ func stopMetricsClients() {
|
||||||
metrics.StopDatadog()
|
metrics.StopDatadog()
|
||||||
metrics.StopStatsd()
|
metrics.StopStatsd()
|
||||||
metrics.StopInfluxDB()
|
metrics.StopInfluxDB()
|
||||||
|
metrics.StopInfluxDB2()
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ type Metrics struct {
|
||||||
Datadog *Datadog `description:"Datadog metrics exporter type." json:"datadog,omitempty" toml:"datadog,omitempty" yaml:"datadog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
Datadog *Datadog `description:"Datadog metrics exporter type." json:"datadog,omitempty" toml:"datadog,omitempty" yaml:"datadog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
||||||
StatsD *Statsd `description:"StatsD metrics exporter type." json:"statsD,omitempty" toml:"statsD,omitempty" yaml:"statsD,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
StatsD *Statsd `description:"StatsD metrics exporter type." json:"statsD,omitempty" toml:"statsD,omitempty" yaml:"statsD,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
||||||
InfluxDB *InfluxDB `description:"InfluxDB metrics exporter type." json:"influxDB,omitempty" toml:"influxDB,omitempty" yaml:"influxDB,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
InfluxDB *InfluxDB `description:"InfluxDB metrics exporter type." json:"influxDB,omitempty" toml:"influxDB,omitempty" yaml:"influxDB,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
||||||
|
InfluxDB2 *InfluxDB2 `description:"InfluxDB v2 metrics exporter type." json:"influxDB2,omitempty" toml:"influxDB2,omitempty" yaml:"influxDB2,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prometheus can contain specific configuration used by the Prometheus Metrics exporter.
|
// Prometheus can contain specific configuration used by the Prometheus Metrics exporter.
|
||||||
|
@ -105,6 +106,27 @@ func (i *InfluxDB) SetDefaults() {
|
||||||
i.AddServicesLabels = true
|
i.AddServicesLabels = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InfluxDB2 contains address, token and metrics pushing interval configuration.
|
||||||
|
type InfluxDB2 struct {
|
||||||
|
Address string `description:"InfluxDB v2 address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"`
|
||||||
|
Token string `description:"InfluxDB v2 access token." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"`
|
||||||
|
PushInterval types.Duration `description:"InfluxDB v2 push interval." json:"pushInterval,omitempty" toml:"pushInterval,omitempty" yaml:"pushInterval,omitempty" export:"true"`
|
||||||
|
Org string `description:"InfluxDB v2 org ID." json:"org,omitempty" toml:"org,omitempty" yaml:"org,omitempty" export:"true"`
|
||||||
|
Bucket string `description:"InfluxDB v2 bucket ID." json:"bucket,omitempty" toml:"bucket,omitempty" yaml:"bucket,omitempty" export:"true"`
|
||||||
|
AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"`
|
||||||
|
AddRoutersLabels bool `description:"Enable metrics on routers." json:"addRoutersLabels,omitempty" toml:"addRoutersLabels,omitempty" yaml:"addRoutersLabels,omitempty" export:"true"`
|
||||||
|
AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"`
|
||||||
|
AdditionalLabels map[string]string `description:"Additional labels (influxdb tags) on all metrics" json:"additionalLabels,omitempty" toml:"additionalLabels,omitEmpty" yaml:"additionalLabels,omitEmpty" export:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDefaults sets the default values.
|
||||||
|
func (i *InfluxDB2) SetDefaults() {
|
||||||
|
i.Address = "http://localhost:8086"
|
||||||
|
i.PushInterval = types.Duration(10 * time.Second)
|
||||||
|
i.AddEntryPointsLabels = true
|
||||||
|
i.AddServicesLabels = true
|
||||||
|
}
|
||||||
|
|
||||||
// Statistics provides options for monitoring request and response stats.
|
// Statistics provides options for monitoring request and response stats.
|
||||||
type Statistics struct {
|
type Statistics struct {
|
||||||
RecentErrors int `description:"Number of recent errors logged." json:"recentErrors,omitempty" toml:"recentErrors,omitempty" yaml:"recentErrors,omitempty" export:"true"`
|
RecentErrors int `description:"Number of recent errors logged." json:"recentErrors,omitempty" toml:"recentErrors,omitempty" yaml:"recentErrors,omitempty" export:"true"`
|
||||||
|
|
Loading…
Reference in a new issue