chore(git): 更新.gitignore以忽略新的本地文件
Some checks failed
SonarQube Analysis / sonarqube (push) Has been cancelled
Some checks failed
SonarQube Analysis / sonarqube (push) Has been cancelled
This commit is contained in:
367
.qoder/repowiki/zh/content/配置管理/日志配置.md
Normal file
367
.qoder/repowiki/zh/content/配置管理/日志配置.md
Normal file
@@ -0,0 +1,367 @@
|
||||
# 日志配置
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [cmd/server/main.go](file://cmd/server/main.go)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go)
|
||||
- [go.mod](file://go.mod)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件面向 CarrotSkin 项目的开发者与运维人员,系统性说明日志系统的配置与使用方式。重点围绕以下配置项展开:log.level、format、output、max_size、max_backups、max_age 和 compress;并结合 LogConfig 结构体与实际代码实现,给出不同日志级别选择策略、JSON 格式与文本格式的适用场景、以及基于大小与天数的日志轮转工作机制。最后提供生产环境监控集成建议与最佳实践。
|
||||
|
||||
## 项目结构
|
||||
日志系统由“配置加载层”“日志工厂层”“全局管理器层”“中间件与业务使用层”四部分组成:
|
||||
- 配置加载层:从环境变量加载并解析为 Config,其中包含 LogConfig 字段。
|
||||
- 日志工厂层:根据 LogConfig 构建 zap.Logger。
|
||||
- 全局管理器层:提供 Init、GetLogger、MustGetLogger 等接口,确保单例与线程安全。
|
||||
- 中间件与业务使用层:通过中间件注入日志实例,统一记录 HTTP 请求与异常恢复。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
A["配置加载<br/>pkg/config/config.go"] --> B["日志工厂<br/>pkg/logger/logger.go"]
|
||||
B --> C["全局管理器<br/>pkg/logger/manager.go"]
|
||||
C --> D["中间件使用<br/>internal/middleware/logger.go"]
|
||||
C --> E["恢复中间件<br/>internal/middleware/recovery.go"]
|
||||
C --> F["应用入口初始化<br/>cmd/server/main.go"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L1-L305)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L1-L69)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L1-L40)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L1-L30)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L1-L124)
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L1-L305)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L1-L69)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L1-L124)
|
||||
|
||||
## 核心组件
|
||||
- LogConfig 结构体:定义日志系统的核心配置项,来源于环境变量映射。
|
||||
- New:根据 LogConfig 构建 zap.Logger,支持 JSON/Console 编码器、stdout 或文件输出。
|
||||
- Init/GetLogger/MustGetLogger:全局单例管理,保证线程安全与幂等初始化。
|
||||
- 中间件 Logger/Recovery:在请求处理前后记录日志,并在 panic 时记录堆栈与上下文。
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L79-L88)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L1-L69)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L1-L40)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L1-L30)
|
||||
|
||||
## 架构总览
|
||||
下图展示了从配置到日志输出的关键流程:应用启动时加载配置,初始化日志管理器,随后中间件与业务代码通过全局日志实例进行记录。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as "应用入口<br/>cmd/server/main.go"
|
||||
participant Cfg as "配置加载<br/>pkg/config/config.go"
|
||||
participant LMgr as "日志管理器<br/>pkg/logger/manager.go"
|
||||
participant LNew as "日志工厂<br/>pkg/logger/logger.go"
|
||||
participant MW as "中间件<br/>internal/middleware/logger.go"
|
||||
participant Rec as "恢复中间件<br/>internal/middleware/recovery.go"
|
||||
App->>Cfg : 加载配置
|
||||
Cfg-->>App : 返回 Config(LogConfig)
|
||||
App->>LMgr : Init(LogConfig)
|
||||
LMgr->>LNew : New(LogConfig)
|
||||
LNew-->>LMgr : 返回 zap.Logger
|
||||
LMgr-->>App : 初始化完成
|
||||
App->>MW : 注入日志实例
|
||||
App->>Rec : 注入日志实例
|
||||
MW-->>App : 记录请求日志
|
||||
Rec-->>App : 记录 panic 与堆栈
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L27-L40)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L108-L133)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L20-L29)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L14-L68)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L10-L39)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L11-L29)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 配置项详解与选择策略
|
||||
- log.level
|
||||
- 取值范围:debug、info、warn、error,默认 info。
|
||||
- 选择策略:
|
||||
- 开发/调试:debug,便于定位问题。
|
||||
- 生产:info,平衡可观测性与性能;仅在需要深入排查时临时提升到 debug。
|
||||
- 严重问题:error,聚焦错误事件,避免过多噪声。
|
||||
- log.format
|
||||
- 取值:console、json。
|
||||
- 适用场景:
|
||||
- console:本地开发终端阅读友好,便于快速定位。
|
||||
- json:便于日志收集与结构化分析,适合生产与集中化监控。
|
||||
- log.output
|
||||
- 取值:空/“stdout”表示输出到标准输出;其他路径将自动创建目录并写入文件。
|
||||
- 适用场景:
|
||||
- 容器化部署:stdout,配合容器日志采集。
|
||||
- 传统部署:文件路径,结合日志轮转策略。
|
||||
- log.max_size、log.max_backups、log.max_age、log.compress
|
||||
- 作用:控制日志轮转策略(按大小与天数)与压缩开关。
|
||||
- 工作机制(基于大小与天数):
|
||||
- 当单个日志文件达到 max_size(MB)时触发轮转。
|
||||
- 最多保留 max_backups 个历史备份文件。
|
||||
- 历史文件保留不超过 max_age(天)。
|
||||
- compress=true 时对旧文件进行压缩,节省磁盘空间。
|
||||
- 注意:当前代码实现中并未直接使用上述字段进行轮转配置,而是采用文件输出与基础写入同步。若需启用基于大小/天数的轮转,可在日志工厂中引入外部轮转库(如 lumberjack)并传入上述参数。
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L79-L88)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L170-L178)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L43-L60)
|
||||
|
||||
### 日志级别选择策略
|
||||
- debug:用于开发阶段的详细追踪,包含大量上下文信息。
|
||||
- info:生产环境默认级别,记录关键业务事件与系统状态。
|
||||
- warn:潜在问题或异常流程,需关注但不影响整体运行。
|
||||
- error:错误事件,必须处理与上报。
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L16-L28)
|
||||
|
||||
### JSON 格式与文本格式的适用场景
|
||||
- JSON:
|
||||
- 优点:结构化强,便于日志聚合、检索与告警。
|
||||
- 适用:生产环境、集中化日志平台(如 ELK、Loki、Cloud Logging)。
|
||||
- Console:
|
||||
- 优点:人类可读性强,适合本地开发与快速排障。
|
||||
- 适用:本地调试、临时诊断。
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L30-L41)
|
||||
|
||||
### 日志轮转策略(基于大小与天数)
|
||||
- 当前实现要点:
|
||||
- 输出到文件时会自动创建目录并追加写入。
|
||||
- 未显式配置基于大小/天数的轮转。
|
||||
- 建议扩展方案:
|
||||
- 引入外部轮转库(如 lumberjack),在 New 中根据 max_size、max_backups、max_age、compress 进行轮转配置。
|
||||
- 将轮转配置作为可选参数传入,保持现有接口兼容。
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L43-L60)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L79-L88)
|
||||
|
||||
### 日志工厂与全局管理器
|
||||
- New:根据 LogConfig 构建 zap.Logger,设置级别、编码器与输出目标。
|
||||
- Init/GetLogger/MustGetLogger:提供线程安全的单例初始化与获取能力,避免重复初始化。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class LogConfig {
|
||||
+string level
|
||||
+string format
|
||||
+string output
|
||||
+int max_size
|
||||
+int max_backups
|
||||
+int max_age
|
||||
+bool compress
|
||||
}
|
||||
class LoggerFactory {
|
||||
+New(cfg LogConfig) *zap.Logger
|
||||
}
|
||||
class LogManager {
|
||||
+Init(cfg LogConfig) error
|
||||
+GetLogger() (*zap.Logger, error)
|
||||
+MustGetLogger() *zap.Logger
|
||||
}
|
||||
LogConfig --> LoggerFactory : "输入"
|
||||
LoggerFactory --> LogManager : "被调用"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L79-L88)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L14-L68)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L20-L46)
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L14-L68)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
|
||||
### 中间件与业务使用
|
||||
- Logger 中间件:记录每次 HTTP 请求的方法、路径、状态码、耗时、客户端 IP、User-Agent 等。
|
||||
- Recovery 中间件:捕获 panic 并记录错误、路径、方法、IP 与完整堆栈,返回统一错误响应。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "客户端"
|
||||
participant Router as "Gin 路由"
|
||||
participant MW as "日志中间件"
|
||||
participant Handler as "业务处理器"
|
||||
participant Rec as "恢复中间件"
|
||||
Client->>Router : 发起请求
|
||||
Router->>MW : 进入日志中间件
|
||||
MW->>MW : 记录请求开始时间与上下文
|
||||
MW->>Handler : 继续处理
|
||||
Handler-->>MW : 返回响应
|
||||
MW->>MW : 记录状态码、耗时、IP、UA
|
||||
MW-->>Router : 返回响应
|
||||
Note over MW : 若发生 panic,由恢复中间件接管
|
||||
Router->>Rec : 进入恢复中间件
|
||||
Rec->>Rec : 记录错误与堆栈
|
||||
Rec-->>Client : 返回 500 错误
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L10-L39)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L11-L29)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L81-L90)
|
||||
|
||||
章节来源
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L1-L40)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L1-L30)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L81-L90)
|
||||
|
||||
## 依赖关系分析
|
||||
- 外部依赖:zap 用于高性能日志记录;viper 用于配置加载;godotenv 用于 .env 支持。
|
||||
- 内部依赖:配置模块提供 LogConfig;日志模块提供 Init/GetLogger;中间件依赖日志实例。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "外部依赖"
|
||||
Z["go.uber.org/zap"]
|
||||
V["github.com/spf13/viper"]
|
||||
D["github.com/joho/godotenv"]
|
||||
end
|
||||
subgraph "内部模块"
|
||||
CFG["pkg/config/config.go"]
|
||||
LOGF["pkg/logger/logger.go"]
|
||||
LOGM["pkg/logger/manager.go"]
|
||||
MWL["internal/middleware/logger.go"]
|
||||
MWR["internal/middleware/recovery.go"]
|
||||
MAIN["cmd/server/main.go"]
|
||||
end
|
||||
V --> CFG
|
||||
D --> CFG
|
||||
CFG --> LOGM
|
||||
LOGM --> LOGF
|
||||
MAIN --> LOGM
|
||||
MAIN --> MWL
|
||||
MAIN --> MWR
|
||||
Z --> LOGF
|
||||
Z --> MWL
|
||||
Z --> MWR
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [go.mod](file://go.mod#L7-L22)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L1-L305)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L1-L69)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L1-L40)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L1-L30)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L1-L124)
|
||||
|
||||
章节来源
|
||||
- [go.mod](file://go.mod#L7-L22)
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L1-L305)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L1-L69)
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L1-L51)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L1-L40)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L1-L30)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L1-L124)
|
||||
|
||||
## 性能考量
|
||||
- 使用 zap:具备高性能与零分配特性,适合高并发场景。
|
||||
- 选择合适的日志级别:生产环境默认 info,避免 debug 的额外开销。
|
||||
- 输出目标选择:stdout 便于容器日志采集;文件输出需注意磁盘 IO 与轮转策略。
|
||||
- 压缩与保留策略:合理设置 max_size、max_backups、max_age 与 compress,平衡磁盘占用与检索效率。
|
||||
|
||||
## 故障排查指南
|
||||
- 未初始化日志即使用:
|
||||
- 现象:调用 GetLogger 返回错误提示“日志未初始化,请先调用 logger.Init()”。
|
||||
- 排查:确认应用入口是否在启动时调用了 logger.Init(cfg.Log)。
|
||||
- 输出到文件失败:
|
||||
- 现象:初始化日志时报错,无法打开文件。
|
||||
- 排查:检查 log.output 指定路径是否存在写权限,目录是否可创建。
|
||||
- panic 未记录:
|
||||
- 现象:服务崩溃但无日志记录。
|
||||
- 排查:确认已注册 Recovery 中间件并注入了日志实例。
|
||||
- 日志轮转未生效:
|
||||
- 现象:日志文件持续增大。
|
||||
- 排查:当前实现未使用 max_size/max_backups/max_age/compress 进行轮转,需扩展轮转逻辑。
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/manager.go](file://pkg/logger/manager.go#L31-L37)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L43-L60)
|
||||
- [internal/middleware/recovery.go](file://internal/middleware/recovery.go#L11-L29)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go#L81-L90)
|
||||
|
||||
## 结论
|
||||
- CarrotSkin 的日志系统以 zap 为核心,通过配置驱动实现灵活的日志级别、编码器与输出目标切换。
|
||||
- 当前未直接启用基于大小/天数的轮转,建议在日志工厂中引入轮转库并使用 LogConfig 的 max_size、max_backups、max_age、compress 字段。
|
||||
- 在生产环境中推荐使用 JSON 格式与 stdout 输出,结合集中化日志平台与告警策略,提升可观测性与可维护性。
|
||||
|
||||
## 附录
|
||||
|
||||
### 配置项一览与默认值
|
||||
- log.level:默认 info
|
||||
- log.format:默认 json
|
||||
- log.output:默认 logs/app.log(文件输出)
|
||||
- log.max_size:默认 100 MB
|
||||
- log.max_backups:默认 3
|
||||
- log.max_age:默认 28 天
|
||||
- log.compress:默认 true
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L170-L178)
|
||||
|
||||
### 环境变量映射
|
||||
- LOG_LEVEL → log.level
|
||||
- LOG_FORMAT → log.format
|
||||
- LOG_OUTPUT → log.output
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L224-L228)
|
||||
|
||||
### 配置示例与最佳实践
|
||||
- 示例一:本地开发(控制台输出,便于阅读)
|
||||
- LOG_LEVEL=debug
|
||||
- LOG_FORMAT=console
|
||||
- LOG_OUTPUT=stdout
|
||||
- 示例二:生产(结构化日志,集中化采集)
|
||||
- LOG_LEVEL=info
|
||||
- LOG_FORMAT=json
|
||||
- LOG_OUTPUT=stdout
|
||||
- 示例三:传统服务器(文件输出,配合轮转)
|
||||
- LOG_LEVEL=info
|
||||
- LOG_FORMAT=json
|
||||
- LOG_OUTPUT=/var/log/carrotskin/app.log
|
||||
- max_size=100
|
||||
- max_backups=3
|
||||
- max_age=28
|
||||
- compress=true
|
||||
- 最佳实践:
|
||||
- 生产环境统一使用 JSON 格式与 stdout,便于容器日志采集。
|
||||
- 严格控制日志级别,避免 debug 在生产长期开启。
|
||||
- 对关键路径增加结构化字段(如用户 ID、请求 ID),便于关联追踪。
|
||||
- 在中间件中统一记录请求上下文,确保异常时具备足够信息。
|
||||
- 如需文件轮转,建议在日志工厂中引入轮转库并使用上述配置项。
|
||||
|
||||
章节来源
|
||||
- [pkg/config/config.go](file://pkg/config/config.go#L170-L178)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go#L30-L41)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go#L30-L37)
|
||||
Reference in New Issue
Block a user