237 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			237 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Go
		
	
	
	
| package datadogunifi
 | |
| 
 | |
| import (
 | |
| 	"github.com/unpoller/unifi"
 | |
| )
 | |
| 
 | |
| // uapT is used as a name for printed/logged counters.
 | |
| const uapT = item("UAP")
 | |
| 
 | |
| // batchRogueAP generates metric points for neighboring access points.
 | |
| func (u *DatadogUnifi) batchRogueAP(r report, s *unifi.RogueAP) {
 | |
| 	if s.Age.Val == 0 {
 | |
| 		return // only keep metrics for things that are recent.
 | |
| 	}
 | |
| 
 | |
| 	tags := cleanTags(map[string]string{
 | |
| 		"security":   s.Security,
 | |
| 		"oui":        s.Oui,
 | |
| 		"band":       s.Band,
 | |
| 		"mac":        s.Bssid,
 | |
| 		"ap_mac":     s.ApMac,
 | |
| 		"radio":      s.Radio,
 | |
| 		"radio_name": s.RadioName,
 | |
| 		"site_name":  s.SiteName,
 | |
| 		"name":       s.Essid,
 | |
| 		"source":     s.SourceName,
 | |
| 	})
 | |
| 
 | |
| 	data := map[string]float64{
 | |
| 		"age":         s.Age.Val,
 | |
| 		"bw":          s.Bw.Val,
 | |
| 		"center_freq": s.CenterFreq.Val,
 | |
| 		"channel":     float64(s.Channel),
 | |
| 		"freq":        s.Freq.Val,
 | |
| 		"noise":       s.Noise.Val,
 | |
| 		"rssi":        s.Rssi.Val,
 | |
| 		"rssi_age":    s.RssiAge.Val,
 | |
| 		"signal":      s.Signal.Val,
 | |
| 	}
 | |
| 
 | |
| 	metricName := metricNamespace("uap_rogue")
 | |
| 
 | |
| 	reportGaugeForFloat64Map(r, metricName, data, tags)
 | |
| }
 | |
| 
 | |
| // batchUAP generates Wireless-Access-Point datapoints for Datadog.
 | |
| // These points can be passed directly to datadog.
 | |
| func (u *DatadogUnifi) batchUAP(r report, s *unifi.UAP) {
 | |
| 	if !s.Adopted.Val || s.Locating.Val {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	tags := cleanTags(map[string]string{
 | |
| 		"mac":       s.Mac,
 | |
| 		"site_name": s.SiteName,
 | |
| 		"source":    s.SourceName,
 | |
| 		"name":      s.Name,
 | |
| 		"version":   s.Version,
 | |
| 		"model":     s.Model,
 | |
| 		"serial":    s.Serial,
 | |
| 		"type":      s.Type,
 | |
| 		"ip":        s.IP,
 | |
| 	})
 | |
| 	data := CombineFloat64(u.processUAPstats(s.Stat.Ap), u.batchSysStats(s.SysStats, s.SystemStats))
 | |
| 	data["bytes"] = s.Bytes.Val
 | |
| 	data["last_seen"] = s.LastSeen.Val
 | |
| 	data["rx_bytes"] = s.RxBytes.Val
 | |
| 	data["tx_bytes"] = s.TxBytes.Val
 | |
| 	data["uptime"] = s.Uptime.Val
 | |
| 	data["user_num_sta"] = s.UserNumSta.Val
 | |
| 	data["guest_num_sta"] = s.GuestNumSta.Val
 | |
| 	data["num_sta"] = s.NumSta.Val
 | |
| 	data["upgradeable"] = boolToFloat64(s.Upgradable.Val)
 | |
| 
 | |
| 	r.addCount(uapT)
 | |
| 
 | |
| 	metricName := metricNamespace("uap")
 | |
| 
 | |
| 	reportGaugeForFloat64Map(r, metricName, data, tags)
 | |
| 
 | |
| 	u.processVAPTable(r, tags, s.VapTable)
 | |
| 	u.batchPortTable(r, tags, s.PortTable)
 | |
| }
 | |
| 
 | |
| func (u *DatadogUnifi) processUAPstats(ap *unifi.Ap) map[string]float64 {
 | |
| 	if ap == nil {
 | |
| 		return map[string]float64{}
 | |
| 	}
 | |
| 
 | |
| 	// Accumulative Statistics.
 | |
| 	return map[string]float64{
 | |
| 		"stat_user-rx_packets":  ap.UserRxPackets.Val,
 | |
| 		"stat_guest-rx_packets": ap.GuestRxPackets.Val,
 | |
| 		"stat_rx_packets":       ap.RxPackets.Val,
 | |
| 		"stat_user-rx_bytes":    ap.UserRxBytes.Val,
 | |
| 		"stat_guest-rx_bytes":   ap.GuestRxBytes.Val,
 | |
| 		"stat_rx_bytes":         ap.RxBytes.Val,
 | |
| 		"stat_user-rx_errors":   ap.UserRxErrors.Val,
 | |
| 		"stat_guest-rx_errors":  ap.GuestRxErrors.Val,
 | |
| 		"stat_rx_errors":        ap.RxErrors.Val,
 | |
| 		"stat_user-rx_dropped":  ap.UserRxDropped.Val,
 | |
| 		"stat_guest-rx_dropped": ap.GuestRxDropped.Val,
 | |
| 		"stat_rx_dropped":       ap.RxDropped.Val,
 | |
| 		"stat_user-rx_crypts":   ap.UserRxCrypts.Val,
 | |
| 		"stat_guest-rx_crypts":  ap.GuestRxCrypts.Val,
 | |
| 		"stat_rx_crypts":        ap.RxCrypts.Val,
 | |
| 		"stat_user-rx_frags":    ap.UserRxFrags.Val,
 | |
| 		"stat_guest-rx_frags":   ap.GuestRxFrags.Val,
 | |
| 		"stat_rx_frags":         ap.RxFrags.Val,
 | |
| 		"stat_user-tx_packets":  ap.UserTxPackets.Val,
 | |
| 		"stat_guest-tx_packets": ap.GuestTxPackets.Val,
 | |
| 		"stat_tx_packets":       ap.TxPackets.Val,
 | |
| 		"stat_user-tx_bytes":    ap.UserTxBytes.Val,
 | |
| 		"stat_guest-tx_bytes":   ap.GuestTxBytes.Val,
 | |
| 		"stat_tx_bytes":         ap.TxBytes.Val,
 | |
| 		"stat_user-tx_errors":   ap.UserTxErrors.Val,
 | |
| 		"stat_guest-tx_errors":  ap.GuestTxErrors.Val,
 | |
| 		"stat_tx_errors":        ap.TxErrors.Val,
 | |
| 		"stat_user-tx_dropped":  ap.UserTxDropped.Val,
 | |
| 		"stat_guest-tx_dropped": ap.GuestTxDropped.Val,
 | |
| 		"stat_tx_dropped":       ap.TxDropped.Val,
 | |
| 		"stat_user-tx_retries":  ap.UserTxRetries.Val,
 | |
| 		"stat_guest-tx_retries": ap.GuestTxRetries.Val,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // processVAPTable creates points for Wifi Radios. This works with several types of UAP-capable devices.
 | |
| func (u *DatadogUnifi) processVAPTable(r report, t map[string]string, vt unifi.VapTable) { // nolint: funlen
 | |
| 	for _, s := range vt {
 | |
| 		tags := map[string]string{
 | |
| 			"device_name": t["name"],
 | |
| 			"site_name":   t["site_name"],
 | |
| 			"source":      t["source"],
 | |
| 			"ap_mac":      s.ApMac,
 | |
| 			"bssid":       s.Bssid,
 | |
| 			"id":          s.ID,
 | |
| 			"name":        s.Name,
 | |
| 			"radio_name":  s.RadioName,
 | |
| 			"radio":       s.Radio,
 | |
| 			"essid":       s.Essid,
 | |
| 			"site_id":     s.SiteID,
 | |
| 			"usage":       s.Usage,
 | |
| 			"state":       s.State,
 | |
| 			"is_guest":    s.IsGuest.Txt,
 | |
| 		}
 | |
| 		data := map[string]float64{
 | |
| 			"ccq":                       float64(s.Ccq),
 | |
| 			"mac_filter_rejections":     float64(s.MacFilterRejections),
 | |
| 			"num_satisfaction_sta":      s.NumSatisfactionSta.Val,
 | |
| 			"avg_client_signal":         s.AvgClientSignal.Val,
 | |
| 			"satisfaction":              s.Satisfaction.Val,
 | |
| 			"satisfaction_now":          s.SatisfactionNow.Val,
 | |
| 			"num_sta":                   float64(s.NumSta),
 | |
| 			"channel":                   s.Channel.Val,
 | |
| 			"rx_bytes":                  s.RxBytes.Val,
 | |
| 			"rx_crypts":                 s.RxCrypts.Val,
 | |
| 			"rx_dropped":                s.RxDropped.Val,
 | |
| 			"rx_errors":                 s.RxErrors.Val,
 | |
| 			"rx_frags":                  s.RxFrags.Val,
 | |
| 			"rx_nwids":                  s.RxNwids.Val,
 | |
| 			"rx_packets":                s.RxPackets.Val,
 | |
| 			"tx_bytes":                  s.TxBytes.Val,
 | |
| 			"tx_dropped":                s.TxDropped.Val,
 | |
| 			"tx_errors":                 s.TxErrors.Val,
 | |
| 			"tx_packets":                s.TxPackets.Val,
 | |
| 			"tx_power":                  s.TxPower.Val,
 | |
| 			"tx_retries":                s.TxRetries.Val,
 | |
| 			"tx_combined_retries":       s.TxCombinedRetries.Val,
 | |
| 			"tx_data_mpdu_bytes":        s.TxDataMpduBytes.Val,
 | |
| 			"tx_rts_retries":            s.TxRtsRetries.Val,
 | |
| 			"tx_success":                s.TxSuccess.Val,
 | |
| 			"tx_total":                  s.TxTotal.Val,
 | |
| 			"tx_tcp_goodbytes":          s.TxTCPStats.Goodbytes.Val,
 | |
| 			"tx_tcp_lat_avg":            s.TxTCPStats.LatAvg.Val,
 | |
| 			"tx_tcp_lat_max":            s.TxTCPStats.LatMax.Val,
 | |
| 			"tx_tcp_lat_min":            s.TxTCPStats.LatMin.Val,
 | |
| 			"rx_tcp_goodbytes":          s.RxTCPStats.Goodbytes.Val,
 | |
| 			"rx_tcp_lat_avg":            s.RxTCPStats.LatAvg.Val,
 | |
| 			"rx_tcp_lat_max":            s.RxTCPStats.LatMax.Val,
 | |
| 			"rx_tcp_lat_min":            s.RxTCPStats.LatMin.Val,
 | |
| 			"wifi_tx_latency_mov_avg":   s.WifiTxLatencyMov.Avg.Val,
 | |
| 			"wifi_tx_latency_mov_max":   s.WifiTxLatencyMov.Max.Val,
 | |
| 			"wifi_tx_latency_mov_min":   s.WifiTxLatencyMov.Min.Val,
 | |
| 			"wifi_tx_latency_mov_total": s.WifiTxLatencyMov.Total.Val,
 | |
| 			"wifi_tx_latency_mov_cuont": s.WifiTxLatencyMov.TotalCount.Val,
 | |
| 		}
 | |
| 
 | |
| 		metricName := metricNamespace("uap_vaps")
 | |
| 
 | |
| 		reportGaugeForFloat64Map(r, metricName, data, tags)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (u *DatadogUnifi) processRadTable(r report, t map[string]string, rt unifi.RadioTable, rts unifi.RadioTableStats) {
 | |
| 	for _, p := range rt {
 | |
| 		tags := map[string]string{
 | |
| 			"device_name": t["name"],
 | |
| 			"site_name":   t["site_name"],
 | |
| 			"source":      t["source"],
 | |
| 			"channel":     p.Channel.Txt,
 | |
| 			"radio":       p.Radio,
 | |
| 			"ht":          p.Ht.Txt,
 | |
| 		}
 | |
| 		data := map[string]float64{
 | |
| 			"current_antenna_gain": p.CurrentAntennaGain.Val,
 | |
| 			"max_txpower":          p.MaxTxpower.Val,
 | |
| 			"min_txpower":          p.MinTxpower.Val,
 | |
| 			"nss":                  p.Nss.Val,
 | |
| 			"radio_caps":           p.RadioCaps.Val,
 | |
| 		}
 | |
| 
 | |
| 		for _, t := range rts {
 | |
| 			if t.Name == p.Name {
 | |
| 				data["ast_be_xmit"] = t.AstBeXmit.Val
 | |
| 				data["channel"] = t.Channel.Val
 | |
| 				data["cu_self_rx"] = t.CuSelfRx.Val
 | |
| 				data["cu_self_tx"] = t.CuSelfTx.Val
 | |
| 				data["cu_total"] = t.CuTotal.Val
 | |
| 				data["ext_channel"] = t.Extchannel.Val
 | |
| 				data["gain"] = t.Gain.Val
 | |
| 				data["guest_num_sta"] = t.GuestNumSta.Val
 | |
| 				data["num_sta"] = t.NumSta.Val
 | |
| 				data["tx_packets"] = t.TxPackets.Val
 | |
| 				data["tx_power"] = t.TxPower.Val
 | |
| 				data["tx_retries"] = t.TxRetries.Val
 | |
| 				data["user_num_sta"] = t.UserNumSta.Val
 | |
| 
 | |
| 				break
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		metricName := metricNamespace("uap_radios")
 | |
| 
 | |
| 		reportGaugeForFloat64Map(r, metricName, data, tags)
 | |
| 	}
 | |
| }
 |