2025-10-27 23:12:15 +08:00
|
|
|
|
package middleware
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"time"
|
|
|
|
|
|
|
2026-03-18 21:51:17 +08:00
|
|
|
|
"NetworkAuth/utils/logger"
|
|
|
|
|
|
|
2025-10-27 23:12:15 +08:00
|
|
|
|
"github.com/gin-gonic/gin"
|
2026-03-18 21:51:17 +08:00
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
|
|
"github.com/spf13/viper"
|
2025-10-27 23:12:15 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// 结构体定义
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
// LoggingMiddleware 日志记录中间件结构体
|
|
|
|
|
|
// 用于记录HTTP请求的详细信息,包括方法、路径、状态码和响应时间
|
|
|
|
|
|
type LoggingMiddleware struct {
|
|
|
|
|
|
logger *logger.Logger
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// 构造函数
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
// NewLoggingMiddleware 创建新的日志记录中间件实例
|
|
|
|
|
|
func NewLoggingMiddleware(logger *logger.Logger) *LoggingMiddleware {
|
|
|
|
|
|
return &LoggingMiddleware{
|
|
|
|
|
|
logger: logger,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// 中间件函数
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
// Handler 返回Gin中间件函数,用于记录HTTP请求日志
|
2026-03-18 21:51:17 +08:00
|
|
|
|
// 记录格式参考了更灵活的 NetworkAuth 实现,支持配置开关和日志级别检查
|
2025-10-27 23:12:15 +08:00
|
|
|
|
func (lm *LoggingMiddleware) Handler() gin.HandlerFunc {
|
|
|
|
|
|
return func(c *gin.Context) {
|
2026-03-18 21:51:17 +08:00
|
|
|
|
// 检查是否启用了访问日志
|
|
|
|
|
|
if !viper.GetBool("server.access_log") {
|
|
|
|
|
|
c.Next()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果日志级别不是Debug或更高(Trace),则不记录访问日志
|
|
|
|
|
|
// 避免在Info级别输出过多的访问日志干扰正常业务日志
|
|
|
|
|
|
if lm.logger.Level < logrus.DebugLevel {
|
|
|
|
|
|
c.Next()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-27 23:12:15 +08:00
|
|
|
|
start := time.Now()
|
2026-03-18 21:51:17 +08:00
|
|
|
|
path := c.Request.URL.Path
|
|
|
|
|
|
raw := c.Request.URL.RawQuery
|
2025-10-27 23:12:15 +08:00
|
|
|
|
|
|
|
|
|
|
// 处理请求
|
|
|
|
|
|
c.Next()
|
|
|
|
|
|
|
2026-03-18 21:51:17 +08:00
|
|
|
|
// 计算响应时间
|
2025-10-27 23:12:15 +08:00
|
|
|
|
duration := time.Since(start)
|
|
|
|
|
|
|
2026-03-18 21:51:17 +08:00
|
|
|
|
if raw != "" {
|
|
|
|
|
|
path = path + "?" + raw
|
|
|
|
|
|
}
|
2025-10-27 23:12:15 +08:00
|
|
|
|
|
2026-03-18 21:51:17 +08:00
|
|
|
|
// 记录请求日志
|
2025-10-27 23:12:15 +08:00
|
|
|
|
lm.logger.LogRequestWithHeaders(
|
|
|
|
|
|
c.Request.Method,
|
2026-03-18 21:51:17 +08:00
|
|
|
|
path,
|
|
|
|
|
|
c.ClientIP(), // 使用 Gin 内置的方法获取 IP
|
2025-10-27 23:12:15 +08:00
|
|
|
|
c.Writer.Status(),
|
|
|
|
|
|
duration,
|
2026-03-18 21:51:17 +08:00
|
|
|
|
c.Errors.ByType(gin.ErrorTypePrivate).String(),
|
2025-10-27 23:12:15 +08:00
|
|
|
|
c.Request.UserAgent(),
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// 公共函数
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
// WrapHandler 创建Gin日志中间件
|
|
|
|
|
|
// 使用全局日志记录器创建日志中间件
|
|
|
|
|
|
func WrapHandler() gin.HandlerFunc {
|
2026-03-18 21:51:17 +08:00
|
|
|
|
log := logger.GetLogger()
|
|
|
|
|
|
middleware := NewLoggingMiddleware(log)
|
2025-10-27 23:12:15 +08:00
|
|
|
|
return middleware.Handler()
|
|
|
|
|
|
}
|