會有這篇文章,主要還是因為在工作上踩了好幾次坑,很多次都遇到了log檔佔用了太多的硬碟空間,所以趁這機會好好研究一下linux上相關的設定。
在Linux上Distro,Log 相關的 daemon主要有以下幾個:
(1) rsyslogd
(2) systemd-journald
(3) logrotate.d
而它們各自有不同的工作要處理,下面就分別來介紹每個daemon service:
rsyslogd
rsyslogd is the enhancement of syslogd, a service that takes care of managing centralized log files. Syslogd has been around for a long time.
https://www.golinuxcloud.com/systemd-journald-how-logging-works-rhel-7/
rsyslogd
算是syslogd
的進化版本,相對於syslogd
, 它提供更有效率的log 處理方式
預設的log 會寫入到/var/log/syslog
裡,而相關的設定檔則是放在/etc/rsyslog.conf
與/etc/rsyslog.d/50-default.conf
裡面。
在ubuntu20.04中,rsyslog.conf
的設定來看,它預設是從imuxsock
裡讀取到log 訊息,並寫入到/var/log/syslog
之中。相關在rsyslog.conf
的設定如下:
module(load="imuxsock") # provides support for local system logging
另外,在ubuntu中,是使用systemctl來執行這個daemon,所以我們可以透過下面這個指令來看其執行狀態:
sudo systemctl status rsyslog.service
而相關的輸出大概會是長這樣:
● rsyslog.service - System Logging Service
Loaded: loaded (/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2021-08-26 11:12:02 UTC; 1 weeks 1 days ago
TriggeredBy: ● syslog.socket
Docs: man:rsyslogd(8)
https://www.rsyslog.com/doc/
Main PID: 269574 (rsyslogd)
Tasks: 4 (limit: 9369)
Memory: 517.1M
CGroup: /system.slice/rsyslog.service
└─269574 /usr/sbin/rsyslogd -n -iNONE
簡單講,rsyslogd
主要就是負責系統所有相關的log的寫入,像是/var/log/syslog
, /var/log/auth.log
, /var/log/kern.log
。
不過對於log 寫入之外的工作,就不是由它來負責的了,而是由另一個服務logrotate
來負責的。
更改設定檔以後,則要使用sudo systemctl restart rsyslog.service
來重啟服務以讀取新的設定檔。
logrotate
從名稱上就可以看得出,這個service主要負責的工作就是做log file的rotate,所以當我們發現/var/log/syslog
的檔案過大時,很大一部分的原因會是我們沒有設定好 /var/log/syslog
的rotate設定。
logrotate
的設定檔位置在/etc/logrotate.conf
,裡面有定義了預設的log檔案rotate設定;而針對於不同log的rotate 客制化設定,則是放在/etc/logrotate.d/
這個資料夾下面。
舉例來說,是rsyslog
的log rotate 設定的位置就是在/etc/logrotate.d/rsyslog
這裡。而相關的範例設定如下:
/var/log/syslog
{
rotate 7
hourly
maxsize 100M
missingok
notifempty
delaycompress
compress
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/mail.log
/var/log/daemon.log
/var/log/kern.log
/var/log/auth.log
/var/log/user.log
/var/log/lpr.log
/var/log/cron.log
/var/log/debug
/var/log/messages
{
rotate 4
weekly
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
NOTE:
如果rotate的time
與size
都有設定的話,那就會以size
為基準。而目前設定檔time
最多只能支援到hourly
。
不過如果是以size
為基準的話,應該也可以設定每分鐘的cron job,定期執行logrotate
另外,與一般的system service不一樣的地方是,logrotate
是透過cron job
的方式執行的,它的基本運作方式是,當我們執行了下面的指令去讀取新的rotate設定時
sudo logrotate /etc/logrotate.conf
logrotate
這個程式除了會去執行對應的rotate工作外,還會根據設定去產生對應的cron jobs。
舉例來說,如果我們設定syslog的rotate檢查頻率為hourly,那我們就可以找到對應的/etc/cron.hourly/logrotate
的cron job。
更改設定檔以後,則要使用sudo logrotate /etc/logrotate.conf
來重啟服務以讀取新的設定檔。
systemd-journald
With the introduction of systemd, the journald log service systemd-journald has been introduced also. This service is tightly integrated with systemd, which allows administrators to read detailed information from the journal while monitoring service status using the systemctl status command.
https://www.golinuxcloud.com/systemd-journald-how-logging-works-rhel-7/
journald
是近年來在Linux上常被預設啟用的另一個log deamon service,它主要與systemd services 作整合,而與rsyslogd
不同之處可以參考這裡:
Journald provides structure and indexed log files (called journals) in a secure manner. Therefore, not only are the journal files easier to search, it is harder for system intruders to cover their tracks.. Also you can maintain rsyslog messages in structured format.
Another advantage of using the systemd-journald service over traditional logging daemons is that journal files are automatically rotated if they grow above certain limits. This reduces log file maintenance issues and complexity.
The journalctl utility is used to read the journal binary log files and this command provides several means of filtering the data which is very powerful.
https://www.golinuxcloud.com/systemd-journald-how-logging-works-rhel-7/
簡單來說,它可以看成是rsyslogd
的加強版,除了提供更安全的log儲存方式外,還額外提供了log rotate的功能,另外其搭配的cli journalctl
還可以方便使用者檢索需要的log內容。
基本上journald
的儲存相關設定主要是分為runtime
與system
:
- runtime: 所以runtime 相關的journals 會存放在
/run/log/journal/
下,一旦重新開機以後,舊的journals是不會保留的。 - system: 如果下面的路徑
/var/log/journal
存在且有對應的權限時,那麼journald
就不會去寫log到/run/log/journal/
底下了,而是持續性的寫入到/var/log/journal/
下,在這情況下,即使重開機以後,舊的journals還是會保留的。
在ubuntu20.04中,journald
的log 存放位置是在/var/log/journal
,而設定檔的位置則是在/etc/systemd/journald.conf
。 相關的設定檔說明可以參考ubuntu這文章。
journald
預設是透過systemd service
的方式啟用的,所以透過下面的指令可以看得出目前journald
的運作狀況:
sudo systemctl status systemd-journald.service
範例輸出結果為:
● systemd-journald.service - Journal Service
Loaded: loaded (/lib/systemd/system/systemd-journald.service; static; vendor preset: enabled)
Active: active (running) since Wed 2021-07-28 09:56:47 UTC; 1 months 7 days ago
TriggeredBy: ● systemd-journald-dev-log.socket
● systemd-journald-audit.socket
● systemd-journald.socket
Docs: man:systemd-journald.service(8)
man:journald.conf(5)
Main PID: 186 (systemd-journal)
Status: "Processing requests…"
Tasks: 1 (limit: 9369)
Memory: 39.4M
CGroup: /system.slice/systemd-journald.service
└─186 /lib/systemd/systemd-journald
Warning: journal has been rotated since unit was started, output may be incomplete.
journalctl 指令的使用
通常主要是透過journalctl
指令來讀取log與變更log檔的一些設定,一些透過journalctl過濾/讀取log的相關技巧可以參考這邊;
而一些常用journal 相關的管理指令如下:
- 顯示目前所有journal的在硬碟上的使用空間
journalctl --disk-usage
- 一次性的限制所有journal可以使用的硬碟空間 (e.g. 1GB),另外在清理時只會針對被archived 過的journal作清理。
sudo journalctl --vacuum-size=1G
更多journald 與rsyslog的整合與比較可以參考這裡
- https://sematext.com/blog/journald-logging-tutorial/#toc-journald-vs-syslog-14
- https://serverfault.com/questions/959982/is-rsyslog-redundant-on-when-using-journald
相關設定以確保log 檔案不會過大
在了解rsyslog
, logroate
與 journald
的一些運作模式以後,接下來回到之前常遇到的問題,log檔案size過大,而導致系統運作不正常的這個問題。
由於ubuntu20.04預設是同時會執行rsyslogd
與journald
的,所以基本上我們要關注的log檔案有兩個位置,分別是/var/log/syslog
與/var/log/journal
。
syslog的相關設定
基本上,針對syslog
,logrotate
預設是每天會做一次rotate,所以為了避免我們的應用程式在短時間製造過多的log,我們可以修改/etc/logrotate.d/rsyslog
如下:
sudo vim /etc/logrotate.d/rsyslog
接著修改設定檔中的/var/log/syslog
部分如下
/var/log/syslog
{
rotate 3
hourly
maxsize 100M
missingok
notifempty
delaycompress
compress
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
以這樣來限制syslog
的檔案大小
journald
以ubuntu20.04為例,它預設就是寫入到/var/log/journal
,也就是說,我們必須去設定/etc/systemd/journald.conf
中的System*
相關參數,詳細設定如下:
SystemMaxUse=1G
SystemKeepFree=
SystemMaxFileSize=100M
SystemMaxFiles=10
清除過大的log檔案
SYSLOG
如果目前的syslog 真的長的太大了,且裡面的內容是可丟棄的情況下,則可以使用下面的指令來清空目前的/var/log/syslog
。
# this command needs to be ran as root
> /var/log/syslog
JOURNAL
如果是journal的話,則可以先將目前的journal archived,再做清理,詳細指令如下:
sudo journalctl --rotate
sudo journalctl --vacuum-time=1s
其它相關的清理方式可以參考這裡
reference:
- https://www.opencli.com/linux/log-tools-logrotate
- https://www.twblogs.net/a/5b89545a2b71775d1ce13be1
- http://linux.vbird.org/linux_basic/0570syslog.php
- https://askubuntu.com/questions/925440/relationship-of-rsyslog-and-journald-on-ubuntu-16-04
- http://manpages.ubuntu.com/manpages/bionic/zh_TW/man5/journald.conf.5.html
- https://sematext.com/blog/journald-logging-tutorial/#toc-journald-vs-syslog-14
- https://serverfault.com/questions/959982/is-rsyslog-redundant-on-when-using-journald
- https://unix.stackexchange.com/questions/139513/how-to-clear-journalctl
- https://www.golinuxcloud.com/systemd-journald-how-logging-works-rhel-7/
- https://stackoverflow.com/questions/35638219/ubuntu-large-syslog-and-kern-log-files