技術・開発

【AWStats】ログローテーションが「日付形式」でも大丈夫!過去ログを自動で取り込むシェルスクリプト

2010年9月3日

前回、Apacheでログローテーションの設定を行いました。

これでサーバーのディスク容量問題は解決!と思いきや、今度はアクセス解析ツール 「AWStats」 が正常に更新されなくなるトラブルが発生…。

原因は、ログローテーションの設定(logrotate.conf)で dateext オプションを有効にしたため、ログファイル名が連番(access_log.1)から 日付付き(access_log-20230101) に変わってしまったことでした。

ファイル管理としては日付の方が分かりやすいのですが、AWStats側がファイルを追えなくなってしまたため、集計用のシェルスクリプトを改修して対応しました。

日付形式のログに対応するシェルスクリプト

仕組みは単純で、「過去10日分のログファイルをさかのぼって存在チェックし、あれば結合してAWStatsに食わせる」というものです。

以下のスクリプトは私の環境用(UTF-8変換処理など含む)ですが、パスなどを環境に合わせて書き換えてご使用ください。

#!/bin/sh

# --- 設定:パスは環境に合わせて変更してください ---
ALOG=/var/log/apache2/access_log
A1LOG=/var/log/apache2/access_log-
NEWLOG=/var/log/apache2/access_log.new
UTF8LOG=/var/log/apache2/access_log.utf8

# 独自のPerlスクリプトやAWStatsのパス
UTF8DECODE=/home/hoge/public_html/awstats_utf8_decode.pl
AWSTATS=/home/hoge/public_html/awstats_awstats.pl
LOG=/var/log/awstats.log

# --- 処理開始 ---

# 新しいログファイルを初期化(空にする、またはヘッダー等があれば入れる)
# cat /var/log/apache2/test.txt > $NEWLOG # 必要なければコメントアウト
: > $NEWLOG # ファイルを空にするコマンド

# 10日前から当日までループ処理
a=10
while [ $a -ge 0 ]
do
    # 日付の計算(今日から a日前)
    day=`date -d "$a days ago" '+%Y%m%d'`
    
    # 対象となるログファイル名を作成
    day2=$A1LOG$day
    
    # ファイルが存在するかチェック
    if [ -e $day2 ]; then
        echo "$day2 が対象です。"
        # 存在すれば結合用ファイルに追記
        cat $day2 >> $NEWLOG
    fi

    # カウンタを減らす
    a=`expr $a - 1`
done

# 最後に現在のアクセスログを結合
cat $ALOG >> $NEWLOG

# UTF-8デコード処理(必要な場合)
$UTF8DECODE < $NEWLOG > $UTF8LOG

# AWStatsの更新実行
$AWSTATS -config=awstats.conf -update > $LOG

# ログの権限設定(セキュリティのため)
chmod 600 $LOG

スクリプトの解説

シェルスクリプトはあまり書き慣れていないのでざっくりとした作りですが、ポイントは以下の通りです。

  1. while [ $a -ge 0 ]: 変数 a(日数)が0になるまでループします。今回は「10日前」からスタートしています。
  2. date -d ...: date コマンドで「○日前」の日付文字列(YYYYMMDD)を生成し、ログファイル名と一致させます。
  3. 存在チェック: if [ -e $day2 ] でその日付のログファイルがあるか確認し、存在する場合のみ cat コマンドで一時ファイル($NEWLOG)に結合します。
  4. 現在のログ: ループ終了後、現在進行系で書き込まれている最新の access_log も忘れずに結合します。

logrotate の設定で dateext を使うと管理が楽になりますが、こういったバッチ処理への影響もあるので注意が必要ですね。 同じような環境でAWStatsが止まってしまった方は、ぜひ参考にしてみてください。

-技術・開発
-, , , , , ,