Files
unpoller/pkg/datadogunifi/vpn.go
Cody Lee 18c6e66a8e feat: add Site Magic site-to-site VPN metrics (closes #926) (#983)
* feat: add Site Magic site-to-site VPN metrics (closes #926)

Bump github.com/unpoller/unifi/v5 to v5.25.0 which adds:
- GetMagicSiteToSiteVPN / GetMagicSiteToSiteVPNSite API methods
- MagicSiteToSiteVPN types with mesh, connection, device, and status structs
- Missing VPN health fields on Site.Health (SiteToSiteNumActive/Inactive,
  SiteToSiteRxBytes/TxBytes/RxPackets/TxPackets)

Implement VPN metrics collection across all output plugins:
- Collect Site Magic VPN mesh data per-site in inputunifi pollController
- Propagate VPNMeshes through poller.Metrics / AppendMetrics
- Apply DefaultSiteNameOverride for VPN meshes in augmentMetrics /
  applySiteNameOverride
- influxunifi: vpn_mesh, vpn_mesh_connection, vpn_mesh_status tables
- promunifi: vpn_mesh_*, vpn_tunnel_*, vpn_mesh_status_* gauges
- datadogunifi: unifi.vpn_mesh.*, unifi.vpn_tunnel.*, unifi.vpn_mesh_status.*

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* feat(otelunifi): add Site Magic VPN metrics to OpenTelemetry output

Adds exportVPNMeshes to the otel output plugin, emitting the same
unifi_vpn_mesh_*, unifi_vpn_tunnel_*, and unifi_vpn_mesh_status_*
gauges as the other output plugins.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:08:09 -05:00

68 lines
1.7 KiB
Go

package datadogunifi
import (
"github.com/unpoller/unifi/v5"
)
// batchMagicSiteToSiteVPN generates Site Magic VPN datapoints for Datadog.
func (u *DatadogUnifi) batchMagicSiteToSiteVPN(r report, m *unifi.MagicSiteToSiteVPN) {
if m == nil {
return
}
meshMetric := metricNamespace("vpn_mesh")
meshTags := []string{
tag("site_name", m.SiteName),
tag("source", m.SourceName),
tag("mesh_name", m.Name),
}
paused := 0.0
if m.Pause.Val {
paused = 1.0
}
_ = r.reportGauge(meshMetric("paused"), paused, meshTags)
_ = r.reportGauge(meshMetric("connections_total"), float64(len(m.Connections)), meshTags)
_ = r.reportGauge(meshMetric("devices_total"), float64(len(m.Devices)), meshTags)
tunnelMetric := metricNamespace("vpn_tunnel")
statusMetric := metricNamespace("vpn_mesh_status")
for i := range m.Status {
s := &m.Status[i]
statusTags := []string{
tag("site_name", m.SiteName),
tag("source", m.SourceName),
tag("mesh_name", m.Name),
tag("status_site", s.SiteID),
}
_ = r.reportGauge(statusMetric("errors"), float64(len(s.Errors)), statusTags)
_ = r.reportGauge(statusMetric("warnings"), float64(len(s.Warnings)), statusTags)
for j := range s.Connections {
conn := &s.Connections[j]
connected := 0.0
if conn.Connected.Val {
connected = 1.0
}
connTags := []string{
tag("site_name", m.SiteName),
tag("source", m.SourceName),
tag("mesh_name", m.Name),
tag("connection_id", conn.ConnectionID),
tag("status_site", s.SiteID),
}
_ = r.reportGauge(tunnelMetric("connected"), connected, connTags)
_ = r.reportGauge(tunnelMetric("association_time"), conn.AssociationTime.Val, connTags)
_ = r.reportGauge(tunnelMetric("errors"), float64(len(conn.Errors)), connTags)
}
}
}