summaryrefslogtreecommitdiff
path: root/server/middleware/log.go
diff options
context:
space:
mode:
Diffstat (limited to 'server/middleware/log.go')
-rw-r--r--server/middleware/log.go56
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)))
+ }
+ })
+}