読者です 読者をやめる 読者になる 読者になる

生涯未熟

プログラミングをちょこちょこと。

apacheのlogrotateを1時間毎に吐き出そうとした記録

サーバ屋さんじゃないのにサーバ屋さんっぽいことをやってます。


apacheにはlogrotateというログを産む機械(システム)があるんですが、
これがデフォルトだと超絶イケてない。

logrotate.conf

 # see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# uncomment this if you want your log files compressed
#compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp -- we'll rotate them here
/var/log/wtmp {
    monthly
    create 0664 root utmp
    rotate 1
}


oh...
何がひどいってこのまま運用して、万が一アクセス数が超うなぎ登りになるとログファイルのファットさがすごいことになる。

しかも、1週間に1回のローテーション設定なのでログファイルをvimで開こうとするとひじょーに重い。


で、このイケてないlogrotate設定をイケファイ(イケてるファイルの意)にしたい。

サイズでローテーションする

まず、ログファイルのファットさを解消するためにサイズでローテーションする。

 # see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# uncomment this if you want your log files compressed
#compress

# ローテーションするサイズを指定
size 30M

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp -- we'll rotate them here
/var/log/wtmp {
    monthly
    create 0664 root utmp
    rotate 1
}

sizeを使うことによって、もしlogrotateが実行された時にログファイルが30M以上あるとローテーションしてくれる。
あとminsizeを指定すると「1週間後かつminsizeに設定したファイルサイズ以上ならローテーション」とできる。

sizeはor判定で、minsizeはand判定になるのですなー。

1時間に1回logrotateが動くようにする

/etc/cron.dailyの中にlogrotatedってファイルがあると思うので、このファイルを/etc/cron.hourly内にコピー、以上。

世代交代したログファイルのお尻にyyyymmddhhを付加する

これがちょっぴり厄介。
apacheを使ってる人だとデフォルトで/etc/logrotate.d内にhttpdというファイルがあると思うので、このファイルをおもむろに編集しましょう。

デフォルトだと以下の感じ。

/var/log/httpd/*log {
    missingok
    notifempty
    sharedscripts
    delaycompress
    postrotate
        /sbin/service httpd reload > /dev/null 2>/dev/null || true
    endscript
}


これをこんな感じにするとおk

/var/log/httpd/*log {
    missingok
    notifempty
    sharedscripts
    delaycompress
    postrotate
        EXT=`date +%Y%m%d%H%M`
        for f in $1;
        do mv $f.1 $f.$EXT > /dev/null 2> /dev/null
        done
        /sbin/service httpd reload > /dev/null 2>/dev/null || true
    endscript
}

多分do mv~のとこの/dev/nullは要らないと思うが、一応。


こんな感じでやると「1時間ごとにlogrotateを実行し、ログファイルのサイズが30M以上または1週間経った時にローテーションされる」設定になります。


色々とまだイケてないところはありますが、とりあえずログの肥大化は防げる設定かなと。
apacheチューニングむずい・・・

[追記:2015/06/11]
logrotateの3.8.5からhourly対応したみたいです!
詳しくはこちらの方の記事をご参照ください。

タイトルとか決めてないけどこのままでもいいかもしんない: logrotateでnginxのログを1時間ごとにローテートをする