search
LoginSignup
65

More than 5 years have passed since last update.

posted at

updated at

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

はじめに

そういやログローテーションちゃんと設定できてるっけ?
確認してみよう!というのが始まり。

インストール~設定まで

インストール

基本的には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にすらならないとか。こちら を参考にさせていただきました。 

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
65