tsweb: cache prometheus metric names & types

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
pull/6069/head
Anton Tolchanov 2022-11-17 11:33:19 -08:00 committed by Anton Tolchanov
parent 3c27632ffe
commit f40bb199f5
2 changed files with 34 additions and 11 deletions

View File

@ -455,18 +455,30 @@ func WritePrometheusExpvar(w io.Writer, kv expvar.KeyValue) {
writePromExpVar(w, "", kv) writePromExpVar(w, "", kv)
} }
func writePromExpVar(w io.Writer, prefix string, kv expvar.KeyValue) { type prometheusMetricDetails struct {
key := kv.Key Name string
Type string
Label string
}
var prometheusMetricCache sync.Map // string => *prometheusMetricDetails
func prometheusMetric(prefix string, key string) (string, string, string) {
cachekey := prefix + key
if v, ok := prometheusMetricCache.Load(cachekey); ok {
d := v.(*prometheusMetricDetails)
return d.Name, d.Type, d.Label
}
var typ string var typ string
var label string var label string
switch { switch {
case strings.HasPrefix(kv.Key, gaugePrefix): case strings.HasPrefix(key, gaugePrefix):
typ = "gauge" typ = "gauge"
key = strings.TrimPrefix(kv.Key, gaugePrefix) key = strings.TrimPrefix(key, gaugePrefix)
case strings.HasPrefix(kv.Key, counterPrefix): case strings.HasPrefix(key, counterPrefix):
typ = "counter" typ = "counter"
key = strings.TrimPrefix(kv.Key, counterPrefix) key = strings.TrimPrefix(key, counterPrefix)
} }
if strings.HasPrefix(key, labelMapPrefix) { if strings.HasPrefix(key, labelMapPrefix) {
key = strings.TrimPrefix(key, labelMapPrefix) key = strings.TrimPrefix(key, labelMapPrefix)
@ -474,7 +486,18 @@ func writePromExpVar(w io.Writer, prefix string, kv expvar.KeyValue) {
label, key = a, b label, key = a, b
} }
} }
name := strings.ReplaceAll(prefix+key, "-", "_") d := &prometheusMetricDetails{
Name: strings.ReplaceAll(prefix+key, "-", "_"),
Type: typ,
Label: label,
}
prometheusMetricCache.Store(cachekey, d)
return d.Name, d.Type, d.Label
}
func writePromExpVar(w io.Writer, prefix string, kv expvar.KeyValue) {
key := kv.Key
name, typ, label := prometheusMetric(prefix, key)
switch v := kv.Value.(type) { switch v := kv.Value.(type) {
case PrometheusVar: case PrometheusVar:

View File

@ -450,15 +450,15 @@ func TestVarzHandler(t *testing.T) {
}, },
{ {
"func_float64_gauge", "func_float64_gauge",
"gauge_x", "gauge_y",
expvar.Func(func() any { return float64(1.2) }), expvar.Func(func() any { return float64(1.2) }),
"# TYPE x gauge\nx 1.2\n", "# TYPE y gauge\ny 1.2\n",
}, },
{ {
"func_float64_untyped", "func_float64_untyped",
"x", "z",
expvar.Func(func() any { return float64(1.2) }), expvar.Func(func() any { return float64(1.2) }),
"x 1.2\n", "z 1.2\n",
}, },
{ {
"metrics_label_map", "metrics_label_map",