stats.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package nebula
  2. import (
  3. "errors"
  4. "fmt"
  5. "log"
  6. "net"
  7. "net/http"
  8. "time"
  9. graphite "github.com/cyberdelia/go-metrics-graphite"
  10. mp "github.com/nbrownus/go-metrics-prometheus"
  11. "github.com/prometheus/client_golang/prometheus"
  12. "github.com/prometheus/client_golang/prometheus/promhttp"
  13. "github.com/rcrowley/go-metrics"
  14. )
  15. func startStats(c *Config, configTest bool) error {
  16. mType := c.GetString("stats.type", "")
  17. if mType == "" || mType == "none" {
  18. return nil
  19. }
  20. interval := c.GetDuration("stats.interval", 0)
  21. if interval == 0 {
  22. return fmt.Errorf("stats.interval was an invalid duration: %s", c.GetString("stats.interval", ""))
  23. }
  24. switch mType {
  25. case "graphite":
  26. startGraphiteStats(interval, c, configTest)
  27. case "prometheus":
  28. startPrometheusStats(interval, c, configTest)
  29. default:
  30. return fmt.Errorf("stats.type was not understood: %s", mType)
  31. }
  32. metrics.RegisterDebugGCStats(metrics.DefaultRegistry)
  33. metrics.RegisterRuntimeMemStats(metrics.DefaultRegistry)
  34. go metrics.CaptureDebugGCStats(metrics.DefaultRegistry, interval)
  35. go metrics.CaptureRuntimeMemStats(metrics.DefaultRegistry, interval)
  36. return nil
  37. }
  38. func startGraphiteStats(i time.Duration, c *Config, configTest bool) error {
  39. proto := c.GetString("stats.protocol", "tcp")
  40. host := c.GetString("stats.host", "")
  41. if host == "" {
  42. return errors.New("stats.host can not be empty")
  43. }
  44. prefix := c.GetString("stats.prefix", "nebula")
  45. addr, err := net.ResolveTCPAddr(proto, host)
  46. if err != nil {
  47. return fmt.Errorf("error while setting up graphite sink: %s", err)
  48. }
  49. l.Infof("Starting graphite. Interval: %s, prefix: %s, addr: %s", i, prefix, addr)
  50. if !configTest {
  51. go graphite.Graphite(metrics.DefaultRegistry, i, prefix, addr)
  52. }
  53. return nil
  54. }
  55. func startPrometheusStats(i time.Duration, c *Config, configTest bool) error {
  56. namespace := c.GetString("stats.namespace", "")
  57. subsystem := c.GetString("stats.subsystem", "")
  58. listen := c.GetString("stats.listen", "")
  59. if listen == "" {
  60. return fmt.Errorf("stats.listen should not be empty")
  61. }
  62. path := c.GetString("stats.path", "")
  63. if path == "" {
  64. return fmt.Errorf("stats.path should not be empty")
  65. }
  66. pr := prometheus.NewRegistry()
  67. pClient := mp.NewPrometheusProvider(metrics.DefaultRegistry, namespace, subsystem, pr, i)
  68. go pClient.UpdatePrometheusMetrics()
  69. if !configTest {
  70. go func() {
  71. l.Infof("Prometheus stats listening on %s at %s", listen, path)
  72. http.Handle(path, promhttp.HandlerFor(pr, promhttp.HandlerOpts{ErrorLog: l}))
  73. log.Fatal(http.ListenAndServe(listen, nil))
  74. }()
  75. }
  76. return nil
  77. }