console.log语句未写入PM2日志文件的原因排查
为何PM2未记录console.log输出?
问题场景
我编写了一个简单的测试脚本:
function tester() { console.log('hello there', process.env.NODE_APP_INSTANCE); setTimeout(tester, 1000); } tester();
PM2配置文件config.cjs内容如下:
module.exports = { apps: [ { name: 'tester', script: 'node scripts/tester', } ] }
通过以下命令启动PM2集群模式(5个实例):
npx pm2 start config.cjs --name tester -i 5 --time
启动后进程状态显示全部在线,但执行pm2 logs看不到应用的console.log输出,日志目录下的所有日志文件大小均为0。
原因分析
- 脚本路径配置错误:PM2的
script字段写了node scripts/tester,会导致PM2启动一个node进程去执行这条命令,嵌套的子进程输出无法被PM2捕获。 - Cluster模式下的stdout缓冲:Node.js在cluster子进程中默认开启stdout缓冲,输出不会立即写入文件,需要手动触发刷新。
- 日志捕获逻辑未生效:默认配置下PM2应该捕获输出,但可能因路径或配置优先级问题导致失效。
解决办法
1. 修正PM2脚本路径配置
修改config.cjs中的script字段,直接指向脚本文件(需确保文件后缀正确,比如.js),去掉多余的node前缀:
module.exports = { apps: [ { name: 'tester', script: './scripts/tester.js', } ] }
修改后重启PM2:
npx pm2 restart config.cjs
2. 强制刷新stdout缓冲区
在测试脚本中添加强制刷新逻辑,确保输出立即写入文件:
function tester() { console.log('hello there', process.env.NODE_APP_INSTANCE); process.stdout.flush(); // 强制刷新标准输出 setTimeout(tester, 1000); } tester();
或者全局禁用stdout缓冲:
// 在脚本开头添加 process.stdout._handle.setBlocking(true); function tester() { console.log('hello there', process.env.NODE_APP_INSTANCE); setTimeout(tester, 1000); } tester();
3. 明确配置PM2日志路径
在config.cjs中显式指定日志文件路径,确保输出被正确捕获:
module.exports = { apps: [ { name: 'tester', script: './scripts/tester.js', out_file: './.pm2/logs/tester-out.log', error_file: './.pm2/logs/tester-error.log', log_date_format: 'YYYY-MM-DD HH:mm:ss' } ] }
4. 检查日志目录权限
确保.pm2/logs目录有读写权限:
chmod -R 755 ~/.pm2/logs/
内容的提问来源于stack exchange,提问作者patrick
相关产品推荐
相关产品推荐

