stats.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package nebula
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/cyberdelia/go-metrics-graphite"
  6. mp "github.com/nbrownus/go-metrics-prometheus"
  7. "github.com/prometheus/client_golang/prometheus"
  8. "github.com/prometheus/client_golang/prometheus/promhttp"
  9. "github.com/rcrowley/go-metrics"
  10. "log"
  11. "net"
  12. "net/http"
  13. "time"
  14. )
  15. func startStats(c *Config) 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)
  27. case "prometheus":
  28. startPrometheusStats(interval, c)
  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) 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. go graphite.Graphite(metrics.DefaultRegistry, i, prefix, addr)
  51. return nil
  52. }
  53. func startPrometheusStats(i time.Duration, c *Config) error {
  54. namespace := c.GetString("stats.namespace", "")
  55. subsystem := c.GetString("stats.subsystem", "")
  56. listen := c.GetString("stats.listen", "")
  57. if listen == "" {
  58. return fmt.Errorf("stats.listen should not be emtpy")
  59. }
  60. path := c.GetString("stats.path", "")
  61. if path == "" {
  62. return fmt.Errorf("stats.path should not be emtpy")
  63. }
  64. pr := prometheus.NewRegistry()
  65. pClient := mp.NewPrometheusProvider(metrics.DefaultRegistry, namespace, subsystem, pr, i)
  66. go pClient.UpdatePrometheusMetrics()
  67. go func() {
  68. l.Infof("Prometheus stats listening on %s at %s", listen, path)
  69. http.Handle(path, promhttp.HandlerFor(pr, promhttp.HandlerOpts{ErrorLog: l}))
  70. log.Fatal(http.ListenAndServe(listen, nil))
  71. }()
  72. return nil
  73. }