Files
server/docs/SYSTEM_LOG_GUIDE.md
T
2026-01-16 15:49:34 +08:00

9.2 KiB

系统日志记录指南

日志级别记录策略

需要记录到系统日志的级别

1. error(错误)级别 - 必须记录

  • 数据库操作失败 - 创建、更新、删除数据失败
  • 文件操作失败 - 保存、删除文件失败
  • 系统服务异常 - 缓存、队列、分片表等基础设施错误
  • 关键业务逻辑错误 - 订单创建失败、支付失败等影响业务流程的错误
  • 外部服务调用失败 - 第三方API调用失败

2. warning(警告)级别 - 应该记录

  • 非关键操作失败但可继续 - 如分片删除失败、分片读取失败(不影响主流程)
  • 资源清理失败 - 临时文件清理失败、缓存清理失败等
  • 性能警告 - 操作耗时过长、资源使用率高等
  • 配置问题 - 配置缺失或无效,但系统仍可运行

不需要记录到系统日志的级别

3. info(信息)级别 - 不记录到数据库

  • 正常业务流程 - 订单创建成功、支付成功等
  • 操作统计 - 用户登录、数据导出等
  • 系统状态 - 服务启动、配置加载等
  • 说明:这些信息只在文件日志中记录,不写入数据库,避免产生大量日志

4. debug(调试)级别 - 不记录到数据库

  • 调试信息 - 变量值、函数调用栈等
  • 详细执行流程 - 仅在开发环境需要
  • 说明:只在开发环境的文件日志中记录,生产环境通常不记录

原则总结

需要记录到系统日志的错误:

  1. 数据库操作失败 - 创建、更新、删除数据失败
  2. 文件操作失败 - 保存、删除文件失败
  3. 系统服务异常 - 缓存、队列、分片表等基础设施错误
  4. 关键业务逻辑错误 - 订单创建失败、支付失败等影响业务流程的错误
  5. 外部服务调用失败 - 第三方API调用失败

需要记录到系统日志的警告:

  1. 非关键操作失败 - 不影响主流程但需要关注的问题
  2. 资源清理失败 - 临时文件、缓存清理失败等
  3. 性能警告 - 需要监控的性能问题

不需要记录到系统日志的错误:

  1. 参数验证错误 - 如"订单ID不能为空"、"user_id不能为空"
  2. 业务逻辑的正常错误 - 如"订单不存在"、"用户不存在"、"记录不存在"
  3. 查询不存在的记录 - 这些是正常的业务场景,不是系统错误

需要记录的错误清单

1. order_service.go

需要记录

  • fmt.Errorf("获取锁失败: %v", err) - 系统服务异常
  • fmt.Errorf("生成唯一订单号失败,请重试") - 关键业务逻辑错误
  • fmt.Errorf("创建订单失败: %v", err) - 数据库操作失败
  • fmt.Errorf("创建订单详情失败: %v", err) - 数据库操作失败
  • fmt.Errorf("删除订单详情失败: %v", err) - 数据库操作失败

不需要记录

  • fmt.Errorf("订单ID不能为空") - 参数验证错误
  • fmt.Errorf("订单不存在") - 业务逻辑的正常错误(多次出现)

2. attachment_service.go

需要记录

  • fmt.Errorf("保存分片失败: %w", err) - 文件操作失败
  • fmt.Errorf("创建目标目录失败: %w", err) - 文件操作失败
  • fmt.Errorf("创建目标文件失败: %w", err) - 文件操作失败
  • fmt.Errorf("写入分片 %d 失败: %w", i, err) - 文件操作失败
  • fmt.Errorf("关闭目标文件失败: %w", err) - 文件操作失败
  • fmt.Errorf("创建附件记录失败: %w", err) - 数据库操作失败
  • fmt.Errorf("保存文件失败: %w", err) - 文件操作失败
  • fmt.Errorf("更新附件显示名称失败: %v", err) - 数据库操作失败
  • fmt.Errorf("删除文件失败: %w", err) - 文件操作失败
  • fmt.Errorf("删除附件记录失败: %w", err) - 数据库操作失败

不需要记录

  • fmt.Errorf("分片索引无效") - 参数验证错误
  • fmt.Errorf("分片 %d 不存在", i) - 业务逻辑的正常错误
  • fmt.Errorf("附件不存在: %v", err) - 业务逻辑的正常错误(多次出现)
  • fmt.Errorf("查询附件失败: %v", err) - 查询错误,但可能是正常的"不存在"情况

3. user_service.go

需要记录

  • fmt.Errorf("更新用户余额失败: %v", err) - 数据库操作失败
  • fmt.Errorf("创建余额变动记录失败: %v", err) - 数据库操作失败

不需要记录

  • fmt.Errorf("用户不存在: %v", err) - 业务逻辑的正常错误
  • fmt.Errorf("余额不足,当前余额: %.2f", user.Balance) - 业务逻辑的正常错误
  • fmt.Errorf("无效的变动类型: %s", logType) - 参数验证错误

4. user_balance_log_service.go

需要记录

  • fmt.Errorf("创建余额变动记录失败: %v", err) - 数据库操作失败

不需要记录

  • fmt.Errorf("user_id 不能为空,GORM Sharding 需要 ShardingKey") - 参数验证错误(多次出现)
  • fmt.Errorf("用户不存在: %v", err) - 业务逻辑的正常错误

5. export_service.go

需要记录

  • fmt.Errorf("写入CSV表头失败: %w", err) - 文件操作失败
  • fmt.Errorf("写入CSV数据失败: %w", err) - 文件操作失败
  • fmt.Errorf("CSV写入失败: %w", err) - 文件操作失败
  • fmt.Errorf("保存文件失败: %w", err) - 文件操作失败

不需要记录

  • fmt.Errorf("Excel导出功能暂未实现,请使用CSV格式") - 功能未实现,不是错误

6. export_record_service.go

需要记录

  • fmt.Errorf("删除导出记录失败: %v", err) - 数据库操作失败
  • fmt.Errorf("批量删除导出记录失败: %v", err) - 数据库操作失败

不需要记录

  • fmt.Errorf("导出记录不存在: %v", err) - 业务逻辑的正常错误(多次出现)
  • fmt.Errorf("查询导出记录失败: %v", err) - 查询错误

7. 各种 service 的 GetByID 方法

不需要记录(统一处理)

以下错误都是查询不存在的记录,属于正常业务场景:

  • fmt.Errorf("系统日志不存在: %v", err)
  • fmt.Errorf("操作日志不存在: %v", err)
  • fmt.Errorf("登录日志不存在: %v", err)
  • fmt.Errorf("部门不存在: %v", err)
  • fmt.Errorf("权限不存在: %v", err)
  • fmt.Errorf("角色不存在: %v", err)
  • fmt.Errorf("黑名单不存在: %v", err)
  • fmt.Errorf("字典不存在: %v", err)
  • fmt.Errorf("管理员不存在: %v", err)

8. 基础设施相关

需要记录

  • providers/database_service_provider.go: fmt.Errorf("获取 GORM DB 实例失败: %v", err) - 系统服务异常
  • providers/database_service_provider.go: fmt.Errorf("注册 GORM Sharding 插件失败: %v", err) - 系统服务异常
  • utils/gorm_sharding.go: fmt.Errorf("ORM 未初始化") - 系统服务异常
  • utils/gorm_sharding.go: fmt.Errorf("无法通过反射获取原生 GORM DB 实例...") - 系统服务异常
  • utils/sharding_helper.go: fmt.Errorf("查询分表失败: %v", err) - 系统服务异常(多次出现)
  • services/sharding_service.go: fmt.Errorf("创建分表 %s 失败: %v", tableName, err) - 系统服务异常
  • console/commands/create_order_sharding_tables.go: fmt.Errorf("创建分表 %s 失败: %v", tableName, err) - 系统服务异常(多次出现)
  • console/commands/queue_clear.go: 所有 Redis 相关错误 - 系统服务异常
  • console/commands/queue_stats.go: 所有 Redis 相关错误 - 系统服务异常

不需要记录

  • console/commands/create_order_sharding_tables.go: fmt.Errorf("月份格式错误...") - 参数验证错误

9. 控制器相关

不需要记录

  • order_controller.go: 时间格式验证错误 - 参数验证错误

10. 其他服务

需要记录

  • google_authenticator_service.go: 所有错误 - 外部服务调用失败

不需要记录

  • admin_service.go: fmt.Errorf("查询管理员失败: %v", err) - 查询错误,可能是正常的"不存在"

实现建议

方式1:使用 errorlog.RecordHTTP(推荐)

import "goravel/app/utils/errorlog"

// 在 HTTP 请求处理中
if err != nil {
    errorlog.RecordHTTP(ctx, "order", "创建订单失败", map[string]any{
        "error": err.Error(),
        "user_id": userID,
        "amount": amount,
    }, "创建订单失败: %v", err)
    return nil, nil, fmt.Errorf("创建订单失败: %v", err)
}

方式2:使用 response.ErrorWithLog

import "goravel/app/http/response"

// 在控制器中
if err != nil {
    return response.ErrorWithLog(ctx, http.StatusInternalServerError, "create_failed", "order", "创建订单失败", err)
}

方式3:使用 systemLogService.RecordHTTP

import "goravel/app/services"

systemLogService := services.NewSystemLogService()
_ = systemLogService.RecordHTTP(ctx, "error", "order", "创建订单失败", map[string]any{
    "error": err.Error(),
    "user_id": userID,
})

注意事项

  1. 避免重复记录:如果已经在 controller 层记录了日志,service 层就不需要再记录
  2. 记录上下文信息:尽量记录相关的业务数据(如订单ID、用户ID等),方便排查问题
  3. 日志级别:大部分错误使用 "error" 级别,警告使用 "warning" 级别
  4. 性能考虑:系统日志记录是异步的,但也要避免在高频操作中记录过多日志