github.com/simpleiot/simpleiot@v0.18.3/client/metric.go (about) 1 package client 2 3 import ( 4 "sync" 5 "time" 6 7 "github.com/nats-io/nats.go" 8 "github.com/simpleiot/simpleiot/data" 9 ) 10 11 // Metric is a type that can be used to track metrics and periodically report 12 // them to a node point. Data is queued and averaged and then the average is sent 13 // out as a point. 14 type Metric struct { 15 // config 16 nc *nats.Conn 17 nodeID string 18 reportPeriod time.Duration 19 20 // internal state 21 lastReport time.Time 22 lock sync.Mutex 23 avg *data.PointAverager 24 } 25 26 // NewMetric creates a new metric 27 func NewMetric(nc *nats.Conn, nodeID, pointType string, reportPeriod time.Duration) *Metric { 28 return &Metric{ 29 nc: nc, 30 nodeID: nodeID, 31 reportPeriod: reportPeriod, 32 lastReport: time.Now(), 33 avg: data.NewPointAverager(pointType), 34 } 35 } 36 37 // SetNodeID -- this is a bit of a hack to get around some init issues 38 func (m *Metric) SetNodeID(id string) { 39 m.lock.Lock() 40 defer m.lock.Unlock() 41 m.nodeID = id 42 } 43 44 // AddSample adds a sample and reports it if reportPeriod has expired 45 func (m *Metric) AddSample(s float64) error { 46 m.lock.Lock() 47 defer m.lock.Unlock() 48 now := time.Now() 49 m.avg.AddPoint(data.Point{ 50 Time: now, 51 Value: s, 52 }) 53 54 if now.Sub(m.lastReport) > m.reportPeriod { 55 err := SendNodePoint(m.nc, m.nodeID, m.avg.GetAverage(), false) 56 if err != nil { 57 return err 58 } 59 60 m.avg.ResetAverage() 61 m.lastReport = now 62 } 63 64 return nil 65 }