南京網(wǎng)站開(kāi)發(fā)注冊(cè)app近期國(guó)內(nèi)新聞熱點(diǎn)事件
文章目錄
- 一、logrotate概述
- 二、logrotate基本用法
- 三、logrotate運(yùn)行機(jī)制
- logrotate參數(shù)
- 四、logrotate是怎么做到滾動(dòng)日志時(shí)不影響程序正常的日志輸出呢?
- Linux文件操作機(jī)制
- 方案一
- 方案二
- 五、logrotate實(shí)戰(zhàn)--Ceph日志轉(zhuǎn)儲(chǔ)
- 參考
一、logrotate概述
logrotate是一個(gè)用于管理Linux系統(tǒng)上的日志文件的工具,它的主要目的是確保日志文件不會(huì)變得過(guò)大,從而占用過(guò)多的磁盤(pán)空間并影響系統(tǒng)性能。當(dāng)系統(tǒng)運(yùn)行時(shí)間越長(zhǎng),生成的日志文件就越多,這些文件可能會(huì)變得非常大,導(dǎo)致磁盤(pán)空間不足。此外,如果日志文件太大,它們可能會(huì)變得不可讀,從而導(dǎo)致難以診斷和解決問(wèn)題。logrotate可以定期輪換舊的日志文件,并將它們壓縮或刪除,以釋放磁盤(pán)空間并保持日志文件的可讀性。它還可以在輪換時(shí)創(chuàng)建新的日志文件,以確保系統(tǒng)仍然可以記錄重要的事件和錯(cuò)誤信息。
logrotate旨在簡(jiǎn)化生成大量日志文件的系統(tǒng)上日志文件的管理。logrotate允許自動(dòng)滾動(dòng)、壓縮、刪除和郵寄日志文件。logrotate可以設(shè)置為每小時(shí)、每天、每周、每月或當(dāng)日志文件達(dá)到一定大小時(shí)處理日志文件。因此,logrotate對(duì)于維護(hù)系統(tǒng)的穩(wěn)定性和可靠性非常重要。它可以確保系統(tǒng)管理員能夠及時(shí)發(fā)現(xiàn)和解決潛在的問(wèn)題,并避免因日志文件過(guò)大而導(dǎo)致的性能問(wèn)題。
二、logrotate基本用法
logrotate [OPTION...] <configfile>
-d, --debug :debug模式,測(cè)試配置文件是否有錯(cuò)誤。
-f, --force :強(qiáng)制轉(zhuǎn)儲(chǔ)文件。
-m, --mail=command :壓縮日志后,發(fā)送日志到指定郵箱。
-s, --state=statefile :使用指定的狀態(tài)文件。
-v, --verbose :顯示轉(zhuǎn)儲(chǔ)過(guò)程。
排障過(guò)程中的最佳選擇是使用-d
選項(xiàng)以預(yù)演方式運(yùn)行l(wèi)ogrotate。要進(jìn)行驗(yàn)證,不用實(shí)際輪循任何日志文件,可以模擬演練日志輪循并顯示其輸出。
logrotate -d 配置文件
即使輪循條件沒(méi)有滿足,我們也可以通過(guò)使用-f
選項(xiàng)來(lái)強(qiáng)制logrotate輪循日志文件,-v
參數(shù)提供了詳細(xì)的輸出。
logrotate -vf 配置文件
三、logrotate運(yùn)行機(jī)制
logrotate的運(yùn)行依賴于Linux上的定時(shí)任務(wù)命令crontab:Linux crontab 命令
crontab命令會(huì)定時(shí)運(yùn)行l(wèi)ogrotate,一般是每天一次。crontab會(huì)每天定時(shí)執(zhí)行/etc/cron.daily
目錄下的腳本,而這個(gè)目錄下有個(gè)文件叫l(wèi)ogrotate。
[root@ceph01 cron.daily]# cat logrotate
#!/bin/sh/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit $EXITVALUE
Linux系統(tǒng)默認(rèn)安裝logrotate,它的配置文件在:
/etc/logrotate.conf
/etc/logrotate.d/
日志輪轉(zhuǎn)是系統(tǒng)自動(dòng)完成的。實(shí)際運(yùn)行時(shí),logrotate會(huì)調(diào)用配置文件/etc/logrotate.conf
。可以在/etc/logrotate.d/
目錄里放置自定義好的配置文件,用來(lái)覆蓋logrotate的缺省值。
查看/etc/logrotate.conf文件
[root@ceph01 ceph]# cat /etc/logrotate.conf
# see "man logrotate" for details
# rotate log files weekly
weekly # 默認(rèn)每周執(zhí)行一次rotate輪轉(zhuǎn)任務(wù)# keep 4 weeks worth of backlogs
rotate 4 # 保留多少日志文件,默認(rèn)保留4個(gè),0表示沒(méi)有備份# create new (empty) log files after rotating old ones
create # 自動(dòng)創(chuàng)建新的日志文件,新的日志文件具有和原來(lái)的文件相同的權(quán)限;因?yàn)槿罩颈桓拿?因此要?jiǎng)?chuàng)建一個(gè)新的來(lái)繼續(xù)存儲(chǔ)之前的日志# use date as a suffix of the rotated file
dateext # 切割后日志文件以當(dāng)前日期為后綴結(jié)尾,如xxx.log-20230912,如果注釋掉,切割出來(lái)是按數(shù)字遞增,即xxx.log-1這種格式# uncomment this if you want your log files compressed
#compress # 是否通過(guò)gzip壓縮轉(zhuǎn)儲(chǔ)以后的日志文件,如xxx.log-20131216.gz ;如果不需要壓縮,注釋掉# RPM packages drop log rotation information into this directory
include /etc/logrotate.d # 將/etc/logrotate.d/ 目錄中的所有文件都加載進(jìn)來(lái)# system-specific logs may be also be configured here.
logrotate參數(shù)
compress 通過(guò)gzip 壓縮轉(zhuǎn)儲(chǔ)以后的日志
nocompress 不做gzip壓縮處理
copytruncate 用于還在打開(kāi)中的日志文件,把當(dāng)前日志備份并截?cái)?#xff1b;是先拷貝再清空的方式,拷貝和清空之間有一個(gè)時(shí)間差,可能會(huì)丟失部分日志數(shù)據(jù)。
nocopytruncate 備份日志文件不過(guò)不截?cái)?create mode owner group 輪轉(zhuǎn)時(shí)指定創(chuàng)建新文件的屬性,如create 0777 nobody nobody
nocreate 不建立新的日志文件
delaycompress 和compress 一起使用時(shí),轉(zhuǎn)儲(chǔ)的日志文件到下一次轉(zhuǎn)儲(chǔ)時(shí)才壓縮
nodelaycompress 覆蓋 delaycompress 選項(xiàng),轉(zhuǎn)儲(chǔ)同時(shí)壓縮。
missingok 如果日志丟失,不報(bào)錯(cuò)繼續(xù)滾動(dòng)下一個(gè)日志
errors address 專(zhuān)儲(chǔ)時(shí)的錯(cuò)誤信息發(fā)送到指定的Email 地址
ifempty 即使日志文件為空文件也做輪轉(zhuǎn),這個(gè)是logrotate的缺省選項(xiàng)。
notifempty 當(dāng)日志文件為空時(shí),不進(jìn)行輪轉(zhuǎn)
mail address 把轉(zhuǎn)儲(chǔ)的日志文件發(fā)送到指定的E-mail 地址
nomail 轉(zhuǎn)儲(chǔ)時(shí)不發(fā)送日志文件
olddir directory 轉(zhuǎn)儲(chǔ)后的日志文件放入指定的目錄,必須和當(dāng)前日志文件在同一個(gè)文件系統(tǒng)
noolddir 轉(zhuǎn)儲(chǔ)后的日志文件和當(dāng)前日志文件放在同一個(gè)目錄下
sharedscripts 運(yùn)行postrotate腳本,作用是在所有日志都輪轉(zhuǎn)后統(tǒng)一執(zhí)行一次腳本。如果沒(méi)有配置這個(gè),那么每個(gè)日志輪轉(zhuǎn)后都會(huì)執(zhí)行一次腳本
prerotate 在logrotate轉(zhuǎn)儲(chǔ)之前需要執(zhí)行的指令,例如修改文件的屬性等動(dòng)作;必須獨(dú)立成行
postrotate 在logrotate轉(zhuǎn)儲(chǔ)之后需要執(zhí)行的指令,例如重新啟動(dòng) (kill -HUP) 某個(gè)服務(wù)!必須獨(dú)立成行
daily 指定轉(zhuǎn)儲(chǔ)周期為每天
weekly 指定轉(zhuǎn)儲(chǔ)周期為每周
monthly 指定轉(zhuǎn)儲(chǔ)周期為每月
rotate count 指定日志文件刪除之前轉(zhuǎn)儲(chǔ)的次數(shù),0 指沒(méi)有備份,5 指保留5 個(gè)備份
dateext 使用當(dāng)期日期作為命名格式
dateformat %Y%m%d%H.%s 配合dateext使用,緊跟在下一行出現(xiàn),定義文件切割后的文件名,必須配合dateext使用,只支持 %Y %m %d %s 這四個(gè)參數(shù)
size(或minsize) log-size 當(dāng)日志文件到達(dá)指定的大小時(shí)才轉(zhuǎn)儲(chǔ),log-size能指定bytes(缺省)及KB (sizek)或MB(sizem).
當(dāng)日志文件 >= log-size 的時(shí)候就轉(zhuǎn)儲(chǔ)。 以下為合法格式:(其他格式的單位大小寫(xiě)沒(méi)有試過(guò))
size = 5 或 size 5 (>= 5 個(gè)字節(jié)就轉(zhuǎn)儲(chǔ))
size = 100k 或 size 100k
size = 100M 或 size 100M
四、logrotate是怎么做到滾動(dòng)日志時(shí)不影響程序正常的日志輸出呢?
Linux文件操作機(jī)制
詳細(xì)講解,Linux內(nèi)核——文件系統(tǒng)(建議收藏)-目錄的存儲(chǔ)
目錄也是文件,目錄文件里存著文件名和對(duì)應(yīng)的inode編號(hào)。通過(guò)這個(gè)inode編號(hào)可以查到文件的元數(shù)據(jù)和文件內(nèi)容。文件的元數(shù)據(jù)有引用計(jì)數(shù)、操作權(quán)限、擁有者ID、創(chuàng)建時(shí)間、最后修改時(shí)間等等。文件名并不在元數(shù)據(jù)里而是在目錄文件中。因此文件改名、移動(dòng),都不會(huì)修改文件,而是修改目錄文件。
進(jìn)程每新打開(kāi)一個(gè)文件,系統(tǒng)會(huì)分配一個(gè)新的文件描述符給這個(gè)文件。文件描述符對(duì)應(yīng)著一個(gè)文件表。表里面存著文件的狀態(tài)信息(O_APPEND
/O_CREAT
/O_DIRECT
…)、當(dāng)前文件位置和文件的inode信息。系統(tǒng)會(huì)為每個(gè)進(jìn)程創(chuàng)建獨(dú)立的文件描述符和文件表,不同進(jìn)程是不會(huì)共用同一個(gè)文件表。正因?yàn)槿绱?#xff0c;不同進(jìn)程可以同時(shí)用不同的狀態(tài)操作同一個(gè)文件的不同位置。文件表中存的是inode信息而不是文件路徑,所以文件路徑發(fā)生改變不會(huì)影響文件操作。
方案一
這個(gè)方案的思路是重命名原日志文件,創(chuàng)建新的日志文件。詳細(xì)步驟如下:
- 重命名程序當(dāng)前正在輸出日志的程序。因?yàn)橹孛粫?huì)修改目錄文件的內(nèi)容,而進(jìn)程操作文件靠的是inode編號(hào),所以并不影響程序繼續(xù)輸出日志。
- 創(chuàng)建新的日志文件,文件名和原來(lái)日志文件一樣。雖然新的日志文件和原來(lái)日志文件的名字一樣,但是inode編號(hào)不一樣,所以程序輸出的日志還是往原日志文件輸出。
- 通過(guò)某些方式通知程序,重新打開(kāi)日志文件。程序重新打開(kāi)日志文件,靠的是文件路徑而不是inode編號(hào),所以打開(kāi)的是新的日志文件。
什么方式通知程序我重新打開(kāi)日志呢,簡(jiǎn)單粗暴的方法是殺死進(jìn)程重新打開(kāi)。很多場(chǎng)景這種作法會(huì)影響在線的服務(wù),于是有些程序提供了重新打開(kāi)日志的接口,比如可以通過(guò)信號(hào)通知nginx。各種IPC方式都可以,前提是程序自身要支持這個(gè)功能。
有個(gè)地方值得一提,一個(gè)程序可能輸出了多個(gè)需要滾動(dòng)的日志文件。每滾動(dòng)一個(gè)就通知程序重新打開(kāi)所有日志文件不太劃得來(lái)。有個(gè)sharedscripts的參數(shù),讓程序把所有日志都重命名了以后,只通知一次。
方案二
如果程序不支持重新打開(kāi)日志的功能,又不能粗暴地重啟程序,怎么滾動(dòng)日志呢?copytruncate的方案出場(chǎng)了。
這個(gè)方案的思路是把正在輸出的日志拷(copy)一份出來(lái),再清空(trucate)原來(lái)的日志。詳細(xì)步驟如下:
- 拷貝程序當(dāng)前正在輸出的日志文件,保存文件名為滾動(dòng)結(jié)果文件名。這期間程序照常輸出日志到原來(lái)的文件中,原來(lái)的文件名也沒(méi)有變。
- 清空程序正在輸出的日志文件。清空后程序輸出的日志還是輸出到這個(gè)日志文件中,因?yàn)榍蹇瘴募皇前盐募膬?nèi)容刪除了,文件的inode編號(hào)并沒(méi)有發(fā)生變化,變化的是元信息中文件內(nèi)容的信息。
結(jié)果上看,舊的日志內(nèi)容存在滾動(dòng)的文件里,新的日志輸出到空的文件里。實(shí)現(xiàn)了日志的滾動(dòng)。
這個(gè)方案有兩個(gè)有趣的地方:
- 文件清空并不影響到輸出日志的程序的文件表里的文件位置信息,因?yàn)楦鬟M(jìn)程的文件表是獨(dú)立的。那么文件清空后,程序輸出的日志應(yīng)該接著之前日志的偏移位置輸出,這個(gè)位置之前會(huì)被
\0
填充才對(duì)。但實(shí)際上logrotate清空日志文件后,程序輸出的日志都是從文件開(kāi)始處開(kāi)始寫(xiě)的。這是怎么做到的?這個(gè)問(wèn)題讓我糾結(jié)了很久,直到某天靈光一閃,這不是logrotate做的,而是成熟的寫(xiě)日志的方式,都是用O_APPEND
的方式寫(xiě)的。如果程序沒(méi)有用O_APPEND
方式打開(kāi)日志文件,變會(huì)出現(xiàn)copytruncate后日志文件前面會(huì)被一堆\0
填充的情況。 - 日志在拷貝完到清空文件這段時(shí)間內(nèi),程序輸出的日志沒(méi)有備份就清空了,這些日志不是丟了嗎?是的,copytruncate有丟失部分日志內(nèi)容的風(fēng)險(xiǎn)。所以能用create的方案就別用copytruncate。所以很多程序提供了通知我更新打開(kāi)日志文件的功能來(lái)支持create方案,或者自己做了日志滾動(dòng),不依賴logrotate。
五、logrotate實(shí)戰(zhàn)–Ceph日志轉(zhuǎn)儲(chǔ)
以Ceph的日志文件 /var/log/ceph/*.log
為例:
Ceph的日志滾動(dòng)也是基于logrotate實(shí)現(xiàn)的,日志配置文件位于/etc/logrotate.d/ceph
,默認(rèn)情況下的日志配置文件如下:
[root@ceph01 logrotate.d]# cat ceph
/var/log/ceph/*.log {rotate 7dailycompresssharedscriptspostrotatekillall -q -1 ceph-mon ceph-mgr ceph-mds ceph-osd ceph-fuse radosgw rbd-mirror || pkill -1 -x "ceph-mon|ceph-mgr|ceph-mds|ceph-osd|ceph-fuse|radosgw|rbd-mirror" || trueendscriptmissingoknotifemptysu root ceph
}
默認(rèn)情況下,每天備份一次,要做到每天備份,依賴于crontab定時(shí)任務(wù)。在/etc/cron.daily/
目錄下,有l(wèi)ogrotate腳本,每天定時(shí)執(zhí)行,也可以把腳本移動(dòng)到/etc/cron.hourly/
目錄下做到每小時(shí)執(zhí)行日志轉(zhuǎn)儲(chǔ)。
如果想要按照日志文件大小進(jìn)行轉(zhuǎn)儲(chǔ)該如何做?
-
刪除
/etc/cron.daily/
目錄下的logrotate腳本(刪除前做好備份) -
修改
/etc/logrotate.d/ceph
文件,里面的參數(shù)根據(jù)實(shí)際需求設(shè)置,我這里設(shè)置日志刪除前轉(zhuǎn)儲(chǔ)7次,日志文件大小超過(guò)1M,時(shí)間格式重命名壓縮轉(zhuǎn)儲(chǔ)。[root@ceph01 etc]# cat /etc/logrotate.d/ceph /var/log/ceph/*.log {rotate 7size 1Mdateextdateformat %Y%m%d%H.%scompresssharedscriptspostrotatekillall -q -1 ceph-mon ceph-mgr ceph-mds ceph-osd ceph-fuse radosgw rbd-mirror || pkill -1 -x "ceph-mon|ceph-mgr|ceph-mds|ceph-osd|ceph-fuse|radosgw|rbd-mirror" || trueendscriptmissingoknotifemptysu root ceph }
-
在/etc/crontab中添加自定義的定時(shí)任務(wù)(具體參數(shù)含義看上面的鏈接)。這里設(shè)置的是每分鐘檢查日志文件大小是否超過(guò)1M,超過(guò)就執(zhí)行l(wèi)ogrotate命令進(jìn)行日志轉(zhuǎn)儲(chǔ)。
[root@ceph01 etc]# cat /etc/crontab SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root# For details see man 4 crontabs# Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed * * * * * root /usr/sbin/logrotate /etc/logrotate.conf > /dev/null 2>&1
一些可能讓你迷惑的地方參考:logrotate詳情和坑點(diǎn)
參考
- https://www.cnblogs.com/txlsz/p/13126723.html
- https://zhuanlan.zhihu.com/p/90507023
- https://www.cnblogs.com/sailrancho/p/4784763.html
- https://blog.csdn.net/sinat_36358653/article/details/107390349
- https://blog.csdn.net/ht9999i/article/details/119001732
- https://blog.csdn.net/sinat_36358653/article/details/107390349