PM2反复报ENOENT错误致服务停止,重启后恢复,求原因分析
PM2反复因日志文件缺失崩溃的原因分析
Hey there, let's break down why your PM2-managed Node.js service keeps crashing with that ENOENT error.
First, let's look at your crontab cleanup command:
0 0 * * * find /home/user/.pm2/logs* -mtime +2 -exec rm -rf {} \;
The key issue here is how you're deleting the logs, combined with how PM2 handles open file handles.
What's going wrong:
- You're deleting files PM2 is still using: When PM2 runs your app, it keeps an open file handle to
out.loganderror.logto stream logs. If yourfindcommand matches these active log files (maybe they're older than 2 days if your app doesn't log frequently),rm -rfdeletes the file from the filesystem. But here's the catch: in Linux, a file isn't truly deleted until all processes holding its handle close it. PM2 still has that handle open, so it can keep writing... until something triggers PM2 to try re-opening the file (like restarting the app instance, log rotation, or internal PM2 maintenance). At that point, PM2 looks for/home/user/.pm2/logs/out.logand can't find it—boom, ENOENT error. - Possible path mismatch in your crontab: The
logs*wildcard might be matching more than just files inside thelogsdirectory. If you meant to target files within the logs folder, you should use/home/user/.pm2/logs/*instead oflogs*. Without the trailing slash, if there's any file or directory starting withlogs(like thelogsdirectory itself), it gets included in the find results, which could lead to accidental deletion of the entire logs directory in edge cases.
How to fix this:
You have a few better options than manually deleting logs with crontab:
- Use PM2's built-in log management: PM2 has native support for log rotation and flushing. Instead of your crontab command, use
pm2 flushto clear logs, or configure log rotation in your PM2 ecosystem file (ecosystem.config.js) to automatically roll over old logs and keep only recent ones. Here's a quick example:module.exports = { apps: [{ name: 'app', script: 'app.js', error_file: '/home/user/.pm2/logs/app-error.log', out_file: '/home/user/.pm2/logs/app-out.log', log_rotate_size: '10M', // Rotate logs when they hit 10MB log_rotate_keep: 7, // Keep last 7 rotated logs log_date_format: 'YYYY-MM-DD HH:mm:ss' }] }; - Truncate instead of delete: If you still want to use crontab, don't delete the files—empty their contents with
truncate. This way, PM2's open file handle stays valid, and it can keep writing to the file:0 0 * * * find /home/user/.pm2/logs/* -mtime +2 -exec truncate -s 0 {} \; - Restart PM2 after cleanup (last resort): If you must delete the files, add a PM2 reload command after the cleanup to refresh the file handles:
But this isn't ideal since it will briefly restart your app.0 0 * * * find /home/user/.pm2/logs/* -mtime +2 -exec rm -rf {} \; && pm2 reload all
The root cause is that deleting files while a process holds an open handle to them causes inconsistencies when the process tries to re-access the file path later. Using PM2's native tools avoids this entirely.
内容的提问来源于stack exchange,提问作者Ravi
相关产品推荐
相关产品推荐

