Skip to content

Commit c972f24

Browse files
committed
fix(api): downgrade client cancellation from error to warning
When a client disconnects (user cancel or LB timeout), the request context is canceled. Previously this was logged at Error level and marked as an error span in OTEL traces, creating noise alongside real server errors. Now context.Canceled is detected in both the logging middleware and the OTEL tracing middleware: log level is downgraded to Warn and the span gets a client.canceled attribute instead of an error status.
1 parent e236dcc commit c972f24

2 files changed

Lines changed: 13 additions & 4 deletions

File tree

packages/api/internal/middleware/otel/tracing/middleware.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package tracing // import "go.opentelemetry.io/contrib/instrumentation/github.co
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223
"strings"
2324
"time"
@@ -112,9 +113,15 @@ func Middleware(tracerProvider oteltrace.TracerProvider, service string) gin.Han
112113

113114
status := c.Writer.Status()
114115
attrs := semconv.HTTPAttributesFromHTTPStatusCode(status)
115-
spanStatus, spanMessage := semconv.SpanStatusFromHTTPStatusCode(status)
116116
span.SetAttributes(attrs...)
117-
span.SetStatus(spanStatus, spanMessage)
117+
118+
if errors.Is(ctx.Err(), context.Canceled) {
119+
span.SetAttributes(attribute.Bool("client.canceled", true))
120+
} else {
121+
spanStatus, spanMessage := semconv.SpanStatusFromHTTPStatusCode(status)
122+
span.SetStatus(spanStatus, spanMessage)
123+
}
124+
118125
if len(c.Errors) > 0 {
119126
span.SetAttributes(attribute.String("gin.errors", strings.TrimSpace(c.Errors.String())))
120127
}

packages/shared/pkg/middleware/logging.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package middleware
22

33
import (
4+
"context"
45
"errors"
56
"net/http"
67
"regexp"
@@ -100,9 +101,10 @@ func LoggingMiddleware(logger logger.Logger, conf Config) gin.HandlerFunc {
100101
}
101102

102103
level := conf.DefaultLevel
103-
if status >= http.StatusInternalServerError {
104+
switch {
105+
case status >= http.StatusInternalServerError && !errors.Is(ctx.Err(), context.Canceled):
104106
level = zapcore.ErrorLevel
105-
} else if status >= http.StatusBadRequest {
107+
case status >= http.StatusBadRequest || errors.Is(ctx.Err(), context.Canceled):
106108
level = zapcore.WarnLevel
107109
}
108110

0 commit comments

Comments
 (0)