Ubuntu 上用日志快速定位 Node.js 问题的实操流程
一 定位日志来源与实时查看
- 应用日志常见位置:项目目录下的 logs/(如 app.log、error.log),或在配置文件(如 config.json、settings.js)中自定义路径。直接查看或实时跟踪:
- 查看目录:ls -l logs
- 实时跟踪:tail -f logs/app.log 或 tail -f logs/error.log
- 使用 PM2 管理时,统一查看与过滤:
- 查看全部:pm2 logs
- 指定应用:pm2 logs <app_name_or_id>
- 最近 N 行并持续跟踪:pm2 logs --lines 1000 --follow
- 系统层面线索:
- 系统日志:sudo tail -f /var/log/syslog
- systemd 服务日志:sudo journalctl -u <service_name>;查看最近时间窗:journalctl -u <service_name> --since “10 minutes ago” --no-pager
- 若由 Nginx/Apache 反向代理或承载,同时检查其错误日志(如 /var/log/nginx/error.log),便于发现上游连接与权限问题。
二 高效检索与过滤
- 关键词定位:grep -i “error” logs/error.log;按时间窗口过滤:grep “2025-12-04 10:2” logs/app.log
- 级别筛选(PM2):pm2 logs --lines 200 | grep WARN
- 追踪异常堆栈:优先阅读包含堆栈跟踪(stack trace)的日志条目,定位到具体文件与行号
- 大文件分析:对体积大的日志,结合 head/tail/sed/awk 做分段查看,避免一次性加载全量日志。
三 常见错误模式与一键处置
| 现象关键词 |
典型原因 |
快速定位 |
处置命令示例 |
| EADDRINUSE |
端口被占用 |
grep -i “EADDRINUSE” logs/app.log;确认端口 |
sudo lsof -i :3000;sudo kill -9 |
| EACCES |
权限不足(文件/端口/目录) |
grep -i “EACCES” logs/app.log |
修正目录/文件权限或以合适用户运行 |
| Module not found |
依赖缺失 |
grep -i “Module not found” logs/app.log |
npm install <module_name> |
| SyntaxError |
语法错误 |
查看报错文件与行号 |
修正代码后重启 |
| UnhandledPromiseRejectionWarning |
Promise 未 catch |
grep -i “UnhandledPromiseRejectionWarning” |
为所有 Promise 加 .catch;全局监听 process.on(‘unhandledRejection’) |
| MaxListenersExceededWarning |
事件监听器泄漏 |
grep -i “MaxListenersExceededWarning” |
移除重复监听或 emitter.setMaxListeners() |
| ENOMEM / heap out of memory |
内存不足/泄漏 |
grep -i “heap out of memory” logs/app.log |
node --max-old-space-size=4096 app.js;用 clinic/heapdump 分析 |
| DeprecationWarning |
使用了废弃 API |
grep -i “DeprecationWarning” logs/app.log |
升级 Node 与依赖;替换废弃 API(如 Buffer() → Buffer.alloc()) |
| 以上模式与处置要点可显著缩短定位时间,尤其是端口占用、未处理 Promise、监听器泄漏与内存问题。 |
|
|
|
四 提升日志可观测性
- 结构化与多目标日志:使用 Winston/Pino 输出到文件与控制台,按级别分流(如 error/combined),便于检索与聚合。
- 示例(Winston):创建 error.log 与 combined.log 两个 transport,分别记录 error 与 info+ 级别。
- 进程管理:使用 PM2 统一启动、重启与日志轮转,配合 pm2 logs 快速排查。
- 集中化与可视化:引入 ELK Stack(Elasticsearch, Logstash, Kibana)/Graylog,对多实例与多服务日志进行集中存储、检索与可视化分析。
五 无法立即复现时的调试与兜底
- 远程调试:node --inspect-brk app.js,在 Chrome 打开 chrome://inspect 连接调试器,断点排查变量与调用栈。
- 全局兜底:在入口处注册
- process.on(‘uncaughtException’):记录完整堆栈、清理资源、必要时安全退出
- process.on(‘unhandledRejection’):记录未处理的拒绝原因与堆栈
- 运行环境核对:printenv 检查环境变量;核对配置文件路径、数据库/缓存连接串与权限;npm list 检查依赖版本一致性。