1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-02-17 11:55:32 +02:00

Add processing options and source image URL to error reports

This commit is contained in:
DarthSim 2024-03-10 20:44:45 +03:00
parent 8392e2e79b
commit 71aea9b507
8 changed files with 101 additions and 31 deletions

View File

@ -1,6 +1,9 @@
# Changelog # Changelog
## [Unreleased] ## [Unreleased]
### Add
- Add processing/info options and source image URL to error reports.
### Change ### Change
- Support configuring OpenTelemetry with standard [general](https://opentelemetry.io/docs/languages/sdk-configuration/general/) and [OTLP Exporter](https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/) environment variables. - Support configuring OpenTelemetry with standard [general](https://opentelemetry.io/docs/languages/sdk-configuration/general/) and [OTLP Exporter](https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/) environment variables.
- `IMGPROXY_MAX_SRC_RESOLUTION` default value is increased to 50. - `IMGPROXY_MAX_SRC_RESOLUTION` default value is increased to 50.

View File

@ -2,12 +2,18 @@ package airbrake
import ( import (
"net/http" "net/http"
"strings"
"github.com/airbrake/gobrake/v5" "github.com/airbrake/gobrake/v5"
"github.com/imgproxy/imgproxy/v3/config" "github.com/imgproxy/imgproxy/v3/config"
) )
var notifier *gobrake.Notifier var (
notifier *gobrake.Notifier
metaReplacer = strings.NewReplacer(" ", "-")
)
func Init() { func Init() {
if len(config.AirbrakeProjecKey) > 0 { if len(config.AirbrakeProjecKey) > 0 {
@ -19,10 +25,19 @@ func Init() {
} }
} }
func Report(err error, req *http.Request) { func Report(err error, req *http.Request, meta map[string]any) {
if notifier != nil { if notifier == nil {
notifier.Notify(err, req) return
} }
notice := notifier.Notice(err, req, 2)
for k, v := range meta {
key := metaReplacer.Replace(strings.ToLower(k))
notice.Context[key] = v
}
notifier.SendNoticeAsync(notice)
} }
func Close() { func Close() {

View File

@ -4,6 +4,7 @@ import (
"net/http" "net/http"
"github.com/bugsnag/bugsnag-go/v2" "github.com/bugsnag/bugsnag-go/v2"
"github.com/imgproxy/imgproxy/v3/config" "github.com/imgproxy/imgproxy/v3/config"
) )
@ -19,8 +20,15 @@ func Init() {
} }
} }
func Report(err error, req *http.Request) { func Report(err error, req *http.Request, meta map[string]any) {
if enabled { if !enabled {
bugsnag.Notify(err, req) return
} }
extra := make(bugsnag.MetaData)
for k, v := range meta {
extra.Add("Processing Context", k, v)
}
bugsnag.Notify(err, req, extra)
} }

View File

@ -1,6 +1,7 @@
package errorreport package errorreport
import ( import (
"context"
"net/http" "net/http"
"github.com/imgproxy/imgproxy/v3/errorreport/airbrake" "github.com/imgproxy/imgproxy/v3/errorreport/airbrake"
@ -9,6 +10,8 @@ import (
"github.com/imgproxy/imgproxy/v3/errorreport/sentry" "github.com/imgproxy/imgproxy/v3/errorreport/sentry"
) )
type metaCtxKey struct{}
func Init() { func Init() {
bugsnag.Init() bugsnag.Init()
honeybadger.Init() honeybadger.Init()
@ -16,11 +19,30 @@ func Init() {
airbrake.Init() airbrake.Init()
} }
func StartRequest(req *http.Request) context.Context {
meta := make(map[string]any)
return context.WithValue(req.Context(), metaCtxKey{}, meta)
}
func SetMetadata(req *http.Request, key string, value any) {
meta, ok := req.Context().Value(metaCtxKey{}).(map[string]any)
if !ok || meta == nil {
return
}
meta[key] = value
}
func Report(err error, req *http.Request) { func Report(err error, req *http.Request) {
bugsnag.Report(err, req) meta, ok := req.Context().Value(metaCtxKey{}).(map[string]any)
honeybadger.Report(err, req) if !ok {
sentry.Report(err, req) meta = nil
airbrake.Report(err, req) }
bugsnag.Report(err, req, meta)
honeybadger.Report(err, req, meta)
sentry.Report(err, req, meta)
airbrake.Report(err, req, meta)
} }
func Close() { func Close() {

View File

@ -5,13 +5,14 @@ import (
"strings" "strings"
"github.com/honeybadger-io/honeybadger-go" "github.com/honeybadger-io/honeybadger-go"
"github.com/imgproxy/imgproxy/v3/config" "github.com/imgproxy/imgproxy/v3/config"
) )
var ( var (
enabled bool enabled bool
headersReplacer = strings.NewReplacer("-", "_") metaReplacer = strings.NewReplacer("-", "_", " ", "_")
) )
func Init() { func Init() {
@ -24,15 +25,22 @@ func Init() {
} }
} }
func Report(err error, req *http.Request) { func Report(err error, req *http.Request, meta map[string]any) {
if enabled { if !enabled {
headers := make(honeybadger.CGIData) return
for k, v := range req.Header {
key := "HTTP_" + headersReplacer.Replace(strings.ToUpper(k))
headers[key] = v[0]
}
honeybadger.Notify(err, req.URL, headers)
} }
extra := make(honeybadger.CGIData, len(req.Header)+len(meta))
for k, v := range req.Header {
key := "HTTP_" + metaReplacer.Replace(strings.ToUpper(k))
extra[key] = v[0]
}
for k, v := range meta {
key := metaReplacer.Replace(strings.ToUpper(k))
extra[key] = v
}
honeybadger.Notify(err, req.URL, extra)
} }

View File

@ -5,6 +5,7 @@ import (
"time" "time"
"github.com/getsentry/sentry-go" "github.com/getsentry/sentry-go"
"github.com/imgproxy/imgproxy/v3/config" "github.com/imgproxy/imgproxy/v3/config"
) )
@ -26,14 +27,21 @@ func Init() {
} }
} }
func Report(err error, req *http.Request) { func Report(err error, req *http.Request, meta map[string]any) {
if enabled { if !enabled {
hub := sentry.CurrentHub().Clone() return
hub.Scope().SetRequest(req) }
hub.Scope().SetLevel(sentry.LevelError)
eventID := hub.CaptureException(err) hub := sentry.CurrentHub().Clone()
if eventID != nil { hub.Scope().SetRequest(req)
hub.Flush(timeout) hub.Scope().SetLevel(sentry.LevelError)
}
if meta != nil {
hub.Scope().SetContext("Processing context", meta)
}
eventID := hub.CaptureException(err)
if eventID != nil {
hub.Flush(timeout)
} }
} }

View File

@ -241,6 +241,9 @@ func handleProcessing(reqID string, rw http.ResponseWriter, r *http.Request) {
po, imageURL, err := options.ParsePath(path, r.Header) po, imageURL, err := options.ParsePath(path, r.Header)
checkErr(ctx, "path_parsing", err) checkErr(ctx, "path_parsing", err)
errorreport.SetMetadata(r, "Source Image URL", imageURL)
errorreport.SetMetadata(r, "Processing Options", po)
err = security.VerifySourceURL(imageURL) err = security.VerifySourceURL(imageURL)
checkErr(ctx, "security", err) checkErr(ctx, "security", err)

View File

@ -132,6 +132,9 @@ func withSecret(h router.RouteHandler) router.RouteHandler {
func withPanicHandler(h router.RouteHandler) router.RouteHandler { func withPanicHandler(h router.RouteHandler) router.RouteHandler {
return func(reqID string, rw http.ResponseWriter, r *http.Request) { return func(reqID string, rw http.ResponseWriter, r *http.Request) {
ctx := errorreport.StartRequest(r)
r = r.WithContext(ctx)
defer func() { defer func() {
if rerr := recover(); rerr != nil { if rerr := recover(); rerr != nil {
if rerr == http.ErrAbortHandler { if rerr == http.ErrAbortHandler {