服务无日志主因是默认走journald而非落盘,需查systemctl status、journalctl输出及service文件中StandardOutput/StandardError配置,必要时修改journald.conf或添加StandardOutput=append:/var/log/.log并reload。

服务启动了但 /var/log/ 下没日志文件
不是日志被删了,而是服务压根没配置写日志,或者日志被重定向到其他地方。很多 systemd 服务默认不落盘,只走 journald。
- 先查
systemctl status,看最后一行有没有类似journalctl -u的提示 - 运行
journalctl -u看实时日志输出,确认服务是否真在跑、有没有报错--since "1 hour ago" - 检查服务单元文件:
systemctl cat,重点看StandardOutput和StandardError字段——如果设成journal或null,就不会生成传统日志文件 - 若想强制落盘,需在 service 文件里加
StandardOutput=append:/var/log/并 reload:先.log systemctl daemon-reload,再systemctl restart
journalctl 查不到最近的日志
常见于系统重启后日志被轮转或限制了保留策略,不是命令用错了。
- 默认
journald只存内存+有限磁盘空间(通常 10% 或 4G),老日志会被自动清理。查当前配额:journalctl --disk-usage - 看保留策略:
cat /etc/systemd/journald.conf | grep -E "^(Storage|SystemMaxUse|SystemMaxFileSize)";若Storage=volatile,那所有日志都在/run/log/journal/,重启即丢 - 临时扩大空间:改
SystemMaxUse=500M后执行systemctl kill --signal=SIGUSR1 --kill-who=main systemd-journald触发重载(不用 restart) - 注意:
--since时间格式要严格,"2024-05-20 14:30:00"比"2 hours ago"更可靠,后者依赖系统时钟精度
服务进程在跑,但 journalctl 和文件日志都空
大概率是进程自己接管了 stdout/stderr,又没做任何输出,或者输出被重定向到某个没权限写的路径。
- 用
ps auxf | grep找主进程 PID,再查它的文件描述符:ls -l /proc/—— 如果指向/fd/{1,2} /dev/null或一个不存在的路径,就解释得通 - 有些程序(如 Node.js 的
pm2、Go 的二进制)默认静默,需显式加--log或设置环境变量如LOG_LEVEL=debug - 检查服务是否以非 root 用户运行,而日志路径(比如
/var/log/myapp/)属主是 root 且无写权限 ——journalctl不报权限错,但写文件会静默失败 - 抓一把实时输出:
strace -p,看它到底往哪写、写了啥-e write -s 200 2>&1 | grep -E "(write|\"[^\"]{5,}\")"
想让日志同时进 journald 和文件,但内容不一致
不是同步问题,是输出流被复制时发生了缓冲或截断 —— 尤其是短生命周期进程或带颜色输出的命令。
- 避免用
tee简单分流,它无法处理行缓冲和全缓冲混用的情况。正确做法是在服务配置中分别指定:StandardOutput=journal+StandardError=journal,再用systemd-cat做桥接(见下条) - 若必须落地文件,用
ExecStartPre=-/bin/mkdir -p /var/log/确保路径存在,再用ExecStart=/usr/bin/stdbuf -oL -eL /path/to/binary 2>&1 | /usr/bin/systemd-cat -t -
stdbuf -oL -eL强制行缓冲,防止日志卡在缓冲区不吐;systemd-cat保证每行都进 journal,且能被journalctl -t过滤 - 注意:
systemd-cat不会自动创建日志文件,它只负责把标准输入转发给 journald —— 落盘还得靠systemd-journald自身的持久化配置
Storage=auto 在某些发行版里实际等价于 volatile,或者 StandardOutput=journal 时连 printf 都可能因缓冲不刷新而消失。










