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