diff options
Diffstat (limited to 'server/middleware/log.go')
-rw-r--r-- | server/middleware/log.go | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/server/middleware/log.go b/server/middleware/log.go new file mode 100644 index 0000000..a872daa --- /dev/null +++ b/server/middleware/log.go @@ -0,0 +1,56 @@ +package middleware + +import ( + "bytes" + "fmt" + "log/slog" + "net/http" + "os" + "time" +) + +type LoggingResponseWriter struct { + http.ResponseWriter + statusCode int + responseBody *bytes.Buffer +} + +func (w *LoggingResponseWriter) WriteHeader(code int) { + w.statusCode = code + w.ResponseWriter.WriteHeader(code) +} + +func (w *LoggingResponseWriter) Write(b []byte) (int, error) { + w.responseBody.Write(b) + return w.ResponseWriter.Write(b) +} + +func (w *LoggingResponseWriter) Flush() { + if f, ok := w.ResponseWriter.(http.Flusher); ok { + f.Flush() + } +} + +func Log(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + + rw := &LoggingResponseWriter{ + ResponseWriter: w, + statusCode: http.StatusOK, + responseBody: &bytes.Buffer{}, + } + + jsonHandler := slog.NewJSONHandler(os.Stderr, nil) + myslog := slog.New(jsonHandler) + next.ServeHTTP(rw, r) + + if rw.statusCode >= 400 { + myslog.Error("Request", "IP", r.RemoteAddr, "Method", r.Method, "Path", r.URL.Path, "Status", + rw.statusCode, "Duration", fmt.Sprint(time.Since(start)), "Response", rw.responseBody.String()) + } else { + myslog.Info("Request", "IP", r.RemoteAddr, "Method", r.Method, "Path", r.URL.Path, "Status", + rw.statusCode, "Duration", fmt.Sprint(time.Since(start))) + } + }) +} |