Node.js 中日志写入失败通常不是单一原因,而是权限、路径、磁盘、并发、流状态、异常未捕获等综合问题。下面按最常见的场景 + 排查方法系统说明。
| 原因 | 说明 |
|---|---|
| 文件路径不存在 | 目录未创建 |
| 权限不足 | 无写权限 |
| 磁盘满 | ENOSPC |
| 文件被占用 | Windows 常见 |
| 流已关闭 | write after end |
| 并发写同一文件 | 内容错乱或失败 |
| 未捕获异常 | 程序直接退出 |
| 日志库配置错误 | winston / pino 等 |
| 容器环境 | /var/log 不可写 |
| 异步错误未处理 | callback / promise |
fs.writeFileSync('./logs/app.log', 'hello');
如果 logs/ 目录不存在,会直接失败。
const fs = require('fs');
const path = require('path');
const logPath = path.join(__dirname, 'logs/app.log');
fs.mkdirSync(path.dirname(logPath), { recursive: true });
fs.writeFileSync(logPath, 'hello');
✅ 一定要确保目录存在
EACCES: permission denied
ls -l app.log
whoami
df -h
chmod 777 logs/
const os = require('os');
os.tmpdir(); // /tmp
ENOSPC: no space left on device
df -h
✅ 常见于:
✅ 解决方案:
fs.createWriteStream('app.log', { flags: 'a' });
const ws = fs.createWriteStream('app.log');
ws.end();
ws.write('data'); // ❌ write after end
ws.write('data\n');
ws.end();
或监听错误:
ws.on('error', err => {
console.error('日志写入失败', err);
});
多个请求同时写 app.log
✅ 使用日志库
✅ 或加锁 / 队列(不推荐自己写)
const winston = require('winston');
const logger = winston.createLogger({
transports: [
new winston.transports.File({
filename: 'logs/app.log',
level: 'info'
})
]
});
filename 路径不存在✅ 建议:
logger.on('error', err => {
console.error('winston error', err);
});
fs.writeFile('a.log', data); // 错误被吞
fs.writeFile('a.log', data, err => {
if (err) console.error(err);
});
或:
try {
await fs.promises.writeFile('a.log', data);
} catch (e) {
console.error(e);
}
/var/log 不可写✅ 建议:
docker run -v $(pwd)/logs:/app/logs
✅ 按这个顺序查:
你可以直接贴:
我可以精准定位是哪一类问题,并给你最小修复方案。