changes.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package aggregator
  2. import (
  3. "sync"
  4. "time"
  5. )
  6. // changesAggregator is a MetricAggregator which counts how many times the
  7. // sample value changed between consecutive samples, equivalent to
  8. // PromQL's changes(). Updates must arrive in timestamp order; out-of-order
  9. // or duplicate timestamps are ignored.
  10. type changesAggregator struct {
  11. lock sync.Mutex
  12. labelValues []string
  13. initialized bool
  14. lastValue float64
  15. lastTime time.Time
  16. changes float64
  17. }
  18. func Changes(labelValues []string) MetricAggregator {
  19. return &changesAggregator{
  20. labelValues: labelValues,
  21. }
  22. }
  23. func (a *changesAggregator) AdditionInfo() map[string]string {
  24. return nil
  25. }
  26. func (a *changesAggregator) LabelValues() []string {
  27. return a.labelValues
  28. }
  29. func (a *changesAggregator) Update(value float64, timestamp time.Time, additionalInfo map[string]string) {
  30. a.lock.Lock()
  31. defer a.lock.Unlock()
  32. if a.initialized && !timestamp.After(a.lastTime) {
  33. return
  34. }
  35. if a.initialized && value != a.lastValue {
  36. a.changes++
  37. }
  38. a.initialized = true
  39. a.lastValue = value
  40. a.lastTime = timestamp
  41. }
  42. func (a *changesAggregator) Value() []MetricValue {
  43. a.lock.Lock()
  44. defer a.lock.Unlock()
  45. return []MetricValue{
  46. {Value: a.changes},
  47. }
  48. }