logrotate沒有rotate的排查過程


前言

背景
xxx,你過來把squid的日志檢查一下,是否做了日志切割;於是乎開啟了logrotate沒有切割日志的排查旅程,em~~。只能說過程很爽,平時疲於應付繁瑣的事情,難得有點時間能一條線慢慢的捋清楚一件事情。現在唯一想做的事情就是慢慢的把技術知識一點一點捋順了,查漏補缺,然后深入。
 
排查過程
知道logrotate這個東西,但是僅限於知道,只能一點點的邊學習,邊排查。重點在於他依賴於定時任務,在這個地方又是另一個知識點了,其實很多東西都是由基礎的東西構成的。排查定時任務的時候卡在了兩種定時任務Crontab和Systemd timer;其實logrotate使用這兩種方式都可以,只是剛開始的時候腦袋太亂了,因此沒搞明白。下面就把這兩種方式總結一下。
 

方式一、Crontab模式

剛開始的時候是往Crontab方向排查的,采用由 外到內的方式;
 
1)檢查Cron服務的狀態
systemctl status cron.service 

 

2)檢查執行Logrotate的定時任務
#cat /etc/crontab 
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6   * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

 

定時任務不執行一般問題都出現在后面的命令,所以檢查一下,手動執行“test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )”,看是否報錯,這里我的就是 anacron是沒有安裝
 
3)檢查系統日志cron是否有在規定的時間執行
 
cat  /var/log/syslog,可以看到定時任務是有在規定時間執行的
Dec  8 06:25:01 (root) CMD (test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ))

 

4)檢查定時任務下logrotate腳本
 
cat /etc/cron.daily/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
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
    /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit $EXITVALUE

 

因為我的squid的定時切割是每天,所以需要/etc/cron.daily;同樣可以手動執行(bash -x logrotate)一次這個腳本,看是否能成功,在這里,發現我的腳本在執行第一個檢查的時候這一步退出了;然后花了大量的時候查找為什么會做這一步檢查,后來經過網上的搜索發現/run/systemd/system這個目錄下放着與時間相關的Systemd任務,所以這一步的判斷是為了檢測是否用了方式二Systemd timer做了定時任務,如果有這個目錄,則不再做Crontab的定時任務;

 
# bash -x /etc/cron.daily/logrotate 
if [ -d /run/systemd/system ]; then
    exit 0
fi

 

因此到了這里發現了logrotate是有兩種方式做定時任務的,如果使用Crontab模式,則把 /etc/cron.daily/logrotate這個文件里檢測/run/systemd/system目錄的這3行注釋掉就可以;然后停掉logrotate.timer(systemctl stop logrotate.timer);
 
5)檢查logrotate服務的狀態
 
systemctl status logrotate.service     
● logrotate.service - Rotate log files
     Loaded: loaded (/lib/systemd/system/logrotate.service; static; vendor preset: enabled)
     Active: failed (Result: exit-code) since Wed 2021-12-08 00:00:03 +08; 16h ago
TriggeredBy: ● logrotate.timer
       Docs: man:logrotate(8)
             man:logrotate.conf(5)
   Main PID: 2811680 (code=exited, status=1/FAILURE)
 
Dec 08 00:00:01 systemd[1]: Starting Rotate log files...
Dec 08 00:00:03 logrotate[2811680]: error: failed to rename /usr/squid/logs/access.log to /usr/squid/logs/access.log-20211208: Read-only file system
 
這里通過 TriggeredBy:logrotate.timer可以發現logrotate確實是通過Systemd timer的方式來做定時任務的。
 

方式二:Systemd模式

使用Systemd timer模式主要是兩個服務,一個是 logrotate.service,logrotate.timer
 
1)查看logrotate.service的狀態

systemctl status logrotate.service 
 
● logrotate.service - Rotate log files
     Loaded: loaded (/lib/systemd/system/logrotate.service; static; vendor preset: enabled)
     Active: failed (Result: exit-code) since Wed 2021-12-08 00:00:03 +08; 16h ago
TriggeredBy: ● logrotate.timer
       Docs: man:logrotate(8)
             man:logrotate.conf(5)
   Main PID: 2811680 (code=exited, status=1/FAILURE)
 
Dec 08 00:00:01 systemd[1]: Starting Rotate log files...
Dec 08 00:00:03 logrotate[2811680]: error: failed to rename /usr/squid/logs/access.log to /usr/squid/logs/access.log-20211208: Read-only file system

 

TriggeredBy: logrotate.timer,這里可以知道這個服務是由logrotate.timer觸發執行的;這里有 Read-only file system的報錯,主要是Systemd的logrotate.service文件中,對logrotate加了文件讀寫保護,當 ProtectSystem=full這個參數時,會把 /usr/, /boot, /efi, /etc 掛載為只讀,如果是 ProtectSystem=strict 那么整個文件系統都會掛載為只讀。剛好我的日志目錄就在/usr/下,因此需要再加一個參數:ReadWritePaths=/usr/squid/logs即可,然后systemctl daemon-reload && systemctl restart logrotate.service。這里需要思考的問題是日志目錄設置在/usr/下是否合理?
 
[Unit]
Description=Rotate log files
Documentation=man:logrotate(8) man:logrotate.conf(5)
ConditionACPower=true
 
[Service]
Type=oneshot
ExecStart=/usr/sbin/logrotate /etc/logrotate.conf
 
# performance options
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
 
# hardening options
#  details: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
#  no ProtectHome for userdir logs
#  no PrivateNetwork for mail deliviery
#  no ProtectKernelTunables for working SELinux with systemd older than 235
#  no MemoryDenyWriteExecute for gzip on i686
PrivateDevices=true
PrivateTmp=true
ProtectControlGroups=true
ProtectKernelModules=true
ProtectSystem=full
RestrictRealtime=true
ReadWritePaths=/usr/squid/logs

 

2)檢查logrotate.timer的狀態
 
systemctl status logrotate.timer
 
● logrotate.timer - Daily rotation of log files
     Loaded: loaded (/lib/systemd/system/logrotate.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since Thu 2021-08-05 11:08:00 +08; 4 months 3 days ago
    Trigger: Thu 2021-12-09 00:00:00 +08; 7h left
   Triggers: ● logrotate.service
       Docs: man:logrotate(8)
             man:logrotate.conf(5)

 

Trigger:可以看出他的觸發時間
Triggers:可以看出他將觸發的服務
 
查看logrotate.timer的配置
 
[Unit]
Description=Daily rotation of log files
Documentation=man:logrotate(8) man:logrotate.conf(5)
 
[Timer]
OnCalendar=daily
AccuracySec=12h
Persistent=true
#Unit:真正要執行的任務,默認是同名的帶有.service后綴的單元
 
[Install]
WantedBy=timers.target
 
3)檢查logrotate腳本
 
使用logrotate切割的腳本一般都放在/etc/logrotate.d/ 下,因此我的squid切割也在這個目錄下,可以通過 logrotate -d /etc/logrotate.d/squid 檢測一下,-d表示debug模式;在這里debug時候發現logrotate有一個status狀態文件 /var/lib/logrotate/status,也就是記錄下文件logrotate的時間,在今天有做過rotate的話,那么就不會再一次進行,如果想要測試,可以編輯這個文件你想要測試的文件的時間,比如發現里面有一條日志:"/usr/squid/logs/access.log" 2021-12-9-14:33:28 說明今天做了切割了,還想做測試則可以改為:"/usr/squid/logs/access.log" 2021-12-7-14:33:28,那么就可以再一次測試了。 注意:這個status的狀態只能改時間,直接刪除這一條是不生效的。
 
4)驗證
 
重新執行systemctl restart logrotate.service后,就可以看到被切割的日志;如:access.log-20211209等
 

待加強的知識點

1)anacron與cron的區別?

2)systemd創建定時任務與Cron創建定時任務的區別,優缺點?

3)systemd的配置以及整個systemd需要加強理解,系統學習

4)crontab定時任務的系統學習

5)logrotate系統的學習,配置等

6)看logrotate源碼,用Python或Go模擬

 

很多基礎都只是知道的層次,需要下點功夫了。
 

最后

歡迎大家關注我的公眾號,一起交流、學習。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM