印刷用表示へ切り替え 通常表示へ切り替え 更新履歴を表示 更新履歴を隠す
Linux Apache のログファイルを月別に分割したい

ログのローテートを行わなかったために巨大なファイルになってしまった access_log を月別に分割したい。

■ ■ ■

このサイトでは,ログがローテートして消えていってしまうのを避けるため,/etc/logrotate.d/apache を削除していた。そのため,Apache のログ /var/log/httpd/access_log は巨大なファイルになってしまった。2004年1月からログを採り始め,現在 580 MB にまでなっている。これを月別に分割して,3月分は access_log.200503 のように名前をつけて保存していきたいと思っている(nlog(n): Apache のログを月別に保存したい)。分割して保存するメリットは次の通り。

  • Webalizer の処理時間短縮
  • ディスク容量の節約

統計情報集計ソフト Webalizer は過去1年間分の情報しか対象としないので,古いログを分離して処理の対象外とすれば,処理時間の短縮が期待できる。また,古いログを圧縮してしまえば,ディスクの節約になるからである。テキストファイルの場合,約10分の1に圧縮されるのでかなりお得。

しかし,そのためには access_log を月別に分割しなければならない。2004年1月からだと,15分割しなければならない。手作業でもできそうだが,少し楽がしたい。そこで次のような Perl スクリプト monthout.pl を書いた(名前は適当)。Apache のログの日時部分にマッチして,指定した月のものだけを出力する。

#!/usr/bin/perl

$year = shift(@ARGV);
$month = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')[shift(@ARGV)-1];

while (<>) {
  if ($_ =~ m|\[\d+/$month/$year:\d+:\d+:\d+ \+0900\]|) {
    print;
  }
}

使い方は,引数に年と月とファイル名を与えるようにする。例えば 2004年3月分なら次のように指定する。結果は標準出力に出力される。

$ perl monthout.pl 2004 03 /var/log/httpd/apache_log

もちろん,monthout.pl に実行許可を与えておけば,最初の「perl」は不要である。

このスクリプトを使ってファイルに出力するようにするために,次のような Bourne Shell のスクリプト monthout.sh を書いた(これも名前は適当)。

#!/bin/sh

LOGNAME="/var/log/httpd/access_log"

for Y in 2004 2005;
do
  for M in 01 02 03 04 05 06 07 08 09 10 11 12;
  do
     perl monthout.pl $Y $M $LOGNAME >> $LOGNAME.$Y$M
  done
done

余分に出来てしまう未来のログ access_log.200505 .. access_log.200512 は手で削除する。しかし,考えてみれば2004年分と2005年分を別ループにすれば,余分なファイルは発生しないのだった。失敗した。残念!!..._| ̄|○

つまりこういうことだ。

#!/bin/sh

LOGNAME="/var/log/httpd/access_log"

for Y in 2004;
do
  for M in 01 02 03 04 05 06 07 08 09 10 11 12;
  do
     perl monthout.pl $Y $M $LOGNAME >> $LOGNAME.$Y$M
  done
done
for Y in 2005;
do
  for M in 01 02 03 04;
  do
     perl monthout.pl $Y $M $LOGNAME >> $LOGNAME.$Y$M
  done
done

となると,Y をループにする必要もないことになる。まぁ,気にしないことにしよう。1度しか使わないし…。しかし,よく思い返してみると,この手の作って直ぐに捨てるコードを沢山書いてきて,再利用することは考えていなかったような気がする。ここに残しておけば再利用することがあるかも知れない。

構文のチェックは sh に -xv オプションをつけるとできる(シェルスクリプトのデバッグ シェルスクリプトのデバッグ - UNIX & Linux コマンド・シェルスクリプト リファレンス)。

$ sh -xv monthout.sh

元の巨大な access_log は念のためバックアップ。現在は2005年4月なので,httpd を停止した後に,root 権限で monthout.sh を実行し,access_log.200504 を access_log に名前を変更すれば,希望の処理が完了する。

Posted by n at 2005-04-15 00:18 | Edit | Comments (0) | Trackback(0)
Trackbacks

  • 「手違いで複数トラックバックを送ってしまった!」という場合でも気にしないでください (重複分はこちらで勝手に削除させていただきます)
  • タイムアウトエラーは,こちらのサーバの処理能力不足が原因です (詳細は トラックバック送信時のエラー をご覧ください)
  • トラックバックする記事には,この記事へのリンクを含めてください(詳細は 迷惑トラックバック対策 をご覧ください)
Comments
Post a comment
  • 電子メールアドレスは必須ですが,表示されません (気になる場合は「メールアドレスのような」文字列でもOKです)
  • URL を入力した場合はリンクが張られます
  • コメント欄内ではタグは使えません
  • コメント欄内に URL を記入した場合は自動的にリンクに変換されます
  • コメント欄内の改行はそのまま改行となります
  • 「Confirmation Code」に表示されている数字を入力してください (迷惑コメント対策です)


(必須, 表示されます)


(必須, 表示されません)


(任意, リンクされます)


Confirmation Code (必須)


Remember info (R)?