monitoring.go 4.3 KB

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