Skip to content

Commit e92b01c

Browse files
ldeztraefiker
authored andcommitted
Merge current v1.7 into master
1 parent dad0e75 commit e92b01c

File tree

8 files changed

+130
-26
lines changed

8 files changed

+130
-26
lines changed

docs/configuration/backends/kubernetes.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ The endpoint may be specified to override the environment variable values inside
108108

109109
When the environment variables are not found, Traefik will try to connect to the Kubernetes API server with an external-cluster client.
110110
In this case, the endpoint is required.
111-
Specifically, it may be set to the URL used by `kubectl proxy` to connect to a Kubernetes cluster using the granted autentication and authorization of the associated kubeconfig.
111+
Specifically, it may be set to the URL used by `kubectl proxy` to connect to a Kubernetes cluster using the granted authentication and authorization of the associated kubeconfig.
112112

113113
### `labelselector`
114114

docs/configuration/tracing.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Tracing
22

3-
Tracing system allows developers to visualize call flows in there infrastructures.
3+
The tracing system allows developers to visualize call flows in their infrastructure.
44

55
We use [OpenTracing](http://opentracing.io). It is an open standard designed for distributed tracing.
66

docs/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ IP: 172.27.0.3
138138
Run more instances of your `whoami` service with the following command:
139139

140140
```shell
141-
docker-compose up -d --scale whoami=2
141+
docker-compose scale whoami=2
142142
```
143143

144144
Go back to your browser ([http://localhost:8080](http://localhost:8080)) and see that Træfik has automatically detected the new instance of the container.

docs/user-guide/docker-and-lets-encrypt.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ Finally but not unimportantly, we tell Træfik to route **to** port `9000`, sinc
232232
`Service labels` allow managing many routes for the same container.
233233

234234
When both `container labels` and `service labels` are defined, `container labels` are just used as default values for missing `service labels` but no frontend/backend are going to be defined only with these labels.
235-
Obviously, labels `traefik.frontend.rule` and `traefik.port` described above, will only be used to complete information set in `service labels` during the container frontends/bakends creation.
235+
Obviously, labels `traefik.frontend.rule` and `traefik.port` described above, will only be used to complete information set in `service labels` during the container frontends/backends creation.
236236

237237
In the example, two service names are defined : `basic` and `admin`.
238238
They allow creating two frontends and two backends.

metrics/prometheus.go

+43-16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"sync"
88

99
"github.com/containous/mux"
10+
"github.com/containous/traefik/log"
1011
"github.com/containous/traefik/safe"
1112
"github.com/containous/traefik/types"
1213
"github.com/go-kit/kit/metrics"
@@ -15,25 +16,31 @@ import (
1516
)
1617

1718
const (
18-
metricNamePrefix = "traefik_"
19+
// MetricNamePrefix prefix of all metric names
20+
MetricNamePrefix = "traefik_"
1921

2022
// server meta information
21-
configReloadsTotalName = metricNamePrefix + "config_reloads_total"
22-
configReloadsFailuresTotalName = metricNamePrefix + "config_reloads_failure_total"
23-
configLastReloadSuccessName = metricNamePrefix + "config_last_reload_success"
24-
configLastReloadFailureName = metricNamePrefix + "config_last_reload_failure"
23+
metricConfigPrefix = MetricNamePrefix + "config_"
24+
configReloadsTotalName = metricConfigPrefix + "reloads_total"
25+
configReloadsFailuresTotalName = metricConfigPrefix + "reloads_failure_total"
26+
configLastReloadSuccessName = metricConfigPrefix + "last_reload_success"
27+
configLastReloadFailureName = metricConfigPrefix + "last_reload_failure"
2528

2629
// entrypoint
27-
entrypointReqsTotalName = metricNamePrefix + "entrypoint_requests_total"
28-
entrypointReqDurationName = metricNamePrefix + "entrypoint_request_duration_seconds"
29-
entrypointOpenConnsName = metricNamePrefix + "entrypoint_open_connections"
30-
31-
// backend level
32-
backendReqsTotalName = metricNamePrefix + "backend_requests_total"
33-
backendReqDurationName = metricNamePrefix + "backend_request_duration_seconds"
34-
backendOpenConnsName = metricNamePrefix + "backend_open_connections"
35-
backendRetriesTotalName = metricNamePrefix + "backend_retries_total"
36-
backendServerUpName = metricNamePrefix + "backend_server_up"
30+
metricEntryPointPrefix = MetricNamePrefix + "entrypoint_"
31+
entrypointReqsTotalName = metricEntryPointPrefix + "requests_total"
32+
entrypointReqDurationName = metricEntryPointPrefix + "request_duration_seconds"
33+
entrypointOpenConnsName = metricEntryPointPrefix + "open_connections"
34+
35+
// backend level.
36+
37+
// MetricBackendPrefix prefix of all backend metric names
38+
MetricBackendPrefix = MetricNamePrefix + "backend_"
39+
backendReqsTotalName = MetricBackendPrefix + "requests_total"
40+
backendReqDurationName = MetricBackendPrefix + "request_duration_seconds"
41+
backendOpenConnsName = MetricBackendPrefix + "open_connections"
42+
backendRetriesTotalName = MetricBackendPrefix + "retries_total"
43+
backendServerUpName = MetricBackendPrefix + "server_up"
3744
)
3845

3946
// promState holds all metric state internally and acts as the only Collector we register for Prometheus.
@@ -61,6 +68,16 @@ func (h PrometheusHandler) AddRoutes(router *mux.Router) {
6168
// RegisterPrometheus registers all Prometheus metrics.
6269
// It must be called only once and failing to register the metrics will lead to a panic.
6370
func RegisterPrometheus(config *types.Prometheus) Registry {
71+
standardRegistry := initStandardRegistry(config)
72+
73+
if !registerPromState() {
74+
return nil
75+
}
76+
77+
return standardRegistry
78+
}
79+
80+
func initStandardRegistry(config *types.Prometheus) Registry {
6481
buckets := []float64{0.1, 0.3, 1.2, 5.0}
6582
if config.Buckets != nil {
6683
buckets = config.Buckets
@@ -137,7 +154,6 @@ func RegisterPrometheus(config *types.Prometheus) Registry {
137154
backendRetries.cv.Describe,
138155
backendServerUp.gv.Describe,
139156
}
140-
stdprometheus.MustRegister(promState)
141157

142158
return &standardRegistry{
143159
enabled: true,
@@ -156,6 +172,17 @@ func RegisterPrometheus(config *types.Prometheus) Registry {
156172
}
157173
}
158174

175+
func registerPromState() bool {
176+
if err := stdprometheus.Register(promState); err != nil {
177+
if _, ok := err.(stdprometheus.AlreadyRegisteredError); !ok {
178+
log.Errorf("Unable to register Traefik to Prometheus: %v", err)
179+
return false
180+
}
181+
log.Debug("Prometheus collector already registered.")
182+
}
183+
return true
184+
}
185+
159186
// OnConfigurationUpdate receives the current configuration from Traefik.
160187
// It then converts the configuration to the optimized package internal format
161188
// and sets it to the promState.

metrics/prometheus_test.go

+74
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,82 @@ import (
1111
"github.com/containous/traefik/types"
1212
"github.com/prometheus/client_golang/prometheus"
1313
dto "github.com/prometheus/client_model/go"
14+
"github.com/stretchr/testify/assert"
1415
)
1516

17+
func TestRegisterPromState(t *testing.T) {
18+
// Reset state of global promState.
19+
defer promState.reset()
20+
21+
testCases := []struct {
22+
desc string
23+
prometheusSlice []*types.Prometheus
24+
initPromState bool
25+
unregisterPromState bool
26+
expectedNbRegistries int
27+
}{
28+
{
29+
desc: "Register once",
30+
prometheusSlice: []*types.Prometheus{{}},
31+
expectedNbRegistries: 1,
32+
initPromState: true,
33+
},
34+
{
35+
desc: "Register once with no promState init",
36+
prometheusSlice: []*types.Prometheus{{}},
37+
expectedNbRegistries: 0,
38+
},
39+
{
40+
desc: "Register twice",
41+
prometheusSlice: []*types.Prometheus{{}, {}},
42+
expectedNbRegistries: 2,
43+
initPromState: true,
44+
},
45+
{
46+
desc: "Register twice with no promstate init",
47+
prometheusSlice: []*types.Prometheus{{}, {}},
48+
expectedNbRegistries: 0,
49+
},
50+
{
51+
desc: "Register twice with unregister",
52+
prometheusSlice: []*types.Prometheus{{}, {}},
53+
unregisterPromState: true,
54+
expectedNbRegistries: 2,
55+
initPromState: true,
56+
},
57+
{
58+
desc: "Register twice with unregister but no promstate init",
59+
prometheusSlice: []*types.Prometheus{{}, {}},
60+
unregisterPromState: true,
61+
expectedNbRegistries: 0,
62+
},
63+
}
64+
65+
for _, test := range testCases {
66+
actualNbRegistries := 0
67+
for _, prom := range test.prometheusSlice {
68+
if test.initPromState {
69+
initStandardRegistry(prom)
70+
}
71+
72+
promReg := registerPromState()
73+
if promReg != false {
74+
actualNbRegistries++
75+
}
76+
77+
if test.unregisterPromState {
78+
prometheus.Unregister(promState)
79+
}
80+
81+
promState.reset()
82+
}
83+
84+
prometheus.Unregister(promState)
85+
86+
assert.Equal(t, test.expectedNbRegistries, actualNbRegistries)
87+
}
88+
}
89+
1690
// reset is a utility method for unit testing. It should be called after each
1791
// test run that changes promState internally in order to avoid dependencies
1892
// between unit tests.

requirements.txt

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
mkdocs>=0.17.3
2-
pymdown-extensions>=1.4
3-
mkdocs-bootswatch>=0.4.0
4-
mkdocs-material>=2.2.6
1+
mkdocs==0.17.5
2+
pymdown-extensions==4.12
3+
mkdocs-bootswatch==0.5.0
4+
mkdocs-material==2.9.4

server/server.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -633,8 +633,11 @@ func registerMetricClients(metricsConfig *types.Metrics) metrics.Registry {
633633

634634
var registries []metrics.Registry
635635
if metricsConfig.Prometheus != nil {
636-
registries = append(registries, metrics.RegisterPrometheus(metricsConfig.Prometheus))
637-
log.Debug("Configured Prometheus metrics")
636+
prometheusRegister := metrics.RegisterPrometheus(metricsConfig.Prometheus)
637+
if prometheusRegister != nil {
638+
registries = append(registries, prometheusRegister)
639+
log.Debug("Configured Prometheus metrics")
640+
}
638641
}
639642
if metricsConfig.Datadog != nil {
640643
registries = append(registries, metrics.RegisterDatadog(metricsConfig.Datadog))

0 commit comments

Comments
 (0)