298 lines
6.9 KiB
Markdown
298 lines
6.9 KiB
Markdown
# 📝 日志系统说明
|
||
|
||
## 概述
|
||
|
||
本项目使用增强的日志系统,支持按日分包和按大小分包,使用 `lumberjack` 进行日志轮转管理。
|
||
|
||
## 功能特性
|
||
|
||
### ✅ 按日分包
|
||
- 日志按日期自动分包存储
|
||
- 目录结构:`logs/2024-01-01/app.log`
|
||
- 便于按日期查找和管理日志
|
||
|
||
### ✅ 按大小分包
|
||
- 单个日志文件最大大小限制(默认100MB)
|
||
- 超过大小限制时自动创建新文件
|
||
- 文件命名:`app.log`, `app.log.1`, `app.log.2` 等
|
||
|
||
### ✅ 自动轮转
|
||
- 支持压缩旧日志文件
|
||
- 自动删除超过保留期限的日志
|
||
- 限制备份文件数量
|
||
|
||
### ✅ 生产环境持久化
|
||
- 日志目录挂载到宿主机 `./logs`
|
||
- 容器重启后日志不丢失
|
||
- 便于日志收集和分析
|
||
|
||
## 配置说明
|
||
|
||
### 基础配置 (`config.yaml`)
|
||
|
||
```yaml
|
||
logger:
|
||
level: "info" # 日志级别
|
||
format: "console" # 日志格式 (console/json)
|
||
output: "stdout" # 输出目标 (stdout/stderr/file)
|
||
log_dir: "logs" # 日志目录
|
||
max_size: 100 # 单个文件最大大小(MB)
|
||
max_backups: 3 # 最大备份文件数
|
||
max_age: 7 # 最大保留天数
|
||
compress: true # 是否压缩
|
||
use_color: true # 是否使用彩色输出
|
||
use_daily: false # 是否按日分包
|
||
```
|
||
|
||
### 生产环境配置 (`configs/env.production.yaml`)
|
||
|
||
```yaml
|
||
logger:
|
||
level: warn # 生产环境只记录警告及以上级别
|
||
format: json # JSON格式便于日志分析
|
||
output: "file" # 输出到文件
|
||
log_dir: "/app/logs" # 容器内日志目录
|
||
max_size: 100 # 100MB
|
||
max_backups: 5 # 5个备份文件
|
||
max_age: 30 # 保留30天
|
||
compress: true # 启用压缩
|
||
use_daily: true # 启用按日分包
|
||
```
|
||
|
||
## 日志目录结构
|
||
|
||
### 按日分包模式
|
||
```
|
||
logs/
|
||
├── 2024-01-01/
|
||
│ ├── app.log # 当前日志文件
|
||
│ ├── app.log.1 # 第一个备份文件
|
||
│ ├── app.log.2 # 第二个备份文件
|
||
│ └── app.log.3.gz # 压缩的备份文件
|
||
├── 2024-01-02/
|
||
│ ├── app.log
|
||
│ └── app.log.1
|
||
└── 2024-01-03/
|
||
└── app.log
|
||
```
|
||
|
||
### 传统模式
|
||
```
|
||
logs/
|
||
├── app.log # 当前日志文件
|
||
├── app.log.1 # 第一个备份文件
|
||
├── app.log.2 # 第二个备份文件
|
||
└── app.log.3.gz # 压缩的备份文件
|
||
```
|
||
|
||
## 日志级别
|
||
|
||
| 级别 | 说明 | 使用场景 |
|
||
|------|------|----------|
|
||
| `debug` | 调试信息 | 开发环境详细调试 |
|
||
| `info` | 一般信息 | 业务流程关键节点 |
|
||
| `warn` | 警告信息 | 需要注意但不影响功能 |
|
||
| `error` | 错误信息 | 业务逻辑错误 |
|
||
| `fatal` | 致命错误 | 系统无法继续运行 |
|
||
| `panic` | 恐慌错误 | 程序崩溃 |
|
||
|
||
## 日志格式
|
||
|
||
### JSON格式(生产环境)
|
||
```json
|
||
{
|
||
"timestamp": "2024-01-01T12:00:00Z",
|
||
"level": "info",
|
||
"message": "用户注册成功",
|
||
"user_id": "12345",
|
||
"phone": "138****8888",
|
||
"request_id": "req-123456",
|
||
"caller": "user_handler.go:45"
|
||
}
|
||
```
|
||
|
||
### 控制台格式(开发环境)
|
||
```
|
||
2024-01-01T12:00:00Z INFO 用户注册成功 {"user_id": "12345", "phone": "138****8888"}
|
||
```
|
||
|
||
## 使用方法
|
||
|
||
### 1. 查看日志
|
||
|
||
```bash
|
||
# 查看实时日志
|
||
docker logs -f tyapi-app-prod
|
||
|
||
# 查看最近的日志
|
||
docker logs --tail 100 tyapi-app-prod
|
||
|
||
# 查看宿主机日志文件
|
||
tail -f logs/2024-01-01/app.log
|
||
|
||
# 查看错误日志
|
||
grep "ERROR" logs/2024-01-01/app.log
|
||
```
|
||
|
||
### 2. 日志管理
|
||
|
||
```bash
|
||
# 查看日志统计信息
|
||
./scripts/log-manager.sh stats
|
||
|
||
# 查看日志目录大小
|
||
./scripts/log-manager.sh size
|
||
|
||
# 列出所有日志文件
|
||
./scripts/log-manager.sh list
|
||
|
||
# 清理旧日志文件
|
||
./scripts/log-manager.sh clean
|
||
```
|
||
|
||
### 3. 日志分析
|
||
|
||
```bash
|
||
# 使用jq分析JSON日志
|
||
cat logs/2024-01-01/app.log | jq 'select(.level == "error")'
|
||
|
||
# 统计错误类型
|
||
cat logs/2024-01-01/app.log | jq -r '.level' | sort | uniq -c
|
||
|
||
# 查看特定用户的请求
|
||
cat logs/2024-01-01/app.log | jq 'select(.user_id == "12345")'
|
||
```
|
||
|
||
## 代码示例
|
||
|
||
### 基本日志记录
|
||
```go
|
||
import "tyapi-server/internal/shared/logger"
|
||
|
||
// 获取日志器
|
||
log := logger.GetLogger()
|
||
|
||
// 记录不同级别的日志
|
||
log.Info("用户登录成功", logger.String("user_id", "12345"))
|
||
log.Warn("用户多次登录失败", logger.String("phone", "138****8888"))
|
||
log.Error("数据库连接失败", logger.Error(err))
|
||
```
|
||
|
||
### 带上下文的日志
|
||
```go
|
||
// 从Gin上下文获取日志器
|
||
ctx := c.Request.Context()
|
||
log := logger.GetLogger().WithContext(ctx)
|
||
|
||
log.Info("处理用户请求",
|
||
logger.String("action", "user_login"),
|
||
logger.String("ip", c.ClientIP()),
|
||
)
|
||
```
|
||
|
||
### 结构化日志字段
|
||
```go
|
||
log.Info("业务操作",
|
||
logger.String("operation", "create_user"),
|
||
logger.String("user_id", user.ID),
|
||
logger.Int("age", user.Age),
|
||
logger.Float64("score", 95.5),
|
||
logger.Bool("is_active", true),
|
||
logger.Error(err),
|
||
)
|
||
```
|
||
|
||
## 监控和告警
|
||
|
||
### 1. 日志监控
|
||
- 使用 ELK Stack (Elasticsearch + Logstash + Kibana)
|
||
- 或使用 Grafana + Loki
|
||
- 实时监控错误日志和性能指标
|
||
|
||
### 2. 告警配置
|
||
- 错误日志数量告警
|
||
- 日志文件大小告警
|
||
- 磁盘空间告警
|
||
|
||
### 3. 性能监控
|
||
```bash
|
||
# 监控日志写入性能
|
||
iostat -x 1
|
||
|
||
# 监控磁盘使用情况
|
||
df -h logs/
|
||
|
||
# 监控日志文件增长
|
||
watch -n 1 'ls -lh logs/$(date +%Y-%m-%d)/app.log'
|
||
```
|
||
|
||
## 故障排除
|
||
|
||
### 常见问题
|
||
|
||
1. **日志文件权限问题**
|
||
```bash
|
||
# 修复权限
|
||
chmod -R 755 logs/
|
||
chown -R $(whoami) logs/
|
||
```
|
||
|
||
2. **磁盘空间不足**
|
||
```bash
|
||
# 清理旧日志
|
||
./scripts/log-manager.sh clean
|
||
|
||
# 检查磁盘使用情况
|
||
df -h
|
||
```
|
||
|
||
3. **日志轮转失败**
|
||
```bash
|
||
# 检查lumberjack配置
|
||
# 确保有足够的磁盘空间
|
||
# 检查文件权限
|
||
```
|
||
|
||
### 性能优化
|
||
|
||
1. **异步日志写入**
|
||
- 使用缓冲写入减少I/O操作
|
||
- 批量写入提高性能
|
||
|
||
2. **日志级别控制**
|
||
- 生产环境使用 `warn` 级别
|
||
- 减少不必要的日志输出
|
||
|
||
3. **定期清理**
|
||
- 设置合理的保留期限
|
||
- 定期清理旧日志文件
|
||
|
||
## 最佳实践
|
||
|
||
### 1. 日志内容
|
||
- ✅ 记录关键业务操作
|
||
- ✅ 包含足够的上下文信息
|
||
- ✅ 使用结构化的字段
|
||
- ❌ 避免记录敏感信息
|
||
- ❌ 避免过度详细的调试信息
|
||
|
||
### 2. 日志管理
|
||
- ✅ 定期清理旧日志
|
||
- ✅ 监控日志文件大小
|
||
- ✅ 设置合理的轮转策略
|
||
- ✅ 备份重要日志
|
||
|
||
### 3. 性能考虑
|
||
- ✅ 使用异步日志写入
|
||
- ✅ 合理设置日志级别
|
||
- ✅ 避免在循环中记录日志
|
||
- ✅ 使用结构化日志字段
|
||
|
||
## 相关文件
|
||
|
||
- `internal/shared/logger/logger.go` - 日志系统核心实现
|
||
- `internal/config/config.go` - 日志配置结构
|
||
- `config.yaml` - 基础日志配置
|
||
- `configs/env.production.yaml` - 生产环境日志配置
|
||
- `docker-compose.prod.yml` - Docker日志卷挂载配置
|
||
- `scripts/log-manager.sh` - 日志管理脚本 |