From a972953040d4bf77884da17b72e15643ce8beb3a Mon Sep 17 00:00:00 2001 From: Ryan McGuire Date: Sun, 24 Aug 2025 11:46:17 -0400 Subject: [PATCH] refactors HTTP server initialization, improves logging middleware, and updates documentation --- pkg/srv/http/http.go | 7 +++++-- pkg/srv/http/http_log.go | 36 ++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/pkg/srv/http/http.go b/pkg/srv/http/http.go index 8f7ec42..78bbea6 100644 --- a/pkg/srv/http/http.go +++ b/pkg/srv/http/http.go @@ -1,3 +1,6 @@ +// Package http provides functionality for setting up and managing HTTP servers. +// It includes features for health checks, Prometheus metrics, OpenTelemetry +// tracing, and custom middleware integration. package http import ( @@ -133,8 +136,8 @@ func prepHTTPServer(opts *opts.AppHTTP) *http.Server { } } -// Returns a shutdown func and a done channel if the -// server aborts abnormally. Returns error on failure to start +// InitHTTPServer returns a shutdown func and a done channel if the +// server aborts abnormally. Returns error on failure to start. func InitHTTPServer(opts *opts.AppHTTP) ( func(context.Context) error, <-chan any, error, ) { diff --git a/pkg/srv/http/http_log.go b/pkg/srv/http/http_log.go index 6e9b520..4304a36 100644 --- a/pkg/srv/http/http_log.go +++ b/pkg/srv/http/http_log.go @@ -41,29 +41,29 @@ func loggingMiddleware(appCtx context.Context, next http.Handler) http.Handler { Dur("duration", time.Since(start)). Msg("http request served") - // Log response body - trcLog := log.Trace(). - Str("path", r.URL.Path). - Int("statusCode", lrr.statusCode) + // Log response with body if not 204 + if lrr.statusCode != http.StatusNoContent { + trcLog := log.Trace(). + Str("path", r.URL.Path). + Int("statusCode", lrr.statusCode) + firstByte, err := lrr.body.ReadByte() + if err != nil { + trcLog.Err(errors.New("invalid response body")).Send() + return + } + lrr.body.UnreadByte() - // Check if it's JSON - firstByte, err := lrr.body.ReadByte() - if err != nil { - trcLog.Err(errors.New("invalid response body")).Send() - return + if firstByte == '{' { + trcLog = trcLog.RawJSON("response", lrr.body.Bytes()) + } else { + trcLog = trcLog.Bytes("response", lrr.body.Bytes()) + } + trcLog.Msg("http response") } - lrr.body.UnreadByte() - - if firstByte == '{' { - trcLog = trcLog.RawJSON("response", lrr.body.Bytes()) - } else { - trcLog = trcLog.Bytes("response", lrr.body.Bytes()) - } - trcLog.Msg("response payload") }) } -// Implement Flush to support the http.Flusher interface +// Flush implements the http.Flusher interface to allow flushing buffered data. func (w *LoggingResponseWriter) Flush() { if flusher, ok := w.ResponseWriter.(http.Flusher); ok { flusher.Flush()