You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.log and error.log to stream logs. If your find command matches these active log files (maybe they're older than 2 days if your app doesn't log frequently), rm -rf deletes 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.log and can't find it—boom, ENOENT error.
  • Possible path mismatch in your crontab: The logs* wildcard might be matching more than just files inside the logs directory. If you meant to target files within the logs folder, you should use /home/user/.pm2/logs/* instead of logs*. Without the trailing slash, if there's any file or directory starting with logs (like the logs directory 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 flush to 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:
    0 0 * * * find /home/user/.pm2/logs/* -mtime +2 -exec rm -rf {} \; && pm2 reload all
    
    But this isn't ideal since it will briefly restart your app.

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 06:22:34