0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

はじめに

先日設定したlogrotateの設定を間違えアラートを鳴らした忘備録として、logrotateの設定について記述していきます。

※要件的な部分で/etc/anacrontabではなく、/etc/logrotate.d/【固有の設定】を利用しています。


問題の原因

下記設定の/*.log*としたことで、フォルダ内に出力される毎日のログと、世代管理するために生成された(本来であれば対象外となる)ログの全てがローテーションしてしまい、世代管理で生成されたログの世代管理のログの、、、という収集がつかない程のログが作成されました。

/infra/log/*.log*{
 【個々の設定】
}

何が起きたか?

logrotateの世代管理はリネームすることでログを管理するため、名前が次第に長くなり、24時間で全てのログのリネームが終了せずゾンビ化してCPUを圧迫していき、アラート通知。


logrotate 設定ハンズオン

0.ログ出力までの準備

0.1.EC2にSSH接続してシェルスクリプト・ログ用のディレクトリ作成

EC2にSSH接続し、管理者権限でシェルスクリプト置き場と、出力ログ置き場となるディレクトリを作成

sudo su -
mkdir -p /infra/{log,script}

0.2.EC2にSSH接続してシェルスクリプト・ログ用のディレクトリ作成

検証用シェルスクリプトlogrotate.shを作成

vi /infra/scipt/logrotate.sh
【設定後、下記で権限変更して起動できるようにする】
chmod +x logrotate.sh
bash logrotate.sh

【検証用シェルスクリプト内容】

#/bin/bash
# reate : 2022/11/12
# desc : logrotate.sh
#############################################
# Local
HOSTNAME=`uname -n | awk -F"." '{print $1}'`
LOG=/infra/log/logrotate.log
#############################################
# Main
# log出力する
echo `LANG=C ; date` : "[INFO]:${HOSTNAME}:logrotate." | sudo tee -a  ${LOG}
exit 0

0.3.crontab でシェルスクリプトを10分毎に設定する

シェルスクリプト10分毎に起動するためのcronを設定する

crontab -e

【crontab内容】

#おまじない
PATH=/sbin:/bin:/usr/sbin:/user/bin
MAILTO=""
HOME=/

#  ... 1分ごとにシェルスクリプトを押下する
# 
# 
# 
# 曜日

*/10 * * * * /infra/script/logrotate.sh

0.4.ログ出力されているか確認する

/infra/log/の配下に、logrotate.logが出力されていることが確認できる。

ll /infra/log
-rw-r--r-- 1 root root 804 Nov 12 01:40 logrotate.log

0.5.検証するためにログを用意する

次工程の確認用のためにログを増やします。
今回の検証ではlogrotate5と設定するので、自動的に削除されるようにlogrotate.logの他に5つのlogrotate.log-2022*を作成しておく。

ll /infra/log

total 156
-rw-r--r-- 1 root root 1273 Nov 12 02:50 logrotate.log
-rw-r--r-- 1 root root 1206 Nov 12 02:45 logrotate.log-20221107
-rw-r--r-- 1 root root 1206 Nov 12 02:45 logrotate.log-20221108
-rw-r--r-- 1 root root 1206 Nov 12 02:45 logrotate.log-20221109
-rw-r--r-- 1 root root 1206 Nov 12 02:45 logrotate.log-20221110
-rw-r--r-- 1 root root 1206 Nov 12 02:45 logrotate.log-20221111

1.logrotateの設定

1.1.logrotateの設定ファイル(logdelete)を作成する

ファイル構成

【logdelete作成後、treeコマンドで表示画面(一部抜粋)】

/etc/
├── logrotate.conf(共通設定)
├── logrotate.d
│   ├─【個別の設定ファイル一部省略】
│   └── logdelete(個別設定)
│  

/etc/logrotate.confに全ての設定を記載することも可能ですが、/etc/logrotate.confには、/etc/logrotate.d配下の個別の設定を呼び出すこともincludeされているため、サービス毎に設定ファイルを作成することが可能です。

設定ファイル(logdelete)の作成
# vi /etc/logrotate.d/logdelete

【logdelete内容】

/infra/log/logrotate.log {
		rotate 5
		daily
		ifempty
		missingok
		create 0644 root root
		dateext
		dateformat -%Y%m%d
}

【logdelete設定内容の詳細】

コマンド 内容
/infra/log/logrotate.log 対象とするログ
rotate ローテーションする回数の指定
daily ログを毎日ローテーションする
ifempty ログファイルが空でもローテーションする
missingok ログファイルが存在しなくてもエラーを出さずに処理を続行
create (世代管理のため)新しく作成されたログファイルの権限
dateext 旧バージョンのログファイルに日付を付加する
dateformat 日付フォーマットを指定する

1.2.logrotateの設定ファイル(/etc/logrotate.d/logdelete(個別設定))に問題ないかでデバッグで検証する

logrotate -d /etc/logrotate.d/logdeleteを実行します。
-dオプションを付けることで、実際にlogrotateは行われずに、どのように動作するのかをデバッグすることが可能です。

# logrotate -dv /etc/logrotate.d/logdelete
Allocating hash table for state file, size 64 entries
Creating new state
Handling 1 logs

rotating pattern: /infra/log/logrotate.log  after 1 days (5 rotations)
empty log files are rotated, old logs are removed
considering log /infra/log/logrotate.log
Creating new state
  Now: 2022-11-12 02:22
  Last rotated at 2022-11-12 02:00
  log does not need rotating (log has already been rotated)

2.logが手動で削除されるかの検証

2.1.logrotate.statusの設定変更

logrotaetは初日に対象ログのタイムスタンプを記録するため、初日からログがローテートすることはありません。
ただし実際にローテーションを確認したいので、logrotateが実行完了した際に記録される結果ファイル(/var/lib/logrotate/logrotate.status)の編集していきます。

vi /var/lib/logrotate/logrotate.status 

【logrotate.statusの詳細】
当日の日付が記載されている場合、記載よりも24h前の時間を記載(24時間以内だと、1.2.と同様の結果となります)

(例)

logrotate state -- version 2
"/infra/log/logrotate.log" 2022-11-12-2:0:0

↓ 記録がない場合でも、ログの出力先と時間を記述して保存します

logrotate state -- version 2
"/infra/log/logrotate.log" 2022-11-11-2:0:0

2.2.再度1.2.と同様の検証を実行する

再度logrotate -d /etc/logrotate.d/logdeleteを実行します。

Allocating hash table for state file, size 64 entries
Creating new state
Handling 1 logs
rotating pattern: /infra/log/logrotate.log  after 1 days (5 rotations)
empty log files are rotated, old logs are removed
considering log /infra/log/logrotate.log
  Now: 2022-11-12 03:31
  Last rotated at 2022-11-11 02:00
  log needs rotating
rotating log /infra/log/logrotate.log, log->rotateCount is 5
Converted ' -%Y%m%d' -> '-%Y%m%d'
dateext suffix '-20221112'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
renaming /infra/log/logrotate.log to /infra/log/logrotate.log-20221112
creating new /infra/log/logrotate.log mode = 0644 uid = 0 gid = 0
removing old log /infra/log/logrotate.log-20221107

下から4行目に想定したようにrenaming /infra/log/logrotate.log to /infra/log/logrotate.log-20221112とリネームされていること
最後の行に/infra/log/logrotate.log-20221107が削除されていることが確認できました。

【ローテーションの理解】
検証日:2022年11月12日

  1. logrotateを実行する
  2. logrotate.logをリネームして、新しくlogrotate.log-20221112を作成する
  3. logrotate.log-2022*という名前で世代管理している数が、logrotate5を超えるため、一番古いネームのlogrotate.log-20221107が削除される

3.cronで実行するための設定

3.1.anacrontabのコメントアウト

要件に従いanacrontabをコメントアウトする

vi /etc/anacrontab

【anacrontabの設定】
下から3行目のcron.daily部分をコメントアウトする

# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22

#period in days   delay in minutes   job-identifier   command
#1      5       cron.daily              nice run-parts /etc/cron.daily
7      25      cron.weekly             nice run-parts /etc/cron.weekly
@monthly 45    cron.monthly            nice run-parts /etc/cron.monthly

3.2.crontabの設定

crontabで今回は設定をしていくのでファイルを編集します。

vi /etc/crontab

【crontabの設定】

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
59 23 * * * root run-parts /etc/cron.daily

末尾の部分で、23:59に/etc/cron.dailyを呼び出すように記述を足しておきます

3.3./etc/cron.daily/logrotateが存在しているか確認する

/etc/cron.daily/配下にlogrotateが存在しているかの確認です、ファイルがない場合は後述のように作成します

cat /etc/cron.daily/logrotate
【logrotateの詳細内容】
chmod 755 logrotate

【logrotateの詳細内容】
ファイルを見ると/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.confの部分から、/usr/sbin/logrotate == logrotate-s == logrotateのオプションで、ステータスファイルを参照(/var/lib/logrotate/logrotate.status)を利用して/etc/logrotate.confを実行していることがわかります。

#!/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

おまけ. logをcronを利用して削除されるかの検証(※ドライランでなく実際にlogrotate.conf起動させていきます)

おまけ.1.crontabを現在の時間に沿って変更する

crontabを修正

vi /etc/crontab

【crontabの設定】
ちょうど 0分になりそうだったので時間を設定します

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
0 * * * * root run-parts /etc/cron.daily

おまけ.2.起動したことを確認する

cronの実行ログを確認すると、ちょうど00分に起動を設定したlogrotateが起動していることが確認できます。

tail /var/log/cron
Nov 12 06:00:01 ip-192-168-20-179 run-parts[12051]: (/etc/cron.daily) starting logrotate
Nov 12 06:00:01 ip-192-168-20-179 run-parts[12051]: (/etc/cron.daily) finished logrotate
Nov 12 06:00:01 ip-192-168-20-179 run-parts[12051]: (/etc/cron.daily) starting update-client-config-packages
Nov 12 06:00:01 ip-192-168-20-179 run-parts[12051]: (/etc/cron.daily) finished update-client-config-packages

おまけ.3.起動したことを確認する

logrotate -d /etc/logrotate.confで確認していた通りですが、logrotate.log-20221107が自動的に削除されていることを確認できました

-rw-r--r-- 1 root root   67 Nov 12 06:00 logrotate.log
-rw-r--r-- 1 root root 1206 Nov 12 02:45 logrotate.log-20221108
-rw-r--r-- 1 root root 1206 Nov 12 02:45 logrotate.log-20221109
-rw-r--r-- 1 root root 1206 Nov 12 02:45 logrotate.log-20221110
-rw-r--r-- 1 root root 1206 Nov 12 02:45 logrotate.log-20221111
-rw-r--r-- 1 root root 2479 Nov 12 05:50 logrotate.log-20221112

4.まとめ

ここまでの流れを振り返りとして

1.crontabにより、23:59に/etc/cron.dailyが起動する

2./etc/cron.daily配下のlogrotateの記載にあるコマンドlogrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.confを実行する

3./etc/logrotate.confが設定ファイル/var/lib/logrotate/logrotate.statusのステータスを参照して実行

4. /etc/logrotate.confにインクルードされている/etc/logrotate.d/deletelot(固有の設定)が起動する

という、今回は上記の流れを確認してきました


おわりに

実際に構築している時は、自分が何処の部分を検証してるのか?など疑問に思ったりなどして最終的な全体図を描けなかったため、諸々のテストに抜け漏れが生じていき、最終的な設定ファイルの記載漏れを防げませんでした。
検証の時間をきちんととり、構築に納得し、求めている値が出力できるまで、粘り切りたいと思える機会になりました。

0
0
0

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
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?