最後更新: 2018-05-08
目錄
- logrotate.conf 及設定
- 其他 Daemon 的設定目錄
- logrotate multiple files
- 立即執行
- state file
介紹
logrotate 是由 cron job 定時發動的, 所以修改了它後是不用 reload 的
相關設定檔有
- /etc/logrotate.conf
- /etc/logrotate.d/
/etc/logrotate.conf
# 多久 rotate 一次, 另有 daily, monthly weekly # 只 keep 4 份 copy rotate 4 # rotate 後會自動建立原本名稱的 log 當 (error.log -> error.log-20230103) create # 自動 gzip log 檔. Default: nocompress compress # use date as a suffix of the rotated file (e.g. access_log-20140624) dateext # 載入每個 Service 的 log 設定 include /etc/logrotate.d
Notes:
* 如果個別 Proccess 想不用 dateext, 那可以用 nodateext
* 指定 weekly 的日子
- Log files are rotated once each "weekday". Default: 0 (Sunday)
- weekday 0=Sunday, 1=Monday, ..., 7 = each 7 days(special value)
* create mode owner group
- Default: same values as the original log file
- Immediately after rotation (before the postrotate script is run) the log file is created.
i.e.
create 640 nginx adm
其他有用選項:
missingok
# go on to the next one without issuing an error message
notifempty
# Do not rotate the log if it is empty
copy
# Make a copy of the log file, but don't change the original at all
copytruncate
# Truncate the original log file to zero size in place after creating a copy
rotate 4
logrotate -v -f /etc/logrotate.d/websocket
reading config file /etc/logrotate.d/websocket Allocating hash table for state file, size 15360 B Handling 1 logs rotating pattern: /home/vhosts/MyDomain/websocket/start-ws.log forced from command line (4 rotations) empty log files are not rotated, old logs are removed considering log /home/vhosts/MyDomain/websocket/start-ws.log log needs rotating rotating log /home/vhosts/MyDomain/websocket/start-ws.log, log->rotateCount is 4 dateext suffix '-20180508' glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' renaming /home/vhosts/MyDomain/websocket/start-ws.log.4 to /home/vhosts/MyDomain/websocket/start-ws.log.5 (rotatecount 4, logstart 1, i 4), renaming /home/vhosts/MyDomain/websocket/start-ws.log.3 to /home/vhosts/MyDomain/websocket/start-ws.log.4 (rotatecount 4, logstart 1, i 3), renaming /home/vhosts/MyDomain/websocket/start-ws.log.2 to /home/vhosts/MyDomain/websocket/start-ws.log.3 (rotatecount 4, logstart 1, i 2), renaming /home/vhosts/MyDomain/websocket/start-ws.log.1 to /home/vhosts/MyDomain/websocket/start-ws.log.2 (rotatecount 4, logstart 1, i 1), renaming /home/vhosts/MyDomain/websocket/start-ws.log.0 to /home/vhosts/MyDomain/websocket/start-ws.log.1 (rotatecount 4, logstart 1, i 0), old log /home/vhosts/MyDomain/websocket/start-ws.log.0 does not exist copying /home/vhosts/MyDomain/websocket/start-ws.log to /home/vhosts/MyDomain/websocket/start-ws.log.1 truncating /home/vhosts/MyDomain/websocket/start-ws.log removing old log /home/vhosts/MyDomain/websocket/start-ws.log.5
其他 Daemon 的設定目錄
/etc/logrotate.d/httpd
/var/log/httpd/*log { missingok # 當 log file 不在時, 照行下一個 notifempty # 當 log file 是 empty 時, 就不理它 sharedscripts compress delaycompress # 要 compress 在才有用 # 它會遲一個 log file 去 compress # 比如 error.log, error.log.1, error.log.2.gz postrotate /sbin/service httpd reload > /dev/null 2>/dev/null || true endscript }
/etc/logrotate.d/libvirtd
/var/log/libvirt/libvirtd.log { weekly minsize 100k <-- log > 100 kb 及 過了一星期才會做 rotate missingok rotate 4 compress delaycompress copytruncate }
/etc/logrotate.d/openvpn
/var/log/openvpn/openvpn.log
{
create 640 root adm <--- 設定 rotate 後 log file 的 permission
missingok
notifempty
rotate 4
weekly
}
sharedscripts 功能是 postrotate script will only be run once(after the old logs have been compressed),
not once for each log which is rotated.
行 script 的次序:
........
prerotate
script
endscript
postrotate
script
endscript
........
假設 /etc/logrotate.d/sockd 有以下設定
postrotate kill -s SIGHUP $(cat /var/run/sockd.pid) endscript
logrotate -v -f /etc/logrotate.d/sockd
... running postrotate script logrotate_script: line 1: kill: SIGHUP: invalid signal specification ...
解決方法
將 kill 改成 Full Path 的 /usr/bin/kill
- create # new file will use the same values as the original log file
- create owner group
- create perm user group
# Immediately after rotation (before the postrotate script is run) the log file is created
# This option can be disabled using the nocreate option
logrotate multiple files
方式1:
/var/log/myapp/*.log { ........... }
方式2:
/var/log/httpd/access.log /var/log/httpd/error.log { rotate 4 mail [email protected] # 在 rotate 最後一份 log file 前, 會把它 mail 走後再刪除 size=100k sharedscripts postrotate /sbin/killall -HUP httpd endscript }
立即執行
全部:
logrotate -v -f /etc/logrotate.conf
個別 service 的 log rotate:
logrotate -v -f /etc/logrotate.d/httpd
記得 httpd 內要有
weekly rotate 4 create dateext compress
因為如果沒有這設定, 那會與 "/etc/logrotate.conf" 不一至
- -f 強制
- -v 詳細
# 不加 -v, 什麼都無得看
State file
cat cron.daily/logrotate
#!/bin/sh /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
--state file
Tells logrotate to use an alternate state file.
The default state file is /var/lib/logrotate.status
This is useful if logrotate is being run as a different user for various sets of log files.
cat /var/lib/logrotate/logrotate.status
logrotate state -- version 2 "/var/log/nginx/error.log" 2022-10-28-3:30:1 "/var/log/yum.log" 2022-10-1-0:0:1 "/var/log/firewalld" 2022-10-27-23:58:1 "/var/named/data/named.run" 2022-10-27-23:58:1 ...
Rotate script log
# /etc/logrotate.d/websocket
/home/vhosts/MyDomain/start-ws.log { missingok notifempty copytruncate compress delaycompress weekly rotate 4 create 660 root MyDomain }
# 測試
logrotate -v -f /etc/logrotate.d/websocket
copytruncate 777 folder
/etc/logrotate.d/owncloud
/var/www/owncloud/data/owncloud.log {
daily
rotate 14
dateext
missingok
compress
copytruncate
su root root
}
不使用 "su"
considering log /home/vhosts/owncloud/data/owncloud.log
error: skipping "/home/vhosts/owncloud/data/owncloud.log" because parent directory has insecure permissions
(It's world writable or writable by group which is not "root")
Set "su" directive in config file to tell logrotate which user/group should be used for rotation.
su
Rotate log files set under this user and group instead of using default user/group (usually root).
Troubleshoot
logrotate 沒有完成, ps 有 cron job hang 了
ps aux | grep cron
root 18154 0.0 0.0 4628 564 ? SN Jul21 0:00
awk -v progname=/etc/cron.daily/logrotate progname {????? print progname ":\n"????? progname="";???? }????
查看 logrotate, 沒可疑之處 (沒有用到 awk)
/etc/cron.daily/logrotate
#!/bin/sh /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 0
查看 awk 由那 process 產生
pstree
├─anacron───run-parts───awk
anacrontab 負責發動 cron.daily, cron.weekly, cron.monthly
/etc/anacrontab
#period in days delay in minutes job-identifier command 1 5 cron.daily nice run-parts /etc/cron.daily 7 25 cron.weekly nice run-parts /etc/cron.weekly @monthly 45 cron.monthly nice run-parts /etc/cron.monthly
/usr/bin/run-parts - It has logic in it that detects executable files and runs awk.
...
# "$i" 是 script 的 full path
logger -p cron.notice -t "run-parts($1)[$$]" "starting $(basename $i)"
$i 2>&1 | awk -v "progname=$i" \
'progname {
print progname ":\n"
progname="";
}
{ print; }'
logger -i -p cron.notice -t "run-parts($1)" "finished $(basename $i)"
...
Fix
Upgrade 到 crontabs-1.11
https://github.com/cronie-crond/crontabs/releases