このサイトで実践しているApache access_logの整形方法をご紹介。以下の文字列を正規表現一発で解析するのはほぼ不可能に近い。
157.55.39.58 - - 2020/03/08:03:13:09 "GET /wp-content/uploads/2019/06/straightnochaser.mp3 HTTP/1.1" 200 575865 "-" "msnbot/2.0b (+http://search.msn.com/msnbot.htm)"
正規表現パズル好きにはたまらないかもしれない。でも僕には耐えられない。手抜き集計で十分だ。
まずはLogFormat最低限のカスタマイズ。日付を YYYY/MM/DD:hh:mm:ss 形式にしてある。
LogFormat "%h %l %u %{%Y/%m/%d:%H:%M:%S}t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
元の日付フォーマットでは例えば ”01/Mar/2020″ となってしまいソートができない(Apr → Marとなる)と。他パラメータはデフォルトである。妥当なオプションだと思っている。
これを数えていく。一発では綺麗に整形できないので一時ファイルに出力する。
tmpf="/tmp/date +%Y%m%d%H%M%S
.access.sum"
自分のアクセスであろうIPを調べる。 管理画面に入って何かしていて、かつOSやユーザエージェントが自分のアクセスを外すため。
jogai=""
jogai_tmp=grep 管理画面 $logd/access_log* | egrep '(エージェントとか|OSとか)' | awk '{ print $1 }' | awk -F: '{print $NF}' | sort | uniq | tr '\n' ' '
botと画像ファイル、ローカルからのアクセス(Wordpress?)を除外対象とする。力技である。
jogai_tmp="$jogai_tmp bot Bot doing_wp_cron 127.0.0.1 .css .js .png .jpeg .jpg python-request"
今時HTTP/1.0はbotでしょう。POSTは普通のアクセスではない。
jogai_tmp=$jogai_tmp" HTTP/1.0"
jogai_tmp=$jogai_tmp" POST"
egrep用の文字列を作成。(egrepのmanを読むべし)
for t in $jogai_tmp
do
jogai="$t|$jogai"
done
jogai=echo $jogai | sed 's/|$//'
除外した上で HTTP 200 OKリクエストを抽出する。
cat access_log | egrep -v "$jogai" | grep -w '200' > $tmpf
IPアドレスのユニーク数をカウント。≒ユニークユーザー数である。
printf "IP: " cat $tmpf | awk '{print $1}' | sort | uniq | wc -l
日付を取り出して sort | uniq -c 。日別アクセス数が分かる。下のロジックは周りくどいかもしれない。要するに YYYY/MM/DD だけ出力して sort | uniq -c やってるだけ。
cat $tmpf | awk '{print $1,$4}' | tr -d '[' | tr -d '-' | awk -F: '{print $1}' | awk '{print $2}' | sort | uniq -c
sedでGET以前の文字列を削除するのがポイント。awk – print $1 すればアクセス先ページを取得できる。
cat $tmpf | sed 's/^.*GET//' | awk '{ print $1 }' | sort | uniq -c
ask -F\” がポイント。$4でリファラー(リンク元ページ)を取得できる。
cat $tmpf | awk -F\" '{print $4}' | sort | uniq -c
ポイントを繰り返す。sed で GET以前の文字列をバッサリ切る処理と、awk -F\” でダブルクオーテーションを区切り文字としてしまう処理である。これで簡単にGET先とリファラーが取れる。難しく考えない方が上手くいくようだ。
以上。