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