Skip to content

请求日志

go
func LoggerWithTrace() gin.HandlerFunc {

	// ANSI 颜色码
	const (
		colorReset   = "\033[0m"
		colorRed     = "\033[31m"
		colorGreen   = "\033[32m"
		colorYellow  = "\033[33m"
		colorBlue    = "\033[34m"
		colorMagenta = "\033[35m"
		colorCyan    = "\033[36m"
	)

	// 状态码颜色
	colorForStatus := func(code int) string {
		switch {
		case code >= 200 && code < 300:
			return colorGreen
		case code >= 300 && code < 400:
			return colorBlue
		case code >= 400 && code < 500:
			return colorYellow
		default:
			return colorRed
		}
	}

	// HTTP 方法颜色
	colorForMethod := func(method string) string {
		switch method {
		case "GET":
			return colorCyan
		case "POST":
			return colorGreen
		case "PUT":
			return colorYellow
		case "DELETE":
			return colorRed
		default:
			return colorMagenta
		}
	}

	// 日志中耗时超过阈值标红
	formatLatency := func(latency time.Duration) string {
		if latency > 500*time.Millisecond {
			return fmt.Sprintf("%s%v%s", colorRed, latency, colorReset)
		}
		return fmt.Sprintf("%v", latency)
	}

	return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {

		traceID := "-"
		if v, ok := param.Keys["trace_id"]; ok {
			if s, ok := v.(string); ok {
				traceID = s
			}
		}

		statusColor := colorForStatus(param.StatusCode)
		methodColor := colorForMethod(param.Method)
		latencyStr := formatLatency(param.Latency)

		return fmt.Sprintf(
			"%s | %s%3d%s | %s%-7s%s %s | %s | %15s | trace=%s\n",
			param.TimeStamp.Format("2006-01-02 15:04:05"), // 时间戳
			statusColor, param.StatusCode, colorReset, // 状态码
			methodColor, param.Method, colorReset, // HTTP 方法
			param.Path,     // 请求路径
			latencyStr,     // 耗时
			param.ClientIP, // IP
			traceID,        // trace_id
		)
	})
}