add middlewares
This commit is contained in:
75
pkgs/middleware/httplog/log.go
Normal file
75
pkgs/middleware/httplog/log.go
Normal file
@ -0,0 +1,75 @@
|
||||
package httplog
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.jeffthecoder.xyz/guochao/cache-proxy/pkgs/middleware/handlerlog"
|
||||
)
|
||||
|
||||
type ctxKey int
|
||||
|
||||
const (
|
||||
loggerKey ctxKey = iota
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
LogStart bool
|
||||
LogStartLevel slog.Level
|
||||
|
||||
LogFinish bool
|
||||
LogFinishLevel slog.Level
|
||||
}
|
||||
|
||||
type responseRecorder struct {
|
||||
http.ResponseWriter
|
||||
StatusCode int
|
||||
}
|
||||
|
||||
func (recorder *responseRecorder) WriteHeader(statusCode int) {
|
||||
recorder.StatusCode = statusCode
|
||||
|
||||
recorder.ResponseWriter.WriteHeader(statusCode)
|
||||
}
|
||||
|
||||
func Log(config Config) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
args := []any{
|
||||
"remote_addr", r.RemoteAddr,
|
||||
"host", r.Host,
|
||||
"path", r.URL.Path,
|
||||
}
|
||||
|
||||
if pattern, handlerFound := handlerlog.Pattern(r); handlerFound {
|
||||
args = append(args, "handler", pattern)
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
if config.LogStart {
|
||||
slog.With(append(args, "time", startTime)...).Log(r.Context(), config.LogStartLevel, "request start")
|
||||
}
|
||||
recorder := &responseRecorder{ResponseWriter: w, StatusCode: 200}
|
||||
next.ServeHTTP(recorder, r.WithContext(context.WithValue(r.Context(), loggerKey, slog.With(args...))))
|
||||
if config.LogFinish {
|
||||
finishTime := time.Now()
|
||||
slog.With(append(args, "time", finishTime, "duration", finishTime.Sub(startTime), "status", recorder.StatusCode)...).Log(r.Context(), config.LogFinishLevel, "request finished")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Logger(r *http.Request) *slog.Logger {
|
||||
if logger, ok := r.Context().Value(loggerKey).(*slog.Logger); ok {
|
||||
return logger.With("time", time.Now())
|
||||
}
|
||||
|
||||
return slog.With(
|
||||
"remote_addr", r.RemoteAddr,
|
||||
"host", r.Host,
|
||||
"path", r.URL.Path,
|
||||
"time", time.Now(),
|
||||
)
|
||||
}
|
Reference in New Issue
Block a user