logrotate

最後更新: 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

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

  • 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

 


 

 

 

Creative Commons license icon Creative Commons license icon