Fix data-race in metric without code and method but with `WithLabelFromCtx` (#1318)
This commit fixes a data race that exists when the metric used in any `promhttp` middleware doesn't collect the `code` and `method` but uses `WithLabelFromCtx` to collect values from context. The problem happens because when no `code` and `method` tags are collected, the `labels` function returns a pre-initialized map `emptyLabels` for every request. When one or multipe `WithLabelFromCtx` options are configured, the returned map from the `labels` function call is used to collect the metrics from context which creates a multi-write data race. Signed-off-by: Tiago Silva <tiago.silva@goteleport.com>
This commit is contained in:
parent
7f2db5f1ed
commit
59c00e3e9c
|
@ -389,16 +389,13 @@ func isLabelCurried(c prometheus.Collector, label string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// emptyLabels is a one-time allocation for non-partitioned metrics to avoid
|
||||
// unnecessary allocations on each request.
|
||||
var emptyLabels = prometheus.Labels{}
|
||||
|
||||
func labels(code, method bool, reqMethod string, status int, extraMethods ...string) prometheus.Labels {
|
||||
if !(code || method) {
|
||||
return emptyLabels
|
||||
}
|
||||
labels := prometheus.Labels{}
|
||||
|
||||
if !(code || method) {
|
||||
return labels
|
||||
}
|
||||
|
||||
if code {
|
||||
labels["code"] = sanitizeCode(status)
|
||||
}
|
||||
|
|
|
@ -250,7 +250,7 @@ func TestLabels(t *testing.T) {
|
|||
}{
|
||||
"empty": {
|
||||
varLabels: []string{},
|
||||
wantLabels: emptyLabels,
|
||||
wantLabels: prometheus.Labels{},
|
||||
reqMethod: "GET",
|
||||
respStatus: 200,
|
||||
ok: true,
|
||||
|
|
Loading…
Reference in New Issue