telemetry.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package metrics
  2. import (
  3. "fmt"
  4. "github.com/opencost/opencost/pkg/build"
  5. "sync"
  6. "github.com/kubecost/events"
  7. "github.com/prometheus/client_golang/prometheus"
  8. )
  9. var (
  10. once sync.Once
  11. dispatcher events.Dispatcher[HttpHandlerMetricEvent]
  12. // -- append new dispatchers here for new event types
  13. // prometheus metrics
  14. requestsCount *prometheus.CounterVec
  15. responseTime *prometheus.HistogramVec
  16. responseSize *prometheus.SummaryVec
  17. buildInfo *prometheus.GaugeVec
  18. )
  19. // InitKubecostTelemetry registers kubecost application telemetry.
  20. func InitKubecostTelemetry(config *MetricsConfig) {
  21. // TODO(bolt): Check MetricsConfig for disabled metrics
  22. once.Do(func() {
  23. // register prometheus metrics
  24. buildInfo = prometheus.NewGaugeVec(prometheus.GaugeOpts{
  25. Name: "opencost_build_info",
  26. Help: "opencost_build_info Build information",
  27. }, []string{"version", "revision"})
  28. buildVersion := build.GetVersion()
  29. buildInfo.WithLabelValues(buildVersion.Version, buildVersion.Revision).Set(1.0)
  30. requestsCount = prometheus.NewCounterVec(prometheus.CounterOpts{
  31. Name: "kubecost_http_requests_total",
  32. Help: "kubecost_http_requests_total Total number of HTTP requests",
  33. }, []string{"handler", "method", "code"})
  34. var buckets = []float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120, 240, 360, 720}
  35. responseTime = prometheus.NewHistogramVec(prometheus.HistogramOpts{
  36. Name: "kubecost_http_response_time_seconds",
  37. Help: "kubecost_http_response_time_seconds Response time in seconds",
  38. Buckets: buckets,
  39. }, []string{"handler", "method", "code"})
  40. responseSize = prometheus.NewSummaryVec(prometheus.SummaryOpts{
  41. Name: "kubecost_http_response_size_bytes",
  42. Help: "kubecost_http_response_size_bytes Response size in bytes",
  43. }, []string{"handler", "method", "code"})
  44. prometheus.MustRegister(requestsCount, responseTime, responseSize, buildInfo)
  45. // register event listeners
  46. dispatcher = events.GlobalDispatcherFor[HttpHandlerMetricEvent]()
  47. dispatcher.AddEventHandler(onHttpHandlerMetricEvent)
  48. // -- append new event handlers here
  49. })
  50. }
  51. // onHttpHandlerMetricEvent handles all incoming HttpHandlerMetricEvents
  52. func onHttpHandlerMetricEvent(event HttpHandlerMetricEvent) {
  53. code := fmt.Sprintf("%d", event.Code)
  54. requestsCount.WithLabelValues(event.Handler, event.Method, code).Inc()
  55. responseSize.WithLabelValues(event.Handler, event.Method, code).Observe(float64(event.ResponseSize))
  56. responseTime.WithLabelValues(event.Handler, event.Method, code).Observe(event.ResponseTime.Seconds())
  57. }