Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions internal/middleware/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ func (r *statusRecorder) Write(b []byte) (int, error) {
return n, err
}

// Flush propagates to the wrapped writer so SSE/streaming handlers can
// flush through this middleware. Without it, w.(http.Flusher) fails and
// streaming endpoints error out.
func (r *statusRecorder) Flush() {
if f, ok := r.ResponseWriter.(http.Flusher); ok {
f.Flush()
}
}

// Unwrap exposes the wrapped writer for http.ResponseController.
func (r *statusRecorder) Unwrap() http.ResponseWriter { return r.ResponseWriter }

// AccessLog logs one structured line per HTTP request: method, path,
// status, duration, request ID, and principal ID.
//
Expand Down
11 changes: 11 additions & 0 deletions internal/middleware/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ func (r *metricsRecorder) Write(b []byte) (int, error) {
return n, err
}

// Flush propagates to the wrapped writer so SSE/streaming handlers can
// flush through the metrics middleware.
func (r *metricsRecorder) Flush() {
if f, ok := r.ResponseWriter.(http.Flusher); ok {
f.Flush()
}
}

// Unwrap exposes the wrapped writer for http.ResponseController.
func (r *metricsRecorder) Unwrap() http.ResponseWriter { return r.ResponseWriter }

// normalizePath strips URL parameters to keep metric cardinality
// bounded. Document and section IDs are replaced with a placeholder.
func normalizePath(path string) string {
Expand Down
11 changes: 11 additions & 0 deletions internal/middleware/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ func (r *tracingRecorder) WriteHeader(code int) {
r.ResponseWriter.WriteHeader(code)
}

// Flush propagates to the wrapped writer so SSE/streaming handlers can
// flush through the tracing middleware.
func (r *tracingRecorder) Flush() {
if f, ok := r.ResponseWriter.(http.Flusher); ok {
f.Flush()
}
}

// Unwrap exposes the wrapped writer for http.ResponseController.
func (r *tracingRecorder) Unwrap() http.ResponseWriter { return r.ResponseWriter }

// TraceIDFromContext extracts the trace ID string from the current span,
// useful for correlating logs with traces.
func TraceIDFromContext(ctx context.Context) string {
Expand Down
Loading