mirror of
https://github.com/tailscale/tailscale.git
synced 2025-07-15 18:18:49 +00:00
metrics: use constants for metric types
NewMultiLabelMap does not return an error so it's easy for someone to pass an incorrect/unsupported metric type and serve invalid metrics to Prometheus. This would read as `metrics.Counter` and `metrics.Gauge` when used, which seems readable enough; but if you think bare strings are better, an alternative to this approach might be to verify string value in `NewMultiLabelMap` and panic? Updates tailscale/corp#22075 Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This commit is contained in:
parent
10662c4282
commit
b615a1d4db
@ -13,6 +13,13 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MetricType is a Prometheus metric type. At the moment we only support
|
||||||
|
// counter and gauge.
|
||||||
|
type MetricType string
|
||||||
|
|
||||||
|
const Counter MetricType = "counter"
|
||||||
|
const Gauge MetricType = "gauge"
|
||||||
|
|
||||||
// MultiLabelMap is a struct-value-to-Var map variable that satisfies the
|
// MultiLabelMap is a struct-value-to-Var map variable that satisfies the
|
||||||
// [expvar.Var] interface but also allows for multiple Prometheus labels to be
|
// [expvar.Var] interface but also allows for multiple Prometheus labels to be
|
||||||
// associated with each value.
|
// associated with each value.
|
||||||
@ -22,7 +29,7 @@ import (
|
|||||||
// The struct fields must all be strings, and the string values must be valid
|
// The struct fields must all be strings, and the string values must be valid
|
||||||
// Prometheus label values without requiring quoting.
|
// Prometheus label values without requiring quoting.
|
||||||
type MultiLabelMap[T comparable] struct {
|
type MultiLabelMap[T comparable] struct {
|
||||||
Type string // optional Prometheus type ("counter", "gauge")
|
Type MetricType
|
||||||
Help string // optional Prometheus help string
|
Help string // optional Prometheus help string
|
||||||
|
|
||||||
m sync.Map // map[T]expvar.Var
|
m sync.Map // map[T]expvar.Var
|
||||||
@ -33,7 +40,7 @@ type MultiLabelMap[T comparable] struct {
|
|||||||
|
|
||||||
// NewMultiLabelMap creates and publishes (via expvar.Publish) a new
|
// NewMultiLabelMap creates and publishes (via expvar.Publish) a new
|
||||||
// MultiLabelMap[T] variable with the given name and returns it.
|
// MultiLabelMap[T] variable with the given name and returns it.
|
||||||
func NewMultiLabelMap[T comparable](name string, promType, helpText string) *MultiLabelMap[T] {
|
func NewMultiLabelMap[T comparable](name string, promType MetricType, helpText string) *MultiLabelMap[T] {
|
||||||
m := &MultiLabelMap[T]{
|
m := &MultiLabelMap[T]{
|
||||||
Type: promType,
|
Type: promType,
|
||||||
Help: helpText,
|
Help: helpText,
|
||||||
@ -105,7 +112,7 @@ func (v *MultiLabelMap[T]) WritePrometheus(w io.Writer, name string) {
|
|||||||
io.WriteString(w, "# TYPE ")
|
io.WriteString(w, "# TYPE ")
|
||||||
io.WriteString(w, name)
|
io.WriteString(w, name)
|
||||||
io.WriteString(w, " ")
|
io.WriteString(w, " ")
|
||||||
io.WriteString(w, v.Type)
|
io.WriteString(w, string(v.Type))
|
||||||
io.WriteString(w, "\n")
|
io.WriteString(w, "\n")
|
||||||
}
|
}
|
||||||
if v.Help != "" {
|
if v.Help != "" {
|
||||||
|
@ -82,7 +82,7 @@ func TestMultiLabelMapTypes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m := new(MultiLabelMap[LabelTypes])
|
m := new(MultiLabelMap[LabelTypes])
|
||||||
m.Type = "counter"
|
m.Type = Counter
|
||||||
m.Help = "some good stuff"
|
m.Help = "some good stuff"
|
||||||
m.Add(LabelTypes{"a", true, -1, 2}, 3)
|
m.Add(LabelTypes{"a", true, -1, 2}, 3)
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
Loading…
x
Reference in New Issue
Block a user