67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package middleware
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.toowon.com/jimmy/go-common/logger"
|
|
)
|
|
|
|
// responseWriter 包装 ResponseWriter 以捕获状态码
|
|
type responseWriter struct {
|
|
http.ResponseWriter
|
|
statusCode int
|
|
}
|
|
|
|
func (rw *responseWriter) WriteHeader(statusCode int) {
|
|
rw.statusCode = statusCode
|
|
rw.ResponseWriter.WriteHeader(statusCode)
|
|
}
|
|
|
|
// LoggingConfig 日志中间件配置
|
|
type LoggingConfig struct {
|
|
Logger *logger.Logger
|
|
SkipPaths []string
|
|
}
|
|
|
|
// Logging HTTP 访问日志(固定 Info 级别)
|
|
func Logging(config *LoggingConfig) func(http.Handler) http.Handler {
|
|
if config == nil {
|
|
config = &LoggingConfig{}
|
|
}
|
|
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if shouldSkipPath(r.URL.Path, config.SkipPaths) {
|
|
next.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
start := time.Now()
|
|
rw := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
|
|
next.ServeHTTP(rw, r)
|
|
|
|
fields := map[string]any{
|
|
"method": r.Method,
|
|
"path": r.URL.Path,
|
|
"duration": time.Since(start).Milliseconds(),
|
|
}
|
|
|
|
log := logger.FromContext(r.Context())
|
|
if config.Logger != nil {
|
|
log = logger.FromContextWithLogger(r.Context(), config.Logger)
|
|
}
|
|
log.Info("HTTP Request", fields)
|
|
})
|
|
}
|
|
}
|
|
|
|
func shouldSkipPath(path string, skipPaths []string) bool {
|
|
for _, skip := range skipPaths {
|
|
if path == skip {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|