以 Rsyslog Ruleset 簡易存放多來源的日誌
本篇目的是透過 Rsyslog ruleset 儲存多個來源的日誌,定義從各個 Port 傳入的日誌該儲至何處,搭配 Logrotate 每小時壓縮輪替管理。 為甚麼選擇由 Port 下手呢?因為若來源 IP 如果更動了,那份日誌便無法保留~
以下使用 Debian GNU/Linux 11 (bullseye) 與內建的 Rsyslog 8.2102.0、Logrotate 3.18.0 及 Crontab 操作。
備註 1:創建 /syslog/ 用來存放各個設備傳回的日誌,並以 /syslog/編號-名稱/ 儲存資料。
備註 2:直接使用 $ sudo su 切換為系統 Root 身分進行設定。
Rsyslog 存放日誌
Rsyslog 服務設定檔為 /etc/rsyslog.conf,Rsyslog 會讀取設定檔並進行相對應的操作;首先執行 $ cp /etc/rsyslog.conf /etc/rsyslog.conf.bak 保留原始設定。
透過 Vim、Nano 或其他編輯器修改設定檔,找到 #### MODULES #### 的區塊註解,往下新增一行內容,以引入 imudp 模組。
# ---/etc/rsyslog.conf---
module(load="imudp")
定義第一個 ruleset 為 remote52000,某一遠端主機將日誌以 Port 52000 傳入,系統將內容存入 /syslog/00-first-item/ 且檔名為 00-first-item.log;請先創建好 /syslog/00-first-item/ 存放日誌的目錄。
注意!每條 ruleset 需要搭配 input 函式綁定欲使用的 Port。
# ---/etc/rsyslog.conf---
ruleset(name="remote52000") { action(type="omfile" file="/syslog/00-first-item/00-first-item.log") }
input(type="imudp" port="52000" ruleset="remote52000")
也就是說,若現在有三個遠端主機傳回日誌,則 Rsyslog 設定檔能定義如下。
# ---/etc/rsyslog.conf---
ruleset(name="remote52000") { action(type="omfile" file="/syslog/00-first-item/00-first-item.log") }
ruleset(name="remote52001") { action(type="omfile" file="/syslog/01-second-item/01-second-item.log") }
ruleset(name="remote52002") { action(type="omfile" file="/syslog/02-third-item/02-third-item.log") }
input(type="imudp" port="52000" ruleset="remote52000")
input(type="imudp" port="52001" ruleset="remote52001")
input(type="imudp" port="52002" ruleset="remote52002")
更動 /etc/rsyslog.conf 設定後,需要儲存並重啟 Rsyslog 服務 $ systemctl restart rsyslog,開始觀察日誌是否成功傳入日誌伺服器。
Logrotate 輪替日誌
內建的 Logrotate 服務用來把過舊的日誌刪除,創建一個空白檔案來存入較新的資料。透過滾動式的管理,能根據檔案大小及存在天數來處理。
該服務的設定檔為 /etc/logrotate.conf,可以忽略原有內容,直接在最末行新增以下內容。
# ---/etc/logrotate.conf---
/syslog/*/*.log {
hourly
rotate 4500
su root root
create 600
# add suffex to filenames
dateext
dateformat -%Y%m%d%H%M
compress
sharedscripts
prerotate
endscript
# reload settings of service of syslog and rsyslog
sharedscripts
postrotate
/usr/bin/systemctl kill -s HUP syslog.socket > /dev/null 2>&1 || true
/usr/bin/systemctl kill -s HUP rsyslog.service > /dev/null 2>&1 || true
endscript
}
-
/syslog/*/*.log以正規表示式匹配目錄內的檔名,找到需要處理的日誌。 -
hourly將特定檔案以小時為單位進行滾動切割。 -
rotate 4500保留最近 4500 個小時的內容,約半年多。 -
su root rootcreate 600以 root 身分創建檔案並定義權限。 -
dateextdateformat -%Y%m%d%H%M讓處理過的檔案,名稱新增後綴日期時間。 -
compress讓處理過的檔案被壓縮,以節省硬碟空間。 -
prerotate沒有針對日誌預處理所以留空。 -
postrotate使用/usr/bin/systemctl kill -s HUP重新載入設定,不重啟服務。
設定完成後手動執行 logrotate -d /etc/logrotate.conf,以參數 -d 開啟測試模式,輸出處理過程,但不異動任何資料,藉此判斷設定檔的可執行性。
Crontab 排程啟動
使用 Cron 排程服務自動觸發 Logrotate,開始編輯內建的 /etc/crontab。
系統已有設定每小時執行 /etc/cron.hourly/ 內定義的排程,但觸發時間為每時 17 分,這裡我們將它改為每時 0 分,能註解原設定並複製內容修改即可。
# ---/etc/crontab---
...
# 17 * * * * root cd / && run-parts --report /etc/cron.hourly
00 * * * * root cd / && run-parts --report /etc/cron.hourly
接著需要定義排程任務內容,讓 Cron 可以準確執行 Logrotate 任務,這裡複製 /etc/cron.daily/logrotate 的內容來用,$ cp /etc/cron.daily/logrotate /etc/cron.hourly/(預設是每天執行一次 Logrotate)。
修改內容如下,主要註解 /run/systemd/system 檢查,並新增 > /dev/null 2>&1 忽略錯誤訊息。
# ---/etc/cron.hourly/logrotate---
#!/bin/sh
## skip in favour of systemd timer
#if [ -d /run/systemd/system ]; then
# exit 0
#fi
# this cronjob persists removals (but not purges)
if [ ! -x /usr/sbin/logrotate ]; then
exit 0
fi
#/usr/sbin/logrotate /etc/logrotate.conf
/usr/sbin/logrotate /etc/logrotate.conf > /dev/null 2>&1
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit $EXITVALUE
最後以 $ run-parts --test /etc/cron.hourly 檢查資料夾內可執行的設定(但不執行),結果須包含 /etc/cron.hourly/logrotate,若沒出現,需檢查是否具有 +x 可執行權限。
備註:關於上述提到需要註解 /run/systemd/system 檢查是因為內建 logrotate 定時器 /usr/lib/systemd/system/logrotate.timer 每天執行
指令備註
-
$ grep cron /var/log/syslog搜尋 syslog 內有關 Cron 的紀錄,檢查 Logrotate 是否正確被觸發,例如下方輸出。May 12 22:00:01 hostname-syslog CRON[420967]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly) May 12 23:00:01 hostname-syslog CRON[421202]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly) May 13 00:00:01 hostname-syslog CRON[421434]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly) -
$ systemctl status cron -
$ systemctl status rsyslog.service使用 systemctl 系統服務管理指令來查看 Rsyslog 的狀態。 -
$ rsyslogd -v以 rsyslogd 來顯示其他資訊 -
$ /var/lib/logrotate/status紀錄各日誌檔案最新異動時間;讓它能根據所列的項目及時間判斷是否進行轉儲。logrotate state -- version 2 "/syslog/00-first-item/00-first-item.log" 2024-5-12-23:0:5 # ... -
(承上)
$ cat /var/lib/logrotate/status | grep -v syslog若存放的日誌種類多樣,篩選包含 syslog 字串的項目。 -
$ logrotate -f /etc/logrotate.conf強制執行。 -
$ logrotate -vf /etc/logrotate.conf強制執行,且顯示過程。
參考資料
- 原文作者:Anthy
- 原文連結:https://blog.anthy.cc/posts/2024/rsyslog-ruleset-logrotate-20240512/
- 版權聲明:本作品採用姓名標示-非商業性-禁止改作 4.0 國際. 進行許可,非商業轉載請註明出處(作者,原文連結),商業轉載請聯繫作者獲得授權。