Files
huobao-drama/infrastructure/database/custom_logger.go

104 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package database
import (
"context"
"strings"
"time"
"gorm.io/gorm/logger"
)
// CustomLogger 自定义 GORM logger截断过长的 SQL 参数(如 base64 数据)
type CustomLogger struct {
logger.Interface
}
// NewCustomLogger 创建自定义 logger
func NewCustomLogger() logger.Interface {
return &CustomLogger{
Interface: logger.Default.LogMode(logger.Silent),
}
}
// Trace 重写 Trace 方法,禁用 SQL 日志输出
func (l *CustomLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
// 不输出任何 SQL 日志
// 如果需要调试,可以临时取消注释下面的代码
/*
sql, rows := fc()
sql = truncateLongValues(sql)
elapsed := time.Since(begin)
if err != nil {
l.Interface.Error(ctx, "SQL error: %v [%v] %s", err, elapsed, sql)
} else {
l.Interface.Info(ctx, "[%.3fms] [rows:%d] %s", float64(elapsed.Nanoseconds())/1e6, rows, sql)
}
*/
}
// truncateLongValues 截断 SQL 中的长字符串值
func truncateLongValues(sql string) string {
// 查找 base64 格式的数据 (data:image/...;base64,...)
if strings.Contains(sql, "data:image/") && strings.Contains(sql, ";base64,") {
parts := strings.Split(sql, "\"")
for i, part := range parts {
if strings.HasPrefix(part, "data:image/") && strings.Contains(part, ";base64,") {
if len(part) > 100 {
// 保留前50字符添加截断标记
parts[i] = part[:50] + "...[base64 data truncated]"
}
}
}
sql = strings.Join(parts, "\"")
}
// 截断其他过长的值
if len(sql) > 5000 {
// 查找 VALUES 或 SET 后的内容
if idx := strings.Index(sql, " VALUES "); idx > 0 && len(sql) > idx+5000 {
sql = sql[:idx+5000] + "...[truncated]"
} else if idx := strings.Index(sql, " SET "); idx > 0 && len(sql) > idx+3000 {
sql = sql[:idx+3000] + "...[truncated]"
} else if len(sql) > 5000 {
sql = sql[:5000] + "...[truncated]"
}
}
return sql
}
// Info 实现 Info 方法
func (l *CustomLogger) Info(ctx context.Context, msg string, data ...interface{}) {
l.Interface.Info(ctx, msg, data...)
}
// Warn 实现 Warn 方法
func (l *CustomLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
l.Interface.Warn(ctx, msg, data...)
}
// Error 实现 Error 方法
func (l *CustomLogger) Error(ctx context.Context, msg string, data ...interface{}) {
// 检查并截断 data 中的长字符串
truncatedData := make([]interface{}, len(data))
for i, d := range data {
if str, ok := d.(string); ok && len(str) > 200 {
if strings.HasPrefix(str, "data:image/") {
truncatedData[i] = str[:50] + "...[base64 data]"
} else {
truncatedData[i] = str[:200] + "..."
}
} else {
truncatedData[i] = d
}
}
l.Interface.Error(ctx, msg, truncatedData...)
}
// LogMode 实现 LogMode 方法
func (l *CustomLogger) LogMode(level logger.LogLevel) logger.Interface {
newLogger := *l
newLogger.Interface = l.Interface.LogMode(level)
return &newLogger
}