mirror of
https://github.com/unpoller/unpoller.git
synced 2026-03-31 06:24:19 -04:00
feat: Add WAN metrics to InfluxDB and Datadog exporters
Add comprehensive WAN metrics support to InfluxDB and Datadog exporters:
InfluxDB Metrics (measurement: wan):
- Configuration: failover_priority, load_balance_weight, provider_download_kbps,
provider_upload_kbps, smartq_enabled, magic_enabled, vlan_enabled
- Statistics: uptime_percentage, peak_download_percent, peak_upload_percent,
max_rx_bytes_rate, max_tx_bytes_rate
- Service Provider: service_provider_asn
- Metadata: creation_timestamp
Tags: wan_id, wan_name, wan_networkgroup, wan_type, wan_load_balance_type,
isp_name, isp_city
Datadog Metrics (namespace: unpoller.wan.*):
- Same metrics as InfluxDB with gauge type
- All metrics tagged with WAN and ISP information
Changes:
- pkg/influxunifi/wan.go: New WAN exporter for InfluxDB
- pkg/influxunifi/influxdb.go: Add WAN to loopPoints and switchExport
- pkg/datadogunifi/wan.go: New WAN exporter for Datadog
- pkg/datadogunifi/datadog.go: Add WAN to loopPoints and switchExport
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2
go.mod
2
go.mod
@@ -47,4 +47,4 @@ require (
|
|||||||
google.golang.org/protobuf v1.36.11 // indirect
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/unpoller/unifi/v5 => ../unifi
|
// replace github.com/unpoller/unifi/v5 => ../unifi
|
||||||
|
|||||||
@@ -317,6 +317,10 @@ func (u *DatadogUnifi) loopPoints(r report) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reportClientDPItotals(r, appTotal, catTotal)
|
reportClientDPItotals(r, appTotal, catTotal)
|
||||||
|
|
||||||
|
for _, w := range m.WANConfigs {
|
||||||
|
u.switchExport(r, w)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *DatadogUnifi) switchExport(r report, v any) { //nolint:cyclop
|
func (u *DatadogUnifi) switchExport(r report, v any) { //nolint:cyclop
|
||||||
@@ -353,6 +357,8 @@ func (u *DatadogUnifi) switchExport(r report, v any) { //nolint:cyclop
|
|||||||
u.batchAnomaly(r, v)
|
u.batchAnomaly(r, v)
|
||||||
case *unifi.SpeedTestResult:
|
case *unifi.SpeedTestResult:
|
||||||
u.batchSpeedTest(r, v)
|
u.batchSpeedTest(r, v)
|
||||||
|
case *unifi.WANEnrichedConfiguration:
|
||||||
|
u.batchWAN(r, v)
|
||||||
default:
|
default:
|
||||||
if u.Collector != nil && u.Collector.Poller().LogUnknownTypes {
|
if u.Collector != nil && u.Collector.Poller().LogUnknownTypes {
|
||||||
u.LogDebugf("unknown export type: %T", v)
|
u.LogDebugf("unknown export type: %T", v)
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ func (u *DatadogUnifi) batchUBB(r report, s *unifi.UBB) { // nolint: funlen
|
|||||||
data["p2p_tx_rate"] = s.P2PStats.TXRate.Val
|
data["p2p_tx_rate"] = s.P2PStats.TXRate.Val
|
||||||
data["p2p_throughput"] = s.P2PStats.Throughput.Val
|
data["p2p_throughput"] = s.P2PStats.Throughput.Val
|
||||||
}
|
}
|
||||||
|
|
||||||
data["link_quality"] = s.LinkQuality.Val
|
data["link_quality"] = s.LinkQuality.Val
|
||||||
data["link_quality_current"] = s.LinkQualityCurrent.Val
|
data["link_quality_current"] = s.LinkQualityCurrent.Val
|
||||||
data["link_capacity"] = s.LinkCapacity.Val
|
data["link_capacity"] = s.LinkCapacity.Val
|
||||||
@@ -97,52 +98,52 @@ func (u *DatadogUnifi) batchUBBstats(stat *unifi.UBBStat) map[string]float64 {
|
|||||||
|
|
||||||
// Total aggregated stats across both radios
|
// Total aggregated stats across both radios
|
||||||
return map[string]float64{
|
return map[string]float64{
|
||||||
"stat_bytes": bb.Bytes.Val,
|
"stat_bytes": bb.Bytes.Val,
|
||||||
"stat_duration": bb.Duration.Val,
|
"stat_duration": bb.Duration.Val,
|
||||||
"stat_rx_packets": bb.RxPackets.Val,
|
"stat_rx_packets": bb.RxPackets.Val,
|
||||||
"stat_rx_bytes": bb.RxBytes.Val,
|
"stat_rx_bytes": bb.RxBytes.Val,
|
||||||
"stat_rx_errors": bb.RxErrors.Val,
|
"stat_rx_errors": bb.RxErrors.Val,
|
||||||
"stat_rx_dropped": bb.RxDropped.Val,
|
"stat_rx_dropped": bb.RxDropped.Val,
|
||||||
"stat_rx_crypts": bb.RxCrypts.Val,
|
"stat_rx_crypts": bb.RxCrypts.Val,
|
||||||
"stat_rx_frags": bb.RxFrags.Val,
|
"stat_rx_frags": bb.RxFrags.Val,
|
||||||
"stat_tx_packets": bb.TxPackets.Val,
|
"stat_tx_packets": bb.TxPackets.Val,
|
||||||
"stat_tx_bytes": bb.TxBytes.Val,
|
"stat_tx_bytes": bb.TxBytes.Val,
|
||||||
"stat_tx_errors": bb.TxErrors.Val,
|
"stat_tx_errors": bb.TxErrors.Val,
|
||||||
"stat_tx_dropped": bb.TxDropped.Val,
|
"stat_tx_dropped": bb.TxDropped.Val,
|
||||||
"stat_tx_retries": bb.TxRetries.Val,
|
"stat_tx_retries": bb.TxRetries.Val,
|
||||||
"stat_mac_filter_rejections": bb.MacFilterRejections.Val,
|
"stat_mac_filter_rejections": bb.MacFilterRejections.Val,
|
||||||
"stat_wifi_tx_attempts": bb.WifiTxAttempts.Val,
|
"stat_wifi_tx_attempts": bb.WifiTxAttempts.Val,
|
||||||
"stat_wifi_tx_dropped": bb.WifiTxDropped.Val,
|
"stat_wifi_tx_dropped": bb.WifiTxDropped.Val,
|
||||||
// User aggregated stats
|
// User aggregated stats
|
||||||
"stat_user_rx_packets": bb.UserRxPackets.Val,
|
"stat_user_rx_packets": bb.UserRxPackets.Val,
|
||||||
"stat_user_rx_bytes": bb.UserRxBytes.Val,
|
"stat_user_rx_bytes": bb.UserRxBytes.Val,
|
||||||
"stat_user_rx_errors": bb.UserRxErrors.Val,
|
"stat_user_rx_errors": bb.UserRxErrors.Val,
|
||||||
"stat_user_rx_dropped": bb.UserRxDropped.Val,
|
"stat_user_rx_dropped": bb.UserRxDropped.Val,
|
||||||
"stat_user_rx_crypts": bb.UserRxCrypts.Val,
|
"stat_user_rx_crypts": bb.UserRxCrypts.Val,
|
||||||
"stat_user_rx_frags": bb.UserRxFrags.Val,
|
"stat_user_rx_frags": bb.UserRxFrags.Val,
|
||||||
"stat_user_tx_packets": bb.UserTxPackets.Val,
|
"stat_user_tx_packets": bb.UserTxPackets.Val,
|
||||||
"stat_user_tx_bytes": bb.UserTxBytes.Val,
|
"stat_user_tx_bytes": bb.UserTxBytes.Val,
|
||||||
"stat_user_tx_errors": bb.UserTxErrors.Val,
|
"stat_user_tx_errors": bb.UserTxErrors.Val,
|
||||||
"stat_user_tx_dropped": bb.UserTxDropped.Val,
|
"stat_user_tx_dropped": bb.UserTxDropped.Val,
|
||||||
"stat_user_tx_retries": bb.UserTxRetries.Val,
|
"stat_user_tx_retries": bb.UserTxRetries.Val,
|
||||||
"stat_user_mac_filter_rejections": bb.UserMacFilterRejections.Val,
|
"stat_user_mac_filter_rejections": bb.UserMacFilterRejections.Val,
|
||||||
"stat_user_wifi_tx_attempts": bb.UserWifiTxAttempts.Val,
|
"stat_user_wifi_tx_attempts": bb.UserWifiTxAttempts.Val,
|
||||||
"stat_user_wifi_tx_dropped": bb.UserWifiTxDropped.Val,
|
"stat_user_wifi_tx_dropped": bb.UserWifiTxDropped.Val,
|
||||||
// wifi0 radio stats (5GHz)
|
// wifi0 radio stats (5GHz)
|
||||||
"stat_wifi0_rx_packets": bb.Wifi0RxPackets.Val,
|
"stat_wifi0_rx_packets": bb.Wifi0RxPackets.Val,
|
||||||
"stat_wifi0_rx_bytes": bb.Wifi0RxBytes.Val,
|
"stat_wifi0_rx_bytes": bb.Wifi0RxBytes.Val,
|
||||||
"stat_wifi0_rx_errors": bb.Wifi0RxErrors.Val,
|
"stat_wifi0_rx_errors": bb.Wifi0RxErrors.Val,
|
||||||
"stat_wifi0_rx_dropped": bb.Wifi0RxDropped.Val,
|
"stat_wifi0_rx_dropped": bb.Wifi0RxDropped.Val,
|
||||||
"stat_wifi0_rx_crypts": bb.Wifi0RxCrypts.Val,
|
"stat_wifi0_rx_crypts": bb.Wifi0RxCrypts.Val,
|
||||||
"stat_wifi0_rx_frags": bb.Wifi0RxFrags.Val,
|
"stat_wifi0_rx_frags": bb.Wifi0RxFrags.Val,
|
||||||
"stat_wifi0_tx_packets": bb.Wifi0TxPackets.Val,
|
"stat_wifi0_tx_packets": bb.Wifi0TxPackets.Val,
|
||||||
"stat_wifi0_tx_bytes": bb.Wifi0TxBytes.Val,
|
"stat_wifi0_tx_bytes": bb.Wifi0TxBytes.Val,
|
||||||
"stat_wifi0_tx_errors": bb.Wifi0TxErrors.Val,
|
"stat_wifi0_tx_errors": bb.Wifi0TxErrors.Val,
|
||||||
"stat_wifi0_tx_dropped": bb.Wifi0TxDropped.Val,
|
"stat_wifi0_tx_dropped": bb.Wifi0TxDropped.Val,
|
||||||
"stat_wifi0_tx_retries": bb.Wifi0TxRetries.Val,
|
"stat_wifi0_tx_retries": bb.Wifi0TxRetries.Val,
|
||||||
"stat_wifi0_mac_filter_rejections": bb.Wifi0MacFilterRejections.Val,
|
"stat_wifi0_mac_filter_rejections": bb.Wifi0MacFilterRejections.Val,
|
||||||
"stat_wifi0_wifi_tx_attempts": bb.Wifi0WifiTxAttempts.Val,
|
"stat_wifi0_wifi_tx_attempts": bb.Wifi0WifiTxAttempts.Val,
|
||||||
"stat_wifi0_wifi_tx_dropped": bb.Wifi0WifiTxDropped.Val,
|
"stat_wifi0_wifi_tx_dropped": bb.Wifi0WifiTxDropped.Val,
|
||||||
// terra2 radio stats (60GHz - 802.11ad)
|
// terra2 radio stats (60GHz - 802.11ad)
|
||||||
"stat_terra2_rx_packets": bb.Terra2RxPackets.Val,
|
"stat_terra2_rx_packets": bb.Terra2RxPackets.Val,
|
||||||
"stat_terra2_rx_bytes": bb.Terra2RxBytes.Val,
|
"stat_terra2_rx_bytes": bb.Terra2RxBytes.Val,
|
||||||
@@ -159,20 +160,20 @@ func (u *DatadogUnifi) batchUBBstats(stat *unifi.UBBStat) map[string]float64 {
|
|||||||
"stat_terra2_wifi_tx_attempts": bb.Terra2WifiTxAttempts.Val,
|
"stat_terra2_wifi_tx_attempts": bb.Terra2WifiTxAttempts.Val,
|
||||||
"stat_terra2_wifi_tx_dropped": bb.Terra2WifiTxDropped.Val,
|
"stat_terra2_wifi_tx_dropped": bb.Terra2WifiTxDropped.Val,
|
||||||
// User wifi0 stats
|
// User wifi0 stats
|
||||||
"stat_user_wifi0_rx_packets": bb.UserWifi0RxPackets.Val,
|
"stat_user_wifi0_rx_packets": bb.UserWifi0RxPackets.Val,
|
||||||
"stat_user_wifi0_rx_bytes": bb.UserWifi0RxBytes.Val,
|
"stat_user_wifi0_rx_bytes": bb.UserWifi0RxBytes.Val,
|
||||||
"stat_user_wifi0_rx_errors": bb.UserWifi0RxErrors.Val,
|
"stat_user_wifi0_rx_errors": bb.UserWifi0RxErrors.Val,
|
||||||
"stat_user_wifi0_rx_dropped": bb.UserWifi0RxDropped.Val,
|
"stat_user_wifi0_rx_dropped": bb.UserWifi0RxDropped.Val,
|
||||||
"stat_user_wifi0_rx_crypts": bb.UserWifi0RxCrypts.Val,
|
"stat_user_wifi0_rx_crypts": bb.UserWifi0RxCrypts.Val,
|
||||||
"stat_user_wifi0_rx_frags": bb.UserWifi0RxFrags.Val,
|
"stat_user_wifi0_rx_frags": bb.UserWifi0RxFrags.Val,
|
||||||
"stat_user_wifi0_tx_packets": bb.UserWifi0TxPackets.Val,
|
"stat_user_wifi0_tx_packets": bb.UserWifi0TxPackets.Val,
|
||||||
"stat_user_wifi0_tx_bytes": bb.UserWifi0TxBytes.Val,
|
"stat_user_wifi0_tx_bytes": bb.UserWifi0TxBytes.Val,
|
||||||
"stat_user_wifi0_tx_errors": bb.UserWifi0TxErrors.Val,
|
"stat_user_wifi0_tx_errors": bb.UserWifi0TxErrors.Val,
|
||||||
"stat_user_wifi0_tx_dropped": bb.UserWifi0TxDropped.Val,
|
"stat_user_wifi0_tx_dropped": bb.UserWifi0TxDropped.Val,
|
||||||
"stat_user_wifi0_tx_retries": bb.UserWifi0TxRetries.Val,
|
"stat_user_wifi0_tx_retries": bb.UserWifi0TxRetries.Val,
|
||||||
"stat_user_wifi0_mac_filter_rejections": bb.UserWifi0MacFilterRejections.Val,
|
"stat_user_wifi0_mac_filter_rejections": bb.UserWifi0MacFilterRejections.Val,
|
||||||
"stat_user_wifi0_wifi_tx_attempts": bb.UserWifi0WifiTxAttempts.Val,
|
"stat_user_wifi0_wifi_tx_attempts": bb.UserWifi0WifiTxAttempts.Val,
|
||||||
"stat_user_wifi0_wifi_tx_dropped": bb.UserWifi0WifiTxDropped.Val,
|
"stat_user_wifi0_wifi_tx_dropped": bb.UserWifi0WifiTxDropped.Val,
|
||||||
// User terra2 stats (60GHz)
|
// User terra2 stats (60GHz)
|
||||||
"stat_user_terra2_rx_packets": bb.UserTerra2RxPackets.Val,
|
"stat_user_terra2_rx_packets": bb.UserTerra2RxPackets.Val,
|
||||||
"stat_user_terra2_rx_bytes": bb.UserTerra2RxBytes.Val,
|
"stat_user_terra2_rx_bytes": bb.UserTerra2RxBytes.Val,
|
||||||
@@ -189,10 +190,10 @@ func (u *DatadogUnifi) batchUBBstats(stat *unifi.UBBStat) map[string]float64 {
|
|||||||
"stat_user_terra2_wifi_tx_attempts": bb.UserTerra2WifiTxAttempts.Val,
|
"stat_user_terra2_wifi_tx_attempts": bb.UserTerra2WifiTxAttempts.Val,
|
||||||
"stat_user_terra2_wifi_tx_dropped": bb.UserTerra2WifiTxDropped.Val,
|
"stat_user_terra2_wifi_tx_dropped": bb.UserTerra2WifiTxDropped.Val,
|
||||||
// Interface-specific stats
|
// Interface-specific stats
|
||||||
"stat_user_wifi0_ath0_rx_packets": bb.UserWifi0Ath0RxPackets.Val,
|
"stat_user_wifi0_ath0_rx_packets": bb.UserWifi0Ath0RxPackets.Val,
|
||||||
"stat_user_wifi0_ath0_rx_bytes": bb.UserWifi0Ath0RxBytes.Val,
|
"stat_user_wifi0_ath0_rx_bytes": bb.UserWifi0Ath0RxBytes.Val,
|
||||||
"stat_user_wifi0_ath0_tx_packets": bb.UserWifi0Ath0TxPackets.Val,
|
"stat_user_wifi0_ath0_tx_packets": bb.UserWifi0Ath0TxPackets.Val,
|
||||||
"stat_user_wifi0_ath0_tx_bytes": bb.UserWifi0Ath0TxBytes.Val,
|
"stat_user_wifi0_ath0_tx_bytes": bb.UserWifi0Ath0TxBytes.Val,
|
||||||
"stat_user_terra2_wlan0_rx_packets": bb.UserTerra2Wlan0RxPackets.Val,
|
"stat_user_terra2_wlan0_rx_packets": bb.UserTerra2Wlan0RxPackets.Val,
|
||||||
"stat_user_terra2_wlan0_rx_bytes": bb.UserTerra2Wlan0RxBytes.Val,
|
"stat_user_terra2_wlan0_rx_bytes": bb.UserTerra2Wlan0RxBytes.Val,
|
||||||
"stat_user_terra2_wlan0_tx_packets": bb.UserTerra2Wlan0TxPackets.Val,
|
"stat_user_terra2_wlan0_tx_packets": bb.UserTerra2Wlan0TxPackets.Val,
|
||||||
|
|||||||
70
pkg/datadogunifi/wan.go
Normal file
70
pkg/datadogunifi/wan.go
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package datadogunifi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/unpoller/unifi/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
// batchWAN generates WAN configuration datapoints for Datadog.
|
||||||
|
// These points can be passed directly to Datadog.
|
||||||
|
func (u *DatadogUnifi) batchWAN(r report, w *unifi.WANEnrichedConfiguration) {
|
||||||
|
if w == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
metricName := metricNamespace("wan")
|
||||||
|
|
||||||
|
cfg := w.Configuration
|
||||||
|
stats := w.Statistics
|
||||||
|
details := w.Details
|
||||||
|
|
||||||
|
tags := []string{
|
||||||
|
tag("wan_id", cfg.ID),
|
||||||
|
tag("wan_name", cfg.Name),
|
||||||
|
tag("wan_networkgroup", cfg.WANNetworkgroup),
|
||||||
|
tag("wan_type", cfg.WANType),
|
||||||
|
tag("wan_load_balance_type", cfg.WANLoadBalanceType),
|
||||||
|
tag("isp_name", details.ServiceProvider.Name),
|
||||||
|
tag("isp_city", details.ServiceProvider.City),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert boolean FlexBool values to float64 for Datadog
|
||||||
|
smartQEnabled := 0.0
|
||||||
|
if cfg.WANSmartqEnabled.Val {
|
||||||
|
smartQEnabled = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
magicEnabled := 0.0
|
||||||
|
if cfg.WANMagicEnabled.Val {
|
||||||
|
magicEnabled = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
vlanEnabled := 0.0
|
||||||
|
if cfg.WANVlanEnabled.Val {
|
||||||
|
vlanEnabled = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
data := map[string]float64{
|
||||||
|
// Configuration
|
||||||
|
"failover_priority": cfg.WANFailoverPriority.Val,
|
||||||
|
"load_balance_weight": cfg.WANLoadBalanceWeight.Val,
|
||||||
|
"provider_download_kbps": cfg.WANProviderCapabilities.DownloadKbps.Val,
|
||||||
|
"provider_upload_kbps": cfg.WANProviderCapabilities.UploadKbps.Val,
|
||||||
|
"smartq_enabled": smartQEnabled,
|
||||||
|
"magic_enabled": magicEnabled,
|
||||||
|
"vlan_enabled": vlanEnabled,
|
||||||
|
// Statistics
|
||||||
|
"uptime_percentage": stats.UptimePercentage,
|
||||||
|
"peak_download_percent": stats.PeakUsage.DownloadPercentage,
|
||||||
|
"peak_upload_percent": stats.PeakUsage.UploadPercentage,
|
||||||
|
"max_rx_bytes_rate": stats.PeakUsage.MaxRxBytesR.Val,
|
||||||
|
"max_tx_bytes_rate": stats.PeakUsage.MaxTxBytesR.Val,
|
||||||
|
// Service Provider
|
||||||
|
"service_provider_asn": details.ServiceProvider.ASN.Val,
|
||||||
|
// Metadata
|
||||||
|
"creation_timestamp": details.CreationTimestamp.Val,
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, value := range data {
|
||||||
|
_ = r.reportGauge(metricName(name), value, tags)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -430,6 +430,10 @@ func (u *InfluxUnifi) loopPoints(r report) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reportClientDPItotals(r, appTotal, catTotal)
|
reportClientDPItotals(r, appTotal, catTotal)
|
||||||
|
|
||||||
|
for _, w := range m.WANConfigs {
|
||||||
|
u.switchExport(r, w)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *InfluxUnifi) switchExport(r report, v any) { //nolint:cyclop
|
func (u *InfluxUnifi) switchExport(r report, v any) { //nolint:cyclop
|
||||||
@@ -466,6 +470,8 @@ func (u *InfluxUnifi) switchExport(r report, v any) { //nolint:cyclop
|
|||||||
u.batchAnomaly(r, v)
|
u.batchAnomaly(r, v)
|
||||||
case *unifi.SpeedTestResult:
|
case *unifi.SpeedTestResult:
|
||||||
u.batchSpeedTest(r, v)
|
u.batchSpeedTest(r, v)
|
||||||
|
case *unifi.WANEnrichedConfiguration:
|
||||||
|
u.batchWAN(r, v)
|
||||||
default:
|
default:
|
||||||
if u.Collector.Poller().LogUnknownTypes {
|
if u.Collector.Poller().LogUnknownTypes {
|
||||||
u.LogDebugf("unknown export type: %T", v)
|
u.LogDebugf("unknown export type: %T", v)
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ func (u *InfluxUnifi) batchUBB(r report, s *unifi.UBB) { // nolint: funlen
|
|||||||
fields["p2p_tx_rate"] = s.P2PStats.TXRate.Val
|
fields["p2p_tx_rate"] = s.P2PStats.TXRate.Val
|
||||||
fields["p2p_throughput"] = s.P2PStats.Throughput.Val
|
fields["p2p_throughput"] = s.P2PStats.Throughput.Val
|
||||||
}
|
}
|
||||||
|
|
||||||
fields["link_quality"] = s.LinkQuality.Val
|
fields["link_quality"] = s.LinkQuality.Val
|
||||||
fields["link_quality_current"] = s.LinkQualityCurrent.Val
|
fields["link_quality_current"] = s.LinkQualityCurrent.Val
|
||||||
fields["link_capacity"] = s.LinkCapacity.Val
|
fields["link_capacity"] = s.LinkCapacity.Val
|
||||||
@@ -91,52 +92,52 @@ func (u *InfluxUnifi) batchUBBstats(stat *unifi.UBBStat) map[string]any {
|
|||||||
|
|
||||||
// Total aggregated stats across both radios
|
// Total aggregated stats across both radios
|
||||||
return map[string]any{
|
return map[string]any{
|
||||||
"stat_bytes": bb.Bytes.Val,
|
"stat_bytes": bb.Bytes.Val,
|
||||||
"stat_duration": bb.Duration.Val,
|
"stat_duration": bb.Duration.Val,
|
||||||
"stat_rx_packets": bb.RxPackets.Val,
|
"stat_rx_packets": bb.RxPackets.Val,
|
||||||
"stat_rx_bytes": bb.RxBytes.Val,
|
"stat_rx_bytes": bb.RxBytes.Val,
|
||||||
"stat_rx_errors": bb.RxErrors.Val,
|
"stat_rx_errors": bb.RxErrors.Val,
|
||||||
"stat_rx_dropped": bb.RxDropped.Val,
|
"stat_rx_dropped": bb.RxDropped.Val,
|
||||||
"stat_rx_crypts": bb.RxCrypts.Val,
|
"stat_rx_crypts": bb.RxCrypts.Val,
|
||||||
"stat_rx_frags": bb.RxFrags.Val,
|
"stat_rx_frags": bb.RxFrags.Val,
|
||||||
"stat_tx_packets": bb.TxPackets.Val,
|
"stat_tx_packets": bb.TxPackets.Val,
|
||||||
"stat_tx_bytes": bb.TxBytes.Val,
|
"stat_tx_bytes": bb.TxBytes.Val,
|
||||||
"stat_tx_errors": bb.TxErrors.Val,
|
"stat_tx_errors": bb.TxErrors.Val,
|
||||||
"stat_tx_dropped": bb.TxDropped.Val,
|
"stat_tx_dropped": bb.TxDropped.Val,
|
||||||
"stat_tx_retries": bb.TxRetries.Val,
|
"stat_tx_retries": bb.TxRetries.Val,
|
||||||
"stat_mac_filter_rejections": bb.MacFilterRejections.Val,
|
"stat_mac_filter_rejections": bb.MacFilterRejections.Val,
|
||||||
"stat_wifi_tx_attempts": bb.WifiTxAttempts.Val,
|
"stat_wifi_tx_attempts": bb.WifiTxAttempts.Val,
|
||||||
"stat_wifi_tx_dropped": bb.WifiTxDropped.Val,
|
"stat_wifi_tx_dropped": bb.WifiTxDropped.Val,
|
||||||
// User aggregated stats
|
// User aggregated stats
|
||||||
"stat_user-rx_packets": bb.UserRxPackets.Val,
|
"stat_user-rx_packets": bb.UserRxPackets.Val,
|
||||||
"stat_user-rx_bytes": bb.UserRxBytes.Val,
|
"stat_user-rx_bytes": bb.UserRxBytes.Val,
|
||||||
"stat_user-rx_errors": bb.UserRxErrors.Val,
|
"stat_user-rx_errors": bb.UserRxErrors.Val,
|
||||||
"stat_user-rx_dropped": bb.UserRxDropped.Val,
|
"stat_user-rx_dropped": bb.UserRxDropped.Val,
|
||||||
"stat_user-rx_crypts": bb.UserRxCrypts.Val,
|
"stat_user-rx_crypts": bb.UserRxCrypts.Val,
|
||||||
"stat_user-rx_frags": bb.UserRxFrags.Val,
|
"stat_user-rx_frags": bb.UserRxFrags.Val,
|
||||||
"stat_user-tx_packets": bb.UserTxPackets.Val,
|
"stat_user-tx_packets": bb.UserTxPackets.Val,
|
||||||
"stat_user-tx_bytes": bb.UserTxBytes.Val,
|
"stat_user-tx_bytes": bb.UserTxBytes.Val,
|
||||||
"stat_user-tx_errors": bb.UserTxErrors.Val,
|
"stat_user-tx_errors": bb.UserTxErrors.Val,
|
||||||
"stat_user-tx_dropped": bb.UserTxDropped.Val,
|
"stat_user-tx_dropped": bb.UserTxDropped.Val,
|
||||||
"stat_user-tx_retries": bb.UserTxRetries.Val,
|
"stat_user-tx_retries": bb.UserTxRetries.Val,
|
||||||
"stat_user-mac_filter_rejections": bb.UserMacFilterRejections.Val,
|
"stat_user-mac_filter_rejections": bb.UserMacFilterRejections.Val,
|
||||||
"stat_user-wifi_tx_attempts": bb.UserWifiTxAttempts.Val,
|
"stat_user-wifi_tx_attempts": bb.UserWifiTxAttempts.Val,
|
||||||
"stat_user-wifi_tx_dropped": bb.UserWifiTxDropped.Val,
|
"stat_user-wifi_tx_dropped": bb.UserWifiTxDropped.Val,
|
||||||
// wifi0 radio stats (5GHz)
|
// wifi0 radio stats (5GHz)
|
||||||
"stat_wifi0-rx_packets": bb.Wifi0RxPackets.Val,
|
"stat_wifi0-rx_packets": bb.Wifi0RxPackets.Val,
|
||||||
"stat_wifi0-rx_bytes": bb.Wifi0RxBytes.Val,
|
"stat_wifi0-rx_bytes": bb.Wifi0RxBytes.Val,
|
||||||
"stat_wifi0-rx_errors": bb.Wifi0RxErrors.Val,
|
"stat_wifi0-rx_errors": bb.Wifi0RxErrors.Val,
|
||||||
"stat_wifi0-rx_dropped": bb.Wifi0RxDropped.Val,
|
"stat_wifi0-rx_dropped": bb.Wifi0RxDropped.Val,
|
||||||
"stat_wifi0-rx_crypts": bb.Wifi0RxCrypts.Val,
|
"stat_wifi0-rx_crypts": bb.Wifi0RxCrypts.Val,
|
||||||
"stat_wifi0-rx_frags": bb.Wifi0RxFrags.Val,
|
"stat_wifi0-rx_frags": bb.Wifi0RxFrags.Val,
|
||||||
"stat_wifi0-tx_packets": bb.Wifi0TxPackets.Val,
|
"stat_wifi0-tx_packets": bb.Wifi0TxPackets.Val,
|
||||||
"stat_wifi0-tx_bytes": bb.Wifi0TxBytes.Val,
|
"stat_wifi0-tx_bytes": bb.Wifi0TxBytes.Val,
|
||||||
"stat_wifi0-tx_errors": bb.Wifi0TxErrors.Val,
|
"stat_wifi0-tx_errors": bb.Wifi0TxErrors.Val,
|
||||||
"stat_wifi0-tx_dropped": bb.Wifi0TxDropped.Val,
|
"stat_wifi0-tx_dropped": bb.Wifi0TxDropped.Val,
|
||||||
"stat_wifi0-tx_retries": bb.Wifi0TxRetries.Val,
|
"stat_wifi0-tx_retries": bb.Wifi0TxRetries.Val,
|
||||||
"stat_wifi0-mac_filter_rejections": bb.Wifi0MacFilterRejections.Val,
|
"stat_wifi0-mac_filter_rejections": bb.Wifi0MacFilterRejections.Val,
|
||||||
"stat_wifi0-wifi_tx_attempts": bb.Wifi0WifiTxAttempts.Val,
|
"stat_wifi0-wifi_tx_attempts": bb.Wifi0WifiTxAttempts.Val,
|
||||||
"stat_wifi0-wifi_tx_dropped": bb.Wifi0WifiTxDropped.Val,
|
"stat_wifi0-wifi_tx_dropped": bb.Wifi0WifiTxDropped.Val,
|
||||||
// terra2 radio stats (60GHz - 802.11ad)
|
// terra2 radio stats (60GHz - 802.11ad)
|
||||||
"stat_terra2-rx_packets": bb.Terra2RxPackets.Val,
|
"stat_terra2-rx_packets": bb.Terra2RxPackets.Val,
|
||||||
"stat_terra2-rx_bytes": bb.Terra2RxBytes.Val,
|
"stat_terra2-rx_bytes": bb.Terra2RxBytes.Val,
|
||||||
@@ -153,20 +154,20 @@ func (u *InfluxUnifi) batchUBBstats(stat *unifi.UBBStat) map[string]any {
|
|||||||
"stat_terra2-wifi_tx_attempts": bb.Terra2WifiTxAttempts.Val,
|
"stat_terra2-wifi_tx_attempts": bb.Terra2WifiTxAttempts.Val,
|
||||||
"stat_terra2-wifi_tx_dropped": bb.Terra2WifiTxDropped.Val,
|
"stat_terra2-wifi_tx_dropped": bb.Terra2WifiTxDropped.Val,
|
||||||
// User wifi0 stats
|
// User wifi0 stats
|
||||||
"stat_user-wifi0-rx_packets": bb.UserWifi0RxPackets.Val,
|
"stat_user-wifi0-rx_packets": bb.UserWifi0RxPackets.Val,
|
||||||
"stat_user-wifi0-rx_bytes": bb.UserWifi0RxBytes.Val,
|
"stat_user-wifi0-rx_bytes": bb.UserWifi0RxBytes.Val,
|
||||||
"stat_user-wifi0-rx_errors": bb.UserWifi0RxErrors.Val,
|
"stat_user-wifi0-rx_errors": bb.UserWifi0RxErrors.Val,
|
||||||
"stat_user-wifi0-rx_dropped": bb.UserWifi0RxDropped.Val,
|
"stat_user-wifi0-rx_dropped": bb.UserWifi0RxDropped.Val,
|
||||||
"stat_user-wifi0-rx_crypts": bb.UserWifi0RxCrypts.Val,
|
"stat_user-wifi0-rx_crypts": bb.UserWifi0RxCrypts.Val,
|
||||||
"stat_user-wifi0-rx_frags": bb.UserWifi0RxFrags.Val,
|
"stat_user-wifi0-rx_frags": bb.UserWifi0RxFrags.Val,
|
||||||
"stat_user-wifi0-tx_packets": bb.UserWifi0TxPackets.Val,
|
"stat_user-wifi0-tx_packets": bb.UserWifi0TxPackets.Val,
|
||||||
"stat_user-wifi0-tx_bytes": bb.UserWifi0TxBytes.Val,
|
"stat_user-wifi0-tx_bytes": bb.UserWifi0TxBytes.Val,
|
||||||
"stat_user-wifi0-tx_errors": bb.UserWifi0TxErrors.Val,
|
"stat_user-wifi0-tx_errors": bb.UserWifi0TxErrors.Val,
|
||||||
"stat_user-wifi0-tx_dropped": bb.UserWifi0TxDropped.Val,
|
"stat_user-wifi0-tx_dropped": bb.UserWifi0TxDropped.Val,
|
||||||
"stat_user-wifi0-tx_retries": bb.UserWifi0TxRetries.Val,
|
"stat_user-wifi0-tx_retries": bb.UserWifi0TxRetries.Val,
|
||||||
"stat_user-wifi0-mac_filter_rejections": bb.UserWifi0MacFilterRejections.Val,
|
"stat_user-wifi0-mac_filter_rejections": bb.UserWifi0MacFilterRejections.Val,
|
||||||
"stat_user-wifi0-wifi_tx_attempts": bb.UserWifi0WifiTxAttempts.Val,
|
"stat_user-wifi0-wifi_tx_attempts": bb.UserWifi0WifiTxAttempts.Val,
|
||||||
"stat_user-wifi0-wifi_tx_dropped": bb.UserWifi0WifiTxDropped.Val,
|
"stat_user-wifi0-wifi_tx_dropped": bb.UserWifi0WifiTxDropped.Val,
|
||||||
// User terra2 stats (60GHz)
|
// User terra2 stats (60GHz)
|
||||||
"stat_user-terra2-rx_packets": bb.UserTerra2RxPackets.Val,
|
"stat_user-terra2-rx_packets": bb.UserTerra2RxPackets.Val,
|
||||||
"stat_user-terra2-rx_bytes": bb.UserTerra2RxBytes.Val,
|
"stat_user-terra2-rx_bytes": bb.UserTerra2RxBytes.Val,
|
||||||
@@ -183,10 +184,10 @@ func (u *InfluxUnifi) batchUBBstats(stat *unifi.UBBStat) map[string]any {
|
|||||||
"stat_user-terra2-wifi_tx_attempts": bb.UserTerra2WifiTxAttempts.Val,
|
"stat_user-terra2-wifi_tx_attempts": bb.UserTerra2WifiTxAttempts.Val,
|
||||||
"stat_user-terra2-wifi_tx_dropped": bb.UserTerra2WifiTxDropped.Val,
|
"stat_user-terra2-wifi_tx_dropped": bb.UserTerra2WifiTxDropped.Val,
|
||||||
// Interface-specific stats
|
// Interface-specific stats
|
||||||
"stat_user-wifi0-ath0-rx_packets": bb.UserWifi0Ath0RxPackets.Val,
|
"stat_user-wifi0-ath0-rx_packets": bb.UserWifi0Ath0RxPackets.Val,
|
||||||
"stat_user-wifi0-ath0-rx_bytes": bb.UserWifi0Ath0RxBytes.Val,
|
"stat_user-wifi0-ath0-rx_bytes": bb.UserWifi0Ath0RxBytes.Val,
|
||||||
"stat_user-wifi0-ath0-tx_packets": bb.UserWifi0Ath0TxPackets.Val,
|
"stat_user-wifi0-ath0-tx_packets": bb.UserWifi0Ath0TxPackets.Val,
|
||||||
"stat_user-wifi0-ath0-tx_bytes": bb.UserWifi0Ath0TxBytes.Val,
|
"stat_user-wifi0-ath0-tx_bytes": bb.UserWifi0Ath0TxBytes.Val,
|
||||||
"stat_user-terra2-wlan0-rx_packets": bb.UserTerra2Wlan0RxPackets.Val,
|
"stat_user-terra2-wlan0-rx_packets": bb.UserTerra2Wlan0RxPackets.Val,
|
||||||
"stat_user-terra2-wlan0-rx_bytes": bb.UserTerra2Wlan0RxBytes.Val,
|
"stat_user-terra2-wlan0-rx_bytes": bb.UserTerra2Wlan0RxBytes.Val,
|
||||||
"stat_user-terra2-wlan0-tx_packets": bb.UserTerra2Wlan0TxPackets.Val,
|
"stat_user-terra2-wlan0-tx_packets": bb.UserTerra2Wlan0TxPackets.Val,
|
||||||
|
|||||||
66
pkg/influxunifi/wan.go
Normal file
66
pkg/influxunifi/wan.go
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package influxunifi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/unpoller/unifi/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
// batchWAN generates WAN configuration datapoints for InfluxDB.
|
||||||
|
// These points can be passed directly to influx.
|
||||||
|
func (u *InfluxUnifi) batchWAN(r report, w *unifi.WANEnrichedConfiguration) {
|
||||||
|
if w == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := w.Configuration
|
||||||
|
stats := w.Statistics
|
||||||
|
details := w.Details
|
||||||
|
|
||||||
|
tags := map[string]string{
|
||||||
|
"wan_id": cfg.ID,
|
||||||
|
"wan_name": cfg.Name,
|
||||||
|
"wan_networkgroup": cfg.WANNetworkgroup,
|
||||||
|
"wan_type": cfg.WANType,
|
||||||
|
"wan_load_balance_type": cfg.WANLoadBalanceType,
|
||||||
|
"isp_name": details.ServiceProvider.Name,
|
||||||
|
"isp_city": details.ServiceProvider.City,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert boolean FlexBool values to int for InfluxDB
|
||||||
|
smartQEnabled := 0
|
||||||
|
if cfg.WANSmartqEnabled.Val {
|
||||||
|
smartQEnabled = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
magicEnabled := 0
|
||||||
|
if cfg.WANMagicEnabled.Val {
|
||||||
|
magicEnabled = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
vlanEnabled := 0
|
||||||
|
if cfg.WANVlanEnabled.Val {
|
||||||
|
vlanEnabled = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := map[string]any{
|
||||||
|
// Configuration
|
||||||
|
"failover_priority": cfg.WANFailoverPriority.Val,
|
||||||
|
"load_balance_weight": cfg.WANLoadBalanceWeight.Val,
|
||||||
|
"provider_download_kbps": cfg.WANProviderCapabilities.DownloadKbps.Val,
|
||||||
|
"provider_upload_kbps": cfg.WANProviderCapabilities.UploadKbps.Val,
|
||||||
|
"smartq_enabled": smartQEnabled,
|
||||||
|
"magic_enabled": magicEnabled,
|
||||||
|
"vlan_enabled": vlanEnabled,
|
||||||
|
// Statistics
|
||||||
|
"uptime_percentage": stats.UptimePercentage,
|
||||||
|
"peak_download_percent": stats.PeakUsage.DownloadPercentage,
|
||||||
|
"peak_upload_percent": stats.PeakUsage.UploadPercentage,
|
||||||
|
"max_rx_bytes_rate": stats.PeakUsage.MaxRxBytesR.Val,
|
||||||
|
"max_tx_bytes_rate": stats.PeakUsage.MaxTxBytesR.Val,
|
||||||
|
// Service Provider
|
||||||
|
"service_provider_asn": details.ServiceProvider.ASN.Val,
|
||||||
|
// Metadata
|
||||||
|
"creation_timestamp": details.CreationTimestamp.Val,
|
||||||
|
}
|
||||||
|
|
||||||
|
r.send(&metric{Table: "wan", Tags: tags, Fields: fields})
|
||||||
|
}
|
||||||
@@ -15,15 +15,15 @@ type wan struct {
|
|||||||
MagicEnabled *prometheus.Desc
|
MagicEnabled *prometheus.Desc
|
||||||
VlanEnabled *prometheus.Desc
|
VlanEnabled *prometheus.Desc
|
||||||
// WAN Statistics metrics
|
// WAN Statistics metrics
|
||||||
UptimePercentage *prometheus.Desc
|
UptimePercentage *prometheus.Desc
|
||||||
PeakDownloadPercent *prometheus.Desc
|
PeakDownloadPercent *prometheus.Desc
|
||||||
PeakUploadPercent *prometheus.Desc
|
PeakUploadPercent *prometheus.Desc
|
||||||
MaxRxBytesR *prometheus.Desc
|
MaxRxBytesR *prometheus.Desc
|
||||||
MaxTxBytesR *prometheus.Desc
|
MaxTxBytesR *prometheus.Desc
|
||||||
// WAN Service Provider metrics
|
// WAN Service Provider metrics
|
||||||
ServiceProviderASN *prometheus.Desc
|
ServiceProviderASN *prometheus.Desc
|
||||||
// WAN Creation timestamp
|
// WAN Creation timestamp
|
||||||
CreationTimestamp *prometheus.Desc
|
CreationTimestamp *prometheus.Desc
|
||||||
}
|
}
|
||||||
|
|
||||||
func descWAN(ns string) *wan {
|
func descWAN(ns string) *wan {
|
||||||
@@ -36,7 +36,7 @@ func descWAN(ns string) *wan {
|
|||||||
"site_name",
|
"site_name",
|
||||||
"source",
|
"source",
|
||||||
}
|
}
|
||||||
|
|
||||||
providerLabels := []string{
|
providerLabels := []string{
|
||||||
"wan_id",
|
"wan_id",
|
||||||
"wan_name",
|
"wan_name",
|
||||||
@@ -59,15 +59,15 @@ func descWAN(ns string) *wan {
|
|||||||
MagicEnabled: nd(ns+"wan_magic_enabled", "Magic WAN enabled (1) or disabled (0)", labels, nil),
|
MagicEnabled: nd(ns+"wan_magic_enabled", "Magic WAN enabled (1) or disabled (0)", labels, nil),
|
||||||
VlanEnabled: nd(ns+"wan_vlan_enabled", "VLAN enabled for WAN (1) or disabled (0)", labels, nil),
|
VlanEnabled: nd(ns+"wan_vlan_enabled", "VLAN enabled for WAN (1) or disabled (0)", labels, nil),
|
||||||
// Statistics
|
// Statistics
|
||||||
UptimePercentage: nd(ns+"wan_uptime_percentage", "WAN uptime percentage", labels, nil),
|
UptimePercentage: nd(ns+"wan_uptime_percentage", "WAN uptime percentage", labels, nil),
|
||||||
PeakDownloadPercent: nd(ns+"wan_peak_download_percent", "Peak download usage as percentage of configured capacity", labels, nil),
|
PeakDownloadPercent: nd(ns+"wan_peak_download_percent", "Peak download usage as percentage of configured capacity", labels, nil),
|
||||||
PeakUploadPercent: nd(ns+"wan_peak_upload_percent", "Peak upload usage as percentage of configured capacity", labels, nil),
|
PeakUploadPercent: nd(ns+"wan_peak_upload_percent", "Peak upload usage as percentage of configured capacity", labels, nil),
|
||||||
MaxRxBytesR: nd(ns+"wan_max_rx_bytes_rate", "Maximum receive bytes rate", labels, nil),
|
MaxRxBytesR: nd(ns+"wan_max_rx_bytes_rate", "Maximum receive bytes rate", labels, nil),
|
||||||
MaxTxBytesR: nd(ns+"wan_max_tx_bytes_rate", "Maximum transmit bytes rate", labels, nil),
|
MaxTxBytesR: nd(ns+"wan_max_tx_bytes_rate", "Maximum transmit bytes rate", labels, nil),
|
||||||
// Service Provider
|
// Service Provider
|
||||||
ServiceProviderASN: nd(ns+"wan_service_provider_asn", "Service provider autonomous system number", providerLabels, nil),
|
ServiceProviderASN: nd(ns+"wan_service_provider_asn", "Service provider autonomous system number", providerLabels, nil),
|
||||||
// Creation
|
// Creation
|
||||||
CreationTimestamp: nd(ns+"wan_creation_timestamp", "WAN configuration creation timestamp", labels, nil),
|
CreationTimestamp: nd(ns+"wan_creation_timestamp", "WAN configuration creation timestamp", labels, nil),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,8 +87,8 @@ func (u *promUnifi) exportWAN(r report, w *unifi.WANEnrichedConfiguration) {
|
|||||||
cfg.WANNetworkgroup,
|
cfg.WANNetworkgroup,
|
||||||
cfg.WANType,
|
cfg.WANType,
|
||||||
cfg.WANLoadBalanceType,
|
cfg.WANLoadBalanceType,
|
||||||
"", // site_name - will be set by caller if available
|
"", // site_name - will be set by caller if available
|
||||||
"", // source - will be set by caller if available
|
"", // source - will be set by caller if available
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert boolean FlexBool values to float64
|
// Convert boolean FlexBool values to float64
|
||||||
@@ -130,8 +130,8 @@ func (u *promUnifi) exportWAN(r report, w *unifi.WANEnrichedConfiguration) {
|
|||||||
cfg.WANNetworkgroup,
|
cfg.WANNetworkgroup,
|
||||||
details.ServiceProvider.Name,
|
details.ServiceProvider.Name,
|
||||||
details.ServiceProvider.City,
|
details.ServiceProvider.City,
|
||||||
"", // site_name
|
"", // site_name
|
||||||
"", // source
|
"", // source
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics = append(metrics, &metric{u.WAN.ServiceProviderASN, gauge, details.ServiceProvider.ASN.Val, providerLabels})
|
metrics = append(metrics, &metric{u.WAN.ServiceProviderASN, gauge, details.ServiceProvider.ASN.Val, providerLabels})
|
||||||
|
|||||||
Reference in New Issue
Block a user