From 04f0010fce1c47ffb5e064b5f9681fba13253711 Mon Sep 17 00:00:00 2001 From: Sebastian Peters <64439522+Nebu2k@users.noreply.github.com> Date: Thu, 6 Aug 2026 23:11:45 +0200 Subject: [PATCH] feat(inputunifi): add save_speedtest toggle for the WAN speed test poll The Site Speed Test poll against the controller's aggregated-dashboard endpoint has always run unconditionally, so operators whose controllers misbehave on that endpoint have no way to skip the request. Every other optional collection already has a save_* flag; this adds the missing one. Defaults to true in all three default paths (local defaults, per-controller defaults and remote discovery) so existing setups keep behaving exactly as before. Refs #1030 Co-Authored-By: Claude Opus 5 --- examples/remote_api_example.conf | 1 + examples/remote_api_example.json | 1 + examples/remote_api_example.yaml | 1 + examples/up.conf.example | 6 ++++++ pkg/inputunifi/collector.go | 12 +++++++----- pkg/inputunifi/input.go | 11 +++++++++++ pkg/inputunifi/interface.go | 1 + pkg/inputunifi/remote.go | 4 ++++ pkg/inputunifi/updateweb.go | 1 + 9 files changed, 33 insertions(+), 5 deletions(-) diff --git a/examples/remote_api_example.conf b/examples/remote_api_example.conf index 149bb204..68c37913 100644 --- a/examples/remote_api_example.conf +++ b/examples/remote_api_example.conf @@ -25,6 +25,7 @@ save_anomalies = true save_ids = true save_traffic = true save_rogue = true +save_speedtest = true save_syslog = true save_protect_logs = false verify_ssl = true diff --git a/examples/remote_api_example.json b/examples/remote_api_example.json index 716cc454..d4faf8dc 100644 --- a/examples/remote_api_example.json +++ b/examples/remote_api_example.json @@ -15,6 +15,7 @@ "save_ids": true, "save_traffic": true, "save_rogue": true, + "save_speedtest": true, "save_syslog": true, "save_protect_logs": false, "verify_ssl": true diff --git a/examples/remote_api_example.yaml b/examples/remote_api_example.yaml index 3f8982ac..4fc00c56 100644 --- a/examples/remote_api_example.yaml +++ b/examples/remote_api_example.yaml @@ -28,6 +28,7 @@ unifi: save_ids: true save_traffic: true save_rogue: true + save_speedtest: true save_syslog: true save_protect_logs: false # Remote API requires SSL verification diff --git a/examples/up.conf.example b/examples/up.conf.example index 3991a4ca..10f7fad5 100644 --- a/examples/up.conf.example +++ b/examples/up.conf.example @@ -226,6 +226,11 @@ ## This saves neighboring access point metrics in a dedicated table or namespace. save_rogue = false + ## WAN speed test results, polled from the controller's aggregated-dashboard + ## endpoint. Enabled by default. Set to false to skip that request entirely if + ## your controller misbehaves on it or you simply don't want the metrics. + save_speedtest = true + # If your UniFi controller has a valid SSL certificate (like lets encrypt), # you can enable this option to validate it. Otherwise, any SSL certificate is # valid. If you don't know if you have a valid SSL cert, then you don't have one. @@ -259,5 +264,6 @@ # save_dpi = false # save_traffic = false # save_rogue = false +# save_speedtest = true # verify_ssl = false # ssl_cert_paths = [] diff --git a/pkg/inputunifi/collector.go b/pkg/inputunifi/collector.go index 6b1343f9..6b790820 100644 --- a/pkg/inputunifi/collector.go +++ b/pkg/inputunifi/collector.go @@ -190,11 +190,13 @@ func (u *InputUnifi) pollController(c *Controller) (*poller.Metrics, error) { len(m.Devices.USWs), len(m.Devices.UDMs)) // Get speed test results for all WANs - if m.SpeedTests, err = c.Unifi.GetSpeedTests(sites, historySeconds); err != nil { - // Don't fail collection if speed tests fail - older controllers may not have this endpoint - u.LogDebugf("unifi.GetSpeedTests(%s): %v (continuing)", c.URL, err) - } else { - u.LogDebugf("Found %d SpeedTests entries", len(m.SpeedTests)) + if c.SaveSpeedTest != nil && *c.SaveSpeedTest { + if m.SpeedTests, err = c.Unifi.GetSpeedTests(sites, historySeconds); err != nil { + // Don't fail collection if speed tests fail - older controllers may not have this endpoint + u.LogDebugf("unifi.GetSpeedTests(%s): %v (continuing)", c.URL, err) + } else { + u.LogDebugf("Found %d SpeedTests entries", len(m.SpeedTests)) + } } // Get DHCP leases with associations. diff --git a/pkg/inputunifi/input.go b/pkg/inputunifi/input.go index ff1d0719..6d1bc139 100644 --- a/pkg/inputunifi/input.go +++ b/pkg/inputunifi/input.go @@ -48,6 +48,7 @@ type Controller struct { SaveDPI *bool `json:"save_dpi" toml:"save_dpi" xml:"save_dpi" yaml:"save_dpi"` SaveTraffic *bool `json:"save_traffic" toml:"save_traffic" xml:"save_traffic" yaml:"save_traffic"` SaveRogue *bool `json:"save_rogue" toml:"save_rogue" xml:"save_rogue" yaml:"save_rogue"` + SaveSpeedTest *bool `json:"save_speedtest" toml:"save_speedtest" xml:"save_speedtest" yaml:"save_speedtest"` HashPII *bool `json:"hash_pii" toml:"hash_pii" xml:"hash_pii" yaml:"hash_pii"` DropPII *bool `json:"drop_pii" toml:"drop_pii" xml:"drop_pii" yaml:"drop_pii"` SaveSites *bool `json:"save_sites" toml:"save_sites" xml:"save_sites" yaml:"save_sites"` @@ -315,6 +316,12 @@ func (u *InputUnifi) setDefaults(c *Controller) { //nolint:cyclop c.SaveRogue = &f } + // Defaults to true: the speed test poll has always run unconditionally, + // so an explicit opt-out keeps existing setups behaving the same. + if c.SaveSpeedTest == nil { + c.SaveSpeedTest = &t + } + if c.SaveIDs == nil { c.SaveIDs = &f } @@ -433,6 +440,10 @@ func (u *InputUnifi) setControllerDefaults(c *Controller) *Controller { //nolint c.SaveRogue = u.Default.SaveRogue } + if c.SaveSpeedTest == nil { + c.SaveSpeedTest = u.Default.SaveSpeedTest + } + if c.SaveEvents == nil { c.SaveEvents = u.Default.SaveEvents } diff --git a/pkg/inputunifi/interface.go b/pkg/inputunifi/interface.go index 9fbfb03b..4d2b00f8 100644 --- a/pkg/inputunifi/interface.go +++ b/pkg/inputunifi/interface.go @@ -190,6 +190,7 @@ func (u *InputUnifi) logController(c *Controller) { u.Logf(" => Save Alarms %v / Anomalies %v / Protect Logs %v (thumbnails: %v)", *c.SaveAlarms, *c.SaveAnomal, *c.SaveProtectLogs, *c.ProtectThumbnails) u.Logf(" => Save Rogue APs: %v", *c.SaveRogue) u.Logf(" => Save Traffic %v", *c.SaveTraffic) + u.Logf(" => Save Speed Tests: %v", *c.SaveSpeedTest) } // Events allows you to pull only events (and IDs) from the UniFi Controller. diff --git a/pkg/inputunifi/remote.go b/pkg/inputunifi/remote.go index 998d2362..dd8bce87 100644 --- a/pkg/inputunifi/remote.go +++ b/pkg/inputunifi/remote.go @@ -155,6 +155,10 @@ func (u *InputUnifi) discoverRemoteControllers(apiKey string) ([]*Controller, er controller.SaveRogue = &f } + if controller.SaveSpeedTest == nil { + controller.SaveSpeedTest = &t + } + if controller.SaveSyslog == nil { controller.SaveSyslog = &f } diff --git a/pkg/inputunifi/updateweb.go b/pkg/inputunifi/updateweb.go index 6f773845..247776fa 100644 --- a/pkg/inputunifi/updateweb.go +++ b/pkg/inputunifi/updateweb.go @@ -74,6 +74,7 @@ func formatControllers(controllers []*Controller) []*Controller { SaveAnomal: c.SaveAnomal, SaveAlarms: c.SaveAlarms, SaveRogue: c.SaveRogue, + SaveSpeedTest: c.SaveSpeedTest, SaveEvents: c.SaveEvents, SaveSyslog: c.SaveSyslog, SaveProtectLogs: c.SaveProtectLogs,