Ubuntu 下用 Node.js 日志高效定位与修复问题
一 日志定位与查看
- 定位日志位置:常见路径包括项目目录的 logs/、系统日志 /var/log/syslog 或 /var/log/messages,以及 systemd 服务日志(journal)。若使用 PM2,日志由 PM2 管理。
- 实时查看与检索:
- 实时查看应用日志文件:tail -f logs/app.log
- 查看 systemd 服务日志:journalctl -u your-node-service --no-pager -f
- 检索关键字:grep -i “error” logs/app.log 或 grep “关键字” /var/log/syslog
- PM2 日志:pm2 logs your-app;仅看警告:pm2 logs your-app --lines 50 | grep WARN
- 分析要点:优先关注包含 Error/Exception 的行及其堆栈跟踪(stack trace),从堆栈顶部向下定位到你的业务代码文件与行号,再结合上下文修复。
二 日志级别与输出策略
- 环境策略:开发环境建议 debug/info,生产环境建议 warn/error,以降低开销并突出关键问题。
- 常用库的级别设置:
- Winston:通过 level 控制,支持多传输(Console/File)与格式。
- Pino:高性能,适合生产,同样通过 level 配置。
- Morgan(HTTP 请求日志):选择 combined/tiny 等格式,或用 skip 仅记录 4xx/5xx。
- 环境变量:用 LOG_LEVEL/WINSTON_LEVEL/PINO_LEVEL 控制级别,便于在不同环境快速切换。
- 示例(Winston,开发输出到控制台为 debug,错误单独落盘):
- 安装:npm i winston
- 配置:
- const winston = require(‘winston’);
- const logger = winston.createLogger({
level: process.env.LOG_LEVEL || ‘info’,
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf(({ timestamp, level, message }) =>
${timestamp} ${level.toUpperCase()}: ${message})
),
transports: [
new winston.transports.Conbine(new winston.transports.Console({ level: ‘debug’ })),
new winston.transports.File({ filename: ‘error.log’, level: ‘error’ }),
new winston.transports.File({ filename: ‘combined.log’ })
]
});
- logger.debug(‘调试信息’); logger.error(‘错误信息’);
- 运行:LOG_LEVEL=debug node app.js
三 常见错误模式与修复动作
- EADDRINUSE(端口被占用):
- 查占用:sudo lsof -i :3000
- 释放:sudo kill -9
- Module not found(模块缺失):npm install <模块名>
- SyntaxError(语法错误):按报错行修复语法(如缺少括号、引号、逗号)。
- UnhandledPromiseRejectionWarning(未处理的 Promise 拒绝):
- 给每个 Promise 加 .catch();async/await 用 try-catch 包裹;
- 临时兜底:process.on(‘unhandledRejection’, (reason) => console.error(reason));
- MaxListenersExceededWarning(监听器泄漏):避免重复添加监听器,必要时 emitter.setMaxListeners(n) 或 removeListener 清理。
- ENOMEM(堆内存不足):
- 临时提升:node --max-old-space-size=4096 app.js
- 排查泄漏:用 clinic 等工具分析并优化数据结构与缓存策略。
四 结合调试器与运行时诊断
- 交互式调试:
- 内置调试器:node inspect app.js,配合 Chrome DevTools 或 CLI 调试;
- VS Code:配置 launch.json 断点、步进、观察表达式;
- 第三方:ndb、旧版 node-inspector。
- 运行时诊断:
- 内存/性能热点:clinic doctor – node app.js;
- 崩溃问题:开启并分析 核心转储(core dump) 以定位原生/内存层问题。
五 高效排查流程清单
- 明确现象与范围:复现路径、触发条件、影响接口/用户。
- 调整日志级别到 debug,在关键路径补充 logger.debug(‘变量状态’, obj)。
- 实时跟踪日志:tail -f 或 journalctl -u,必要时加 grep 过滤关键字。
- 从日志中的 Error/堆栈 定位到具体文件与行号,优先修复根因而非表面报错。
- 若涉及异步:全面处理 Promise 异常(.catch/try-catch),并监听 unhandledRejection。
- 涉及端口/依赖:用 lsof 与 npm install 快速排除资源与模块问题。
- 性能/内存异常:用 clinic 做性能剖析,必要时提升 –max-old-space-size 并继续排查泄漏。
- 回归验证:恢复日志级别为 info/warn,确认问题不再复现并保留关键日志与指标。