Files
plates-server/docs/winston-logger-guide.md
2025-08-13 15:17:33 +08:00

5.3 KiB
Raw Blame History

Winston Logger 配置指南

本项目已配置了基于 Winston 的日志系统,支持日志文件输出、按日期滚动和自动清理。

功能特性

  • 日志文件输出: 自动将日志写入文件
  • 按日期滚动: 每天生成新的日志文件
  • 自动清理: 保留最近7天的日志文件
  • 分级日志: 支持不同级别的日志分离
  • 结构化日志: 支持JSON格式的结构化日志
  • 异常处理: 自动记录未捕获的异常和Promise拒绝

日志文件结构

logs/
├── app-2025-07-21.log          # 应用日志 (info级别及以上)
├── error-2025-07-21.log        # 错误日志 (error级别)
├── debug-2025-07-21.log        # 调试日志 (仅开发环境)
├── exceptions-2025-07-21.log   # 未捕获异常
├── rejections-2025-07-21.log   # 未处理的Promise拒绝
└── .audit-*.json               # 日志轮转审计文件

配置说明

日志级别

  • 生产环境: info 及以上级别
  • 开发环境: debug 及以上级别

文件轮转配置

  • 日期模式: YYYY-MM-DD
  • 保留天数: 7天
  • 单文件大小: 最大20MB
  • 自动压缩: 支持

使用方法

1. 在服务中使用 NestJS Logger

import { Injectable, Logger } from '@nestjs/common';

@Injectable()
export class YourService {
  private readonly logger = new Logger(YourService.name);

  someMethod() {
    this.logger.log('这是一条信息日志');
    this.logger.warn('这是一条警告日志');
    this.logger.error('这是一条错误日志');
    this.logger.debug('这是一条调试日志');
  }
}

2. 直接使用 Winston Logger (推荐用于结构化日志)

import { Injectable, Inject } from '@nestjs/common';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger as WinstonLogger } from 'winston';

@Injectable()
export class YourService {
  constructor(
    @Inject(WINSTON_MODULE_PROVIDER) 
    private readonly winstonLogger: WinstonLogger,
  ) {}

  someMethod() {
    // 结构化日志
    this.winstonLogger.info('用户登录', {
      context: 'AuthService',
      userId: 'user123',
      email: 'user@example.com',
      timestamp: new Date().toISOString()
    });

    // 错误日志
    this.winstonLogger.error('数据库连接失败', {
      context: 'DatabaseService',
      error: 'Connection timeout',
      retryCount: 3
    });
  }
}

3. 在控制器中使用

import { Controller, Logger } from '@nestjs/common';

@Controller('users')
export class UsersController {
  private readonly logger = new Logger(UsersController.name);

  @Get()
  findAll() {
    this.logger.log('获取用户列表请求');
    // 业务逻辑
  }
}

日志格式

控制台输出格式

2025-07-21 10:08:38 info [ServiceName] 日志消息

文件输出格式

2025-07-21 10:08:38 [INFO] [ServiceName] 日志消息

结构化日志格式

{
  "timestamp": "2025-07-21 10:08:38",
  "level": "info",
  "message": "用户登录",
  "context": "AuthService",
  "userId": "user123",
  "email": "user@example.com"
}

环境变量配置

可以通过环境变量调整日志行为:

# 日志级别 (development: debug, production: info)
NODE_ENV=production

# 自定义日志目录 (可选)
LOG_DIR=/var/log/love-tips-server

最佳实践

1. 使用合适的日志级别

  • error: 错误和异常
  • warn: 警告信息
  • info: 重要的业务信息
  • debug: 调试信息 (仅开发环境)

2. 结构化日志

对于重要的业务事件,使用结构化日志:

this.winstonLogger.info('订单创建', {
  context: 'OrderService',
  orderId: order.id,
  userId: user.id,
  amount: order.amount,
  currency: 'CNY'
});

3. 错误日志包含上下文

try {
  // 业务逻辑
} catch (error) {
  this.winstonLogger.error('处理订单失败', {
    context: 'OrderService',
    orderId: order.id,
    error: error.message,
    stack: error.stack
  });
}

4. 避免敏感信息

不要在日志中记录密码、令牌等敏感信息:

// ❌ 错误
this.logger.log(`用户登录: ${JSON.stringify(loginData)}`);

// ✅ 正确
this.logger.log(`用户登录: ${loginData.email}`);

监控和维护

查看实时日志

# 查看应用日志
tail -f logs/app-$(date +%Y-%m-%d).log

# 查看错误日志
tail -f logs/error-$(date +%Y-%m-%d).log

日志分析

# 统计错误数量
grep -c "ERROR" logs/app-*.log

# 查找特定用户的日志
grep "userId.*user123" logs/app-*.log

清理旧日志

日志系统会自动清理7天前的日志文件无需手动维护。

故障排除

1. 日志文件未生成

  • 检查 logs 目录权限
  • 确认应用有写入权限
  • 查看控制台是否有错误信息

2. 日志级别不正确

  • 检查 NODE_ENV 环境变量
  • 确认 winston 配置中的日志级别设置

3. 日志文件过大

  • 检查日志轮转配置
  • 确认 maxSizemaxFiles 设置

相关文件