341 lines
8.6 KiB
Markdown
341 lines
8.6 KiB
Markdown
|
|
# 🚀 新日志系统使用指南
|
||
|
|
|
||
|
|
## 概述
|
||
|
|
|
||
|
|
本项目已重新设计日志系统,完全基于 **Zap 官方最佳实践**,提供高性能、结构化的日志记录功能。
|
||
|
|
|
||
|
|
## ✨ 核心特性
|
||
|
|
|
||
|
|
### 🎯 **基于 Zap 官方推荐**
|
||
|
|
- 使用 `zap.Config` 和官方配置结构
|
||
|
|
- 支持 `zap.NewProductionConfig()` 和 `zap.NewDevelopmentConfig()`
|
||
|
|
- 完整的编码器配置和输出配置
|
||
|
|
|
||
|
|
### 📁 **灵活的日志输出**
|
||
|
|
- **控制台输出**: `stdout`, `stderr`
|
||
|
|
- **文件输出**: 支持日志轮转和压缩
|
||
|
|
- **按日分包**: 自动按日期创建目录
|
||
|
|
- **按级别分文件**: 不同级别写入不同文件
|
||
|
|
|
||
|
|
### 🔧 **智能配置**
|
||
|
|
- 根据环境自动选择最佳配置
|
||
|
|
- 支持选项模式配置
|
||
|
|
- 完整的默认值设置
|
||
|
|
|
||
|
|
## 🏗️ 架构设计
|
||
|
|
|
||
|
|
```
|
||
|
|
应用代码 → Logger接口 → LoggerFactory → Zap核心 → 输出目标
|
||
|
|
```
|
||
|
|
|
||
|
|
### **核心组件**
|
||
|
|
|
||
|
|
1. **`Logger` 接口**: 统一的日志接口
|
||
|
|
2. **`ZapLogger`**: 基于 Zap 的日志实现
|
||
|
|
3. **`LevelLogger`**: 级别分文件日志器
|
||
|
|
4. **`LoggerFactory`**: 日志器工厂,支持多种创建方式
|
||
|
|
|
||
|
|
## 📖 使用方法
|
||
|
|
|
||
|
|
### **1. 基础使用**
|
||
|
|
|
||
|
|
```go
|
||
|
|
import "tyapi-server/internal/shared/logger"
|
||
|
|
|
||
|
|
// 创建日志器
|
||
|
|
log, err := logger.NewLogger(logger.Config{
|
||
|
|
Level: "info",
|
||
|
|
Format: "json",
|
||
|
|
Output: "file",
|
||
|
|
LogDir: "logs",
|
||
|
|
UseDaily: true,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 记录日志
|
||
|
|
log.Info("应用启动成功",
|
||
|
|
logger.String("version", "1.0.0"),
|
||
|
|
logger.String("environment", "production"),
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
### **2. 使用日志工厂**
|
||
|
|
|
||
|
|
```go
|
||
|
|
// 创建工厂
|
||
|
|
factory := logger.NewLoggerFactory(logger.Config{
|
||
|
|
Level: "info",
|
||
|
|
Format: "json",
|
||
|
|
Output: "file",
|
||
|
|
Development: false, // 生产环境
|
||
|
|
})
|
||
|
|
|
||
|
|
// 创建生产环境日志器
|
||
|
|
prodLogger, err := factory.CreateProductionLogger()
|
||
|
|
if err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 创建开发环境日志器
|
||
|
|
devLogger, err := factory.CreateDevelopmentLogger()
|
||
|
|
if err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 根据环境自动选择
|
||
|
|
autoLogger, err := factory.CreateLoggerByEnvironment()
|
||
|
|
if err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### **3. 选项模式配置**
|
||
|
|
|
||
|
|
```go
|
||
|
|
// 使用选项模式
|
||
|
|
logger, err := factory.CreateLoggerWithOptions(
|
||
|
|
logger.WithLevel("debug"),
|
||
|
|
logger.WithFormat("console"),
|
||
|
|
logger.WithOutput("stdout"),
|
||
|
|
logger.WithDevelopment(true),
|
||
|
|
logger.WithColor(true),
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
### **4. 级别分文件日志器**
|
||
|
|
|
||
|
|
```go
|
||
|
|
// 创建级别分文件日志器
|
||
|
|
levelConfig := logger.LevelLoggerConfig{
|
||
|
|
BaseConfig: logger.Config{
|
||
|
|
Level: "info",
|
||
|
|
Format: "json",
|
||
|
|
Output: "file",
|
||
|
|
LogDir: "logs",
|
||
|
|
UseDaily: true,
|
||
|
|
},
|
||
|
|
EnableLevelSeparation: true,
|
||
|
|
LevelConfigs: map[zapcore.Level]logger.LevelFileConfig{
|
||
|
|
zapcore.InfoLevel: {
|
||
|
|
MaxSize: 100,
|
||
|
|
MaxBackups: 5,
|
||
|
|
MaxAge: 30,
|
||
|
|
Compress: true,
|
||
|
|
},
|
||
|
|
zapcore.ErrorLevel: {
|
||
|
|
MaxSize: 200,
|
||
|
|
MaxBackups: 10,
|
||
|
|
MaxAge: 90,
|
||
|
|
Compress: true,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
levelLogger, err := logger.NewLevelLogger(levelConfig)
|
||
|
|
if err != nil {
|
||
|
|
panic(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 不同级别的日志会写入不同文件
|
||
|
|
levelLogger.Info("这是一条信息日志") // 写入 logs/2024-01-01/info.log
|
||
|
|
levelLogger.Error("这是一条错误日志") // 写入 logs/2024-01-01/error.log
|
||
|
|
```
|
||
|
|
|
||
|
|
### **5. 结构化日志**
|
||
|
|
|
||
|
|
```go
|
||
|
|
// 使用 With 添加字段
|
||
|
|
userLogger := log.With(
|
||
|
|
logger.String("user_id", "12345"),
|
||
|
|
logger.String("action", "login"),
|
||
|
|
)
|
||
|
|
|
||
|
|
userLogger.Info("用户登录成功",
|
||
|
|
logger.String("ip", "192.168.1.1"),
|
||
|
|
logger.String("user_agent", "Mozilla/5.0..."),
|
||
|
|
)
|
||
|
|
|
||
|
|
// 使用 WithContext 从上下文提取字段
|
||
|
|
ctx := context.WithValue(context.Background(), "request_id", "req_123")
|
||
|
|
ctx = context.WithValue(ctx, "user_id", "user_456")
|
||
|
|
ctx = context.WithValue(ctx, "trace_id", "trace_789")
|
||
|
|
|
||
|
|
contextLogger := log.WithContext(ctx)
|
||
|
|
contextLogger.Info("处理请求",
|
||
|
|
logger.String("endpoint", "/api/users"),
|
||
|
|
logger.Int("status_code", 200),
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
### **6. 命名日志器**
|
||
|
|
|
||
|
|
```go
|
||
|
|
// 创建命名日志器
|
||
|
|
dbLogger := log.Named("database")
|
||
|
|
dbLogger.Info("数据库连接成功",
|
||
|
|
logger.String("host", "localhost"),
|
||
|
|
logger.String("database", "tyapi"),
|
||
|
|
)
|
||
|
|
|
||
|
|
apiLogger := log.Named("api")
|
||
|
|
apiLogger.Info("API 请求处理",
|
||
|
|
logger.String("method", "GET"),
|
||
|
|
logger.String("path", "/api/v1/users"),
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
## ⚙️ 配置说明
|
||
|
|
|
||
|
|
### **基础配置**
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
logger:
|
||
|
|
# 基础配置
|
||
|
|
level: "info" # 日志级别
|
||
|
|
format: "json" # 输出格式
|
||
|
|
output: "file" # 输出方式
|
||
|
|
log_dir: "logs" # 日志目录
|
||
|
|
use_daily: true # 是否按日分包
|
||
|
|
use_color: false # 是否使用彩色输出
|
||
|
|
|
||
|
|
# 文件配置
|
||
|
|
max_size: 100 # 单个文件最大大小(MB)
|
||
|
|
max_backups: 5 # 最大备份文件数
|
||
|
|
max_age: 30 # 最大保留天数
|
||
|
|
compress: true # 是否压缩
|
||
|
|
|
||
|
|
# 高级功能
|
||
|
|
enable_level_separation: true # 是否启用按级别分文件
|
||
|
|
development: true # 是否为开发环境
|
||
|
|
```
|
||
|
|
|
||
|
|
### **级别配置**
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
logger:
|
||
|
|
level_configs:
|
||
|
|
debug:
|
||
|
|
max_size: 50 # 50MB
|
||
|
|
max_backups: 3
|
||
|
|
max_age: 7 # 7天
|
||
|
|
compress: true
|
||
|
|
info:
|
||
|
|
max_size: 100 # 100MB
|
||
|
|
max_backups: 5
|
||
|
|
max_age: 30 # 30天
|
||
|
|
compress: true
|
||
|
|
error:
|
||
|
|
max_size: 200 # 200MB
|
||
|
|
max_backups: 10
|
||
|
|
max_age: 90 # 90天
|
||
|
|
compress: true
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🔍 日志级别
|
||
|
|
|
||
|
|
### **级别说明**
|
||
|
|
- **`debug`**: 调试信息,开发环境使用
|
||
|
|
- **`info`**: 一般信息,记录应用状态
|
||
|
|
- **`warn`**: 警告信息,需要注意但不影响运行
|
||
|
|
- **`error`**: 错误信息,操作失败但可恢复
|
||
|
|
- **`fatal`**: 致命错误,应用无法继续运行
|
||
|
|
- **`panic`**: 恐慌错误,程序崩溃
|
||
|
|
|
||
|
|
### **级别选择建议**
|
||
|
|
- **开发环境**: `debug` 或 `info`
|
||
|
|
- **测试环境**: `info` 或 `warn`
|
||
|
|
- **生产环境**: `warn` 或 `error`
|
||
|
|
|
||
|
|
## 📊 日志格式
|
||
|
|
|
||
|
|
### **JSON 格式(推荐)**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"level": "info",
|
||
|
|
"timestamp": "2024-01-01T12:00:00.000Z",
|
||
|
|
"logger": "main",
|
||
|
|
"caller": "main.go:25",
|
||
|
|
"message": "应用启动成功",
|
||
|
|
"version": "1.0.0",
|
||
|
|
"environment": "production"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### **Console 格式(开发环境)**
|
||
|
|
```
|
||
|
|
2024-01-01T12:00:00.000Z INFO main/main.go:25 应用启动成功 {"version": "1.0.0", "environment": "production"}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🚀 性能优化
|
||
|
|
|
||
|
|
### **Zap 官方推荐**
|
||
|
|
- 使用结构化字段而不是字符串拼接
|
||
|
|
- 避免在日志记录时进行复杂计算
|
||
|
|
- 合理设置日志级别,避免过度记录
|
||
|
|
|
||
|
|
### **最佳实践**
|
||
|
|
```go
|
||
|
|
// ✅ 推荐:使用结构化字段
|
||
|
|
log.Info("用户操作",
|
||
|
|
logger.String("user_id", userID),
|
||
|
|
logger.String("action", action),
|
||
|
|
logger.String("resource", resource),
|
||
|
|
)
|
||
|
|
|
||
|
|
// ❌ 不推荐:字符串拼接
|
||
|
|
log.Info(fmt.Sprintf("用户 %s 执行了 %s 操作,资源: %s", userID, action, resource))
|
||
|
|
```
|
||
|
|
|
||
|
|
## 🔧 故障排除
|
||
|
|
|
||
|
|
### **常见问题**
|
||
|
|
|
||
|
|
1. **日志文件未创建**
|
||
|
|
- 检查目录权限
|
||
|
|
- 确认配置中的 `log_dir` 路径
|
||
|
|
|
||
|
|
2. **日志级别不生效**
|
||
|
|
- 检查配置中的 `level` 值
|
||
|
|
- 确认日志器创建时使用了正确的配置
|
||
|
|
|
||
|
|
3. **按级别分文件不工作**
|
||
|
|
- 确认 `enable_level_separation: true`
|
||
|
|
- 检查 `level_configs` 配置
|
||
|
|
|
||
|
|
4. **按日分包不工作**
|
||
|
|
- 确认 `use_daily: true`
|
||
|
|
- 检查日期格式是否正确
|
||
|
|
|
||
|
|
### **调试技巧**
|
||
|
|
|
||
|
|
```go
|
||
|
|
// 启用调试模式
|
||
|
|
log.SetLevel(zapcore.DebugLevel)
|
||
|
|
|
||
|
|
// 检查日志器配置
|
||
|
|
if zapLogger, ok := log.(*logger.ZapLogger); ok {
|
||
|
|
config := zapLogger.GetConfig()
|
||
|
|
fmt.Printf("日志器配置: %+v\n", config)
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📚 更多资源
|
||
|
|
|
||
|
|
- [Zap 官方文档](https://pkg.go.dev/go.uber.org/zap)
|
||
|
|
- [Zap 最佳实践](https://github.com/uber-go/zap/blob/master/FAQ.md)
|
||
|
|
- [结构化日志指南](https://github.com/uber-go/zap/blob/master/FAQ.md#q-how-do-i-choose-between-the-json-and-console-encoders)
|
||
|
|
|
||
|
|
## 🎉 总结
|
||
|
|
|
||
|
|
新的日志系统完全基于 Zap 官方最佳实践,提供了:
|
||
|
|
|
||
|
|
1. **高性能**: Zap 是 Go 生态中性能最好的日志库
|
||
|
|
2. **结构化**: 支持结构化字段,便于日志分析
|
||
|
|
3. **灵活性**: 支持多种输出方式和配置选项
|
||
|
|
4. **生产就绪**: 支持日志轮转、压缩、清理等生产环境需求
|
||
|
|
5. **官方推荐**: 完全按照 Zap 官方文档实现,确保最佳实践
|
||
|
|
|
||
|
|
使用新的日志系统,您将获得更好的性能、更清晰的日志结构和更强大的功能!
|