# Node.js 后端 - pino-pretty 问题修复记录 > **修复时间**:2025-12-24 > **问题原因**:生产环境使用了开发依赖pino-pretty > **解决方案**:根据环境变量条件化使用pino-pretty --- ## 🐛 问题描述 ### 错误信息 ``` Error: unable to determine transport target for "pino-pretty" at fixTarget (/app/node_modules/pino/lib/transport.js:160:13) ``` ### 根本原因 1. `pino-pretty` 是一个**devDependency**(开发依赖) 2. Dockerfile使用 `npm ci --production` 只安装生产依赖 3. `pino-pretty` **不会被安装到生产环境** 4. 但 `src/index.ts` 中硬编码了 `pino-pretty` 作为日志格式化工具 5. 生产环境启动时找不到 `pino-pretty`,导致崩溃 --- ## ✅ 解决方案 ### 1. 修改代码 - 条件化使用pino-pretty **文件**:`backend/src/index.ts` **修改前(第29-41行)**: ```typescript const fastify = Fastify({ logger: { level: config.logLevel, transport: { target: 'pino-pretty', // ❌ 硬编码,生产环境会报错 options: { colorize: true, translateTime: 'HH:MM:ss Z', ignore: 'pid,hostname', }, }, }, }); ``` **修改后**: ```typescript // 生产环境使用JSON格式日志(性能更好),开发环境使用pino-pretty(易读) const fastify = Fastify({ logger: config.nodeEnv === 'production' ? { level: config.logLevel, // 生产环境:简单的JSON日志,适合日志收集系统 } : { level: config.logLevel, // 开发环境:使用pino-pretty美化输出 transport: { target: 'pino-pretty', options: { colorize: true, translateTime: 'HH:MM:ss Z', ignore: 'pid,hostname', }, }, }, }); ``` **关键改进**: - ✅ 根据 `NODE_ENV` 条件化配置 - ✅ 生产环境:使用原生JSON日志(性能更好,适合ELK/Loki等日志系统) - ✅ 开发环境:使用pino-pretty(易读,便于调试) ### 2. 重新编译TypeScript ```bash cd backend npm run build ``` **编译结果**:✅ 成功 ### 3. 重新构建镜像 v1.2 ```bash docker build -t crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.2 . ``` **构建结果**: - ✅ 构建成功 - ✅ 耗时:8.4秒(快速,大部分层使用缓存) ### 4. 推送到ACR ```bash docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.2 ``` **推送结果**: - ✅ 推送成功 - ✅ Digest: `sha256:dd48750c5032681613776ea484a2194622e3926c6f49a1d7246105c090ecce35` --- ## 📦 版本对比 | 项目 | v1.0 | v1.1 | v1.2(最新) | |------|------|------|-------------| | **问题** | 缺少config | ❌ 修复 | ❌ 修复 | | **问题** | - | pino-pretty | ✅ 修复 | | **状态** | ❌ 启动失败 | ❌ 启动失败 | ✅ 待验证 | | **修改内容** | - | +config目录 | +条件化日志配置 | | **构建时间** | ~5分钟 | ~1分钟 | ~8秒 | --- ## 🎯 下一步操作 ### 步骤1:登录SAE控制台 访问:https://sae.console.aliyun.com/ ### 步骤2:更新镜像版本为 v1.2 1. 找到应用:`nodejs-backend-test` 2. 配置管理 → 部署配置 → 镜像设置 3. 修改镜像版本: ``` 从:backend-service:v1.1 改为:backend-service:v1.2 ✨ ``` ### 步骤3:重新部署并验证 1. 保存并重新部署 2. 查看实时日志 3. **成功标志**: **✅ 期望的日志格式**(JSON格式,不是pretty格式): ```json {"level":30,"time":1703472498828,"pid":1,"hostname":"xxx","msg":"Server listening at http://0.0.0.0:3001"} {"level":30,"time":1703472498830,"pid":1,"hostname":"xxx","msg":"Config loaded: /app/config/agents.yaml"} {"level":30,"time":1703472498832,"pid":1,"hostname":"xxx","msg":"Database connected successfully"} ``` **❌ 不应该出现**: - `Error: unable to determine transport target for "pino-pretty"` - 任何关于pino-pretty的错误 --- ## 📊 为什么生产环境不用pino-pretty? ### 性能对比 | 指标 | 原生JSON | pino-pretty | |------|---------|-------------| | **吞吐量** | ~30,000 log/s | ~3,000 log/s | | **CPU使用** | 低 | 高(格式化开销) | | **内存使用** | 低 | 高 | | **适用场景** | 生产环境 | 开发环境 | ### 日志系统集成 **生产环境最佳实践**: ``` 应用输出JSON日志 ↓ SAE/K8s收集(stdout/stderr) ↓ 日志系统(ELK/Loki/阿里云SLS) ↓ 可视化分析(Kibana/Grafana) ``` JSON格式日志更适合: - ✅ 结构化查询(字段级搜索) - ✅ 日志聚合和分析 - ✅ 告警规则配置 - ✅ 性能监控 --- ## 🔍 本地测试验证 如果想在本地验证修复,可以这样测试: ### 测试生产环境日志格式 ```bash # 设置生产环境变量 export NODE_ENV=production # 启动应用 npm run dev # 观察日志输出应该是JSON格式 ``` ### 测试开发环境日志格式 ```bash # 设置开发环境变量 export NODE_ENV=development # 启动应用 npm run dev # 观察日志输出应该是pretty格式(彩色、易读) ``` --- ## 💡 经验教训 ### 1. 开发依赖管理 - ✅ **DO**:将格式化工具(如pino-pretty)放在devDependencies - ✅ **DO**:生产环境使用原生日志格式 - ❌ **DON'T**:在生产环境依赖devDependencies ### 2. 环境适配 - ✅ **DO**:根据NODE_ENV配置不同的行为 - ✅ **DO**:生产环境优先考虑性能 - ✅ **DO**:开发环境优先考虑易用性 ### 3. Docker镜像优化 - ✅ **DO**:使用 `npm ci --production` 减小镜像体积 - ✅ **DO**:在代码中适配生产环境 - ❌ **DON'T**:为了方便在生产环境安装所有依赖 --- ## 📝 修复总结 **问题根源**:代码未适配生产环境(硬编码开发工具) **修复方式**:添加环境判断,条件化配置 **影响范围**:仅日志输出格式,不影响功能 **修复时间**:约10分钟(编译2分钟 + 构建8秒 + 推送1分钟) **版本号**:v1.2 --- **文档创建时间**:2025-12-24 **维护人员**:运维团队