tighter for loops

This commit is contained in:
davidnewhall2 2019-11-29 22:35:42 -08:00
parent a58c1210d0
commit 1d93777a0d
6 changed files with 46 additions and 90 deletions

View File

@ -61,7 +61,7 @@ func (u *UnifiPoller) LogExportReport(report *promunifi.Report) {
u.Logf("UniFi Measurements Exported. Site: %d, Client: %d, "+
"UAP: %d, USG/UDM: %d, USW: %d%s, Descs: %d, "+
"Metrics: %d, Errs: %d, 0s: %d, Reqs/Total: %v/%v",
"Metrics: %d, Errs: %d, 0s: %d, Reqs/Total: %v / %v",
len(m.Sites), len(m.Clients), len(m.UAPs), len(m.UDMs)+len(m.USGs), len(m.USWs),
idsMsg, report.Descs, report.Total, report.Errors, report.Zeros,
report.Fetch.Round(time.Millisecond/oneDecimalPoint),

View File

@ -88,9 +88,8 @@ func NewUnifiCollector(opts UnifiCollectorCnfg) prometheus.Collector {
// Describe satisfies the prometheus Collector. This returns all of the
// metric descriptions that this packages produces.
func (u *unifiCollector) Describe(ch chan<- *prometheus.Desc) {
describe := func(from interface{}) {
v := reflect.Indirect(reflect.ValueOf(from))
for _, f := range []interface{}{u.Client, u.Device, u.UAP, u.USG, u.USW, u.Site} {
v := reflect.Indirect(reflect.ValueOf(f))
// Loop each struct member and send it to the provided channel.
for i := 0; i < v.NumField(); i++ {
desc, ok := v.Field(i).Interface().(*prometheus.Desc)
@ -99,44 +98,32 @@ func (u *unifiCollector) Describe(ch chan<- *prometheus.Desc) {
}
}
}
describe(u.Client)
describe(u.Device)
describe(u.UAP)
describe(u.USG)
describe(u.USW)
describe(u.Site)
}
// Collect satisfies the prometheus Collector. This runs the input method to get
// the current metrics (from another package) then exports them for prometheus.
func (u *unifiCollector) Collect(ch chan<- prometheus.Metric) {
r := &Report{
cf: u.Config,
Start: time.Now(),
ch: make(chan []*metricExports, buffer),
}
defer func() {
r.wg.Wait()
close(r.ch)
}()
var err error
r := &Report{cf: u.Config, ch: make(chan []*metricExports, buffer)}
defer r.finish()
r.Start = time.Now()
if r.Metrics, err = r.cf.CollectFn(); err != nil {
r.error(ch, prometheus.NewInvalidDesc(fmt.Errorf("metric fetch failed")), err)
return
}
r.Fetch = time.Since(r.Start)
if r.Metrics.Devices == nil {
r.Metrics.Devices = &unifi.Devices{}
}
// Pass Report interface into our collecting and reporting methods.
go u.exportMetrics(r, ch)
// in loops.go.
u.loopClients(r)
u.loopSites(r)
u.loopUAPs(r)
u.loopUSWs(r)
u.loopUSGs(r)
u.loopUDMs(r)
for _, f := range []func(report){u.loopClients, u.loopSites, u.loopUAPs, u.loopUSWs, u.loopUSGs, u.loopUDMs} {
r.add()
go f(r)
}
}
// This is closely tied to the method above with a sync.WaitGroup.

View File

@ -5,85 +5,43 @@ package promunifi
// they usually all change at once since they're pretty much the same code.
func (u *unifiCollector) loopSites(r report) {
m := r.metrics()
if m == nil || len(m.Sites) < 1 {
return
defer r.done()
for _, s := range r.metrics().Sites {
u.exportSite(r, s)
}
r.add()
go func() {
defer r.done()
for _, s := range m.Sites {
u.exportSite(r, s)
}
}()
}
func (u *unifiCollector) loopUAPs(r report) {
m := r.metrics()
if m == nil || m.Devices == nil || len(m.Devices.UAPs) < 1 {
return
defer r.done()
for _, d := range r.metrics().UAPs {
u.exportUAP(r, d)
}
r.add()
go func() {
defer r.done()
for _, d := range m.Devices.UAPs {
u.exportUAP(r, d)
}
}()
}
func (u *unifiCollector) loopUDMs(r report) {
m := r.metrics()
if m == nil || m.Devices == nil || len(m.Devices.UDMs) < 1 {
return
defer r.done()
for _, d := range r.metrics().UDMs {
u.exportUDM(r, d)
}
r.add()
go func() {
defer r.done()
for _, d := range m.Devices.UDMs {
u.exportUDM(r, d)
}
}()
}
func (u *unifiCollector) loopUSGs(r report) {
m := r.metrics()
if m == nil || m.Devices == nil || len(m.Devices.USGs) < 1 {
return
defer r.done()
for _, d := range r.metrics().USGs {
u.exportUSG(r, d)
}
r.add()
go func() {
defer r.done()
for _, d := range m.Devices.USGs {
u.exportUSG(r, d)
}
}()
}
func (u *unifiCollector) loopUSWs(r report) {
m := r.metrics()
if m == nil || m.Devices == nil || len(m.Devices.USWs) < 1 {
return
defer r.done()
for _, d := range r.metrics().USWs {
u.exportUSW(r, d)
}
r.add()
go func() {
defer r.done()
for _, d := range m.Devices.USWs {
u.exportUSW(r, d)
}
}()
}
func (u *unifiCollector) loopClients(r report) {
m := r.metrics()
if m == nil || len(m.Clients) < 1 {
return
defer r.done()
for _, c := range r.metrics().Clients {
u.exportClient(r, c)
}
r.add()
go func() {
defer r.done()
for _, c := range m.Clients {
u.exportClient(r, c)
}
}()
}

View File

@ -6,6 +6,7 @@ import (
"github.com/davidnewhall/unifi-poller/metrics"
"github.com/prometheus/client_golang/prometheus"
"golift.io/unifi"
)
// This file contains the report interface.
@ -40,6 +41,9 @@ func (r *Report) send(m []*metricExports) {
}
func (r *Report) metrics() *metrics.Metrics {
if r.Metrics == nil {
return &metrics.Metrics{Devices: &unifi.Devices{}}
}
return r.Metrics
}
@ -51,7 +55,7 @@ func (r *Report) report(descs map[*prometheus.Desc]bool) {
if r.cf.LoggingFn == nil {
return
}
r.Descs, r.Elapsed = len(descs), time.Since(r.Start)
r.Descs = len(descs)
r.cf.LoggingFn(r)
}
@ -69,3 +73,10 @@ func (r *Report) error(ch chan<- prometheus.Metric, d *prometheus.Desc, v interf
ch <- prometheus.NewInvalidMetric(d, fmt.Errorf("error: %v", v))
}
}
// finish is not part of the interface.
func (r *Report) finish() {
r.wg.Wait()
r.Elapsed = time.Since(r.Start)
close(r.ch)
}

View File

@ -97,7 +97,7 @@ func (u *unifiCollector) exportUSGstats(r report, labels []string, gw *unifi.Gw,
labelLan := []string{"lan", labels[6], labels[7]}
labelWan := []string{"all", labels[6], labels[7]}
r.send([]*metricExports{
/* // Combined Port Stats
/* // Combined Port Stats - not really needed. sum() the others instead.
{u.USG.WanRxPackets, prometheus.CounterValue, gw.WanRxPackets, labelWan},
{u.USG.WanRxBytes, prometheus.CounterValue, gw.WanRxBytes, labelWan},
{u.USG.WanRxDropped, prometheus.CounterValue, gw.WanRxDropped, labelWan},

View File

@ -99,7 +99,7 @@ func (u *unifiCollector) exportUSW(r report, d *unifi.USW) {
r.send([]*metricExports{{u.Device.FanLevel, prometheus.GaugeValue, d.FanLevel, labels}})
}
// Switch data.
// Switch System Data.
r.send([]*metricExports{
{u.Device.Uptime, prometheus.GaugeValue, d.Uptime, labels},
{u.Device.TotalMaxPower, prometheus.GaugeValue, d.TotalMaxPower, labels},