在 Debian 上 Node.js 日志“丢失”通常不是 Node 本身的问题,而是日志输出方式、systemd、Docker、日志轮转或权限等外部因素导致的。下面按最常见原因 → 排查方法 → 解决方案给你一个系统性的说明。
如果你用 systemd 启动 Node.js:
[Service]
ExecStart=/usr/bin/node /app/server.js
Node 的:
console.log()
console.error()
✅ 不会写文件 ✅ 会被 systemd 接管 ✅ 默认写入 journald
journalctl -u your-service-name -f
✅ 方案 A:用 journalctl 查看(推荐)
journalctl -u your-service.service --since "5 min ago"
✅ 方案 B:重定向到文件
StandardOutput=append:/var/log/node/app.log
StandardError=append:/var/log/node/error.log
Debian 默认 journal 有大小/时间限制。
journalctl --disk-usage
mkdir -p /etc/systemd/journald.conf.d
# /etc/systemd/journald.conf.d/node.conf
Storage=persistent
SystemMaxUse=200M
然后:
systemctl restart systemd-journald
Node.js stdout 在 non-TTY 下是 block buffering
✅ 方案 A:强制 flush
process.stdout.write(log + '\n', () => {});
✅ 方案 B:使用日志库(强烈推荐)
winstonpinoconst logger = require('pino')({
level: 'info'
})
logger.info('hello')
logrotate 默认:
copytruncate
或
create
Node 仍写旧 fd
✅ 方案 A:让 Node 重新打开文件
✅ 方案 B:logrotate 发信号
postrotate
systemctl kill -s USR1 your-service
endscript
fs.writeFileSync('./logs/app.log', data)
/proc/<pid>/cwd
ls -l /proc/$(pidof node)/cwd
✅ 永远用绝对路径
const path = require('path')
const logPath = path.resolve('/var/log/node/app.log')
sudo -u nodeuser touch /var/log/node/test.log
mkdir -p /var/log/node
chown -R nodeuser:nodeuser /var/log/node
如果你在 Docker 里跑 Node:
console.log('hello')
✅ 必须输出到 stdout ❌ 不要写文件
fs.writeFileSync('app.log')
console.log('hello')
docker logs <container>
你可以按顺序查:
# 1. 是不是 systemd
systemctl status your-service
# 2. journal 里有没有
journalctl -u your-service -f
# 3. Node 是不是真的在写
lsof -p $(pidof node) | grep log
# 4. 日志路径是不是绝对路径
readlink -f your-log-path
# 5. journal 是否被清理
journalctl --disk-usage
✅ systemd + journald ✅ 或 systemd + stdout + 日志库 ✅ 或 PM2 + logrotate
pm2 start app.js
pm2 logs
你可以直接贴:
1️⃣ 启动方式(systemd / pm2 / docker / 手动)
2️⃣ 你用的日志代码(console.log / winston / pino)
3️⃣ Debian 版本(cat /etc/os-release)
我可以精确告诉你为什么你的日志会丢,以及怎么改。