timer.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package metrics
  2. import (
  3. "time"
  4. "github.com/prometheus/client_golang/prometheus"
  5. )
  6. // StartTimer begins a timer observation at the callsite. When the target
  7. // operation is completed, the caller should call the return done func().
  8. func StartTimer(timer Timer) (done func()) {
  9. start := time.Now()
  10. return func() {
  11. timer.Update(time.Since(start))
  12. }
  13. }
  14. // Timer is a metric that allows collecting the duration of an action in seconds
  15. type Timer interface {
  16. // Update records an observation, duration, and converts to the target
  17. // units.
  18. Update(duration time.Duration)
  19. // UpdateSince will add the duration from the provided starting time to the
  20. // timer's summary with the precisions that was used in creation of the timer
  21. UpdateSince(time.Time)
  22. }
  23. // LabeledTimer is a timer that must have label values populated before use.
  24. type LabeledTimer interface {
  25. WithValues(labels ...string) *labeledTimerObserver
  26. }
  27. type labeledTimer struct {
  28. m *prometheus.HistogramVec
  29. }
  30. type labeledTimerObserver struct {
  31. m prometheus.Observer
  32. }
  33. func (lbo *labeledTimerObserver) Update(duration time.Duration) {
  34. lbo.m.Observe(duration.Seconds())
  35. }
  36. func (lbo *labeledTimerObserver) UpdateSince(since time.Time) {
  37. lbo.m.Observe(time.Since(since).Seconds())
  38. }
  39. func (lt *labeledTimer) WithValues(labels ...string) *labeledTimerObserver {
  40. return &labeledTimerObserver{m: lt.m.WithLabelValues(labels...)}
  41. }
  42. func (lt *labeledTimer) Describe(c chan<- *prometheus.Desc) {
  43. lt.m.Describe(c)
  44. }
  45. func (lt *labeledTimer) Collect(c chan<- prometheus.Metric) {
  46. lt.m.Collect(c)
  47. }
  48. type timer struct {
  49. m prometheus.Observer
  50. }
  51. func (t *timer) Update(duration time.Duration) {
  52. t.m.Observe(duration.Seconds())
  53. }
  54. func (t *timer) UpdateSince(since time.Time) {
  55. t.m.Observe(time.Since(since).Seconds())
  56. }
  57. func (t *timer) Describe(c chan<- *prometheus.Desc) {
  58. c <- t.m.(prometheus.Metric).Desc()
  59. }
  60. func (t *timer) Collect(c chan<- prometheus.Metric) {
  61. // Are there any observers that don't implement Collector? It is really
  62. // unclear what the point of the upstream change was, but we'll let this
  63. // panic if we get an observer that doesn't implement collector. In this
  64. // case, we should almost always see metricVec objects, so this should
  65. // never panic.
  66. t.m.(prometheus.Collector).Collect(c)
  67. }