mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-12-23 22:11:10 +02:00
173 lines
4.6 KiB
Go
173 lines
4.6 KiB
Go
package monitoring
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
|
|
"github.com/imgproxy/imgproxy/v3/monitoring/cloudwatch"
|
|
"github.com/imgproxy/imgproxy/v3/monitoring/datadog"
|
|
"github.com/imgproxy/imgproxy/v3/monitoring/newrelic"
|
|
"github.com/imgproxy/imgproxy/v3/monitoring/otel"
|
|
"github.com/imgproxy/imgproxy/v3/monitoring/prometheus"
|
|
"github.com/imgproxy/imgproxy/v3/monitoring/stats"
|
|
)
|
|
|
|
// Monitoring holds all monitoring service instances
|
|
type Monitoring struct {
|
|
config *Config
|
|
stats *stats.Stats
|
|
|
|
prometheus *prometheus.Prometheus
|
|
newrelic *newrelic.NewRelic
|
|
datadog *datadog.DataDog
|
|
otel *otel.Otel
|
|
cloudwatch *cloudwatch.CloudWatch
|
|
}
|
|
|
|
// New creates a new Monitoring instance
|
|
func New(ctx context.Context, config *Config, workersNumber int) (*Monitoring, error) {
|
|
if err := config.Validate(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
m := &Monitoring{
|
|
config: config,
|
|
stats: stats.New(workersNumber),
|
|
}
|
|
|
|
var prErr, nlErr, ddErr, otelErr, cwErr error
|
|
|
|
m.prometheus, prErr = prometheus.New(&config.Prometheus, m.stats)
|
|
m.newrelic, nlErr = newrelic.New(&config.NewRelic, m.stats)
|
|
m.datadog, ddErr = datadog.New(&config.DataDog, m.stats)
|
|
m.otel, otelErr = otel.New(&config.OpenTelemetry, m.stats)
|
|
m.cloudwatch, cwErr = cloudwatch.New(ctx, &config.CloudWatch, m.stats)
|
|
|
|
err := errors.Join(prErr, nlErr, ddErr, otelErr, cwErr)
|
|
|
|
return m, err
|
|
}
|
|
|
|
// Enabled returns true if at least one monitoring service is enabled
|
|
func (m *Monitoring) Enabled() bool {
|
|
return m.prometheus.Enabled() ||
|
|
m.newrelic.Enabled() ||
|
|
m.datadog.Enabled() ||
|
|
m.otel.Enabled() ||
|
|
m.cloudwatch.Enabled()
|
|
}
|
|
|
|
// Stats returns the stats instance
|
|
func (m *Monitoring) Stats() *stats.Stats {
|
|
return m.stats
|
|
}
|
|
|
|
// Stop stops all monitoring services
|
|
func (m *Monitoring) Stop(ctx context.Context) {
|
|
m.newrelic.Stop(ctx)
|
|
m.datadog.Stop()
|
|
m.otel.Stop(ctx)
|
|
m.cloudwatch.Stop()
|
|
}
|
|
|
|
// StartPrometheus starts the Prometheus metrics server
|
|
func (m *Monitoring) StartPrometheus(cancel context.CancelFunc) error {
|
|
return m.prometheus.StartServer(cancel)
|
|
}
|
|
|
|
func (m *Monitoring) StartRequest(ctx context.Context, rw http.ResponseWriter, r *http.Request) (context.Context, context.CancelFunc, http.ResponseWriter) {
|
|
promCancel, rw := m.prometheus.StartRequest(rw)
|
|
ctx, nrCancel, rw := m.newrelic.StartTransaction(ctx, rw, r)
|
|
ctx, ddCancel, rw := m.datadog.StartRootSpan(ctx, rw, r)
|
|
ctx, otelCancel, rw := m.otel.StartRootSpan(ctx, rw, r)
|
|
|
|
cancel := func() {
|
|
promCancel()
|
|
nrCancel()
|
|
ddCancel()
|
|
otelCancel()
|
|
}
|
|
|
|
return ctx, cancel, rw
|
|
}
|
|
|
|
func (m *Monitoring) SetMetadata(ctx context.Context, meta Meta) {
|
|
for key, value := range meta {
|
|
m.newrelic.SetMetadata(ctx, key, value)
|
|
m.datadog.SetMetadata(ctx, key, value)
|
|
m.otel.SetMetadata(ctx, key, value)
|
|
}
|
|
}
|
|
|
|
func (m *Monitoring) StartQueueSegment(ctx context.Context) context.CancelFunc {
|
|
promCancel := m.prometheus.StartQueueSegment()
|
|
nrCancel := m.newrelic.StartSegment(ctx, "Queue", nil)
|
|
ddCancel := m.datadog.StartSpan(ctx, "queue", nil)
|
|
otelCancel := m.otel.StartSpan(ctx, "queue", nil)
|
|
|
|
cancel := func() {
|
|
promCancel()
|
|
nrCancel()
|
|
ddCancel()
|
|
otelCancel()
|
|
}
|
|
|
|
return cancel
|
|
}
|
|
|
|
func (m *Monitoring) StartDownloadingSegment(ctx context.Context, meta Meta) context.CancelFunc {
|
|
promCancel := m.prometheus.StartDownloadingSegment()
|
|
nrCancel := m.newrelic.StartSegment(ctx, "Downloading image", meta)
|
|
ddCancel := m.datadog.StartSpan(ctx, "downloading_image", meta)
|
|
otelCancel := m.otel.StartSpan(ctx, "downloading_image", meta)
|
|
|
|
cancel := func() {
|
|
promCancel()
|
|
nrCancel()
|
|
ddCancel()
|
|
otelCancel()
|
|
}
|
|
|
|
return cancel
|
|
}
|
|
|
|
func (m *Monitoring) StartProcessingSegment(ctx context.Context, meta Meta) context.CancelFunc {
|
|
promCancel := m.prometheus.StartProcessingSegment()
|
|
nrCancel := m.newrelic.StartSegment(ctx, "Processing image", meta)
|
|
ddCancel := m.datadog.StartSpan(ctx, "processing_image", meta)
|
|
otelCancel := m.otel.StartSpan(ctx, "processing_image", meta)
|
|
|
|
cancel := func() {
|
|
promCancel()
|
|
nrCancel()
|
|
ddCancel()
|
|
otelCancel()
|
|
}
|
|
|
|
return cancel
|
|
}
|
|
|
|
func (m *Monitoring) StartStreamingSegment(ctx context.Context) context.CancelFunc {
|
|
promCancel := m.prometheus.StartStreamingSegment()
|
|
nrCancel := m.newrelic.StartSegment(ctx, "Streaming image", nil)
|
|
ddCancel := m.datadog.StartSpan(ctx, "streaming_image", nil)
|
|
otelCancel := m.otel.StartSpan(ctx, "streaming_image", nil)
|
|
|
|
cancel := func() {
|
|
promCancel()
|
|
nrCancel()
|
|
ddCancel()
|
|
otelCancel()
|
|
}
|
|
|
|
return cancel
|
|
}
|
|
|
|
func (m *Monitoring) SendError(ctx context.Context, errType string, err error) {
|
|
m.prometheus.IncrementErrorsTotal(errType)
|
|
m.newrelic.SendError(ctx, errType, err)
|
|
m.datadog.SendError(ctx, errType, err)
|
|
m.otel.SendError(ctx, errType, err)
|
|
}
|