metrics.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package metrics
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "github.com/imgproxy/imgproxy/v3/metrics/cloudwatch"
  7. "github.com/imgproxy/imgproxy/v3/metrics/datadog"
  8. "github.com/imgproxy/imgproxy/v3/metrics/newrelic"
  9. "github.com/imgproxy/imgproxy/v3/metrics/otel"
  10. "github.com/imgproxy/imgproxy/v3/metrics/prometheus"
  11. "github.com/imgproxy/imgproxy/v3/structdiff"
  12. )
  13. func Init() error {
  14. prometheus.Init()
  15. if err := newrelic.Init(); err != nil {
  16. return nil
  17. }
  18. datadog.Init()
  19. if err := otel.Init(); err != nil {
  20. return err
  21. }
  22. if err := cloudwatch.Init(); err != nil {
  23. return err
  24. }
  25. return nil
  26. }
  27. func Stop() {
  28. newrelic.Stop()
  29. datadog.Stop()
  30. otel.Stop()
  31. cloudwatch.Stop()
  32. }
  33. func Enabled() bool {
  34. return prometheus.Enabled() ||
  35. newrelic.Enabled() ||
  36. datadog.Enabled() ||
  37. otel.Enabled() ||
  38. cloudwatch.Enabled()
  39. }
  40. func StartRequest(ctx context.Context, rw http.ResponseWriter, r *http.Request) (context.Context, context.CancelFunc, http.ResponseWriter) {
  41. promCancel, rw := prometheus.StartRequest(rw)
  42. ctx, nrCancel, rw := newrelic.StartTransaction(ctx, rw, r)
  43. ctx, ddCancel, rw := datadog.StartRootSpan(ctx, rw, r)
  44. ctx, otelCancel, rw := otel.StartRootSpan(ctx, rw, r)
  45. cancel := func() {
  46. promCancel()
  47. nrCancel()
  48. ddCancel()
  49. otelCancel()
  50. }
  51. return ctx, cancel, rw
  52. }
  53. func setMetadata(ctx context.Context, key string, value any) {
  54. newrelic.SetMetadata(ctx, key, value)
  55. datadog.SetMetadata(ctx, key, value)
  56. otel.SetMetadata(ctx, key, value)
  57. }
  58. func SetMetadata(ctx context.Context, key string, value any) {
  59. if diff, ok := value.(structdiff.Diffable); ok {
  60. m := diff.Diff().Flatten()
  61. for k, v := range m {
  62. setMetadata(ctx, fmt.Sprintf("%s.%s", key, k), v)
  63. }
  64. return
  65. }
  66. setMetadata(ctx, key, value)
  67. }
  68. func StartQueueSegment(ctx context.Context) context.CancelFunc {
  69. promCancel := prometheus.StartQueueSegment()
  70. nrCancel := newrelic.StartSegment(ctx, "Queue")
  71. ddCancel := datadog.StartSpan(ctx, "queue")
  72. otelCancel := otel.StartSpan(ctx, "queue")
  73. cancel := func() {
  74. promCancel()
  75. nrCancel()
  76. ddCancel()
  77. otelCancel()
  78. }
  79. return cancel
  80. }
  81. func StartDownloadingSegment(ctx context.Context) context.CancelFunc {
  82. promCancel := prometheus.StartDownloadingSegment()
  83. nrCancel := newrelic.StartSegment(ctx, "Downloading image")
  84. ddCancel := datadog.StartSpan(ctx, "downloading_image")
  85. otelCancel := otel.StartSpan(ctx, "downloading_image")
  86. cancel := func() {
  87. promCancel()
  88. nrCancel()
  89. ddCancel()
  90. otelCancel()
  91. }
  92. return cancel
  93. }
  94. func StartProcessingSegment(ctx context.Context) context.CancelFunc {
  95. promCancel := prometheus.StartProcessingSegment()
  96. nrCancel := newrelic.StartSegment(ctx, "Processing image")
  97. ddCancel := datadog.StartSpan(ctx, "processing_image")
  98. otelCancel := otel.StartSpan(ctx, "processing_image")
  99. cancel := func() {
  100. promCancel()
  101. nrCancel()
  102. ddCancel()
  103. otelCancel()
  104. }
  105. return cancel
  106. }
  107. func StartStreamingSegment(ctx context.Context) context.CancelFunc {
  108. promCancel := prometheus.StartStreamingSegment()
  109. nrCancel := newrelic.StartSegment(ctx, "Streaming image")
  110. ddCancel := datadog.StartSpan(ctx, "streaming_image")
  111. otelCancel := otel.StartSpan(ctx, "streaming_image")
  112. cancel := func() {
  113. promCancel()
  114. nrCancel()
  115. ddCancel()
  116. otelCancel()
  117. }
  118. return cancel
  119. }
  120. func SendError(ctx context.Context, errType string, err error) {
  121. prometheus.IncrementErrorsTotal(errType)
  122. newrelic.SendError(ctx, errType, err)
  123. datadog.SendError(ctx, errType, err)
  124. otel.SendError(ctx, errType, err)
  125. }
  126. func ObserveBufferSize(t string, size int) {
  127. prometheus.ObserveBufferSize(t, size)
  128. newrelic.ObserveBufferSize(t, size)
  129. datadog.ObserveBufferSize(t, size)
  130. otel.ObserveBufferSize(t, size)
  131. cloudwatch.ObserveBufferSize(t, size)
  132. }
  133. func SetBufferDefaultSize(t string, size int) {
  134. prometheus.SetBufferDefaultSize(t, size)
  135. newrelic.SetBufferDefaultSize(t, size)
  136. datadog.SetBufferDefaultSize(t, size)
  137. otel.SetBufferDefaultSize(t, size)
  138. cloudwatch.SetBufferDefaultSize(t, size)
  139. }
  140. func SetBufferMaxSize(t string, size int) {
  141. prometheus.SetBufferMaxSize(t, size)
  142. newrelic.SetBufferMaxSize(t, size)
  143. datadog.SetBufferMaxSize(t, size)
  144. otel.SetBufferMaxSize(t, size)
  145. cloudwatch.SetBufferMaxSize(t, size)
  146. }