1
0

precisiontiming.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package event
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. // PrecisionTiming keeps min/max/avg information about a timer over a certain interval
  7. type PrecisionTiming struct {
  8. Name string
  9. Min time.Duration
  10. Max time.Duration
  11. Value time.Duration
  12. Count int64
  13. }
  14. // NewPrecisionTiming is a factory for a Timing event, setting the Count to 1 to prevent div_by_0 errors
  15. func NewPrecisionTiming(k string, delta time.Duration) *PrecisionTiming {
  16. return &PrecisionTiming{Name: k, Min: delta, Max: delta, Value: delta, Count: 1}
  17. }
  18. // Update the event with metrics coming from a new one of the same type and with the same key
  19. func (e *PrecisionTiming) Update(e2 Event) error {
  20. if e.Type() != e2.Type() {
  21. return fmt.Errorf("statsd event type conflict: %s vs %s ", e.String(), e2.String())
  22. }
  23. p := e2.Payload().(PrecisionTiming)
  24. e.Count += p.Count
  25. e.Value += p.Value
  26. e.Min = time.Duration(minInt64(int64(e.Min), int64(p.Min)))
  27. e.Max = time.Duration(maxInt64(int64(e.Max), int64(p.Min)))
  28. return nil
  29. }
  30. // Payload returns the aggregated value for this event
  31. func (e PrecisionTiming) Payload() interface{} {
  32. return e
  33. }
  34. // Stats returns an array of StatsD events as they travel over UDP
  35. func (e PrecisionTiming) Stats() []string {
  36. return []string{
  37. fmt.Sprintf("%s.count:%d|c", e.Name, e.Count),
  38. fmt.Sprintf("%s.avg:%.6f|ms", e.Name, float64(int64(e.Value)/e.Count)/1000000), // make sure e.Count != 0
  39. fmt.Sprintf("%s.min:%.6f|ms", e.Name, e.durationToMs(e.Min)),
  40. fmt.Sprintf("%s.max:%.6f|ms", e.Name, e.durationToMs(e.Max)),
  41. }
  42. }
  43. // durationToMs converts time.Duration into the corresponding value in milliseconds
  44. func (e PrecisionTiming) durationToMs(x time.Duration) float64 {
  45. return float64(x) / float64(time.Millisecond)
  46. }
  47. // Key returns the name of this metric
  48. func (e PrecisionTiming) Key() string {
  49. return e.Name
  50. }
  51. // SetKey sets the name of this metric
  52. func (e *PrecisionTiming) SetKey(key string) {
  53. e.Name = key
  54. }
  55. // Type returns an integer identifier for this type of metric
  56. func (e PrecisionTiming) Type() int {
  57. return EventPrecisionTiming
  58. }
  59. // TypeString returns a name for this type of metric
  60. func (e PrecisionTiming) TypeString() string {
  61. return "PrecisionTiming"
  62. }
  63. // String returns a debug-friendly representation of this metric
  64. func (e PrecisionTiming) String() string {
  65. return fmt.Sprintf("{Type: %s, Key: %s, Value: %+v}", e.TypeString(), e.Name, e.Payload())
  66. }