metrics, tsweb/varz: add multi-label map metrics

Updates tailscale/corp#18640

Change-Id: Ia9ae25956038e9d3266ea165537ac6f02485b74c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2024-03-25 15:40:45 -07:00
committed by Brad Fitzpatrick
parent 90a4d6ce69
commit 55baf9474f
4 changed files with 408 additions and 0 deletions

View File

@@ -133,6 +133,9 @@ func writePromExpVar(w io.Writer, prefix string, kv expvar.KeyValue) {
writePromExpVar(w, name+"_", kv)
})
return
case PrometheusWriter:
v.WritePrometheus(w, name)
return
case PrometheusMetricsReflectRooter:
root := v.PrometheusMetricsReflectRoot()
rv := reflect.ValueOf(root)
@@ -233,6 +236,14 @@ func writePromExpVar(w io.Writer, prefix string, kv expvar.KeyValue) {
}
}
// PrometheusWriter is the interface implemented by metrics that can write
// themselves into Prometheus exposition format.
//
// As of 2024-03-25, this is only *metrics.MultiLabelMap.
type PrometheusWriter interface {
WritePrometheus(w io.Writer, name string)
}
var sortedKVsPool = &sync.Pool{New: func() any { return new(sortedKVs) }}
// sortedKV is a KeyValue with a sort key.

View File

@@ -25,6 +25,11 @@ func TestVarzHandler(t *testing.T) {
half := new(expvar.Float)
half.Set(0.5)
type L2 struct {
Foo string `prom:"foo"`
Bar string `prom:"bar"`
}
tests := []struct {
name string
k string // key name
@@ -193,6 +198,18 @@ func TestVarzHandler(t *testing.T) {
})(),
"foo{label=\"a\"} 1\n",
},
{
"metrics_multilabel_map",
"foo",
(func() *metrics.MultiLabelMap[L2] {
m := new(metrics.MultiLabelMap[L2])
m.Add(L2{"a", "b"}, 1)
m.Add(L2{"c", "d"}, 2)
return m
})(),
"foo{foo=\"a\",bar=\"b\"} 1\n" +
"foo{foo=\"c\",bar=\"d\"} 2\n",
},
{
"expvar_label_map",
"counter_labelmap_keyname_m",