graphite.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package metrics
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "net"
  7. "time"
  8. )
  9. // GraphiteConfig provides a container with configuration parameters for
  10. // the Graphite exporter
  11. type GraphiteConfig struct {
  12. Addr *net.TCPAddr // Network address to connect to
  13. Registry Registry // Registry to be exported
  14. FlushInterval time.Duration // Flush interval
  15. DurationUnit time.Duration // Time conversion unit for durations
  16. RateUnit time.Duration // Time conversion unit for rates
  17. Prefix string // Prefix to be prepended to metric names
  18. }
  19. // Graphite is a blocking exporter function which reports metrics in r
  20. // to a graphite server located at addr, flushing them every d duration
  21. // and prepending metric names with prefix.
  22. func Graphite(r Registry, d time.Duration, prefix string, addr *net.TCPAddr) {
  23. GraphiteWithConfig(GraphiteConfig{
  24. Addr: addr,
  25. Registry: r,
  26. FlushInterval: d,
  27. DurationUnit: time.Nanosecond,
  28. RateUnit: time.Nanosecond,
  29. Prefix: prefix,
  30. })
  31. }
  32. // GraphiteWithConfig is a blocking exporter function just like Graphite,
  33. // but it takes a GraphiteConfig instead.
  34. func GraphiteWithConfig(c GraphiteConfig) {
  35. for _ = range time.Tick(c.FlushInterval) {
  36. if err := graphite(&c); nil != err {
  37. log.Println(err)
  38. }
  39. }
  40. }
  41. func graphite(c *GraphiteConfig) error {
  42. now := time.Now().Unix()
  43. du, ru := float64(c.DurationUnit), float64(c.RateUnit)
  44. conn, err := net.DialTCP("tcp", nil, c.Addr)
  45. if nil != err {
  46. return err
  47. }
  48. defer conn.Close()
  49. w := bufio.NewWriter(conn)
  50. c.Registry.Each(func(name string, i interface{}) {
  51. switch m := i.(type) {
  52. case Counter:
  53. fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, m.Count(), now)
  54. case Gauge:
  55. fmt.Fprintf(w, "%s.%s.value %d %d\n", c.Prefix, name, m.Value(), now)
  56. case Histogram:
  57. ps := m.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
  58. fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, m.Count(), now)
  59. fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, m.Min(), now)
  60. fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, m.Max(), now)
  61. fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, m.Mean(), now)
  62. fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, m.StdDev(), now)
  63. fmt.Fprintf(w, "%s.%s.50-percentile %.2f %d\n", c.Prefix, name, ps[0], now)
  64. fmt.Fprintf(w, "%s.%s.75-percentile %.2f %d\n", c.Prefix, name, ps[1], now)
  65. fmt.Fprintf(w, "%s.%s.95-percentile %.2f %d\n", c.Prefix, name, ps[2], now)
  66. fmt.Fprintf(w, "%s.%s.99-percentile %.2f %d\n", c.Prefix, name, ps[3], now)
  67. fmt.Fprintf(w, "%s.%s.999-percentile %.2f %d\n", c.Prefix, name, ps[4], now)
  68. case Meter:
  69. fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, m.Count(), now)
  70. fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, ru*m.Rate1(), now)
  71. fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, ru*m.Rate5(), now)
  72. fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, ru*m.Rate15(), now)
  73. fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, ru*m.RateMean(), now)
  74. case Timer:
  75. ps := m.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
  76. fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, m.Count(), now)
  77. fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, int64(du)*m.Min(), now)
  78. fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, int64(du)*m.Max(), now)
  79. fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, du*m.Mean(), now)
  80. fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, du*m.StdDev(), now)
  81. fmt.Fprintf(w, "%s.%s.50-percentile %.2f %d\n", c.Prefix, name, du*ps[0], now)
  82. fmt.Fprintf(w, "%s.%s.75-percentile %.2f %d\n", c.Prefix, name, du*ps[1], now)
  83. fmt.Fprintf(w, "%s.%s.95-percentile %.2f %d\n", c.Prefix, name, du*ps[2], now)
  84. fmt.Fprintf(w, "%s.%s.99-percentile %.2f %d\n", c.Prefix, name, du*ps[3], now)
  85. fmt.Fprintf(w, "%s.%s.999-percentile %.2f %d\n", c.Prefix, name, du*ps[4], now)
  86. fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, ru*m.Rate1(), now)
  87. fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, ru*m.Rate5(), now)
  88. fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, ru*m.Rate15(), now)
  89. fmt.Fprintf(w, "%s.%s.mean-rate %.2f %d\n", c.Prefix, name, ru*m.RateMean(), now)
  90. }
  91. w.Flush()
  92. })
  93. return nil
  94. }