【Linux】 ログローテーションの設定
ログローテーション
ログファイルの容量が大きくなりすぎないように、一定期間ごとにログファイルをバックアップしたり、新しいログファイルに切り替えたりすること
ログローテーションには以下のような方法があります。
ログファイルを一定期間ごとにローテーションする方法
ログファイルのサイズが一定値を超えたらローテーションする方法
日付単位でログファイルをローテーションする方法
基本的には、crontabなどの定期実行機能を使って、一定期間ごとにログファイルをローテーションするように設定される。
logrotateとスクリプトの違い
logrotateは、Linuxシステム上のログファイルを定期的にローテーションするためのユーティリティであり、システム管理者が手動でスクリプトを書いてログローテーションを実行する必要がないようにすることができる。
スクリプトは、ログファイルをローテーションするためのカスタマイズされる。スクリプトは、logrotateとは異なり、スクリプトを作成して実行する必要があり、ログファイルをバックアップ、削除、アーカイブ、圧縮、移動など、様々な操作を実行するための命令が含まれる。
スクリプトを使用する場合、必要な操作を実行するための命令を自由にカスタマイズできるため、より柔軟なログローテーションが可能になる。
設定例(スクリプト)
最大サイズを超えている場合は、現在の日付を付加したログファイルを作成して、カレントログファイルを作成
#!/bin/bash
# ログファイルのパス
LOG_FILE="/var/log/messages"
# ログファイルをローテーションする期間(日数)
ROTATE_DAYS=7
# ログファイルの最大サイズ(MB)
MAX_SIZE=10
# 現在の日付
CURRENT_DATE=$(date +"%Y%m%d")
# ログファイル名に現在の日付を付加
ROTATE_LOG_FILE="$LOG_FILE.$CURRENT_DATE"
# ログファイルが存在し、サイズが最大サイズを超えている場合
if [ -f $LOG_FILE ] && [ $(du -m $LOG_FILE | awk '{print $1}') -gt $MAX_SIZE ]; then
# 現在の日付を付加したログファイルを作成
mv $LOG_FILE $ROTATE_LOG_FILE
# カレントログファイルを作成
touch $LOG_FILE
# 権限設定
chmod 640 $LOG_FILE
# 所有者をrootに、グループをsyslogに
chown root:syslog $LOG_FILE
fi
# ROTATE_DAYSよりも古いログファイルを削除
find $(dirname $LOG_FILE) -type f -name "$(basename $LOG_FILE).*" -mtime +$ROTATE_DAYS -exec rm -f {} \;
バックアップ
#!/bin/bash
# ログファイルのパスを設定
LOG_FILE=/var/log/messages
# バックアップファイルの保存先を設定
BACKUP_DIR=/var/log/backup
# 保存期間を設定(7日間)
DAYS_TO_KEEP=7
# バックアップファイル名を生成
BACKUP_FILE=$BACKUP_DIR/$(date +%Y%m%d)_$(basename $LOG_FILE)
# バックアップファイルを作成
cp $LOG_FILE $BACKUP_FILE
# バックアップファイルの作成日時が$DAYS_TO_KEEP日より古い場合は削除
find $BACKUP_DIR -type f -name "$(basename $LOG_FILE)_*" -mtime +$DAYS_TO_KEEP -exec rm {} \;
/var/log/messagesをバックアップ先の/var/log/backupに保存。
バックアップファイル名には、バックアップを実行した日付が付加され、
保存期間は7日間で、7日より前のバックアップファイルは自動的に削除。
ログファイルのローテーションと同時に、ログのgzip圧縮
#!/bin/bash
# ログファイルのパスを設定
LOG_FILE=/var/log/messages
# バックアップファイルの保存先を設定
BACKUP_DIR=/var/log/backup
# 保存期間を設定(7日間)
DAYS_TO_KEEP=7
# バックアップファイル名を生成
BACKUP_FILE=$BACKUP_DIR/$(date +%Y%m%d)_$(basename $LOG_FILE)
# ログファイルをバックアップファイルに移動
mv $LOG_FILE $BACKUP_FILE
# gzip圧縮を実行
gzip $BACKUP_FILE
# gzip圧縮されたファイルの拡張子を変更
mv $BACKUP_FILE.gz $BACKUP_FILE.gz.log
# バックアップファイルの作成日時が$DAYS_TO_KEEP日より古い場合は削除
find $BACKUP_DIR -type f -name "$(basename $LOG_FILE)_*.log" -mtime +$DAYS_TO_KEEP -exec rm {} \;
ログファイルのローテーションと同時にログのgzip圧縮を行い、rsyncで別サーバに保管する
#!/bin/bash
# ログファイルのパスを設定
LOG_FILE=/var/log/messages
# ログの保管先のパスを設定
BACKUP_DIR=/var/log/backup
# 保存期間を設定(7日間)
DAYS_TO_KEEP=7
# gzip圧縮する閾値を設定(10MB)
GZIP_THRESHOLD=10000000
# ログファイルが存在するか確認
if [ -f $LOG_FILE ]; then
# ログファイルのサイズを取得
LOG_FILE_SIZE=$(du -b $LOG_FILE | cut -f1)
# ログファイルがgzip圧縮する閾値を超えているか確認
if [ $LOG_FILE_SIZE -gt $GZIP_THRESHOLD ]; then
# gzip圧縮を実行
gzip -c $LOG_FILE > $LOG_FILE.gz
# バックアップファイルの作成日時が$DAYS_TO_KEEP日より古い場合は削除
find $BACKUP_DIR -type f -name "$(basename $LOG_FILE)_*.log.gz" -mtime +$DAYS_TO_KEEP -exec rm {} \;
# ログファイルをバックアップファイルに移動
mv $LOG_FILE.gz $BACKUP_DIR/$(basename $LOG_FILE)_$(date +%Y%m%d%H%M%S).log.gz
else
# バックアップファイルの作成日時が$DAYS_TO_KEEP日より古い場合は削除
find $BACKUP_DIR -type f -name "$(basename $LOG_FILE)_*.log" -mtime +$DAYS_TO_KEEP -exec rm {} \;
# ログファイルをバックアップファイルに移動
mv $LOG_FILE $BACKUP_DIR/$(basename $LOG_FILE)_$(date +%Y%m%d%H%M%S).log
fi
# バックアップファイルを別サーバにrsyncで送信
rsync -avz $BACKUP_DIR user@remote-server:/var/log/backup/
else
echo "ログファイルが存在しません"
fi
一定サイズ以上のログファイルをローテーションし、新しいログファイルを作成した後、ログファイルのサイズを監視し、一定サイズ以上になった場合にメールとアラートを送信する
#!/bin/bash
# ログファイルのパスを設定
LOG_FILE=/var/log/messages
# ログファイルの最大サイズを設定(1GB)
MAX_LOG_SIZE=1000000000
# バックアップファイルの保存先を設定
BACKUP_DIR=/var/log/backup
# 保存期間を設定(7日間)
DAYS_TO_KEEP=7
# ログファイルをバックアップファイルに移動
mv $LOG_FILE $BACKUP_DIR/$(date +%Y%m%d)_$(basename $LOG_FILE)
# 新しいログファイルを作成
touch $LOG_FILE
# ログファイルサイズを監視し、最大サイズを超えた場合はアラートを送信
while true
do
FILE_SIZE=$(stat -c %s $LOG_FILE)
if (( $FILE_SIZE > $MAX_LOG_SIZE )); then
echo "Log file size exceeded maximum size. Sending alert..."
echo "Log file size: $(($FILE_SIZE/1024/1024)) MB" | mail -s "Log file size alert" admin@example.com
fi
sleep 5m
done
ログファイルを毎日ローテーションし、7日間保存。ログファイルのサイズを監視し、1GBを超える場合には、メールとアラートを送信する。
Apacheのアクセスログをローテーション
#!/bin/bash
LOG_PATH="/var/log/httpd/access.log"
BACKUP_PATH="/var/log/httpd/access"
BACKUP_DAYS=30
mv $LOG_PATH $BACKUP_PATH/access-$(date +'%Y%m%d').log
kill -USR1 $(cat /var/run/httpd.pid)
find $BACKUP_PATH/ -mtime +$BACKUP_DAYS -type f -delete
Apacheのアクセスログをローテーションし、過去30日間分のログファイルを保持。Apacheの設定ファイルで、LogFormat ディレクティブで定義されたフォーマットに合わせて、ログファイル名を変更する必要がある。
MySQLのslow queryログをローテーションする
#!/bin/bash
LOG_DIR="/var/log/mysql"
LOG_FILE="$LOG_DIR/mysql-slow.log"
OLD_LOG_FILE="$LOG_DIR/mysql-slow.log.$(date +%F -d "14 days ago").gz"
# gzip圧縮を実行
gzip -f $LOG_FILE
# 過去14日間分のログファイルを削除
find $LOG_DIR -name "mysql-slow.log.*.gz" -type f -mtime +14 -exec rm -f {} \;
# 新しいログファイルを作成
touch $LOG_FILE
# 権限を設定
chown mysql:mysql $LOG_FILE
# 古いログファイルの圧縮が完了したら、新しいログファイルをtouchコマンドで実行
if [ -f $OLD_LOG_FILE ]; then
touch $LOG_FILE
fi
設定例(logrotate)
インストール
コマンドがなければインストールする
yum install logrotate
ログファイルの設定
/etc/logrotate.confと/etc/logrotate.d/
/etc/logrotate.conf
デフォルトのログローテーションの設定を含むファイル。ログファイルをローテーションする頻度や方法、ログファイルを圧縮するかどうか、ログファイルを保持する日数などの設定が含まれる。
/etc/logrotate.d/
独自のログローテーションの設定を含むファイルを配置する。/etc/logrotate.confの設定をオーバーライドすることができ、システムの各コンポーネントやサービスに対して、個別のログローテーションの設定を指定するためのファイルが含まれる。
つまり、/etc/logrotate.confはシステム全体のデフォルト設定を指定し、/etc/logrotate.d/ディレクトリには、個別のサービスのログローテーション設定を追加できる。
/etc/logrotate.confの設定例
# Global options
compress
delaycompress
dateext
rotate 7
maxage 14
missingok
notifempty
create 640 root adm
sharedscripts
# Include configuration files from the directory /etc/logrotate.d
include /etc/logrotate.d
全てのログファイルに共通する設定。スクリプトの始まり方に決まりがないので、最初から設定を記載していく。
compress: 古いログファイルを圧縮
delaycompress: 古いログファイルを圧縮する際に、前回のログローテーションで生成された圧縮ファイルを残す
dateext: 古いログファイルに日付を付加
rotate 7: 古いログファイルを最大7個まで保持
maxage 14: 古いログファイルを最大14日間保持
missingok: ログファイルが存在しなくてもエラーを発生させない
notifempty: 空のログファイルはローテーションしない
create 640 root adm: 新しいログファイルを作成する際に、パーミッションを640、オーナーをroot、グループをadmに設定
sharedscripts: prerotate、postrotate、prerotate、postrotateスクリプトを共有
include:/etc/logrotate.d/ディレクトリにあるログファイルごとの設定ファイルを読み込む
/etc/logrotate.d/の設定例
ディレクトリ以下のファイル名は設定するシステムに合わせて任意で設定する。/etc/logrotate.conf と同じフォーマット。
Apacheのアクセスログのローテーション
vi /etc/logrotate.d/apache_accesslog # 例
---------------------------------------------------------
/var/log/httpd/access_log {
rotate 30
daily
compress
missingok
notifempty
create 640 root adm
sharedscripts
postrotate
/sbin/service httpd reload > /dev/null 2>/dev/null || true
endscript
}
rotate 30: ログファイルを30個までローテーション。
daily: 日次でローテーションする。
monthly: ログファイルを月ごとにローテーションする。
size size: ログファイルが指定されたサイズに達した場合にローテーションする。例: size 100M
delaycompress: 古いログファイルの圧縮を1世代遅らせる。これにより、未圧縮の直近のログファイルが1つ残る。
compress: ローテーション時にgzip圧縮する。
missingok: ログファイルが存在しなくてもエラーにしない。
notifempty: ログファイルが空の場合にローテーションしない。
create 640 root adm: ログファイルが存在しない場合に新しいログファイルを作成し、所有者をroot、グループをadmに設定。
sharedscripts: 複数のログファイルに対して同じスクリプトを実行する場合に使われる。
prerotate script: ローテーション前に実行するスクリプトを指定する。
postrotate: ローテーション後に実行されるコマンドを記述する。
/sbin/service httpd reload > /dev/null 2>/dev/null || true:
Apache HTTP Serverを再起動するコマンドを実行。"/dev/null"は標準出力と標準エラー出力を捨てる。"|| true"はコマンドがエラーで終了した場合でもスクリプトの実行を続けるために使用。dateext: ローテーションされたログファイルの拡張子に日付を追加する。
dateformat format: 日付のフォーマットを指定する。例: dateformat -%Y-%m-%d
その他参考のファイル名
# MySQL の slow query ログローテーション
/var/log/mysql/slow.log {
# Postfix のログローテーション
/var/log/maillog {
# rsyslog のログローテーション
/var/log/rsyslog/*.log {
logrotate は通常、cron を使って定期的に実行される。
/etc/cron.daily/にlogrotate がリストに表示されていれば、デフォルトで毎日実行される。