【Deprecated】logrotateコマンド
はじめに
ディスク圧迫事故、怖いですね。
ある日突然エラーが大量発生してログが増大し限界を超えてシステムダウンなんて発生した日には目も当てられない(実話です)
そんなこともう二度と起こさせない。
しかし、どうすれば、、、
これから教えるコマンドは
logrotateというログファイルを圧縮、削除、メール送信出来る非常に便利なコマンドです。
これさえあればもうディスク容量圧迫してシステムが死ぬということはありません(注:設定によります)
環境構築
Amazon Linux2のEC2立ててSSHで接続した後そこにlog
ディレクトリ作成しておいてください。
(そこで作業します)
$ pwd
/home/ec2-user/log
logrotateとは
configの情報をもとにログをrotate、圧縮、削除等を行います。
$ logrotate <config_file>
今回は以下のような形で実行予定です。
# 注) test_rotateはこちらで作成しました
$ logrotate /etc/logrotate.d/test_rotate
細かい説明をここでするよりかは、実際にみていただいた方が早いかと思われます。
(configは/etc/logrotate.conf
というものがあるのですが後述します)
rotateするとは
2MBのtest.log
を作成します(無限while loopのechoで5秒ほど)
$ while [ 1 ]; do echo "test" >> test.log; done
$ ls -lh
-rw-r--r-- 1 ec2-user ec2-user 2.0M 2月 14 14:47 test.log
logrotateを実行します(config設定済み前提)
$ logrotate /etc/logrotate.d/test_rotate
もう一度ログを確認してみます。
$ ls -lh
-rw-r--r-- 1 ec2-user ec2-user 2.0M 2月 14 14:47 test.1.log
-rw-r--r-- 1 ec2-user ec2-user 0 2月 14 14:48 test.log
test.log
のバイト数が0になり、test.1.log
(2.0M)が作成されました。
もう一度test.log
の中身を適当に増やしてやります。
$ while [ 1 ]; do echo "test" >> test.log; done
$ ls -lh
-rw-r--r-- 1 ec2-user ec2-user 2.0M 2月 14 14:53 test.1.log
-rw-r--r-- 1 ec2-user ec2-user 4.6M 2月 14 14:57 test.log
4.6MBになってのでもう一度logrotate実行してログを確認します。
$ logrotate /etc/logrotate.conf
$ ls -lh
-rw-r--r-- 1 ec2-user ec2-user 4.6M 2月 14 14:57 test.1.log
-rw-r--r-- 1 ec2-user ec2-user 2.0M 2月 14 14:53 test.2.log
-rw-r--r-- 1 ec2-user ec2-user 0 2月 14 14:58 test.log
ログがずれましたね。これがrotateです。
configについて
configの中身を見てみる
configファイルはこんな感じに設定していました。
基本これをテンプレートとしてコピーしたら楽かと思います(または/etc/logrotate.d
ディレクトリ配下に他のconfigが設定されているのでそちらを参考にしても良いと思います)
$ cat /etc/logrotate.d/test_rotate
/home/ec2-user/log/test.log {
missingok
create 644 ec2-user ec2-user
rotate 10
maxsize 1M
su ec2-user ec2-user
extension .log
}
それぞれのディレクティブの説明
読むのが面倒であれば「設定してみよう」まで飛んでください。
missingok
If the log file is missing, go on to the next one without issuing an error message. See also nomissingok.
rotateすべきログファイルなかったとしてもエラーにしない。
create
create <mode> <user> <group>
rotate完了時に空のtest.log
ファイルを作成するか否か。
ファイルの権限もここで指定できる(丁度chmod
とchown
で指定するように)
指定する
$ ls -lh
-rw-r--r-- 1 ec2-user ec2-user 4.6M 2月 14 14:57 test.1.log
-rw-r--r-- 1 ec2-user ec2-user 2.0M 2月 14 14:53 test.2.log
-rw-r--r-- 1 ec2-user ec2-user 0 2月 14 14:58 test.log
指定しない
$ ls -lh
-rw-r--r-- 1 ec2-user ec2-user 4.6M 2月 14 14:57 test.1.log
-rw-r--r-- 1 ec2-user ec2-user 2.0M 2月 14 14:53 test.2.log
rotate
rotate <count>
個人的に一番大事なディレクティブ。
<count>
を5
と設定すると以下のようになります。
test.5.log
以降は削除されていきます。
# 10回logrotate実行
$ ls -lh
-rw-r--r-- 1 ec2-user ec2-user 1.6M 2月 14 15:49 test.1.log
-rw-r--r-- 1 ec2-user ec2-user 1.4M 2月 14 15:48 test.2.log
-rw-r--r-- 1 ec2-user ec2-user 1.9M 2月 14 15:48 test.3.log
-rw-r--r-- 1 ec2-user ec2-user 3.8M 2月 14 15:48 test.4.log
-rw-r--r-- 1 ec2-user ec2-user 3.9M 2月 14 15:48 test.5.log
-rw-r--r-- 1 ec2-user ec2-user 1.2M 2月 14 15:49 test.log
maxsize
1M
と設定した場合はrotate処理対象は1M
超えたログファイルになります。それを超えてないログファイルはrotateされません。こいつがディスク圧迫する時に大いに役立ってくれます。
maxsize <size> # e.g 100 | 100k | 100M | 100G
su
su <user> <group>
rotateを実行するユーザー/グループ
これを正しく設定していないとPermissionに引っかかり実行出来ないため気を付けてください。
extension
extention .log
こうしておかないとrotateする時に.log
が末尾に付かないのでキモくなります。
指定前
$ ls -lh
-rw-rw-r-- 1 ec2-user ec2-user 970K 2月 14 15:38 test.log
-rw-rw-r-- 1 ec2-user ec2-user 4.0M 2月 14 15:38 test.log.1
-rw-rw-r-- 1 ec2-user ec2-user 1.2M 2月 14 15:38 test.log.2
指定後
$ ls -lh
-rw-rw-r-- 1 ec2-user ec2-user 970K 2月 14 15:38 test.log
-rw-rw-r-- 1 ec2-user ec2-user 2.3M 2月 14 15:28 test.1.log
-rw-rw-r-- 1 ec2-user ec2-user 3.2M 2月 14 15:28 test.2.log
設定してみよう
そちらの手元の環境にはtest_rotate
ファイルなんてものはないので
そのまま上の設定をtest_rotate
ファイルをrootユーザーで作成して貼り付けてください。
$ vim /etc/logrotate.d/test_rotate
/home/ec2-user/log/test.log {
missingok
create 644 ec2-user ec2-user
rotate 10
maxsize 1M
su ec2-user ec2-user
extension .log
}
完了です。
logrotate実行する前に
今実行してもrotateするべきファイルが何もないので別画面で以下を実行したままにしてください。
(注:以下のコマンド実行すると大体秒間0.5MBずつ増えていきます)
$ pwd
/home/ec2-user/log
$ while [ 1 ]; do echo "test" >> test.log; done
「あ、ディスク容量やばいかも」となったら止めていただいて構いません。
その場合は大きくなり過ぎたログを削除してコマンドを実行し直してください。
そしてもう一つ画面を開き(なんどもSSHログインするの面倒でしょうけれど)
以下のコマンドを実行してファイルのrotate状況をリアルタイムで監視できるようにしてください。
(watch
コマンドは[Ctrl+C]
でやめられます)
$ pwd
/home/ec2-user/log
$ watch ls -lh
準備は整いました。
logrotate実行
くらえ
# 以下のように指定すると5秒毎にlogrotate実行してくれます(面倒な時に便利です)
$ watch -n 5 logrotate /etc/logrotate.d/test_rotate
watch ls -lh
を実行した画面を見てみてください。
Every 2.0s: ls -lh
合計 39M
-rw-r--r-- 1 ec2-user ec2-user 1.7M 2月 14 16:13 test.1.log
-rw-r--r-- 1 ec2-user ec2-user 6.2M 2月 14 16:04 test.10.log
-rw-r--r-- 1 ec2-user ec2-user 1.7M 2月 14 16:13 test.2.log
-rw-r--r-- 1 ec2-user ec2-user 1.7M 2月 14 16:13 test.3.log
-rw-r--r-- 1 ec2-user ec2-user 1.7M 2月 14 16:13 test.4.log
-rw-r--r-- 1 ec2-user ec2-user 1.7M 2月 14 16:13 test.5.log
-rw-r--r-- 1 ec2-user ec2-user 1.7M 2月 14 16:13 test.6.log
-rw-r--r-- 1 ec2-user ec2-user 5.9M 2月 14 16:13 test.7.log
-rw-r--r-- 1 ec2-user ec2-user 6.2M 2月 14 16:12 test.8.log
-rw-r--r-- 1 ec2-user ec2-user 2.4M 2月 14 16:12 test.9.log
-rw-r--r-- 1 ec2-user ec2-user 733K 2月 14 16:13 test.log
このようにリアルタイムにrotateしている状況が見えているかと思います。
いいですねぇ。
しかし、これではまだ手動でlogrotate実行しているだけなので、どこかに設定しなければなりません。
一度全ての画面で動作しているコマンドを止めて次に進みます。
CRONにlogrotate設定
logrotateは毎日CRON実行されるように設定されています。
(以下を読む必要は別にない)
$ cat /etc/cron.daily/logrotate
#!/bin/sh
### ↓これです
/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
しかし、毎日ではなく毎分実行するようにしたいので、以下のようにCRONをrootユーザーで設定してください(本来であればlogrotate.conf
を指定してそれ経由でtest_rotateファイルを読み込ませる形が望ましいがわかりやすさベースで以下のようにします)
$ crontab -e
# 毎分logrotateコマンド実行
* * * * * /sbin/logrotate /etc/logrotate.d/test_rotate
これで自動実行されるようになりました。
あとは先ほどの手順でそれぞれの画面で以下を実行して様子をみてください。
# 画面A
$ while [ 1 ]; do echo "test" >> test.log; done
# 画面B
$ watch ls -lh
Every 2.0s: ls -lh
-rw-r--r-- 1 ec2-user ec2-user 21M 2月 14 16:28 test.1.log
-rw-r--r-- 1 ec2-user ec2-user 1.8M 2月 14 16:16 test.10.log
-rw-r--r-- 1 ec2-user ec2-user 28M 2月 14 16:27 test.2.log
-rw-r--r-- 1 ec2-user ec2-user 1.8M 2月 14 16:17 test.3.log
-rw-r--r-- 1 ec2-user ec2-user 1.8M 2月 14 16:17 test.4.log
-rw-r--r-- 1 ec2-user ec2-user 1.8M 2月 14 16:17 test.5.log
-rw-r--r-- 1 ec2-user ec2-user 1.8M 2月 14 16:17 test.6.log
-rw-r--r-- 1 ec2-user ec2-user 1.8M 2月 14 16:17 test.7.log
-rw-r--r-- 1 ec2-user ec2-user 1.8M 2月 14 16:17 test.8.log
-rw-r--r-- 1 ec2-user ec2-user 1.8M 2月 14 16:17 test.9.log
-rw-r--r-- 1 ec2-user ec2-user 7.3M 2月 14 16:28 test.log
素晴らしいですね。これで完了です。
これでディスク圧迫に悩まされることはありません。あとは放置です。
(watch
コマンドは状況確認用なので終わったら止めてください)
補足
ファイルを日付にして毎日rotateさせたい
/home/ec2-user/log/test.log {
missingok
create 644 ec2-user ec2-user
rotate 10
maxsize 1M
su ec2-user ec2-user
extension .log
dateext <--- これ
dateformat %Y-%m-%d <--- フォーマット変更したい場合はこれ(dateext指定必須)
daily <--- これ
}
複数ファイル指定したい
# ↓ここ
/home/ec2-user/log/*.txt
/home/ec2-user/log/test2.log
/home/ec2-user/log/test.log {
missingok
create 644 ec2-user ec2-user
rotate 10
maxsize 1M
su ec2-user ec2-user
extension .log
dateext
dateformat %Y-%m-%d
}
ログを圧縮させたい
/home/ec2-user/log/test.log {
missingok
create 644 ec2-user ec2-user
rotate 10
maxsize 1M
su ec2-user ec2-user
extension .log
dateext
dateformat %Y-%m-%d
compress <---- これを指定すると`gzip`により`.gz`になります
}
注意事項
$ logrotate /etc/logrotate.conf
このように指定しても中で/etc/logrotate.d/
ディレクトリ配下のconfigが全てincludeされているので/etc/logrotate.d/test_rotate
は問題なく読み込まれますが、/etc/logrotate.conf
にもdataext
等のディレクティブは設定されているため、もしも/etc/logrotate.conf
には指定されていて/etc/logrotate.d/test_rotate
には指定されていないディレクティブがある場合、/etc/logrotate.conf
側の設定が代わりに使われますので注意が必要です(今回であれば、dateext
がlogrotate.conf
に設定されているので、logrotate /etc/logrotate.conf
とした場合はdateext
の指定されていないtest_rotate
にもその影響を受けます。つまり、test_rotate
ファイルにdateext
設定していないにも関わらずログファイル名に日付が入ります)
最後に
logrotate、便利ですね。
エンジニアならばぜひ覚えておきたいコマンドです。
これさえあれば急激に増加するログにも対応し、ディスク容量枯渇によりシステムが落ちる恐怖に苛まれなくなります。
では、もう深夜になってしまったので自分はベッドにダイブします。
事実確認しながらは流石に疲れました...
Discussion