mirror of
https://github.com/unpoller/unpoller.git
synced 2026-04-05 08:54:00 -04:00
chore: apply linter auto-fixes (wsl_v5, nlreturn, tagalign) (#984)
golangci-lint auto-fixes across multiple packages: - wsl_v5: blank lines between logical blocks - nlreturn: newlines before return statements - tagalign: struct field tag alignment No logic changes. Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -64,46 +64,55 @@ func (u *InputUnifi) collectAlarms(logs []any, sites []*unifi.Site, c *Controlle
|
|||||||
devices, err := c.Unifi.GetDevices(sites)
|
devices, err := c.Unifi.GetDevices(sites)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
u.LogDebugf("Failed to get devices for alarm enrichment: %v (continuing without device names)", err)
|
u.LogDebugf("Failed to get devices for alarm enrichment: %v (continuing without device names)", err)
|
||||||
|
|
||||||
devices = &unifi.Devices{} // Empty devices struct, alarms will not have device names
|
devices = &unifi.Devices{} // Empty devices struct, alarms will not have device names
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build MAC address to device name lookup map
|
// Build MAC address to device name lookup map
|
||||||
macToName := make(map[string]string)
|
macToName := make(map[string]string)
|
||||||
|
|
||||||
for _, d := range devices.UAPs {
|
for _, d := range devices.UAPs {
|
||||||
if d.Mac != "" && d.Name != "" {
|
if d.Mac != "" && d.Name != "" {
|
||||||
macToName[strings.ToLower(d.Mac)] = d.Name
|
macToName[strings.ToLower(d.Mac)] = d.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range devices.USGs {
|
for _, d := range devices.USGs {
|
||||||
if d.Mac != "" && d.Name != "" {
|
if d.Mac != "" && d.Name != "" {
|
||||||
macToName[strings.ToLower(d.Mac)] = d.Name
|
macToName[strings.ToLower(d.Mac)] = d.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range devices.USWs {
|
for _, d := range devices.USWs {
|
||||||
if d.Mac != "" && d.Name != "" {
|
if d.Mac != "" && d.Name != "" {
|
||||||
macToName[strings.ToLower(d.Mac)] = d.Name
|
macToName[strings.ToLower(d.Mac)] = d.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range devices.UDMs {
|
for _, d := range devices.UDMs {
|
||||||
if d.Mac != "" && d.Name != "" {
|
if d.Mac != "" && d.Name != "" {
|
||||||
macToName[strings.ToLower(d.Mac)] = d.Name
|
macToName[strings.ToLower(d.Mac)] = d.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range devices.UXGs {
|
for _, d := range devices.UXGs {
|
||||||
if d.Mac != "" && d.Name != "" {
|
if d.Mac != "" && d.Name != "" {
|
||||||
macToName[strings.ToLower(d.Mac)] = d.Name
|
macToName[strings.ToLower(d.Mac)] = d.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range devices.PDUs {
|
for _, d := range devices.PDUs {
|
||||||
if d.Mac != "" && d.Name != "" {
|
if d.Mac != "" && d.Name != "" {
|
||||||
macToName[strings.ToLower(d.Mac)] = d.Name
|
macToName[strings.ToLower(d.Mac)] = d.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range devices.UBBs {
|
for _, d := range devices.UBBs {
|
||||||
if d.Mac != "" && d.Name != "" {
|
if d.Mac != "" && d.Name != "" {
|
||||||
macToName[strings.ToLower(d.Mac)] = d.Name
|
macToName[strings.ToLower(d.Mac)] = d.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range devices.UCIs {
|
for _, d := range devices.UCIs {
|
||||||
if d.Mac != "" && d.Name != "" {
|
if d.Mac != "" && d.Name != "" {
|
||||||
macToName[strings.ToLower(d.Mac)] = d.Name
|
macToName[strings.ToLower(d.Mac)] = d.Name
|
||||||
@@ -201,6 +210,7 @@ func (u *InputUnifi) collectSyslog(logs []any, sites []*unifi.Site, c *Controlle
|
|||||||
|
|
||||||
// Use v2 system-log API
|
// Use v2 system-log API
|
||||||
req := unifi.DefaultSystemLogRequest(time.Hour)
|
req := unifi.DefaultSystemLogRequest(time.Hour)
|
||||||
|
|
||||||
entries, err := c.Unifi.GetSystemLog(sites, req)
|
entries, err := c.Unifi.GetSystemLog(sites, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return logs, fmt.Errorf("unifi.GetSystemLog(): %w", err)
|
return logs, fmt.Errorf("unifi.GetSystemLog(): %w", err)
|
||||||
@@ -229,6 +239,7 @@ func (u *InputUnifi) collectProtectLogs(logs []any, _ []*unifi.Site, c *Controll
|
|||||||
u.LogDebugf("Collecting Protect logs: %s (%s)", c.URL, c.ID)
|
u.LogDebugf("Collecting Protect logs: %s (%s)", c.URL, c.ID)
|
||||||
|
|
||||||
req := unifi.DefaultProtectLogRequest(0) // Uses default 24-hour window
|
req := unifi.DefaultProtectLogRequest(0) // Uses default 24-hour window
|
||||||
|
|
||||||
entries, err := c.Unifi.GetProtectLogs(req)
|
entries, err := c.Unifi.GetProtectLogs(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return logs, fmt.Errorf("unifi.GetProtectLogs(): %w", err)
|
return logs, fmt.Errorf("unifi.GetProtectLogs(): %w", err)
|
||||||
@@ -245,6 +256,7 @@ func (u *InputUnifi) collectProtectLogs(logs []any, _ []*unifi.Site, c *Controll
|
|||||||
if len(thumbID) > 2 && thumbID[:2] == "e-" {
|
if len(thumbID) > 2 && thumbID[:2] == "e-" {
|
||||||
thumbID = thumbID[2:]
|
thumbID = thumbID[2:]
|
||||||
}
|
}
|
||||||
|
|
||||||
if thumbData, err := c.Unifi.GetProtectEventThumbnail(thumbID); err == nil {
|
if thumbData, err := c.Unifi.GetProtectEventThumbnail(thumbID); err == nil {
|
||||||
e.ThumbnailBase64 = base64.StdEncoding.EncodeToString(thumbData)
|
e.ThumbnailBase64 = base64.StdEncoding.EncodeToString(thumbData)
|
||||||
} else {
|
} else {
|
||||||
@@ -343,6 +355,7 @@ func redactSystemLogEntry(e *unifi.SystemLogEntry, hash *bool, dropPII *bool) *u
|
|||||||
client.ID = RedactMacPII(client.ID, hash, dropPII)
|
client.ID = RedactMacPII(client.ID, hash, dropPII)
|
||||||
client.IP = RedactIPPII(client.IP, hash, dropPII)
|
client.IP = RedactIPPII(client.IP, hash, dropPII)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.Parameters["CLIENT"] = client
|
e.Parameters["CLIENT"] = client
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,6 +368,7 @@ func redactSystemLogEntry(e *unifi.SystemLogEntry, hash *bool, dropPII *bool) *u
|
|||||||
ip.ID = RedactIPPII(ip.ID, hash, dropPII)
|
ip.ID = RedactIPPII(ip.ID, hash, dropPII)
|
||||||
ip.Name = RedactIPPII(ip.Name, hash, dropPII)
|
ip.Name = RedactIPPII(ip.Name, hash, dropPII)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.Parameters["IP"] = ip
|
e.Parameters["IP"] = ip
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,6 +379,7 @@ func redactSystemLogEntry(e *unifi.SystemLogEntry, hash *bool, dropPII *bool) *u
|
|||||||
} else {
|
} else {
|
||||||
admin.Name = RedactNamePII(admin.Name, hash, dropPII)
|
admin.Name = RedactNamePII(admin.Name, hash, dropPII)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.Parameters["ADMIN"] = admin
|
e.Parameters["ADMIN"] = admin
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,6 +430,7 @@ func (u *InputUnifi) extractDeviceNameFromAlarm(alarm *unifi.Alarm, macToName ma
|
|||||||
|
|
||||||
// Simple regex-like search for MAC address in brackets
|
// Simple regex-like search for MAC address in brackets
|
||||||
start := strings.Index(msg, "[")
|
start := strings.Index(msg, "[")
|
||||||
|
|
||||||
end := strings.Index(msg, "]")
|
end := strings.Index(msg, "]")
|
||||||
if start >= 0 && end > start {
|
if start >= 0 && end > start {
|
||||||
potentialMAC := msg[start+1 : end]
|
potentialMAC := msg[start+1 : end]
|
||||||
|
|||||||
@@ -55,17 +55,21 @@ func (u *InputUnifi) Initialize(l poller.Logger) error {
|
|||||||
discovered, err := u.discoverRemoteControllers(c.APIKey)
|
discovered, err := u.discoverRemoteControllers(c.APIKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
u.LogErrorf("Failed to discover remote controllers for controller: %v", err)
|
u.LogErrorf("Failed to discover remote controllers for controller: %v", err)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(discovered) > 0 {
|
if len(discovered) > 0 {
|
||||||
// Replace this controller with discovered ones
|
// Replace this controller with discovered ones
|
||||||
// Remove the current one and add discovered
|
// Remove the current one and add discovered
|
||||||
newControllers := []*Controller{}
|
newControllers := []*Controller{}
|
||||||
|
|
||||||
for _, existing := range u.Controllers {
|
for _, existing := range u.Controllers {
|
||||||
if existing != c {
|
if existing != c {
|
||||||
newControllers = append(newControllers, existing)
|
newControllers = append(newControllers, existing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newControllers = append(newControllers, discovered...)
|
newControllers = append(newControllers, discovered...)
|
||||||
u.Controllers = newControllers
|
u.Controllers = newControllers
|
||||||
}
|
}
|
||||||
@@ -214,6 +218,7 @@ func (u *InputUnifi) Events(filter *poller.Filter) (*poller.Events, error) {
|
|||||||
// Log error but continue to next controller
|
// Log error but continue to next controller
|
||||||
u.LogErrorf("Failed to collect events from controller %s: %v", c.URL, err)
|
u.LogErrorf("Failed to collect events from controller %s: %v", c.URL, err)
|
||||||
collectionErrors = append(collectionErrors, fmt.Errorf("%s: %w", c.URL, err))
|
collectionErrors = append(collectionErrors, fmt.Errorf("%s: %w", c.URL, err))
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ func (u *InputUnifi) discoverRemoteControllers(apiKey string) ([]*Controller, er
|
|||||||
|
|
||||||
if len(consoles) == 0 {
|
if len(consoles) == 0 {
|
||||||
u.Logf("No Network-capable consoles found via remote API (NVR/Protect/display-only consoles are excluded)")
|
u.Logf("No Network-capable consoles found via remote API (NVR/Protect/display-only consoles are excluded)")
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,33 +47,43 @@ func (u *InputUnifi) discoverRemoteControllers(apiKey string) ([]*Controller, er
|
|||||||
if consoleName == "" {
|
if consoleName == "" {
|
||||||
consoleName = console.ReportedState.Name
|
consoleName = console.ReportedState.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
if consoleName == "" {
|
if consoleName == "" {
|
||||||
consoleName = console.ReportedState.Hostname
|
consoleName = console.ReportedState.Hostname
|
||||||
}
|
}
|
||||||
|
|
||||||
if consoleName == "" {
|
if consoleName == "" {
|
||||||
consoleName = console.ID
|
consoleName = console.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
u.LogDebugf("Discovering sites for console: %s (%s)", console.ID, consoleName)
|
u.LogDebugf("Discovering sites for console: %s (%s)", console.ID, consoleName)
|
||||||
|
|
||||||
var sites []unifi.RemoteSite
|
var (
|
||||||
var lastErr error
|
sites []unifi.RemoteSite
|
||||||
|
lastErr error
|
||||||
|
)
|
||||||
|
|
||||||
for attempt := 1; attempt <= discoverMaxAttempts; attempt++ {
|
for attempt := 1; attempt <= discoverMaxAttempts; attempt++ {
|
||||||
sites, lastErr = client.DiscoverSites(console.ID)
|
sites, lastErr = client.DiscoverSites(console.ID)
|
||||||
if lastErr == nil {
|
if lastErr == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if attempt < discoverMaxAttempts {
|
if attempt < discoverMaxAttempts {
|
||||||
u.LogDebugf("Discover sites attempt %d/%d failed for %s: %v; retrying in %v", attempt, discoverMaxAttempts, consoleName, lastErr, discoverRetryDelay)
|
u.LogDebugf("Discover sites attempt %d/%d failed for %s: %v; retrying in %v", attempt, discoverMaxAttempts, consoleName, lastErr, discoverRetryDelay)
|
||||||
time.Sleep(discoverRetryDelay)
|
time.Sleep(discoverRetryDelay)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if lastErr != nil {
|
if lastErr != nil {
|
||||||
u.Logf("Excluding controller %s: api key does not have permissions (after %d attempts)", consoleName, discoverMaxAttempts)
|
u.Logf("Excluding controller %s: api key does not have permissions (after %d attempts)", consoleName, discoverMaxAttempts)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(sites) == 0 {
|
if len(sites) == 0 {
|
||||||
u.LogDebugf("No sites found for console %s", console.ID)
|
u.LogDebugf("No sites found for console %s", console.ID)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,6 +110,7 @@ func (u *InputUnifi) discoverRemoteControllers(apiKey string) ([]*Controller, er
|
|||||||
// Set remote-specific defaults and ensure all boolean pointers are initialized
|
// Set remote-specific defaults and ensure all boolean pointers are initialized
|
||||||
t := true
|
t := true
|
||||||
f := false
|
f := false
|
||||||
|
|
||||||
if controller.VerifySSL == nil {
|
if controller.VerifySSL == nil {
|
||||||
controller.VerifySSL = &t // Remote API should verify SSL
|
controller.VerifySSL = &t // Remote API should verify SSL
|
||||||
}
|
}
|
||||||
@@ -106,39 +118,51 @@ func (u *InputUnifi) discoverRemoteControllers(apiKey string) ([]*Controller, er
|
|||||||
if controller.HashPII == nil {
|
if controller.HashPII == nil {
|
||||||
controller.HashPII = &f
|
controller.HashPII = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.DropPII == nil {
|
if controller.DropPII == nil {
|
||||||
controller.DropPII = &f
|
controller.DropPII = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.SaveSites == nil {
|
if controller.SaveSites == nil {
|
||||||
controller.SaveSites = &t
|
controller.SaveSites = &t
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.SaveDPI == nil {
|
if controller.SaveDPI == nil {
|
||||||
controller.SaveDPI = &f
|
controller.SaveDPI = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.SaveEvents == nil {
|
if controller.SaveEvents == nil {
|
||||||
controller.SaveEvents = &f
|
controller.SaveEvents = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.SaveAlarms == nil {
|
if controller.SaveAlarms == nil {
|
||||||
controller.SaveAlarms = &f
|
controller.SaveAlarms = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.SaveAnomal == nil {
|
if controller.SaveAnomal == nil {
|
||||||
controller.SaveAnomal = &f
|
controller.SaveAnomal = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.SaveIDs == nil {
|
if controller.SaveIDs == nil {
|
||||||
controller.SaveIDs = &f
|
controller.SaveIDs = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.SaveTraffic == nil {
|
if controller.SaveTraffic == nil {
|
||||||
controller.SaveTraffic = &f
|
controller.SaveTraffic = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.SaveRogue == nil {
|
if controller.SaveRogue == nil {
|
||||||
controller.SaveRogue = &f
|
controller.SaveRogue = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.SaveSyslog == nil {
|
if controller.SaveSyslog == nil {
|
||||||
controller.SaveSyslog = &f
|
controller.SaveSyslog = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.SaveProtectLogs == nil {
|
if controller.SaveProtectLogs == nil {
|
||||||
controller.SaveProtectLogs = &f
|
controller.SaveProtectLogs = &f
|
||||||
}
|
}
|
||||||
|
|
||||||
if controller.ProtectThumbnails == nil {
|
if controller.ProtectThumbnails == nil {
|
||||||
controller.ProtectThumbnails = &f
|
controller.ProtectThumbnails = &f
|
||||||
}
|
}
|
||||||
@@ -162,6 +186,7 @@ func (u *InputUnifi) discoverRemoteControllers(apiKey string) ([]*Controller, er
|
|||||||
controller.DefaultSiteNameOverride = consoleName
|
controller.DefaultSiteNameOverride = consoleName
|
||||||
// Keep the actual site name for API calls
|
// Keep the actual site name for API calls
|
||||||
controller.Sites = siteNames
|
controller.Sites = siteNames
|
||||||
|
|
||||||
u.LogDebugf("Using console name '%s' as default site name override for Cloud Gateway (API will use 'default')", consoleName)
|
u.LogDebugf("Using console name '%s' as default site name override for Cloud Gateway (API will use 'default')", consoleName)
|
||||||
} else if len(siteNames) > 0 {
|
} else if len(siteNames) > 0 {
|
||||||
controller.Sites = siteNames
|
controller.Sites = siteNames
|
||||||
|
|||||||
@@ -18,10 +18,12 @@ func controllerID(c *Controller) string {
|
|||||||
if c == nil {
|
if c == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
client := c.Unifi
|
client := c.Unifi
|
||||||
if client == nil {
|
if client == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return client.UUID
|
return client.UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,12 +34,15 @@ func updateWeb(c *Controller, metrics *Metrics) {
|
|||||||
log.Printf("[ERROR] updateWeb panic recovered: %v", r)
|
log.Printf("[ERROR] updateWeb panic recovered: %v", r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if c == nil || metrics == nil {
|
if c == nil || metrics == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Unifi == nil {
|
if c.Unifi == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
webserver.UpdateInput(&webserver.Input{
|
webserver.UpdateInput(&webserver.Input{
|
||||||
Name: PluginName, // Forgetting this leads to 3 hours of head scratching.
|
Name: PluginName, // Forgetting this leads to 3 hours of head scratching.
|
||||||
Sites: formatSites(c, metrics.Sites),
|
Sites: formatSites(c, metrics.Sites),
|
||||||
@@ -97,6 +102,7 @@ func formatSites(c *Controller, sites []*unifi.Site) (s webserver.Sites) {
|
|||||||
if site == nil {
|
if site == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
s = append(s, &webserver.Site{
|
s = append(s, &webserver.Site{
|
||||||
ID: site.ID,
|
ID: site.ID,
|
||||||
Name: site.Name,
|
Name: site.Name,
|
||||||
@@ -114,6 +120,7 @@ func formatClients(c *Controller, clients []*unifi.Client) (d webserver.Clients)
|
|||||||
if client == nil {
|
if client == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
clientType, deviceMAC := "unknown", "unknown"
|
clientType, deviceMAC := "unknown", "unknown"
|
||||||
if client.ApMac != "" {
|
if client.ApMac != "" {
|
||||||
clientType = "wireless"
|
clientType = "wireless"
|
||||||
@@ -157,6 +164,7 @@ func formatDevices(c *Controller, devices *unifi.Devices) (d webserver.Devices)
|
|||||||
if device == nil {
|
if device == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
d = append(d, &webserver.Device{
|
d = append(d, &webserver.Device{
|
||||||
Name: device.Name,
|
Name: device.Name,
|
||||||
SiteID: device.SiteID,
|
SiteID: device.SiteID,
|
||||||
@@ -177,6 +185,7 @@ func formatDevices(c *Controller, devices *unifi.Devices) (d webserver.Devices)
|
|||||||
if device == nil {
|
if device == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
d = append(d, &webserver.Device{
|
d = append(d, &webserver.Device{
|
||||||
Name: device.Name,
|
Name: device.Name,
|
||||||
SiteID: device.SiteID,
|
SiteID: device.SiteID,
|
||||||
@@ -197,6 +206,7 @@ func formatDevices(c *Controller, devices *unifi.Devices) (d webserver.Devices)
|
|||||||
if device == nil {
|
if device == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
d = append(d, &webserver.Device{
|
d = append(d, &webserver.Device{
|
||||||
Name: device.Name,
|
Name: device.Name,
|
||||||
SiteID: device.SiteID,
|
SiteID: device.SiteID,
|
||||||
@@ -217,6 +227,7 @@ func formatDevices(c *Controller, devices *unifi.Devices) (d webserver.Devices)
|
|||||||
if device == nil {
|
if device == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
d = append(d, &webserver.Device{
|
d = append(d, &webserver.Device{
|
||||||
Name: device.Name,
|
Name: device.Name,
|
||||||
SiteID: device.SiteID,
|
SiteID: device.SiteID,
|
||||||
|
|||||||
@@ -28,15 +28,15 @@ const (
|
|||||||
|
|
||||||
// Config is the plugin's input data.
|
// Config is the plugin's input data.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Disable bool `json:"disable" toml:"disable" xml:"disable" yaml:"disable"`
|
Disable bool `json:"disable" toml:"disable" xml:"disable" yaml:"disable"`
|
||||||
VerifySSL bool `json:"verify_ssl" toml:"verify_ssl" xml:"verify_ssl" yaml:"verify_ssl"`
|
VerifySSL bool `json:"verify_ssl" toml:"verify_ssl" xml:"verify_ssl" yaml:"verify_ssl"`
|
||||||
URL string `json:"url" toml:"url" xml:"url" yaml:"url"`
|
URL string `json:"url" toml:"url" xml:"url" yaml:"url"`
|
||||||
Username string `json:"user" toml:"user" xml:"user" yaml:"user"`
|
Username string `json:"user" toml:"user" xml:"user" yaml:"user"`
|
||||||
Password string `json:"pass" toml:"pass" xml:"pass" yaml:"pass"`
|
Password string `json:"pass" toml:"pass" xml:"pass" yaml:"pass"`
|
||||||
TenantID string `json:"tenant_id" toml:"tenant_id" xml:"tenant_id" yaml:"tenant_id"`
|
TenantID string `json:"tenant_id" toml:"tenant_id" xml:"tenant_id" yaml:"tenant_id"`
|
||||||
Interval cnfg.Duration `json:"interval" toml:"interval" xml:"interval" yaml:"interval"`
|
Interval cnfg.Duration `json:"interval" toml:"interval" xml:"interval" yaml:"interval"`
|
||||||
Timeout cnfg.Duration `json:"timeout" toml:"timeout" xml:"timeout" yaml:"timeout"`
|
Timeout cnfg.Duration `json:"timeout" toml:"timeout" xml:"timeout" yaml:"timeout"`
|
||||||
ExtraLabels map[string]string `json:"extra_labels" toml:"extra_labels" xml:"extra_labels" yaml:"extra_labels"`
|
ExtraLabels map[string]string `json:"extra_labels" toml:"extra_labels" xml:"extra_labels" yaml:"extra_labels"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loki is the main library struct. This satisfies the poller.Output interface.
|
// Loki is the main library struct. This satisfies the poller.Output interface.
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ func (r *Report) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s += fmt.Sprintf(", Dur: %v", time.Since(r.Start).Round(time.Millisecond))
|
s += fmt.Sprintf(", Dur: %v", time.Since(r.Start).Round(time.Millisecond))
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,12 @@ func (r *Report) ProtectLogEvent(event *unifi.ProtectLogEntry, logs *Logs) {
|
|||||||
|
|
||||||
// Marshal event to JSON for the log line (without thumbnail to keep it small)
|
// Marshal event to JSON for the log line (without thumbnail to keep it small)
|
||||||
event.ThumbnailBase64 = "" // Temporarily clear for marshaling
|
event.ThumbnailBase64 = "" // Temporarily clear for marshaling
|
||||||
|
|
||||||
msg, err := json.Marshal(event)
|
msg, err := json.Marshal(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg = []byte(event.Msg())
|
msg = []byte(event.Msg())
|
||||||
}
|
}
|
||||||
|
|
||||||
event.ThumbnailBase64 = thumbnailBase64 // Restore
|
event.ThumbnailBase64 = thumbnailBase64 // Restore
|
||||||
|
|
||||||
// Add event log line
|
// Add event log line
|
||||||
@@ -68,4 +70,3 @@ func (r *Report) ProtectLogEvent(event *unifi.ProtectLogEntry, logs *Logs) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
// exportFirewallPolicies emits per-rule and per-site aggregate firewall policy metrics.
|
// exportFirewallPolicies emits per-rule and per-site aggregate firewall policy metrics.
|
||||||
func (u *OtelOutput) exportFirewallPolicies(ctx context.Context, meter metric.Meter, m *poller.Metrics, r *Report) {
|
func (u *OtelOutput) exportFirewallPolicies(ctx context.Context, meter metric.Meter, m *poller.Metrics, r *Report) {
|
||||||
type siteKey struct{ site, source string }
|
type siteKey struct{ site, source string }
|
||||||
|
|
||||||
type siteStats struct {
|
type siteStats struct {
|
||||||
total int
|
total int
|
||||||
enabled int
|
enabled int
|
||||||
|
|||||||
@@ -65,9 +65,9 @@ type OtelUnifi struct {
|
|||||||
|
|
||||||
// OtelOutput is the working struct for this plugin.
|
// OtelOutput is the working struct for this plugin.
|
||||||
type OtelOutput struct {
|
type OtelOutput struct {
|
||||||
Collector poller.Collect
|
Collector poller.Collect
|
||||||
LastCheck time.Time
|
LastCheck time.Time
|
||||||
provider *sdkmetric.MeterProvider
|
provider *sdkmetric.MeterProvider
|
||||||
*OtelUnifi
|
*OtelUnifi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ func (u *OtelOutput) Run(c poller.Collect) error {
|
|||||||
|
|
||||||
// pollController runs the ticker loop, pushing metrics on each tick.
|
// pollController runs the ticker loop, pushing metrics on each tick.
|
||||||
func (u *OtelOutput) pollController() {
|
func (u *OtelOutput) pollController() {
|
||||||
interval := u.Interval.Duration.Round(time.Second)
|
interval := u.Interval.Round(time.Second)
|
||||||
ticker := time.NewTicker(interval)
|
ticker := time.NewTicker(interval)
|
||||||
|
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
@@ -290,7 +290,7 @@ func (u *OtelOutput) setConfigDefaults() {
|
|||||||
u.Interval = cnfg.Duration{Duration: minimumInterval}
|
u.Interval = cnfg.Duration{Duration: minimumInterval}
|
||||||
}
|
}
|
||||||
|
|
||||||
u.Interval = cnfg.Duration{Duration: u.Interval.Duration.Round(time.Second)}
|
u.Interval = cnfg.Duration{Duration: u.Interval.Round(time.Second)}
|
||||||
|
|
||||||
if u.Timeout.Duration == 0 {
|
if u.Timeout.Duration == 0 {
|
||||||
u.Timeout = cnfg.Duration{Duration: 10 * time.Second}
|
u.Timeout = cnfg.Duration{Duration: 10 * time.Second}
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ func (u *OtelOutput) exportUSW(ctx context.Context, meter metric.Meter, r *Repor
|
|||||||
u.recordGauge(ctx, meter, r, "unifi_device_usw_load_avg_1",
|
u.recordGauge(ctx, meter, r, "unifi_device_usw_load_avg_1",
|
||||||
"USW load average 1-minute", s.SysStats.Loadavg1.Val, attrs)
|
"USW load average 1-minute", s.SysStats.Loadavg1.Val, attrs)
|
||||||
u.recordGauge(ctx, meter, r, "unifi_device_usw_rx_bytes",
|
u.recordGauge(ctx, meter, r, "unifi_device_usw_rx_bytes",
|
||||||
"USW total receive bytes", s.Stat.Sw.RxBytes.Val, attrs)
|
"USW total receive bytes", s.Stat.RxBytes.Val, attrs)
|
||||||
u.recordGauge(ctx, meter, r, "unifi_device_usw_tx_bytes",
|
u.recordGauge(ctx, meter, r, "unifi_device_usw_tx_bytes",
|
||||||
"USW total transmit bytes", s.Stat.Sw.TxBytes.Val, attrs)
|
"USW total transmit bytes", s.Stat.TxBytes.Val, attrs)
|
||||||
|
|
||||||
if !u.DeadPorts {
|
if !u.DeadPorts {
|
||||||
for _, p := range s.PortTable {
|
for _, p := range s.PortTable {
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ func (u *UnifiPoller) HealthCheck() error {
|
|||||||
|
|
||||||
// Check if at least one output is enabled.
|
// Check if at least one output is enabled.
|
||||||
hasEnabledOutput := false
|
hasEnabledOutput := false
|
||||||
|
|
||||||
for _, output := range outputs {
|
for _, output := range outputs {
|
||||||
if output.Enabled() {
|
if output.Enabled() {
|
||||||
hasEnabledOutput = true
|
hasEnabledOutput = true
|
||||||
|
|||||||
@@ -6,22 +6,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type controller struct {
|
type controller struct {
|
||||||
Info *prometheus.Desc
|
Info *prometheus.Desc
|
||||||
UptimeSeconds *prometheus.Desc
|
UptimeSeconds *prometheus.Desc
|
||||||
UpdateAvailable *prometheus.Desc
|
UpdateAvailable *prometheus.Desc
|
||||||
UpdateDownloaded *prometheus.Desc
|
UpdateDownloaded *prometheus.Desc
|
||||||
AutobackupEnabled *prometheus.Desc
|
AutobackupEnabled *prometheus.Desc
|
||||||
WebRTCSupport *prometheus.Desc
|
WebRTCSupport *prometheus.Desc
|
||||||
IsCloudConsole *prometheus.Desc
|
IsCloudConsole *prometheus.Desc
|
||||||
DataRetentionDays *prometheus.Desc
|
DataRetentionDays *prometheus.Desc
|
||||||
DataRetention5minHours *prometheus.Desc
|
DataRetention5minHours *prometheus.Desc
|
||||||
DataRetentionHourlyHours *prometheus.Desc
|
DataRetentionHourlyHours *prometheus.Desc
|
||||||
DataRetentionDailyHours *prometheus.Desc
|
DataRetentionDailyHours *prometheus.Desc
|
||||||
DataRetentionMonthlyHours *prometheus.Desc
|
DataRetentionMonthlyHours *prometheus.Desc
|
||||||
UnsupportedDeviceCount *prometheus.Desc
|
UnsupportedDeviceCount *prometheus.Desc
|
||||||
InformPort *prometheus.Desc
|
InformPort *prometheus.Desc
|
||||||
HTTPSPort *prometheus.Desc
|
HTTPSPort *prometheus.Desc
|
||||||
PortalHTTPPort *prometheus.Desc
|
PortalHTTPPort *prometheus.Desc
|
||||||
}
|
}
|
||||||
|
|
||||||
func descController(ns string) *controller {
|
func descController(ns string) *controller {
|
||||||
@@ -31,22 +31,22 @@ func descController(ns string) *controller {
|
|||||||
nd := prometheus.NewDesc
|
nd := prometheus.NewDesc
|
||||||
|
|
||||||
return &controller{
|
return &controller{
|
||||||
Info: nd(ns+"controller_info", "Controller information (always 1)", infoLabels, nil),
|
Info: nd(ns+"controller_info", "Controller information (always 1)", infoLabels, nil),
|
||||||
UptimeSeconds: nd(ns+"controller_uptime_seconds", "Controller uptime in seconds", labels, nil),
|
UptimeSeconds: nd(ns+"controller_uptime_seconds", "Controller uptime in seconds", labels, nil),
|
||||||
UpdateAvailable: nd(ns+"controller_update_available", "Update available (1/0)", labels, nil),
|
UpdateAvailable: nd(ns+"controller_update_available", "Update available (1/0)", labels, nil),
|
||||||
UpdateDownloaded: nd(ns+"controller_update_downloaded", "Update downloaded (1/0)", labels, nil),
|
UpdateDownloaded: nd(ns+"controller_update_downloaded", "Update downloaded (1/0)", labels, nil),
|
||||||
AutobackupEnabled: nd(ns+"controller_autobackup_enabled", "Auto backup enabled (1/0)", labels, nil),
|
AutobackupEnabled: nd(ns+"controller_autobackup_enabled", "Auto backup enabled (1/0)", labels, nil),
|
||||||
WebRTCSupport: nd(ns+"controller_webrtc_support", "WebRTC supported (1/0)", labels, nil),
|
WebRTCSupport: nd(ns+"controller_webrtc_support", "WebRTC supported (1/0)", labels, nil),
|
||||||
IsCloudConsole: nd(ns+"controller_is_cloud_console", "Is cloud console (1/0)", labels, nil),
|
IsCloudConsole: nd(ns+"controller_is_cloud_console", "Is cloud console (1/0)", labels, nil),
|
||||||
DataRetentionDays: nd(ns+"controller_data_retention_days", "Data retention in days", labels, nil),
|
DataRetentionDays: nd(ns+"controller_data_retention_days", "Data retention in days", labels, nil),
|
||||||
DataRetention5minHours: nd(ns+"controller_data_retention_5min_hours", "5-minute scale retention hours", labels, nil),
|
DataRetention5minHours: nd(ns+"controller_data_retention_5min_hours", "5-minute scale retention hours", labels, nil),
|
||||||
DataRetentionHourlyHours: nd(ns+"controller_data_retention_hourly_hours", "Hourly scale retention hours", labels, nil),
|
DataRetentionHourlyHours: nd(ns+"controller_data_retention_hourly_hours", "Hourly scale retention hours", labels, nil),
|
||||||
DataRetentionDailyHours: nd(ns+"controller_data_retention_daily_hours", "Daily scale retention hours", labels, nil),
|
DataRetentionDailyHours: nd(ns+"controller_data_retention_daily_hours", "Daily scale retention hours", labels, nil),
|
||||||
DataRetentionMonthlyHours: nd(ns+"controller_data_retention_monthly_hours", "Monthly scale retention hours", labels, nil),
|
DataRetentionMonthlyHours: nd(ns+"controller_data_retention_monthly_hours", "Monthly scale retention hours", labels, nil),
|
||||||
UnsupportedDeviceCount: nd(ns+"controller_unsupported_device_count", "Number of unsupported devices", labels, nil),
|
UnsupportedDeviceCount: nd(ns+"controller_unsupported_device_count", "Number of unsupported devices", labels, nil),
|
||||||
InformPort: nd(ns+"controller_inform_port", "Inform port number", labels, nil),
|
InformPort: nd(ns+"controller_inform_port", "Inform port number", labels, nil),
|
||||||
HTTPSPort: nd(ns+"controller_https_port", "HTTPS port number", labels, nil),
|
HTTPSPort: nd(ns+"controller_https_port", "HTTPS port number", labels, nil),
|
||||||
PortalHTTPPort: nd(ns+"controller_portal_http_port", "Portal HTTP port number", labels, nil),
|
PortalHTTPPort: nd(ns+"controller_portal_http_port", "Portal HTTP port number", labels, nil),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,9 +55,11 @@ func (u *promUnifi) exportSysinfo(r report, s *unifi.Sysinfo) {
|
|||||||
if hostname == "" {
|
if hostname == "" {
|
||||||
hostname = s.Name
|
hostname = s.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
if hostname == "" {
|
if hostname == "" {
|
||||||
hostname = s.SiteName // fallback when API omits both (e.g. remote/cloud)
|
hostname = s.SiteName // fallback when API omits both (e.g. remote/cloud)
|
||||||
}
|
}
|
||||||
|
|
||||||
labels := []string{hostname, s.SiteName, s.SourceName}
|
labels := []string{hostname, s.SiteName, s.SourceName}
|
||||||
infoLabels := []string{s.Version, s.Build, s.DeviceType, s.ConsoleVer, hostname, s.SiteName, s.SourceName}
|
infoLabels := []string{s.Version, s.Build, s.DeviceType, s.ConsoleVer, hostname, s.SiteName, s.SourceName}
|
||||||
|
|
||||||
@@ -65,18 +67,22 @@ func (u *promUnifi) exportSysinfo(r report, s *unifi.Sysinfo) {
|
|||||||
if s.UpdateAvail {
|
if s.UpdateAvail {
|
||||||
updateAvail = 1
|
updateAvail = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDown := 0
|
updateDown := 0
|
||||||
if s.UpdateDown {
|
if s.UpdateDown {
|
||||||
updateDown = 1
|
updateDown = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
autobackup := 0
|
autobackup := 0
|
||||||
if s.Autobackup {
|
if s.Autobackup {
|
||||||
autobackup = 1
|
autobackup = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
webrtc := 0
|
webrtc := 0
|
||||||
if s.HasWebRTC {
|
if s.HasWebRTC {
|
||||||
webrtc = 1
|
webrtc = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
cloud := 0
|
cloud := 0
|
||||||
if s.IsCloud {
|
if s.IsCloud {
|
||||||
cloud = 1
|
cloud = 1
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ func (u *promUnifi) exportFirewallPolicies(r report, policies []*unifi.FirewallP
|
|||||||
|
|
||||||
// Per-site aggregate counters, keyed by "siteName|source"
|
// Per-site aggregate counters, keyed by "siteName|source"
|
||||||
type siteKey struct{ site, source string }
|
type siteKey struct{ site, source string }
|
||||||
|
|
||||||
type siteStats struct {
|
type siteStats struct {
|
||||||
total int
|
total int
|
||||||
enabled int
|
enabled int
|
||||||
|
|||||||
@@ -59,18 +59,18 @@ type pdu struct {
|
|||||||
OutletPowerFactor *prometheus.Desc
|
OutletPowerFactor *prometheus.Desc
|
||||||
OutletVoltage *prometheus.Desc
|
OutletVoltage *prometheus.Desc
|
||||||
// UPS battery health (vbms_table)
|
// UPS battery health (vbms_table)
|
||||||
BatteryLevelPercent *prometheus.Desc
|
BatteryLevelPercent *prometheus.Desc
|
||||||
BatteryTimeRemaining *prometheus.Desc
|
BatteryTimeRemaining *prometheus.Desc
|
||||||
BatteryCharging *prometheus.Desc
|
BatteryCharging *prometheus.Desc
|
||||||
BatteryMode *prometheus.Desc
|
BatteryMode *prometheus.Desc
|
||||||
BatteriesAvailable *prometheus.Desc
|
BatteriesAvailable *prometheus.Desc
|
||||||
BatteriesReady *prometheus.Desc
|
BatteriesReady *prometheus.Desc
|
||||||
PowerBudgetWatts *prometheus.Desc
|
PowerBudgetWatts *prometheus.Desc
|
||||||
PowerOutputWatts *prometheus.Desc
|
PowerOutputWatts *prometheus.Desc
|
||||||
PowerFactor *prometheus.Desc
|
PowerFactor *prometheus.Desc
|
||||||
OutputVoltage *prometheus.Desc
|
OutputVoltage *prometheus.Desc
|
||||||
OutputCurrentAmps *prometheus.Desc
|
OutputCurrentAmps *prometheus.Desc
|
||||||
LoadPercent *prometheus.Desc
|
LoadPercent *prometheus.Desc
|
||||||
BMSAnomalyCount *prometheus.Desc
|
BMSAnomalyCount *prometheus.Desc
|
||||||
PowerCycleOnRecoveryEnabled *prometheus.Desc
|
PowerCycleOnRecoveryEnabled *prometheus.Desc
|
||||||
}
|
}
|
||||||
@@ -182,6 +182,7 @@ func (u *promUnifi) exportPDU(r report, d *unifi.PDU) {
|
|||||||
if d.VBMSTable != nil {
|
if d.VBMSTable != nil {
|
||||||
u.exportPDUVBMS(r, d, append([]string{d.SiteName, d.Name, d.Mac, d.SourceName}, tag))
|
u.exportPDUVBMS(r, d, append([]string{d.SiteName, d.Name, d.Mac, d.SourceName}, tag))
|
||||||
}
|
}
|
||||||
|
|
||||||
u.exportBYTstats(r, labels, d.TxBytes, d.RxBytes)
|
u.exportBYTstats(r, labels, d.TxBytes, d.RxBytes)
|
||||||
u.exportSYSstats(r, labels, d.SysStats, d.SystemStats)
|
u.exportSYSstats(r, labels, d.SysStats, d.SystemStats)
|
||||||
u.exportSTAcount(r, labels, d.UserNumSta, d.GuestNumSta)
|
u.exportSTAcount(r, labels, d.UserNumSta, d.GuestNumSta)
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ func (r *Report) export(m *metric, v float64) prometheus.Metric {
|
|||||||
for _, label := range m.Labels {
|
for _, label := range m.Labels {
|
||||||
bytes += len(label) + 3 // label value + quotes and comma/equals overhead
|
bytes += len(label) + 3 // label value + quotes and comma/equals overhead
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes += 20 // approximate size for value and timestamp
|
bytes += 20 // approximate size for value and timestamp
|
||||||
|
|
||||||
r.Bytes += bytes
|
r.Bytes += bytes
|
||||||
|
|||||||
Reference in New Issue
Block a user