mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-16 19:49:56 +00:00
* [management, client] Add management-controlled client metrics push Allow enabling/disabling client metrics push from the dashboard via account settings instead of requiring env vars on every client. - Add MetricsConfig proto message to NetbirdConfig - Add MetricsPushEnabled to account Settings (DB-persisted) - Expose metrics_push_enabled in OpenAPI and dashboard API handler - Populate MetricsConfig in sync and login responses - Client dynamically starts/stops push based on management config - NB_METRICS_PUSH_ENABLED env var overrides management when explicitly set - Add activity events for metrics push enable/disable * Remove log line * [management] Fix peer update test for MetricsConfig in NetbirdConfig Update TestUpdateAccountPeers assertions: NetbirdConfig is no longer nil in peer update responses since it now carries MetricsConfig even when STUN/TURN config is absent. * Regenerate proto files with protoc v7.34.1 * [management] Read metrics push setting in Postgres account query getAccountPgx omitted settings_metrics_push_enabled from its hand-written SELECT and Scan, so the toggle was always read back as false on Postgres and never reached clients. * [client] Fix metrics push getting stuck off after engine restart Engine restarts (backoff retries within the same login session) cancel e.ctx, which the push goroutine's lifetime was tied to. The goroutine died silently but ClientMetrics.push stayed non-nil since only an explicit stop clears it, so the next UpdatePushFromMgm call saw a "push already running" state and never restarted it. Give the Engine its own metricsCtx sourced from ConnectClient.ctx, which outlives engine restarts, so handleMetricsUpdate stops tying the push to the wrong-scoped context. Additionally make ClientMetrics.push an atomic.Pointer that the push goroutine clears via CompareAndSwap on exit, so the tracked state can never drift from the goroutine's actual lifetime regardless of which context a future caller passes in. * [management] Regenerate OpenAPI types with oapi-codegen v2.7.1 types.gen.go was regenerated with a stale local v2.6.0 binary, causing the CI git-diff check against generate.sh's pinned v2.7.1 to fail.
101 lines
3.3 KiB
Go
101 lines
3.3 KiB
Go
package metrics
|
|
|
|
import (
|
|
"net/url"
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
const (
|
|
// EnvMetricsPushEnabled controls whether collected metrics are pushed to the backend.
|
|
// Metrics collection itself is always active (for debug bundles).
|
|
// Disabled by default. Set NB_METRICS_PUSH_ENABLED=true to enable push.
|
|
EnvMetricsPushEnabled = "NB_METRICS_PUSH_ENABLED"
|
|
|
|
// EnvMetricsForceSending if set to true, skips remote configuration fetch and forces metric sending
|
|
EnvMetricsForceSending = "NB_METRICS_FORCE_SENDING"
|
|
|
|
// EnvMetricsConfigURL is the environment variable to override the metrics push config ServerAddress
|
|
EnvMetricsConfigURL = "NB_METRICS_CONFIG_URL"
|
|
|
|
// EnvMetricsServerURL is the environment variable to override the metrics server address.
|
|
// When set, this takes precedence over the server_url from remote push config.
|
|
EnvMetricsServerURL = "NB_METRICS_SERVER_URL"
|
|
|
|
// EnvMetricsInterval overrides the push interval from the remote config.
|
|
// Only affects how often metrics are pushed; remote config availability
|
|
// and version range checks are still respected.
|
|
// Format: duration string like "1h", "30m", "4h"
|
|
EnvMetricsInterval = "NB_METRICS_INTERVAL"
|
|
|
|
defaultMetricsConfigURL = "https://ingest.netbird.io/config"
|
|
)
|
|
|
|
// IsMetricsPushEnabled returns true if metrics push is enabled via NB_METRICS_PUSH_ENABLED env var.
|
|
// Disabled by default. Metrics collection is always active for debug bundles.
|
|
func IsMetricsPushEnabled() bool {
|
|
enabled, _ := strconv.ParseBool(os.Getenv(EnvMetricsPushEnabled))
|
|
return enabled
|
|
}
|
|
|
|
// getMetricsInterval returns the metrics push interval from NB_METRICS_INTERVAL env var.
|
|
// Returns 0 if not set or invalid.
|
|
func getMetricsInterval() time.Duration {
|
|
intervalStr := os.Getenv(EnvMetricsInterval)
|
|
if intervalStr == "" {
|
|
return 0
|
|
}
|
|
interval, err := time.ParseDuration(intervalStr)
|
|
if err != nil {
|
|
log.Warnf("invalid metrics interval from env %q: %v", intervalStr, err)
|
|
return 0
|
|
}
|
|
if interval <= 0 {
|
|
log.Warnf("invalid metrics interval from env %q: must be positive", intervalStr)
|
|
return 0
|
|
}
|
|
return interval
|
|
}
|
|
|
|
// isMetricsPushEnvSet returns true if NB_METRICS_PUSH_ENABLED is explicitly set (to any value).
|
|
// When set, the env var takes full precedence over management server configuration.
|
|
func isMetricsPushEnvSet() bool {
|
|
_, set := os.LookupEnv(EnvMetricsPushEnabled)
|
|
return set
|
|
}
|
|
|
|
func isForceSending() bool {
|
|
force, _ := strconv.ParseBool(os.Getenv(EnvMetricsForceSending))
|
|
return force
|
|
}
|
|
|
|
// getMetricsConfigURL returns the URL to fetch push configuration from
|
|
func getMetricsConfigURL() string {
|
|
if envURL := os.Getenv(EnvMetricsConfigURL); envURL != "" {
|
|
return envURL
|
|
}
|
|
return defaultMetricsConfigURL
|
|
}
|
|
|
|
// getMetricsServerURL returns the metrics server URL from NB_METRICS_SERVER_URL env var.
|
|
// Returns nil if not set or invalid.
|
|
func getMetricsServerURL() *url.URL {
|
|
envURL := os.Getenv(EnvMetricsServerURL)
|
|
if envURL == "" {
|
|
return nil
|
|
}
|
|
parsed, err := url.ParseRequestURI(envURL)
|
|
if err != nil || parsed.Host == "" {
|
|
log.Warnf("invalid metrics server URL %q: must be an absolute HTTP(S) URL", envURL)
|
|
return nil
|
|
}
|
|
if parsed.Scheme != "http" && parsed.Scheme != "https" {
|
|
log.Warnf("invalid metrics server URL %q: unsupported scheme %q", envURL, parsed.Scheme)
|
|
return nil
|
|
}
|
|
return parsed
|
|
}
|