温馨提示×

Debian Nodejs日志为何丢失

小樊
45
2026-07-27 13:58:03
栏目: 编程语言

在 Debian 上 Node.js 日志“丢失”通常不是 Node 本身的问题,而是日志输出方式、systemd、Docker、日志轮转或权限等外部因素导致的。下面按最常见原因 → 排查方法 → 解决方案给你一个系统性的说明。


一、最常见原因(90% 都在这里)

1️⃣ systemd 把 stdout/stderr 接管了(最常见)

如果你用 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

2️⃣ 日志被 journald 自动清理

Debian 默认 journal 有大小/时间限制。

检查

journalctl --disk-usage

可能原因

  • 日志太大被自动删除
  • volatile 模式(内存)

解决

mkdir -p /etc/systemd/journald.conf.d
# /etc/systemd/journald.conf.d/node.conf
Storage=persistent
SystemMaxUse=200M

然后:

systemctl restart systemd-journald

3️⃣ 你以为日志在写,其实没 flush

Node.js stdout 在 non-TTY 下是 block buffering

现象

  • 程序运行正常
  • 日志文件为空或不全
  • 重启后突然看到日志

常见触发

  • 后台运行
  • Docker
  • systemd
  • nohup

解决

方案 A:强制 flush

process.stdout.write(log + '\n', () => {});

方案 B:使用日志库(强烈推荐)

  • winston
  • pino
const logger = require('pino')({
  level: 'info'
})
logger.info('hello')

4️⃣ 日志文件被 logrotate 截断

现象

  • 日志文件存在
  • 内容突然没了
  • inode 变了

原因

logrotate 默认:

copytruncate

create

Node 仍写旧 fd

解决

方案 A:让 Node 重新打开文件

  • 用日志库
  • 或每天重启一次

方案 B:logrotate 发信号

postrotate
  systemctl kill -s USR1 your-service
endscript

5️⃣ 你写的是相对路径,结果写到了奇怪的地方

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')

6️⃣ 权限问题(Debian 很常见)

现象

  • 程序能跑
  • 日志没写
  • 没报错(stdout 被吞)

检查

sudo -u nodeuser touch /var/log/node/test.log

解决

mkdir -p /var/log/node
chown -R nodeuser:nodeuser /var/log/node

7️⃣ Docker + Debian 的 stdout 问题

如果你在 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(最简单)

pm2 start app.js
pm2 logs

四、如果你愿意,我可以进一步帮你

你可以直接贴:

1️⃣ 启动方式(systemd / pm2 / docker / 手动)
2️⃣ 你用的日志代码(console.log / winston / pino)
3️⃣ Debian 版本(cat /etc/os-release

我可以精确告诉你为什么你的日志会丢,以及怎么改

0