CentOS
logrotate
centos7

[CentOS7.4] logrotateサービスを入れて日次でログを保存しよう

More than 1 year has passed since last update.


はじめに

そういやログローテーションちゃんと設定できてるっけ?

確認してみよう!というのが始まり。


インストール~設定まで


インストール

基本的にはlogrotateサービスは標準で入っていることと思います。

入っていなかったら入れてください。


console

rpm -qa | grep logrotate

# logrotate-3.8.6-14.el7.x86_64

yum install -y logrotate



ファイル構成

名前・場所
やくめ

/etc/logrotate.conf
ログローテーション全体の管理ファイル

/etc/logrotate.d/*
ログファイル個々の設定ファイル

/var/lib/logrotate/logrotate/status
「最後にローテーションした日時」を管理するファイル


管理ファイル編集

logrotateの管理ファイルはデフォルトだと/etc/logrotate.confに保存されています。

ここを編集していきます。

オプション
内容

compress / nocompress
ログファイル圧縮

create [(パーミッション)] [(ユーザー)] [(グループ)] / nocreate
ローテーション後、新しくファイルを作成できる
パーミッションなども付与することができる
設定しなかった場合、前のファイルの権限を継承する?

rotate
何世代前までログを保存するか

daily / weekly / monthly


  • daily -> 04:02

  • weekly -> 日曜日 04:22

  • monthly -> 毎月1日 04:42

dateext
日付型をファイル末尾に付与する

dateformat
末尾に付与する日付フォーマットの変更
デフォルト:-%Y%m%d

ifempty / notifempty
ログファイルがない場合にローテーションするかどうか

missingok / nomissingok
ログファイルが存在しない場合にエラー

olddir (ディレクトリ) / noolddir
古いログファイルをディレクトリに移行するかどうか

size (ファイルサイズ)
指定したサイズを上回った場合にローテーションする

postrotate / prerotate ~ endscript
pre -> 事前
post -> 事後
に処理するスクリプトを記述する

sharedscripts / nosharedscripts
(ログファイルをワイルドカードで指定した場合など)一つのサービスにつき複数個ログがある場合、スクリプトをそれぞれ実行する(noshared)か一回だけ実行する(shared)かを定義。

su (ユーザー) (グループ)
CentOS 7 以降1
指定したユーザーとしてローテーションを実行する


/etc/logrotate.conf

# see "man logrotate" for details

# ローテーションするサイクル monthly / weekly / daily
daily

# 設定された世代分のログを保管
rotate 14

# ログローテーション後に空のファイルを作成
create

# ファイルの末尾に日付を付与
dateext

# 日付フォーマットの変更
dateformat .%Y%m%d

# ログがなくても怒らない
missingok

# ログが空でもローテーション
ifempty

# ファイルを圧縮
#compress

# 個別設定ファイル保存先
include /etc/logrotate.d

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

/var/log/btmp {
missingok
monthly
create 0600 root utmp
rotate 1
}

# システムのログを以下に追記可能



設定ファイル編集

/etc/logrotate.d/配下にログごとの設定ファイルが保管してあります。

基本的にはこちらの中身をいじっていく。

任意でローテーションしたいログがある場合もこ↑こ↓に設定を記述するシステム。

それぞれのオプションについては上記の設定を参照のこと。

ここでは仮にApacheのログの中身を。

私の書き方が悪いだけだとは思うのですが、*.logのようにワイルドカードで指定した場合、なんかうまくローテーションしない事案が発生しました。


/etc/logrotate.d/httpd

/var/log/httpd/*log {

daily
ifempty
missingok
notifempty
sharedscripts
delaycompress
postrotate
/bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
endscript
}


任意のログファイルをローテーションする

本題。

基本的には/etc/logrotate.d/配下に設定ファイルを追加するだけです。

試しに 以前 設定したMySQLのslow.logをローテーションしてみます。


/etc/logrotate.d/slow

/var/log/slow.log {

daily
ifempty
missingok
notifempty
sharedscripts
delaycompress
postrotate
/bin/systemctl reload mysqld.service > /dev/null 2>/dev/null || true
endscript
}

基本的にコピペしてちょこっと書き換えるだけの簡単仕様です。


デバッグしてみる

以下のコマンドでデバッグを実行してみます。


console

logrotate -dv /etc/logrotate.conf

# reading config file /etc/logrotate.conf
# including /etc/logrotate.d
# reading config file slow
# Allocating hash table for state file, size 15360 B
#
# Handling 12 logs
#
# rotating pattern: /var/log/slow.log
# after 1 days (7 rotations)
# empty log files are rotated, old logs are removed
# considering log /var/log/slow.log
# log does not need rotating (log has been rotated at 2017-12-21 17:19, that is not day ago yet)

# 実際にローテーションさせてみる
logrotate -f /etc/logrotate.conf


本当はもっと長いんですが。対象のファイルにエラーが発生していなければ問題ないかと。


日付を巻き戻してすぐに動作テストがしたい

と思っていた時期が私にもry

以下の手順で実施します。


  • ローテーション情報を書き換える

  • ローテーションを実行する


ローテーション情報を書き換える


/var/lib/logrotate/logrotate.status

logrotate state -- version 2

"/var/log/yum.log" 2017-12-21-17:19:40
"/var/log/php-fpm/*log" 2017-12-21-1:0:0
"/var/log/boot.log" 2017-12-21-17:19:40
"/var/log/httpd/error_log" 2017-12-21-17:19:40
"/var/log/chrony/*.log" 2017-12-21-1:0:0
"/var/log/wtmp" 2017-12-21-17:19:40
"/var/log/spooler" 2017-12-21-17:19:40
"/var/log/mysql/slow.log" 2017-12-21-17:19:40
"/var/log/btmp" 2017-12-21-17:19:40
"/var/log/slow.log" 2017-12-19-17:6:27
"/var/log/maillog" 2017-12-21-17:19:40
"/var/log/wpa_supplicant.log" 2017-12-21-1:0:0
"/var/log/secure" 2017-12-21-17:19:40
"/var/log/messages" 2017-12-21-17:19:40
"/var/log/httpd/access_log" 2017-12-21-16:57:11
"/var/log/cron" 2017-12-21-17:19:40

これの日付を一日前に書き換えて保存。


ローテーションを実行する


console

/etc/cron.daily/logrotate


ファイルサイズが空だったりするとうまくローテーションしない場合があるみたい?


ローテーション時エラー


error: skipping ~ because parent directory has insecure permissions (It's world writable or writable by group which is not "user") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.

ガバガバ翻訳:

エラー:親ディレクトリに安全でないアクセス権があるのでファイル:~をスキップします。

"user"以外のグループによって書き込み可能か確認してください。

設定ファイルに "su"オプションを設定して、どのユーザー/グループでローテーションするべきかを指示してください。


とか怒られる場合があります。1

ユーザーに権限がないだけなので、suオプションを付けて適切なユーザーに変更してあげてください。


/etc/logrotate.d/slow

/var/log/slow.log {

daily
ifempty
missingok
notifempty
sharedscripts
delaycompress
postrotate
/bin/systemctl reload mysqld.service > /dev/null 2>/dev/null || true
endscript
su root root
}





  1. CentOS7系から導入された。そもそもそれ以前では権限が甘いため、Permission Errorにすらならないとか。こちら を参考にさせていただきました。