summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJordan Whited <jordan@tailscale.com>2026-04-13 12:35:54 -0700
committerJordan Whited <jwhited0917@gmail.com>2026-04-16 12:48:41 -0700
commit69572c74357f0abf53187d5b6303e576c7d33255 (patch)
tree9cbf6c091c1064519562ed073f393b03c75d2663
parent1dc08f4d41000f9ea08eb754aa35d91bbad62802 (diff)
downloadtailscale-69572c74357f0abf53187d5b6303e576c7d33255.tar.xz
tailscale-69572c74357f0abf53187d5b6303e576c7d33255.zip
derp/derpserver: add rate limit config metrics
Updates tailscale/corp#40421 Signed-off-by: Jordan Whited <jordan@tailscale.com>
-rw-r--r--derp/derpserver/derpserver.go26
1 files changed, 26 insertions, 0 deletions
diff --git a/derp/derpserver/derpserver.go b/derp/derpserver/derpserver.go
index 40d8d3c51..4e27de84a 100644
--- a/derp/derpserver/derpserver.go
+++ b/derp/derpserver/derpserver.go
@@ -566,11 +566,37 @@ func (s *Server) LoadAndApplyRateConfig(path string) error {
return nil
}
+var publishRateLimitsMetricsOnce sync.Once
+
+func (s *Server) publishRateLimitsMetrics() {
+ // Rate limiting is currently experimental, its APIs are unstable, and it must
+ // be opted-in via --rate-config. Therefore, we only publish related metrics
+ // on demand, to avoid polluting uninterested metrics consumers.
+ //
+ // Note: The [sync.Once] is package-level, and the [expvar.Var] closures
+ // capture [Server], so first [Server] owns these for process lifetime.
+ publishRateLimitsMetricsOnce.Do(func() {
+ expvar.Publish("derp_per_client_rate_limit_bytes_per_second", s.expVarFunc(func() any {
+ return s.rateConfig.PerClientRateLimitBytesPerSec
+ }))
+ expvar.Publish("derp_per_client_rate_burst_bytes", s.expVarFunc(func() any {
+ return s.rateConfig.PerClientRateBurstBytes
+ }))
+ expvar.Publish("derp_global_rate_limit_bytes_per_second", s.expVarFunc(func() any {
+ return s.rateConfig.GlobalRateLimitBytesPerSec
+ }))
+ expvar.Publish("derp_global_rate_burst_bytes", s.expVarFunc(func() any {
+ return s.rateConfig.GlobalRateBurstBytes
+ }))
+ })
+}
+
// UpdateRateLimits sets the receive rate limits, updating all existing client
// connections. It returns the applied config, which may differ from rc. If the
// per-client rate limit is 0, rate limiting is disabled. Mesh peers are always
// exempt from rate limiting.
func (s *Server) UpdateRateLimits(rc RateConfig) (applied RateConfig) {
+ s.publishRateLimitsMetrics()
s.mu.Lock()
defer s.mu.Unlock()
if rc.PerClientRateLimitBytesPerSec == 0 {