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  }