アクセスログの読み方(apache combined logの場合)

ここでは、apache(アパッチ)のアクセスログを読む時の基本を説明したいと思います。

アクセスログは膨大な量の生データです。 そのため、人間の目で見て判断するのはほぼ不可能です。 ここでは、スクリプトを自作しながらアクセスログを解析していきたいと思います。 スクリプトを作成する言語としてはperlを利用したいと思います。 perl以外の言語で書いても解析は行えるのでperlが嫌いな方は必要に応じて別の言語をご利用ください。

perlの準備

perlを使ってスクリプトを書くには、perlを使える環境を整えなければなりません。 perlでプログラムを書いたことがある方は以下を読み飛ばしてください。

多くのLinux及びUNIX系システムでは、perlが標準でインストールされています。 そのような環境では、perlが置いてあるパス(path)だけ把握しておけば、特に用意することはありません。 (perlが置いてあるパスとして一般的なものとしては、「/usr/local/bin/perl」や「/usr/bin/perl」などがあります。) このような環境では、作成したperlスクリプトの実行権限を変更するだけでスクリプトを実行できるようになります。 実行権限を変えるには、chmodコマンドを利用します。 例えば、sample.plというファイル名でスクリプトを書いたとします。 このときは、「chmod 755 sample.pl」を実行すればsample.plを実行できるようになります。

Windows環境では、perlは標準ではないので用意をしないといけません。 個人的にはcygwin+perlという環境をお勧め致します。 cygwinは、linux風のコマンドラインを提供してくれるフリーソフトです。 普通にcygwinをインストールすればperlが入ってきます。 cygwin環境で行う場合には、perlスクリプトを書いて、cygwin環境でlinux環境のようにchmodコマンドを利用するだけです。 仮に、cygwinプロンプトを出したときのホームディレクトリは「c:\cygwin\home\ユーザ名\」になります(ただし、インストール方法によりこれは変わります)。

ここの説明がわかりにくい場合には、ご連絡ください。 加筆します。 もし可能でしたら、どのように解りにくいかもご連絡頂ければ幸いです。 ご協力ありがとうございます。

データを区切る

アクセスログには膨大な量の情報が含まれますが、生データのままでは扱えません。 まず、最初に意味に応じてデータを区切らなければなりません。 例えば、「ある特定のページが一日に何度閲覧されたか」を知りたいとします。 「どのページが閲覧されたか」の情報だけを1行分のデータから抜き出さないと、そのページが一日に何回見られたかを調べることは出来ません。 それには、「どのページが閲覧されたか」という情報を示している部分を抜き出さないといけません。

アクセスログファイルを読み込んで、各項目ごとにデータを区切るperlスクリプト例を以下に示します。 下記サンプルは区切ったデータを表示するだけです。


#!/usr/bin/perl

# (注意)/usr/bin/perlの部分は必要に応じて変更してください。

# (注意)"access_log.txt"は解析するアクセスログのファイル名に
#  変更してください。
open(LOGFILE, "access_log.txt") || die $!;

# 一行ずつアクセスログファイルを読みます。
while (<LOGFILE>) {

# perlのパターンマッチを行っています。
# $1,$2,...$9にマッチした結果が入ります
  /^(.*) (.*) (.*) \[(.*)\] "(.*)" (.*) (.*) "(.*)" "(.*)"/;

# パターンマッチの結果を変数に代入しています。
  $remotehost = $1;
  $fromidentd = $2;
  $remoteuser = $3;
  $datetime = $4;
  $httprequest = $5;
  $httpstatus = $6;
  $databytes = $7;
  $refer = $8;
  $useragent = $9;

# printの部分は表示を行います。
# printの部分はこのサンプルをわかりやすくするために書いているだけです。
# そのため、実際に解析する段階ではprint部分はいりません。
  print $remotehost;
  print "\n";

  print $fromidentd;
  print "\n";

  print $remoteuser;
  print "\n";

  print $datetime;
  print "\n";

  print $httprequest;
  print "\n";

  print $httpstatus;
  print "\n";

  print $databytes;
  print "\n";

  print $refer;
  print "\n";

  print $useragent;
  print "\n";

  print "\n\n";

# ここでwhile文が閉じています。
}

# 開いたアクセスログファイルを閉じています。
close(LOGFILE);

# exitは無くても動きますが、念のため。
exit;

ここでは、apacheのcombined logを前提としています。 その他のlogフォーマットを利用している場合には必要に応じてperlスクリプトサンプルを微調整して下さい。

区切ったデータをどう扱うか

ここでは、とりあえずデータを区切るとこまでの説明とします。 区切った後にどのように料理するかは色々な方法があるので、それぞれについては個別に説明を行いたいと思います。

参考情報

アクセスログの種類(apacheの場合)