SSE 调整

This commit is contained in:
2026-06-10 14:48:28 +08:00
parent eb33f534f5
commit 5f015a5c75
3 changed files with 49 additions and 27 deletions
+4 -21
View File
@@ -4,26 +4,10 @@ import (
"log/slog"
"net/http"
"time"
"github.com/felixge/httpsnoop"
)
// statusRecorder wraps http.ResponseWriter to capture the response status
// code so the Logger middleware can include it in the structured log line.
//
// The default status is initialised to http.StatusOK because net/http
// implicitly emits a 200 when a handler writes a body without calling
// WriteHeader explicitly; mirroring that behaviour keeps logs accurate.
type statusRecorder struct {
http.ResponseWriter
status int
}
// WriteHeader records the status code before delegating to the wrapped
// ResponseWriter so the original response semantics are preserved.
func (s *statusRecorder) WriteHeader(code int) {
s.status = code
s.ResponseWriter.WriteHeader(code)
}
// Logger returns HTTP middleware that emits a single structured log line
// per request once the downstream handler has finished. The line includes
// method, path, response status, elapsed duration in milliseconds, and the
@@ -36,13 +20,12 @@ func Logger(log *slog.Logger) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
rec := &statusRecorder{ResponseWriter: w, status: http.StatusOK}
next.ServeHTTP(rec, r)
metrics := httpsnoop.CaptureMetrics(next, w, r)
ctx := r.Context()
log.LogAttrs(ctx, slog.LevelInfo, "http",
slog.String("method", r.Method),
slog.String("path", r.URL.Path),
slog.Int("status", rec.status),
slog.Int("status", metrics.Code),
slog.Int64("duration_ms", time.Since(start).Milliseconds()),
slog.String("request_id", RequestIDFromContext(ctx)),
)