1. Tổng quan
Trong quá trình viết hoặc triển khai một systemd service cho một script hoặc một chương trình nền (daemon), đôi khi chúng ta không muốn stdout (hoặc stderr) của service ghi log vào journalctl
hay bị forward sang syslog
. Việc ghi log không cần thiết không chỉ gây rác log, mà còn tốn tài nguyên lưu trữ.
Bài viết này sẽ hướng dẫn cách vô hiệu hóa hoàn toàn log hoặc chỉ log vào journal mà không forward sang syslog, một cách hiệu quả và chính xác theo khuyến nghị của systemd.
2. Dùng StandardOutput=null
để tắt hoàn toàn log
Giả sử bạn có một service đơn giản chạy một script Python:
[Service]
ExecStart=/usr/bin/script-python.py
StandardOutput=null
StandardError=null
Điều gì xảy ra?
StandardOutput=null
: Tắt hoàn toàn việc ghi stdout.StandardError=null
: Tắt hoàn toàn việc ghi stderr.- Không có log nào được ghi vào journal hay syslog.
- Tương đương với việc bạn dùng shell redirect:
script-python.py > /dev/null 2>&1
.
🧠 Đây là cách tốt nhất nếu bạn không cần ghi log gì cả.
3. Trường hợp vẫn muốn log vào journal
Nếu bạn vẫn muốn giữ lại log để có thể xem bằng journalctl
, nhưng không muốn ghi vào syslog
, bạn có thể dùng:
[Service]
ExecStart=/usr/bin/script-python.py
StandardOutput=journal
StandardError=journal
Điều này có tác dụng gì?
- Ghi log vào
journalctl -u your-service-name
. - Nhưng có thể vẫn bị forward sang
syslog
nếu file config/etc/systemd/journald.conf
chứa dòngForwardToSyslog=yes
(đây là mặc định của một số hệ thống như Debian/Ubuntu).
🛠 Nếu bạn chỉ cần xem log bằng journalctl và muốn tránh syslog, hãy chắc chắn rằng ForwardToSyslog=no
.
4. So sánh với cách redirect bằng shell
Bạn có thể thấy hai cách viết này là tương đương:
Cách 1:
ExecStart=/bin/sh -c '/usr/bin/script-python.py > /dev/null'
Cách 2:
ExecStart=/usr/bin/script-python.py
StandardOutput=null
Khác biệt ở đây là:
- Cách 1 chỉ redirect stdout của
script-python.py
, nếu bạn có nhiều dòng trong shell script thì những dòng khác vẫn có thể ghi log. - Cách 2 (dùng
StandardOutput=null
) tắt luôn toàn bộ stdout của process chính trong service.
✅ Lời khuyên: Không cần bọc trong shell, systemd có thể chạy trực tiếp script hoặc binary.
🧹 Dọn dẹp cấu hình kiểu cũ (SysV init)
Nhiều người chuyển từ init script cũ (SysV) sang systemd vẫn giữ cấu hình như:
Type=forking
PIDFile=/dev/shm/abc.pid
ExecStart=/usr/bin/myscript.sh
Trong đó, myscript.sh
sẽ gọi một tiến trình chạy nền rồi ghi PID thủ công vào file.
Với systemd, điều này không cần nữa:
- Systemd quản lý PID và trạng thái tiến trình tự động.
- Không cần
Type=forking
, không cầnPIDFile
và cũng không cần&
để chạy nền trong script. - Hãy viết lại đơn giản như sau:
[Service]
ExecStart=/usr/bin/script-python.py
Type=simple
StandardOutput=null
⚡️ Điều này sẽ giúp service gọn gàng, hiệu quả và theo đúng chuẩn systemd.
🧠 Tổng kết
Mục tiêu | Cấu hình đề xuất |
---|---|
Tắt toàn bộ log | StandardOutput=null StandardError=null |
Chỉ log vào journalctl | StandardOutput=journal StandardError=journal |
Tránh dùng sh -c không cần thiết | Chạy trực tiếp script bằng ExecStart=/usr/bin/myscript.py |
Không cần Type=forking hay PIDFile= nữa | Dùng mặc định Type=simple |
📌 Có thể kiểm tra forward syslog
Nếu bạn muốn kiểm tra xem journald
có forward log sang syslog hay không, kiểm tra file:
cat /etc/systemd/journald.conf | grep ForwardToSyslog
Nếu đang là yes
, bạn có thể sửa thành:
ForwardToSyslog=no
Rồi reload lại:
sudo systemctl restart systemd-journald
Hy vọng bài viết này giúp bạn hiểu rõ hơn về cách kiểm soát log trong systemd service. Hãy giữ cấu hình gọn gàng, hiệu quả và chỉ log khi thật sự cần thiết nhé!