Jex’s Note

Logrotate

(最後更新: 2016-04-27)

介紹

設定 log 定期壓縮及輩份,通常是 /var/log 下的 log,主要是控制 log 的大小不要越來越大

如何設定

有兩個地方可以設定

  • /etc/logrotate.conf : 直接寫在裡面
  • /etc/logrotate.d/ : 新增你想要控制 log 的程式,比較建議寫在這裡,一個程序 (i.e. nginx) 就是一個檔案,方便管理

但不管寫在哪裡效果都是一樣的,因為 /etc/logrotate.d/ 下的檔案最後也是會被讀取到 /etc/logrotate.conf 裡執行

參數

  • daily | weekly | monthly : 進行 rotate 的間隔
  • rotate 7 : 保留 7 份 log, 也就是只會保留到 mysql.log.7.gz
  • create : 如果 log 被改名,建立一個新的繼續儲存
  • create 0664 root web-admin : 設定新建的 log 檔的權限與擁有者/群組
  • dateext : 被輪替的檔案加上日期作為檔名
  • compress : 壓縮輩份的 log,預設使用 gzip
  • minsize 50M : rotates only when the file has reached an appropriate size and the set time period has passed. e.g. minsize 50MB + daily If file reaches 50MB before daily time ticked over, it’ll keep growing until the next day.
  • maxsize : will rotate when the log reaches a set size or the appropriate time has passed. e.g. maxsize 50MB + daily. If file is 50MB and we’re not at the next day yet, the log will be rotated. If the file is only 20MB and we roll over to the next day then the file will be rotated.
  • size 10M : will rotate when the log > size. Regardless of whether hourly/daily/weekly/monthly is specified. So if you have size 100M - it means when your log file is > 100M the log will be rotated if logrotate is run when this condition is true.
  • missingok 表示如果找不到 log 檔也沒關係
  • delaycompress 表示延後壓縮直到下一次 rotate
  • notifempty 表示如果 log 檔是空的,就不 rotate
  • copytruncate 先複製 log 檔的內容後,在清空的作法,因為有些程式一定 log 在本來的檔名,例如 rails。另一種方法是 create。
  • If the size directive is used, logrotate will ignore the daily, weekly, monthly, and yearly directives.
  • rotate 完的 log 檔大約會是原檔大小的 1.2/10 e.g. 452MB -> 50MB, 1.5GB -> 170MB, 建議在記算 size 跟 rotate 次數的話抓, 1.5 比較保險

語法參考

你也可以一次指定兩個 log 位置

/var/log/mysql.log /var/log/mysql/*log {

Apache /etc/logrotate.d/apache2 :

/var/log/apache/*.log {
        daily
        missingok
        rotate 30
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
                if /etc/init.d/apache2 status > /dev/null ; then \
                    /etc/init.d/apache2 reload > /dev/null; \
                fi;
        endscript
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi; \
        endscript
}

Nginx (預設) /etc/logrotate.d/nginx :

/var/log/nginx/*.log {
    weekly
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    prerotate
        if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
            run-parts /etc/logrotate.d/httpd-prerotate; \
        fi \
    endscript
    postrotate
        invoke-rc.d nginx rotate >/dev/null 2>&1
    endscript
}

Rails production logrotate /etc/logrotate.d/rails :

/var/www/practice_rails/log/*.log {
  daily
  missingok
  rotate 7
  compress
  delaycompress
  notifempty
  copytruncate
}

何時生效

設定好之後,可以等明天或是執行強制 rotate

sudo logrotate -f /etc/logrotate.conf

如果設定的 logrotate 沒運作成功

使用 -v 啟動顯示模式,會顯示 logrotate 運作的過程

$ sudo logrotate -v /etc/logrotate.conf

reading config file /etc/logrotate.conf
including /etc/logrotate.d
reading config file apport
reading config file apt
reading config file aptitude
Ignoring test-program because of bad file mode.
reading config file dpkg
reading config file landscape-client

可以看到某一個被 Ignore 了, Ignoring test-program because of bad file mode.

這是因為 logrotate 要求你的 .conf 的 owner 是 root 且權限為 644, 如下:

-rw-r--r-- 1 root     ec2-user  146 Apr 17 09:35 test-program.conf

改完後再執行一次就可以正常運作了

  • -d : 開啟除錯模式。在除錯模式之下,紀錄檔將不會有任何的改變
  • -f : 不論設定檔是否符合需要 rotate 的條件,都會強迫執行 rotate 的動作

手動觸發生效

command

sudo /etc/cron.daily/logrotate

讓 logrotate 執行更頻繁

預設執行 logrotate 的時間是每天, 所以即使 log 超過了設定的 size 也不會被 rotate, 要等到下一天執行時才會觸發

每小時執行: on Ubuntu, you can easily switch to hourly rotation by moving the script /etc/cron.daily/logrotate to /etc/cron.hourly/logrotate

每 5 mins 執行: add above to your /etc/crontab file. To run it every 5 minutes.

*/5 * * * * /etc/cron.daily/logrotate

reference

Comments