mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-09 16:11:23 +00:00
tsweb: expose native Prometheus metrics in /debug/varz
The handler will expose built-in process and Go metrics by default,
which currently duplicate some of the expvar-proxied metrics
(`goroutines` vs `go_goroutines`, `memstats` vs `go_memstats`), but as
long as their names are different, Prometheus server will just scrape
both.
This will change /debug/varz behaviour for most tsweb binaries, but
notably not for control, which configures a `tsweb.VarzHandler`
[explicitly](a5b5d5167f/cmd/tailcontrol/tailcontrol.go (L779)
)
Updates https://github.com/tailscale/corp/issues/10205
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This commit is contained in:

committed by
Anton Tolchanov

parent
690446c784
commit
11e6247d2a
@@ -26,6 +26,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/common/expfmt"
|
||||
"go4.org/mem"
|
||||
"tailscale.com/envknob"
|
||||
"tailscale.com/metrics"
|
||||
@@ -672,6 +674,39 @@ func VarzHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// CombinedVarzHandler is an HTTP handler for Prometheus metrics that
|
||||
// combines native metrics with the ones converted from expvar.
|
||||
func CombinedVarzHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err := gatherNativePrometheusMetrics(w); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
VarzHandler(w, r)
|
||||
}
|
||||
|
||||
// gatherNativePrometheusMetrics writes metrics from the default
|
||||
// metric registry in text format.
|
||||
func gatherNativePrometheusMetrics(w http.ResponseWriter) error {
|
||||
enc := expfmt.NewEncoder(w, expfmt.FmtText)
|
||||
mfs, err := prometheus.DefaultGatherer.Gather()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not gather metrics from DefaultGatherer: %w", err)
|
||||
}
|
||||
|
||||
for _, mf := range mfs {
|
||||
if err := enc.Encode(mf); err != nil {
|
||||
return fmt.Errorf("could not encode metric %v: %w", mf, err)
|
||||
}
|
||||
}
|
||||
if closer, ok := enc.(expfmt.Closer); ok {
|
||||
if err := closer.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PrometheusMetricsReflectRooter is an optional interface that expvar.Var implementations
|
||||
// can implement to indicate that they should be walked recursively with reflect to find
|
||||
// sets of fields to export.
|
||||
|
Reference in New Issue
Block a user