优化生产日志体积:访问降噪、压缩清理与退款告警节流
跳过轮询/封面等热路径成功请求,按日 gzip 并保留可配天数,退款 max-retry 汇总告警。
This commit is contained in:
@@ -8,24 +8,40 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// 成功且延迟低于该阈值的热路径请求不再写访问日志(错误/慢请求仍全量记录)。
|
||||
const slowRequestThresholdMs = 200
|
||||
|
||||
func RequestLogger(logger *zap.Logger) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
start := time.Now()
|
||||
c.Next()
|
||||
|
||||
latency := time.Since(start)
|
||||
latencyMs := float64(time.Since(start).Microseconds()) / 1000
|
||||
status := c.Writer.Status()
|
||||
path := c.Request.URL.Path
|
||||
route := c.FullPath()
|
||||
|
||||
if shouldSkipHTTPLog(path, route, status, latencyMs) {
|
||||
return
|
||||
}
|
||||
|
||||
fields := []zap.Field{
|
||||
zap.String("request_id", GetRequestID(c)),
|
||||
zap.String("method", c.Request.Method),
|
||||
zap.String("path", c.Request.URL.Path),
|
||||
zap.String("route", c.FullPath()),
|
||||
zap.Int("status", c.Writer.Status()),
|
||||
zap.Float64("latency_ms", float64(latency.Microseconds())/1000),
|
||||
zap.String("path", path),
|
||||
zap.String("route", route),
|
||||
zap.Int("status", status),
|
||||
zap.Float64("latency_ms", latencyMs),
|
||||
zap.String("client_ip", c.ClientIP()),
|
||||
zap.String("user_agent", c.GetHeader("User-Agent")),
|
||||
zap.String("referer", c.GetHeader("Referer")),
|
||||
zap.Int("response_size", c.Writer.Size()),
|
||||
}
|
||||
// 成功响应省略 UA/referer,错误与 4xx/5xx 保留完整现场
|
||||
if status >= 400 {
|
||||
fields = append(fields,
|
||||
zap.String("user_agent", c.GetHeader("User-Agent")),
|
||||
zap.String("referer", c.GetHeader("Referer")),
|
||||
)
|
||||
}
|
||||
if userID, ok := c.Get(ContextUserID); ok {
|
||||
fields = append(fields, zap.Any("user_id", userID))
|
||||
}
|
||||
@@ -37,12 +53,43 @@ func RequestLogger(logger *zap.Logger) gin.HandlerFunc {
|
||||
}
|
||||
|
||||
switch {
|
||||
case c.Writer.Status() >= 500:
|
||||
case status >= 500:
|
||||
logger.Error("http request", fields...)
|
||||
case c.Writer.Status() >= 400:
|
||||
case status >= 400:
|
||||
logger.Warn("http request", fields...)
|
||||
default:
|
||||
logger.Info("http request", fields...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shouldSkipHTTPLog 判断是否跳过写入:仅跳过「成功 + 非慢请求」的高频热路径。
|
||||
func shouldSkipHTTPLog(path, route string, status int, latencyMs float64) bool {
|
||||
if status >= 400 {
|
||||
return false
|
||||
}
|
||||
if latencyMs >= slowRequestThresholdMs {
|
||||
return false
|
||||
}
|
||||
return isHotPath(path, route)
|
||||
}
|
||||
|
||||
func isHotPath(path, route string) bool {
|
||||
if strings.HasSuffix(path, "/unread-count") {
|
||||
return true
|
||||
}
|
||||
if path == "/api/wallet/balance" {
|
||||
return true
|
||||
}
|
||||
if path == "/api/mobile-home-config" {
|
||||
return true
|
||||
}
|
||||
if strings.HasSuffix(path, "/cover") || route == "/api/listings/:id/cover" {
|
||||
return true
|
||||
}
|
||||
if path == "/api/files/object" || path == "/api/admin/files/object" ||
|
||||
route == "/api/files/object" || route == "/api/admin/files/object" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user