辅助中间件
HTTP 日志
HttpLogger 记录请求详情,支持敏感信息脱敏
HTTP 日志
HttpLogger 提供完整的 HTTP 请求/响应日志记录,支持调试模式下的详细信息记录和敏感数据脱敏。
HttpLogger
func HttpLogger() gin.HandlerFunc日志记录内容
请求开始阶段
基础信息(始终记录):
字段
类型
调试模式额外信息:
字段
类型
请求完成阶段
字段
类型
日志级别策略
| 状态码范围 | 日志级别 | 说明 |
|---|---|---|
| 2xx / 3xx | INFO | 成功请求 |
| 4xx | WARN | 客户端错误 |
| 5xx | ERROR | 服务器错误 |
敏感信息脱敏
请求头脱敏
| 处理方式 | 字段 |
|---|---|
| 完全移除 | Set-Cookie |
| 中间隐藏 | Authorization, Cookie, Proxy-Authorization, X-API-Key, Access-Token |
| 原样保留 | 其他字段 |
请求体脱敏
自动脱敏的 JSON 字段:
sensitiveFields := map[string]bool{
"password": true,
"passwd": true,
"token": true,
"secret": true,
"apikey": true,
"api_key": true,
"x-api-key": true,
"access_token": true,
"refresh_token": true,
"old_password": true,
"new_password": true,
"confirm_password": true,
}脱敏规则
func maskSensitive(value string) string {
// 短值(≤6字符):全部隐藏
if len(value) <= 6 {
return "******"
}
// 长值:保留首尾各3字符
return value[:3] + "..." + value[len(value)-3:]
}示例:
| 原始值 | 脱敏后 |
|---|---|
abc | ****** |
mySecretToken123 | myS...123 |
Bearer eyJhbGciOiJIUzI1NiIs... | Bea...s... |
支持的 Content-Type
请求体日志仅记录以下类型:
application/jsonapplication/x-www-form-urlencodedtext/xmlapplication/xml
使用示例
基础使用
func main() {
router := gin.New()
router.Use(xHelper.RequestContext())
router.Use(xHelper.PanicRecovery())
// 注册 HTTP 日志中间件
router.Use(xHelper.HttpLogger())
router.Run(":8080")
}日志输出示例
请求开始:
2024-01-15 10:30:00.123 [INFO] [abc123] [MIDE] 请求开始
method=POST
path=/api/users/login
client_ip=192.168.1.100
query=
headers={"Content-Type":"application/json","Authorization":"Bea...xyz"}
body={"username":"zhangsan","password":"******"}请求完成:
2024-01-15 10:30:00.456 [INFO] [abc123] [MIDE] 请求完成
status=200
latency_ms=333.45
client_ip=192.168.1.100错误请求:
2024-01-15 10:30:01.123 [WARN] [def456] [MIDE] 请求完成
status=400
latency_ms=12.34
client_ip=192.168.1.100请求体缓存
HttpLogger 会缓存请求体供后续中间件使用:
// 缓存请求体到 Context
c.Set("cached_request_body", bodyBytes)在验证器中使用:
func ValidatorMiddleware() gin.HandlerFunc {
return func(ctx *gin.Context) {
// 获取缓存的请求体
if body, exists := ctx.Get("cached_request_body"); exists {
// 使用缓存的请求体进行验证
}
ctx.Next()
}
}