363 lines
9.0 KiB
Markdown
363 lines
9.0 KiB
Markdown
# 日志系统详细说明
|
||
|
||
## 📋 概述
|
||
|
||
本项目的日志系统基于 Pino 高性能日志库构建,提供完整的日志记录、管理和分析功能。
|
||
|
||
---
|
||
|
||
## 🗂️ 日志文件结构
|
||
|
||
### 开发环境 (`NODE_ENV=development`)
|
||
|
||
```
|
||
logs/
|
||
└── dev.log # 开发环境综合日志(所有级别)
|
||
```
|
||
|
||
**输出方式:**
|
||
- 🖥️ **控制台**:彩色美化输出,便于开发调试
|
||
- 📁 **文件**:保存到 `logs/dev.log`,便于问题追踪
|
||
|
||
### 生产环境 (`NODE_ENV=production`)
|
||
|
||
```
|
||
logs/
|
||
├── app.log # 应用综合日志(info及以上级别)
|
||
├── error.log # 错误日志(error和fatal级别)
|
||
├── access.log # HTTP访问日志(请求响应记录)
|
||
├── app.log.gz # 压缩的历史日志文件
|
||
├── error.log.gz # 压缩的历史错误日志
|
||
└── access.log.gz # 压缩的历史访问日志
|
||
```
|
||
|
||
**输出方式:**
|
||
- 📁 **文件**:分类保存到不同的日志文件
|
||
- 🖥️ **控制台**:仅输出 warn 及以上级别(用于容器日志收集)
|
||
|
||
---
|
||
|
||
## 📊 日志级别和用途
|
||
|
||
| 级别 | 数值 | 用途 | 保存位置 | 示例场景 |
|
||
|------|------|------|----------|----------|
|
||
| **TRACE** | 10 | 极细粒度调试 | dev.log | 循环内变量状态 |
|
||
| **DEBUG** | 20 | 开发调试信息 | dev.log | 方法调用参数 |
|
||
| **INFO** | 30 | 重要业务操作 | app.log, dev.log | 用户登录成功 |
|
||
| **WARN** | 40 | 警告信息 | app.log, dev.log, 控制台 | 参数验证失败 |
|
||
| **ERROR** | 50 | 错误信息 | error.log, app.log, 控制台 | 数据库连接失败 |
|
||
| **FATAL** | 60 | 致命错误 | error.log, app.log, 控制台 | 系统不可用 |
|
||
|
||
---
|
||
|
||
## 🔄 日志轮转和管理
|
||
|
||
### 自动轮转策略
|
||
|
||
| 文件类型 | 轮转频率 | 文件大小限制 | 保留时间 | 压缩策略 |
|
||
|----------|----------|--------------|----------|----------|
|
||
| **app.log** | 每日 | 10MB | 7天 | 7天后压缩 |
|
||
| **error.log** | 每日 | 10MB | 30天 | 7天后压缩 |
|
||
| **access.log** | 每日 | 50MB | 14天 | 7天后压缩 |
|
||
| **dev.log** | 手动 | 无限制 | 无限制 | 不压缩 |
|
||
|
||
### 定时任务
|
||
|
||
| 任务 | 执行时间 | 功能 |
|
||
|------|----------|------|
|
||
| **日志清理** | 每天 02:00 | 删除过期日志文件 |
|
||
| **日志压缩** | 每周日 03:00 | 压缩7天前的日志文件 |
|
||
| **健康监控** | 每小时 | 监控日志系统状态 |
|
||
| **统计报告** | 每天 09:00 | 输出日志统计信息 |
|
||
|
||
---
|
||
|
||
## 🚀 如何使用日志系统
|
||
|
||
### 基本使用
|
||
|
||
```typescript
|
||
import { Injectable } from '@nestjs/common';
|
||
import { AppLoggerService } from '../core/utils/logger/logger.service';
|
||
|
||
@Injectable()
|
||
export class UserService {
|
||
constructor(private readonly logger: AppLoggerService) {}
|
||
|
||
async createUser(userData: CreateUserDto) {
|
||
// 记录操作开始
|
||
this.logger.info('开始创建用户', {
|
||
operation: 'createUser',
|
||
email: userData.email,
|
||
timestamp: new Date().toISOString()
|
||
});
|
||
|
||
try {
|
||
const user = await this.userRepository.save(userData);
|
||
|
||
// 记录成功操作
|
||
this.logger.info('用户创建成功', {
|
||
operation: 'createUser',
|
||
userId: user.id,
|
||
email: userData.email,
|
||
duration: Date.now() - startTime
|
||
});
|
||
|
||
return user;
|
||
} catch (error) {
|
||
// 记录错误
|
||
this.logger.error('用户创建失败', {
|
||
operation: 'createUser',
|
||
email: userData.email,
|
||
error: error.message
|
||
}, error.stack);
|
||
|
||
throw error;
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 请求上下文绑定
|
||
|
||
```typescript
|
||
@Controller('users')
|
||
export class UserController {
|
||
constructor(private readonly logger: AppLoggerService) {}
|
||
|
||
@Get(':id')
|
||
async getUser(@Param('id') id: string, @Req() req: Request) {
|
||
// 绑定请求上下文
|
||
const requestLogger = this.logger.bindRequest(req, 'UserController');
|
||
|
||
requestLogger.info('开始获取用户信息', { userId: id });
|
||
|
||
try {
|
||
const user = await this.userService.findById(id);
|
||
requestLogger.info('用户信息获取成功', { userId: id });
|
||
return user;
|
||
} catch (error) {
|
||
requestLogger.error('用户信息获取失败', error.stack, {
|
||
userId: id,
|
||
reason: error.message
|
||
});
|
||
throw error;
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🔍 日志格式详解
|
||
|
||
### 开发环境日志格式
|
||
|
||
```
|
||
🕐 2024-12-13 14:30:25 📝 INFO pixel-game-server [UserService] 用户创建成功
|
||
operation: "createUser"
|
||
userId: "user_123"
|
||
email: "user@example.com"
|
||
duration: 45
|
||
```
|
||
|
||
### 生产环境日志格式 (JSON)
|
||
|
||
```json
|
||
{
|
||
"level": 30,
|
||
"time": 1702456225000,
|
||
"pid": 12345,
|
||
"hostname": "server-01",
|
||
"app": "pixel-game-server",
|
||
"version": "1.0.0",
|
||
"msg": "用户创建成功",
|
||
"operation": "createUser",
|
||
"userId": "user_123",
|
||
"email": "user@example.com",
|
||
"duration": 45,
|
||
"reqId": "req_1702456225_abc123"
|
||
}
|
||
```
|
||
|
||
### HTTP 请求日志格式
|
||
|
||
```json
|
||
{
|
||
"level": 30,
|
||
"time": 1702456225000,
|
||
"req": {
|
||
"id": "req_1702456225_abc123",
|
||
"method": "POST",
|
||
"url": "/api/users",
|
||
"headers": {
|
||
"host": "localhost:3000",
|
||
"user-agent": "Mozilla/5.0...",
|
||
"content-type": "application/json"
|
||
},
|
||
"ip": "127.0.0.1"
|
||
},
|
||
"res": {
|
||
"statusCode": 201,
|
||
"responseTime": 45
|
||
},
|
||
"msg": "POST /api/users completed in 45ms"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🛠️ 问题排查指南
|
||
|
||
### 1. 如何查找特定用户的操作日志?
|
||
|
||
```bash
|
||
# 在日志文件中搜索特定用户ID
|
||
grep "userId.*user_123" logs/app.log
|
||
|
||
# 搜索特定操作
|
||
grep "operation.*createUser" logs/app.log
|
||
|
||
# 搜索特定时间段的日志
|
||
grep "2024-12-13 14:" logs/app.log
|
||
```
|
||
|
||
### 2. 如何查找错误日志?
|
||
|
||
```bash
|
||
# 查看所有错误日志
|
||
cat logs/error.log
|
||
|
||
# 查看最近的错误
|
||
tail -f logs/error.log
|
||
|
||
# 搜索特定错误
|
||
grep "数据库连接失败" logs/error.log
|
||
```
|
||
|
||
### 3. 如何分析性能问题?
|
||
|
||
```bash
|
||
# 查找响应时间超过1000ms的请求
|
||
grep "responseTime.*[0-9][0-9][0-9][0-9]" logs/access.log
|
||
|
||
# 查找特定接口的性能数据
|
||
grep "POST /api/users" logs/access.log | grep responseTime
|
||
```
|
||
|
||
### 4. 如何监控系统健康状态?
|
||
|
||
```bash
|
||
# 查看日志统计信息
|
||
grep "日志系统健康状态报告" logs/app.log
|
||
|
||
# 查看日志清理记录
|
||
grep "日志清理任务完成" logs/app.log
|
||
|
||
# 查看压缩记录
|
||
grep "日志压缩任务完成" logs/app.log
|
||
```
|
||
|
||
---
|
||
|
||
## 📈 日志分析和监控
|
||
|
||
### 日志统计信息
|
||
|
||
系统会自动收集以下统计信息:
|
||
|
||
- **文件数量**:当前日志文件总数
|
||
- **总大小**:所有日志文件占用的磁盘空间
|
||
- **错误日志数量**:错误级别日志文件数量
|
||
- **最旧/最新文件**:日志文件的时间范围
|
||
- **平均文件大小**:单个日志文件的平均大小
|
||
|
||
### 健康监控告警
|
||
|
||
系统会在以下情况发出警告:
|
||
|
||
- 📊 **磁盘空间告警**:日志文件总大小超过阈值
|
||
- ⚠️ **错误日志告警**:错误日志数量异常增长
|
||
- 🔧 **清理失败告警**:日志清理任务执行失败
|
||
- 💾 **压缩失败告警**:日志压缩任务执行失败
|
||
|
||
---
|
||
|
||
## ⚙️ 配置说明
|
||
|
||
### 环境变量配置
|
||
|
||
```bash
|
||
# 应用名称
|
||
APP_NAME=pixel-game-server
|
||
|
||
# 环境标识
|
||
NODE_ENV=development
|
||
|
||
# 日志级别
|
||
LOG_LEVEL=debug
|
||
|
||
# 日志目录
|
||
LOG_DIR=./logs
|
||
|
||
# 日志保留天数
|
||
LOG_MAX_FILES=7d
|
||
|
||
# 单个日志文件最大大小
|
||
LOG_MAX_SIZE=10m
|
||
```
|
||
|
||
### 高级配置选项
|
||
|
||
如需自定义日志配置,可以修改 `src/core/utils/logger/logger.config.ts`:
|
||
|
||
```typescript
|
||
// 自定义日志轮转策略
|
||
{
|
||
target: 'pino-roll',
|
||
options: {
|
||
file: path.join(logDir, 'app.log'),
|
||
frequency: 'daily', // 轮转频率:daily, hourly, weekly
|
||
size: '10m', // 文件大小限制
|
||
limit: {
|
||
count: 7, // 保留文件数量
|
||
},
|
||
},
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🚨 注意事项
|
||
|
||
### 安全考虑
|
||
|
||
1. **敏感信息过滤**:系统自动过滤密码、token等敏感字段
|
||
2. **访问控制**:确保日志文件只有授权用户可以访问
|
||
3. **传输加密**:生产环境建议使用加密传输日志
|
||
|
||
### 性能考虑
|
||
|
||
1. **异步写入**:Pino 使用异步写入,不会阻塞主线程
|
||
2. **日志级别**:生产环境建议使用 info 及以上级别
|
||
3. **文件轮转**:及时清理和压缩日志文件,避免占用过多磁盘空间
|
||
|
||
### 运维建议
|
||
|
||
1. **监控磁盘空间**:定期检查日志目录的磁盘使用情况
|
||
2. **备份重要日志**:对于重要的错误日志,建议定期备份
|
||
3. **日志分析**:可以集成 ELK Stack 等日志分析工具
|
||
4. **告警设置**:配置日志监控告警,及时发现系统问题
|
||
|
||
---
|
||
|
||
## 🔗 相关文档
|
||
|
||
- [后端开发规范 - 日志系统使用指南](./backend_development_guide.md#四日志系统使用指南)
|
||
- [AI 辅助开发规范指南](./AI辅助开发规范指南.md)
|
||
- [Pino 官方文档](https://getpino.io/)
|
||
- [NestJS Pino 集成文档](https://github.com/iamolegga/nestjs-pino)
|
||
|
||
---
|
||
|
||
**💡 提示:使用 [AI 辅助开发指南](./AI辅助开发规范指南.md) 可以让 AI 帮你自动生成符合规范的日志代码!** |