--- kind: logging_system name: 后端日志系统(Winston 双输出) category: logging_system scope: - '**' source_files: - backend/src/config/logger.js - backend/logs/app.log - backend/src/app.js --- ## 1. 使用的框架与工具 - 后端采用 **winston** 作为统一日志库,通过 `backend/src/config/logger.js` 集中创建 logger 实例并导出。 - 前端(frontend / frontend_v2)未发现统一的日志框架,业务代码中未引入 winston/pino/bunyan 等 Node 端日志库;前端主要依赖浏览器控制台或无日志输出。 ## 2. 核心文件与位置 - `backend/src/config/logger.js`:winston 初始化、格式定义、传输层配置。 - `backend/logs/app.log`:默认文件输出路径,所有进程运行期日志均追加写入该单文件。 - `backend/src/app.js`:应用入口,负责在启动阶段调用 `logger.info/error` 记录数据库建表、服务监听地址等关键生命周期事件。 - 各模块通过 `require('./config/logger')` 复用同一 logger 实例,如 `routes/auth.js`、`config/redis.js` 等。 ## 3. 架构与约定 - **全局单例**:仅通过 `src/config/logger.js` 暴露一个 winston logger,所有模块直接 require 使用,避免重复创建。 - **输出目标(transports)**: - Console:标准输出,便于容器化环境收集 stdout。 - File:固定路径 `backend/logs/app.log`,UTF-8 编码,不区分级别,全部写入同一个文件。 - **日志格式**:自定义 `printf` 模板,形如: ``` YYYY-MM-DD HH:mm:ss - level - message [meta JSON] ``` 当传入 meta 对象时,会以 JSON 字符串拼接在消息末尾,用于携带结构化字段(如用户名、模型 id、S3 路径等)。 - **日志级别策略**:logger 默认 level 为 `info`,即 info/warn/error 会输出,debug 被过滤。业务中广泛使用 `logger.info` 记录业务流程,`logger.warn` 记录登录失败等非致命异常,`logger.error` 记录错误堆栈或外部依赖异常。 - **第三方库日志**:Sequelize 的 SQL 日志在开发环境下通过 `logging: (msg) => console.log(msg)` 直接走 console,生产环境关闭,避免污染 app.log。 ## 4. 开发者应遵循的规则 - **统一入口**:新增日志必须通过 `const logger = require('../config/logger')` 获取,禁止直接使用 `console.log` 输出业务日志。 - **级别选择**: - `info`:记录关键业务流程节点(用户登录、数据创建/更新/删除、外部请求结果摘要等)。 - `warn`:记录可恢复异常或降级场景(登录失败、外部接口 404、缓存未命中等)。 - `error`:记录导致功能失败的异常及错误信息。 - **结构化字段**:需要附加上下文时,以第三个参数传入对象,例如 `logger.info('Model created', { id, brand_name, name })`,最终会被序列化为 JSON 拼接到消息后。 - **敏感信息**:不要在日志中输出密码、token、完整请求体等敏感内容;如需记录请求详情,请脱敏后再传入 meta。 - **文件轮转**:当前未配置 winston 的文件轮转策略,长期运行会导致 `app.log` 持续增长;后续如需扩展可在 transports 中添加 `maxsize`/`maxFiles` 等选项。 - **前端侧**:前端工程未集成统一日志方案,若需在前端埋点,建议在后端提供专用 `/api/log` 接口或通过独立日志 SDK 上报,避免混入业务响应。