diff --git a/integrations/influxunifi/influxdb.go b/integrations/influxunifi/influxdb.go index a2d127ba..67228f7d 100644 --- a/integrations/influxunifi/influxdb.go +++ b/integrations/influxunifi/influxdb.go @@ -179,7 +179,7 @@ func (u *InfluxUnifi) ReportMetrics(m *poller.Metrics, e *poller.Events) (*Repor Events: e, ch: make(chan *metric), Start: time.Now(), - Counts: make(map[item]int), + Counts: &Counts{Val: make(map[item]int)}, } defer close(r.ch) diff --git a/integrations/influxunifi/report.go b/integrations/influxunifi/report.go index d5eeb40f..e485c769 100644 --- a/integrations/influxunifi/report.go +++ b/integrations/influxunifi/report.go @@ -14,7 +14,7 @@ type Report struct { Metrics *poller.Metrics Events *poller.Events Errors []error - Counts map[item]int + Counts *Counts Start time.Time Elapsed time.Duration ch chan *metric @@ -22,6 +22,12 @@ type Report struct { bp influx.BatchPoints } +// Counts holds counters and has a lock to deal with routines. +type Counts struct { + Val map[item]int + sync.RWMutex +} + // report is an internal interface that can be mocked and overridden for tests. type report interface { add() @@ -60,12 +66,15 @@ func (r *Report) send(m *metric) { type item string func (r *Report) addCount(name item, counts ...int) { + r.Counts.Lock() + defer r.Counts.Unlock() + if len(counts) == 0 { - r.Counts[name]++ + r.Counts.Val[name]++ } for _, c := range counts { - r.Counts[name] += c + r.Counts.Val[name] += c } } @@ -88,12 +97,17 @@ func (r *Report) batch(m *metric, p *influx.Point) { } func (r *Report) String() string { + r.Counts.RLock() + defer r.Counts.RUnlock() + + m, c := r.Metrics, r.Counts.Val + return fmt.Sprintf("Site: %d, Client: %d, "+ "%s: %d, %s/%s: %d, %s: %d, %s/%s/%s/%s: %d/%d/%d/%d, "+ "DPI Site/Client: %d/%d, %s: %d, %s: %d, Err: %d, Dur: %v", - len(r.Metrics.Sites), len(r.Metrics.Clients), - uapT, r.Counts[uapT], udmT, usgT, r.Counts[udmT]+r.Counts[usgT], uswT, r.Counts[uswT], - idsT, eventT, alarmT, anomalyT, r.Counts[idsT], r.Counts[eventT], r.Counts[alarmT], r.Counts[anomalyT], - len(r.Metrics.SitesDPI), len(r.Metrics.ClientsDPI), pointT, r.Counts[pointT], - fieldT, r.Counts[fieldT], len(r.Errors), r.Elapsed.Round(time.Millisecond)) + len(m.Sites), len(m.Clients), + uapT, c[uapT], udmT, usgT, c[udmT]+c[usgT], uswT, c[uswT], + idsT, eventT, alarmT, anomalyT, c[idsT], c[eventT], c[alarmT], c[anomalyT], + len(m.SitesDPI), len(m.ClientsDPI), pointT, c[pointT], fieldT, c[fieldT], + len(r.Errors), r.Elapsed.Round(time.Millisecond)) }