watchdog: make metrics rate limit configurable; document env vars

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I01033406c32bd4e31a76e676be97af046a6a6964
This commit is contained in:
raf 2026-03-10 10:00:01 +03:00
commit 9c8f91ef27
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
2 changed files with 21 additions and 9 deletions

View file

@ -90,9 +90,15 @@ func Run(cfg *config.Config) error {
) )
} }
// Add rate limiting to metrics endpoint (30 requests per minute) // Add rate limiting to metrics endpoint
metricsRateLimiter := ratelimit.NewTokenBucket(30, 30, time.Minute) if cfg.Limits.MaxMetricsPerMinute > 0 {
metricsHandler = rateLimitMiddleware(metricsHandler, metricsRateLimiter) metricsRateLimiter := ratelimit.NewTokenBucket(
cfg.Limits.MaxMetricsPerMinute,
cfg.Limits.MaxMetricsPerMinute,
time.Minute,
)
metricsHandler = rateLimitMiddleware(metricsHandler, metricsRateLimiter)
}
mux.Handle(cfg.Server.MetricsPath, metricsHandler) mux.Handle(cfg.Server.MetricsPath, metricsHandler)

View file

@ -45,11 +45,12 @@ type PathConfig struct {
// Cardinality limits // Cardinality limits
type LimitsConfig struct { type LimitsConfig struct {
MaxPaths int `yaml:"max_paths"` MaxPaths int `yaml:"max_paths"`
MaxEventsPerMinute int `yaml:"max_events_per_minute"` MaxEventsPerMinute int `yaml:"max_events_per_minute"`
MaxSources int `yaml:"max_sources"` MaxSources int `yaml:"max_sources"`
MaxCustomEvents int `yaml:"max_custom_events"` MaxCustomEvents int `yaml:"max_custom_events"`
DeviceBreakpoints DeviceBreaks `yaml:"device_breakpoints"` DeviceBreakpoints DeviceBreaks `yaml:"device_breakpoints"`
MaxMetricsPerMinute int `yaml:"max_metrics_per_minute"` // rate limit for metrics endpoint
} }
// Device classification breakpoints // Device classification breakpoints
@ -72,10 +73,11 @@ type CORSConfig struct {
} }
// Authentication for metrics endpoint // Authentication for metrics endpoint
// Password can be set via environment variable: WATCHDOG_SECURITY_METRICS_AUTH_PASSWORD
type AuthConfig struct { type AuthConfig struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
Username string `yaml:"username"` Username string `yaml:"username"`
Password string `yaml:"password"` Password string `yaml:"password"` // can use env var WATCHDOG_SECURITY_METRICS_AUTH_PASSWORD
} }
// Server endpoints // Server endpoints
@ -149,6 +151,10 @@ func (c *Config) Validate() error {
c.Limits.MaxCustomEvents = 100 // Default c.Limits.MaxCustomEvents = 100 // Default
} }
if c.Limits.MaxMetricsPerMinute <= 0 {
c.Limits.MaxMetricsPerMinute = 30 // Default: 30 requests per minute
}
if c.Site.Path.MaxSegments < 0 { if c.Site.Path.MaxSegments < 0 {
return fmt.Errorf("site.path.max_segments cannot be negative") return fmt.Errorf("site.path.max_segments cannot be negative")
} }