package logger import ( "context" "fmt" "time" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gfile" "github.com/gogf/gf/v2/os/glog" "github.com/gogf/gf/v2/util/guid" ) var ( // 不同类型的日志记录器 InfoLogger *glog.Logger ErrorLogger *glog.Logger SQLLogger *glog.Logger ) // InitLogger 初始化日志系统 func InitLogger() { // 创建日志目录 createLogDirs() // 初始化不同类型的日志记录器 InfoLogger = initLoggerByType("log") ErrorLogger = initLoggerByType("error") SQLLogger = initLoggerByType("sql") g.Log().Info(context.Background(), "日志系统初始化完成") } // createLogDirs 创建日志目录 func createLogDirs() { // 创建主日志目录 if err := gfile.Mkdir("logs"); err != nil { g.Log().Fatalf(context.Background(), "创建主日志目录失败: %v", err) } // 创建子目录 dirs := []string{"logs/log", "logs/error", "logs/sql"} for _, dir := range dirs { if err := gfile.Mkdir(dir); err != nil { g.Log().Fatalf(context.Background(), "创建日志目录失败: %v", err) } } } // initLoggerByType 根据类型初始化日志记录器 func initLoggerByType(logType string) *glog.Logger { logger := glog.New() // 生成日志文件名: YYYY_MM_DD_uuid.log now := time.Now() uuid := guid.S() fileName := fmt.Sprintf("%s_%s.log", now.Format("2006_01_02"), uuid[:8], // 使用UUID的前8位 ) // 配置日志记录器 logger.SetConfigWithMap(g.Map{ "path": fmt.Sprintf("logs/%s", logType), // 日志目录统一到logs下 "file": fileName, // 日志文件名 "level": "all", // 日志级别 "stdout": true, // 同时输出到控制台 "rotateSize": "5M", // 5MB切割 "rotateExpire": "7d", // 保留7天 "rotateBackupLimit": 10, // 最多保留10个备份文件 "rotateBackupExpire": "30d", // 备份文件保留30天 "rotateBackupCompress": true, // 压缩备份文件 "rotateCheckInterval": "1m", // 每分钟检查一次是否需要切割 }) return logger } // LogInfo 记录普通信息日志 func LogInfo(ctx context.Context, format string, args ...interface{}) { if InfoLogger != nil { InfoLogger.Infof(ctx, format, args...) } } // LogError 记录错误日志 func LogError(ctx context.Context, format string, args ...interface{}) { if ErrorLogger != nil { ErrorLogger.Errorf(ctx, format, args...) } } // LogSQL 记录SQL执行日志 func LogSQL(ctx context.Context, format string, args ...interface{}) { if SQLLogger != nil { SQLLogger.Infof(ctx, format, args...) } } // LogDebug 记录调试日志 func LogDebug(ctx context.Context, format string, args ...interface{}) { if InfoLogger != nil { InfoLogger.Debugf(ctx, format, args...) } } // LogWarn 记录警告日志 func LogWarn(ctx context.Context, format string, args ...interface{}) { if InfoLogger != nil { InfoLogger.Warningf(ctx, format, args...) } } // LogFatal 记录致命错误日志 func LogFatal(ctx context.Context, format string, args ...interface{}) { if ErrorLogger != nil { ErrorLogger.Fatalf(ctx, format, args...) } } // LogPanic 记录panic日志 func LogPanic(ctx context.Context, format string, args ...interface{}) { if ErrorLogger != nil { ErrorLogger.Panicf(ctx, format, args...) } } // GetLoggerByType 根据类型获取日志记录器 func GetLoggerByType(logType string) *glog.Logger { switch logType { case "info", "log": return InfoLogger case "error": return ErrorLogger case "sql": return SQLLogger default: return InfoLogger } } // LogWithFields 记录带字段的日志 func LogWithFields(ctx context.Context, logType string, level string, message string, fields g.Map) { logger := GetLoggerByType(logType) if logger == nil { return } // 构建日志消息 logMsg := message if len(fields) > 0 { logMsg += " | Fields: " for k, v := range fields { logMsg += fmt.Sprintf("%s=%v ", k, v) } } switch level { case "debug": logger.Debug(ctx, logMsg) case "info": logger.Info(ctx, logMsg) case "warn", "warning": logger.Warning(ctx, logMsg) case "error": logger.Error(ctx, logMsg) case "fatal": logger.Fatal(ctx, logMsg) case "panic": logger.Panic(ctx, logMsg) default: logger.Info(ctx, logMsg) } } // LogRequest 记录请求日志 func LogRequest(ctx context.Context, method, uri, ip, userAgent string, duration time.Duration) { LogInfo(ctx, "请求日志 | Method: %s | URI: %s | IP: %s | UserAgent: %s | Duration: %v", method, uri, ip, userAgent, duration) } // LogResponse 记录响应日志 func LogResponse(ctx context.Context, status int, message string, data interface{}) { LogInfo(ctx, "响应日志 | Status: %d | Message: %s | HasData: %t", status, message, data != nil) } // LogDatabaseError 记录数据库错误 func LogDatabaseError(ctx context.Context, operation string, sql string, err error) { LogError(ctx, "数据库错误 | Operation: %s | SQL: %s | Error: %v", operation, sql, err) } // LogDatabaseQuery 记录数据库查询 func LogDatabaseQuery(ctx context.Context, sql string, args []interface{}, duration time.Duration, rowsAffected int64) { LogSQL(ctx, "SQL执行 | SQL: %s | Args: %v | Duration: %v | RowsAffected: %d", sql, args, duration, rowsAffected) } // LogRedisError 记录Redis错误 func LogRedisError(ctx context.Context, operation string, key string, err error) { LogError(ctx, "Redis错误 | Operation: %s | Key: %s | Error: %v", operation, key, err) } // LogRedisOperation 记录Redis操作 func LogRedisOperation(ctx context.Context, operation string, key string, value interface{}, duration time.Duration) { LogInfo(ctx, "Redis操作 | Operation: %s | Key: %s | HasValue: %t | Duration: %v", operation, key, value != nil, duration) } // LogBusinessError 记录业务错误 func LogBusinessError(ctx context.Context, module string, operation string, err error, extra g.Map) { fields := g.Map{ "module": module, "operation": operation, "error": err.Error(), } // 合并额外字段 for k, v := range extra { fields[k] = v } LogWithFields(ctx, "error", "error", "业务错误", fields) } // LogSystemError 记录系统错误 func LogSystemError(ctx context.Context, component string, err error, extra g.Map) { fields := g.Map{ "component": component, "error": err.Error(), } // 合并额外字段 for k, v := range extra { fields[k] = v } LogWithFields(ctx, "error", "error", "系统错误", fields) }