client/local: add method to set gauge metric to a value

The existing client metric methods only support incrementing (or
decrementing) a delta value.  This new method allows setting the metric
to a specific value.

Updates tailscale/corp#35327

Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
This commit is contained in:
Will Norris
2025-12-15 14:01:00 -08:00
committed by Will Norris
parent f174ecb6fd
commit 0fd1670a59
6 changed files with 52 additions and 25 deletions
+11 -10
View File
@@ -1283,13 +1283,8 @@ func (h *Handler) serveUploadClientMetrics(w http.ResponseWriter, r *http.Reques
http.Error(w, "unsupported method", http.StatusMethodNotAllowed)
return
}
type clientMetricJSON struct {
Name string `json:"name"`
Type string `json:"type"` // one of "counter" or "gauge"
Value int `json:"value"` // amount to increment metric by
}
var clientMetrics []clientMetricJSON
var clientMetrics []clientmetric.MetricUpdate
if err := json.NewDecoder(r.Body).Decode(&clientMetrics); err != nil {
http.Error(w, "invalid JSON body", http.StatusBadRequest)
return
@@ -1299,14 +1294,12 @@ func (h *Handler) serveUploadClientMetrics(w http.ResponseWriter, r *http.Reques
defer metricsMu.Unlock()
for _, m := range clientMetrics {
if metric, ok := metrics[m.Name]; ok {
metric.Add(int64(m.Value))
} else {
metric, ok := metrics[m.Name]
if !ok {
if clientmetric.HasPublished(m.Name) {
http.Error(w, "Already have a metric named "+m.Name, http.StatusBadRequest)
return
}
var metric *clientmetric.Metric
switch m.Type {
case "counter":
metric = clientmetric.NewCounter(m.Name)
@@ -1317,7 +1310,15 @@ func (h *Handler) serveUploadClientMetrics(w http.ResponseWriter, r *http.Reques
return
}
metrics[m.Name] = metric
}
switch m.Op {
case "add", "":
metric.Add(int64(m.Value))
case "set":
metric.Set(int64(m.Value))
default:
http.Error(w, "Unknown metric op "+m.Op, http.StatusBadRequest)
return
}
}