package server import ( "fmt" "github.com/go-chi/chi/v5/middleware" "github.com/sirupsen/logrus" "net/http" "time" ) func newStructuredLogger(logger *logrus.Logger) func(next http.Handler) http.Handler { return middleware.RequestLogger(&StructuredLogger{logger}) } type StructuredLogger struct { Logger *logrus.Logger } func (l *StructuredLogger) NewLogEntry(r *http.Request) middleware.LogEntry { entry := &StructuredLoggerEntry{Logger: logrus.NewEntry(l.Logger)} logFields := logrus.Fields{} logFields["proto"] = r.Proto logFields["method"] = r.Method logFields["remote"] = r.RemoteAddr logFields["uri"] = r.RequestURI entry.Logger = entry.Logger.WithFields(logFields) entry.Logger.Infoln("request started") return entry } type StructuredLoggerEntry struct { Logger logrus.FieldLogger } func (l *StructuredLoggerEntry) Write(status, bytes int, header http.Header, elapsed time.Duration, extra interface{}) { l.Logger = l.Logger.WithFields(logrus.Fields{ "resp_status": status, "resp_bytes_length": bytes, "resp_elapsed_ms": float64(elapsed.Nanoseconds()) / 1000000.0, }) l.Logger.Infoln("request complete") } func (l *StructuredLoggerEntry) Panic(v interface{}, stack []byte) { l.Logger = l.Logger.WithFields(logrus.Fields{ "stack": string(stack), "panic": fmt.Sprintf("%+v", v), }) }