Ubuntu上Node.js日志错误追踪的完整流程
Ubuntu的系统日志会记录Node.js进程的底层错误(如端口冲突、权限问题),主要存储在/var/log目录下。常用命令包括:
cat /var/log/syslog:查看系统综合日志(包含Node.js进程的常规错误);cat /var/log/kern.log:查看内核相关日志(如硬件或驱动问题导致的Node.js崩溃);cat /var/log/error.log:查看系统级错误日志(聚焦严重错误)。若Node.js作为systemd服务运行(如通过systemctl start your-node-service启动),可通过journalctl命令过滤服务相关日志:
journalctl -u your-nodejs-service-name -t "node" # -u指定服务名,-t过滤"node"标签
该命令会显示服务的实时错误日志(如进程崩溃、未捕获异常),适合生产环境的服务级监控。
若应用代码中配置了日志输出(如重定向到文件),可直接查看指定日志文件。例如,若启动命令为:
node app.js > logs/app.log 2>&1 & # 将标准输出和错误输出重定向到logs/app.log
则可通过以下命令实时跟踪错误日志:
tail -f logs/app.log # 实时显示日志末尾新增内容
或搜索特定错误关键词(如"Error"):
grep -i "Error" logs/app.log # -i忽略大小写,筛选含"Error"的行
PM2是Node.js常用的进程管理器,能自动重启崩溃的进程,并集中管理日志。安装与使用步骤:
npm install pm2 -g;pm2 start app.js --name "my-app"(--name指定应用名称);pm2 logs my-app(实时显示应用日志,包含错误堆栈);pm2 save(保存当前进程列表),pm2 startup(生成开机自启脚本)。内置console模块无法满足生产环境需求,推荐使用Winston(功能丰富)或Bunyan(结构化日志)记录错误。以Winston为例:
npm install winston;const winston = require('winston');
const logger = winston.createLogger({
level: process.env.NODE_ENV === 'production' ? 'warn' : 'debug', // 生产环境仅记录warn及以上
format: winston.format.json(), // 结构化日志(便于后续分析)
transports: [
new winston.transports.File({ filename: 'logs/error.log', level: 'error' }), // 错误日志单独存储
new winston.transports.File({ filename: 'logs/combined.log' }), // 所有日志汇总
],
});
// 示例:捕获同步错误
try {
// 业务代码(可能抛出错误)
} catch (error) {
logger.error('同步错误捕获:', { message: error.message, stack: error.stack }); // 记录错误信息与堆栈
}
// 全局捕获未处理异常
process.on('uncaughtException', (error) => {
logger.error('未捕获异常:', { message: error.message, stack: error.stack });
process.exit(1); // 强制退出进程(避免不可控状态)
});
// 全局捕获未处理Promise rejection
process.on('unhandledRejection', (reason, promise) => {
logger.error('未处理Promise rejection:', { reason, promise });
});
通过配置,可将错误日志分级存储(如error.log仅存严重错误),并添加上下文信息(如堆栈、请求ID),便于快速定位问题。app.use((err, req, res, next) => {
logger.error(`请求错误 [${req.method} ${req.url}]:`, { error: err.message, stack: err.stack });
res.status(500).send('Internal Server Error');
});
await database.query('SELECT * FROM users')
.catch(error => logger.error('数据库查询失败:', { query: 'SELECT * FROM users', error: error.message }));
将日志格式化为JSON(如Winston的json()格式化),便于后续用ELK Stack、Graylog等工具分析。例如:
{
"level": "error",
"message": "数据库连接失败",
"timestamp": "2025-09-26T10:00:00Z",
"database": "mysql",
"error": "Connection refused"
}
结构化日志能快速筛选、聚合错误信息,提升分析效率。
使用winston-daily-rotate-file插件自动分割日志文件(如按天分割),避免单个日志文件过大:
const DailyRotateFile = require('winston-daily-rotate-file');
const transport = new DailyRotateFile({
filename: 'logs/application-%DATE%.log',
datePattern: 'YYYY-MM-DD',
maxSize: '20m', // 单个文件最大20MB
maxFiles: '14d', // 保留14天日志
});
const logger = winston.createLogger({
transports: [transport],
});
将日志发送到Sentry、Loggly等平台,实现实时报警与远程分析:
const Sentry = require('@sentry/node');
Sentry.init({ dsn: 'your-sentry-dsn' });
app.use(Sentry.Handlers.errorHandler()); // Express错误处理中间件
// 记录错误到Sentry
logger.error('严重错误:', { error: new Error('Something went wrong') });
Sentry.captureException(new Error('Something went wrong')); // 发送到Sentry
sudo lsof -i :3000查看占用进程,用kill -9 <PID>终止进程;npm install missing-module安装缺失依赖;export DB_URL=your_url设置环境变量;