Ubuntu 下用 Node.js 日志进行故障定位的实用流程
一 定位日志来源与快速查看
- 先确认日志在哪:应用代码自定义目录(如 ./logs/*.log)、系统日志(如 /var/log/syslog)、进程管理器(如 PM2 的 ~/.pm2/logs/)、或 systemd 服务日志(通过 journalctl -u 服务名 查看)。
- 快速查看与过滤常用命令:
- 实时看应用日志:tail -f logs/app.log
- 系统日志中筛 Node:sudo tail -f /var/log/syslog | grep -i node
- PM2 实时日志:pm2 logs 或 pm2 logs
- systemd 服务日志:sudo journalctl -u your-nodejs-service -f
- 关键字定位:grep -i “error” app.log;HTTP 5xx:grep " 5[0-9][0-9] " access.log
这些路径与命令覆盖了最常见的日志落点与排查入口,适合先“看到问题”,再“缩小范围”。
二 从日志中提取有效线索
- 关注三要素:日志级别(如 ERROR/WARN/INFO)、错误消息(如 EADDRINUSE、Module not found、SyntaxError)、堆栈跟踪(定位到具体文件与行号)。
- 结合 HTTP 访问日志分析失败请求:状态码分布、响应时间、URL、来源 IP 等,有助于快速锁定异常接口或上游依赖。
- 若应用日志不足,转向系统层:检查 /var/log/syslog、/var/log/kern.log 中的权限、OOM、网络、驱动等线索;用 journalctl 观察服务启动、崩溃、重启与退出码。
- 典型线索与动作小结:
- 端口占用 EADDRINUSE:lsof -i :3000 找到 PID,kill -9 PID 后重启
- 依赖缺失 Module not found:npm install <模块名>
- 语法错误 SyntaxError:按堆栈提示修复对应文件语法
- HTTP 5xx:grep " 5xx " access.log 并结合业务日志定位根因
通过“级别—消息—堆栈—系统日志”的顺序,通常能把问题从现象推进到根因。
三 代码层增强日志以便快速定位
- 使用结构化日志库(如 Winston)分级输出到不同文件,便于检索与聚合:
- 错误单独落盘(error.log),全量日志(combined.log),必要时输出 JSON 便于 ELK/Graylog 分析。
- 记录 HTTP 请求日志(如 morgan)到文件,保留方法、URL、状态码、响应时间等。
- 全局兜底:捕获 uncaughtException、unhandledRejection 并记录堆栈,必要时安全退出,避免状态不一致。
- 示例(Winston + Morgan,关键片段):
- const winston = require(‘winston’);
const logger = winston.createLogger({
level: process.env.NODE_ENV === ‘production’ ? ‘warn’ : ‘debug’,
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: ‘logs/error.log’, level: ‘error’ }),
new winston.transports.File({ filename: ‘logs/combined.log’ })
]
});
- const morgan = require(‘morgan’); app.use(morgan(‘combined’, { stream: fs.createWriteStream(‘logs/access.log’, { flags: ‘a’ }) }));
- process.on(‘uncaughtException’, err => { logger.error(‘未捕获异常’, { message: err.message, stack: err.stack }); process.exit(1); });
- process.on(‘unhandledRejection’, (reason) => { logger.error(‘未处理 Promise 拒绝’, { reason }); });
上述做法能在问题发生的第一时间保留足够上下文,显著缩短定位时间。
四 运行环境与日志策略优化
- 合理设置日志级别:开发环境用 debug/info,生产环境用 warn/error 控制噪声与性能开销;可通过环境变量(如 LOG_LEVEL)或库配置动态调整。
- 日志轮转与保留:使用如 winston-daily-rotate-file 按天切分,避免单文件过大、便于归档与回溯。
- 集中化与可视化:将日志接入 ELK Stack(Elasticsearch, Logstash, Kibana) 或 Graylog,实现快速检索、聚合分析与告警。
- 进程与部署:用 PM2 管理进程与日志(pm2 logs、日志文件集中、自动重启),或用 systemd 托管并设置持久化 journal,确保崩溃与重启都有据可查。
这些策略能提升日志可用性、可观测性与可维护性,便于长期稳定运行与事后复盘。