thumb

中山テック 代表の中山です。

スクリプト実行で1つのログファイルが大きくなり、可読性が悪くなることが多々あります。

systemctl可能なミドルはそんなに難しくないのですが、自前でこさえるとなるとなかなか大変。

リファレンス的に残す形であること、自前なので参考程度にご覧ください。

-rw-r----- 1 nginx root  112225  7月 12 13:06 access.log
-rw-r--r-- 1 root  root    4863  7月  8 09:10 access.log-20240708.gz
-rw-r----- 1 nginx root    9487  7月  9 10:06 access.log-20240709.gz
-rw-r----- 1 nginx root   48617  7月  9 21:15 access.log-20240710.gz
-rw-r----- 1 nginx root     412  7月 11 11:30 access.log-20240711.gz
-rw-r----- 1 nginx root  729280  7月 12 12:23 access.log-20240712
-rw-r----- 1 nginx root       0  7月 10 15:31 error.log
-rw-r--r-- 1 root  root    1940  7月  8 00:19 error.log-20240708.gz
-rw-r----- 1 nginx root     847  7月  9 10:06 error.log-20240709.gz
-rw-r----- 1 nginx root   22295  7月  9 19:36 error.log-20240710
-rw-r--r-- 1 nginx root 3307324  7月 12 23:28 zabbix_access.log
-rw-r--r-- 1 nginx root    1166  7月 12 13:07 zabbix_error.log

※既にローテートされているログ達ですが今後の流れを説明したいので

ローテートタイミングを1日とします。

赤字の「access.log」を昨日日付にリネームし、新たなaccess.logを作ることです。

ブログを執筆しているのが2024年9月11日ですので9月10のログとして残していきたい、という算段です。

ローテートスクリプト

「rotate.sh」という名前のファイルを作成して下記のプログラムを組みます。

#!/bin/bash

# 今日日付
nowDate=$(date +"%Y%m%d") # ①現在日付を取得し

# ログ
log=/var/log/nginx/access.log

# ログファイルの日付を取得
logFileDate=$(find ${log} -printf '%TY%Tm%Td')
 # ②ローテート対象ファイルの日付を取得
 
# ユーザ・グループ
user=nginx
group=root

if [ ${logFileDate} != ${nowDate} ]; then # ③ログファイルの日付と現在日付が相違の場合、昨日日付付でリネーム

  yesterday_date=$(date -d "yesterday" + "%Y-%m-%d")
  $(mv ${log} ${log}.${yesterday_date})
  touch ${log}
  chown ${user}:${group} ${log}

fi

実行

[root@study01 nginx]# ./rotate.sh

-rw-r--r-- 1 nginx root       0  9月 11 16:06 access.log
-rw-r--r-- 1 root  root    4863  7月  8 09:10 access.log-20240708.gz
-rw-r----- 1 nginx root    9487  7月  9 10:06 access.log-20240709.gz
-rw-r----- 1 nginx root   48617  7月  9 21:15 access.log-20240710.gz
-rw-r----- 1 nginx root     412  7月 11 11:30 access.log-20240711.gz
-rw-r----- 1 nginx root  729280  7月 12 12:23 access.log-20240712
-rw-r----- 1 nginx root  112225  7月 12 13:06 access.log.2024-09-10
-rw-r----- 1 nginx root       0  7月 10 15:31 error.log
-rw-r--r-- 1 root  root    1940  7月  8 00:19 error.log-20240708.gz
-rw-r----- 1 nginx root     847  7月  9 10:06 error.log-20240709.gz
-rw-r----- 1 nginx root   22295  7月  9 19:36 error.log-20240710
-rwxr-xr-x 1 root  root     418  9月 11 16:05 rotate.sh
-rw-r--r-- 1 nginx root 3307324  7月 12 23:28 zabbix_access.log
-rw-r--r-- 1 nginx root    1166  7月 12 13:07 zabbix_error.log

新規access.logが作られ、古いaccess.logは日付付のoldファイルになりました。

ログに書き込む前に上記処理を入れておくことで日時ローテートを実現可能となります。

※リネーム後のファイル名は状況に応じて変えてみてください

応用

$(mv ${log} ${log}.${yesterday_date})

ファイルをリネームしただけなのでサイズが変わっておりません。

もし圧縮・アーカイブ化させたい場合は下記のように指定するのもOK

#!/bin/bash

# 今日日付
nowDate=$(date +"%Y%m%d")

# ログ
log=/var/log/nginx/access.log
log_dir=/var/log/nginx
logfile=access.log

# ログファイルの日付を取得
logFileDate=$(find ${log} -printf '%TY%Tm%Td')

# ユーザ・グループ
user=nginx
group=root

if [ ${logFileDate} != ${nowDate} ]; then

  yesterday_date=$(date -d "yesterday" +"%Y-%m-%d")
  #$(mv ${log} ${log}.${yesterday_date})
  $(tar zcf ${log}-${yesterday_date}.tar.gz -C ${log_dir} ${logfile} )
  #rm ${log} # ←必要に応じて
  #touch ${log} # ←必要に応じて
  #chown ${user}:${group} ${log} # ←必要に応じて

fi

上書き防止のため「-C」を使用してディレクトリとファイルを分けて指定します。

参考サイト

また、青文字の「必要に応じて」の箇所ですが、ファイルを削除して新たなファイルを作成するプログラムになります。

別のディレクトリに配置して良いですし、可能性は無限大です。

まとめ

問題発生時のアプローチとしてログは非常に重要です。

今回のケースに限らずですが、土日で監視する人がいない場合に土日どっちで起きたのか。

また何時ごろ起きたのか、ということを確認します。

膨大なサイズになってしまったログは開くのに時間が掛かる他、検索も非常に難しくなります。

今回は1日おきにローテートさせるプログラムとなりますが、場合によってはファイルサイズでローテートさせる必要も出るでしょう。

ローテートさせていない場合は是非実装してみてください!

おすすめの記事