Jpostalの公開サーバ、jpostal-1006.appspot.comのアクセスログをAWStatsで集計しました。App Engine特有のawstas.conf設定やアクセスログ整形について説明します。
アクセスログ集計解析ソフトとは
アクセスログ集計解析ソフトって何?
アクセスログ集計解析ソフトとは、「月、日、曜日、ページ別、OS別、ブラウザ別」に、「訪問者数、htmlページだけのアクセス数、画像やcssを含む全アクセス数、転送量」を集計して、表やグラフで表示します。
AWStats、analog、webalizerの3つが有名ね
Google Analyticsとは何が違うのかな?
Google Analyticsはブラウザ側アクセスを集計します。Cookieで訪問者を追跡するので、訪問者数が正確です。
アクセスログ集計解析ソフトは、サーバ側アクセスを集計します。アクセス元IPアドレスで訪問者を追跡します。すると、数日後に再訪したとき、IPアドレスが変わっていると、新たな訪問者としてカウントされます。
Google Analyticsを仕込んでいないときや、仕込めないときも、アクセスログを集計します。
また、アクセスログを集計しないと、クローラやボットからのアクセスがわからないことも多いです。
AWStatsとは
AWStats(エーダブリュースタッツ)の名前の由来は、Advanced Web Statisticsです。Perlで開発されているので、Windows、Mac OS X、Linuxで同じzipパッケージを使えます。
AWStatsは、2つの処理と3つのファイルに注目すると、仕組みを理解しやすいです。
集計処理は、cronやJenkinsで定期処理するよ
設定ファイル(awstats.conf)、アクセスログ
↓
集計処理
↓
月別の集計結果ファイル
表示処理は、ブラウザで、/cgi-bin/awstats.plにアクセスしたときね
月別の集計結果ファイル
↓
表示処理
↓
webブラウザ
ファイル | 説明 |
---|---|
awstats.conf | 設定ファイル |
access_log | アクセスログ |
awstats042020.txt | 月別の集計結果 |
ディレクトリ構成
今回のディレクトリ構成です。awstats本体は、別の場所、Dockerコンテナ内にあります。
$ tree -L 2
.
├── awstats
│ ├── awstats.conf
│ ├── logs/
│ └── results/
└── jpostal_log.docker
└── docker-compose.yml
DockerHub
AWStatsをインストール済みのDockerイメージを使います。
docker-compose.yml
version: '2'
services:
web:
tty: true
container_name: awstats.jpostal_log.docker
image: pabra/awstats
ports:
- 3000:80
volumes:
- ../awstats/logs:/var/local/log:ro
- ../awstats/results:/var/lib/awstats
environment:
- TZ:"Asia/Tokyo"
restart: always
Code language: YAML (yaml)
container_name
好みに編集してください。このままでもいいです。
ports
好みに編集してください。このままでもいいです。
restart: always
次回、PC起動時に、このDockerコンテナも自動起動します。
volumes
アクセスログをホスト側の ../awstats/logs/* の位置に保存すると、Dockerコンテナからは、/var/local/log/* の位置に見えます。
集計結果ファイルは、Dockerコンテナは、/va/lib/awstats/* の位置に保存します。ホスト側からは ../awstats/results/* の位置に見えます。
Docker内 | ホスト側 | 説明 |
---|---|---|
/var/local/log/* | ../awstats/logs/* | アクセスログ |
/var/lib/awstats/* | ../awstats/results/* | 結果ファイル |
docker-composeで起動してください。
$ cd jpostal_log.docker
$ sudo docker-compose up -d
Code language: Bash (bash)
webブラウザでhttp://localhost:3000 にアクセスすると、AWStatsの画面が表示されるはずです。
まだ集計していないから、アクセス数はゼロで表示されるよ
awstats.conf
編集するために、Dockerコンテナのawstats.confを取り出します。Dockerコンテナ内の/etc/awstats/awstats.conf にあるので、ホストから見える位置 /var/lib/awstats/ にコピーします。
$ container_name=awstats.jpostal_log.docker
$ sudo docker exec $container_name cp /etc/awstats/awstats.conf /var/lib/awstats/
Code language: Bash (bash)
ホストでは awstats/results/ の位置に見えます。書き込み権限がないので、chmod か chown してください。
$ sudo chmod a+w ../awstats/results/awstats.conf
Code language: Bash (bash)
awstats.confの設定項目は多いから、めまいがしそうだよ。
ほとんどの項目はそのままよ。
SiteDomain
AWStats画面の左上のサイト名に反映されます。
156行目付近です。
SiteDomain="jpostal-1006.appspot.com"
Code language: Bash (bash)
TimeZone
アクセスログの日時に「-0700」とある場合、アクセスログのタイムゾーンは -7 です。
これを日本時間の +9 で表示したいんですね。
そこで、-7 と +9 の差、+16 を設定します。
1408行目付近です。先頭に "#" があったら削除してください。
LoadPlugin="timezone +16"
Code language: Bash (bash)
ValidHTTPCodes
デフォルトでは、status codeが200、304だけが集計対象です。
200は、正常なレスポンス
304は、If-Modified-Sinceでリクエストされたけど、コンテンツは更新されていないときだね。ブラウザはブラウザ内キャッシュから表示したんだね。
これで集計したところ、全リクエストの約75%がstatus code 204で、集計対象から除外されていました。
204は、No Contentってあるけど、304と同じ?
似ているけど、違うわ。
204は、エッジキャッシュから配信されたのね。
ここでは、エッジキャッシュを含めたアクセス数を集計したいので、204も集計対象に含めることにします。
617行目付近のValidHTTPCodesを編集します。
ValidHTTPCodes="200 204 304"
Code language: Bash (bash)
NotPageList
Jpostalはjsとjsonしかないので、PVとして集計されません。そこで、NotPageListから js を除外しました。
601行目付近のNotPageListを編集します。
NotPageList="css class gif jpg jpeg png bmp ico rss xml swf eot woff woff2"
Code language: Bash (bash)
awstats.confをDockerコンテナにコピーするのを忘れないでね
この状態の awstats.conf を Dockerコンテナの /etc/awstats/ へコピーします。Dockerコンテナが再起動すると、/etc/awstats/awstats.conf は初期状態に戻ってしまうので、再起動したらコピーしてください。
$ sudo docker exec awstats.jpostal_log.docker cp /var/lib/awstats/awstats.conf /etc/awstats/
Code language: Bash (bash)
アクセスログの整形
この状態で集計してみました。
$ container_name=awstats.jpostal_log.docker
$ logfile=/var/local/log/2020-04-07-01-15-49.log
$ sudo docker exec $container_name /usr/lib/awstats/cgi-bin/awstats.pl -update -config=default -LogFile="$logfile"
Create/Update database for config "/etc/awstats/awstats.conf" by AWStats version 7.7 (build 20180105)
From data in log file "/var/local/log/2020-04-07-01-15-49.log"...
Phase 1 : First bypass old records, searching new record...
Direct access to last remembered record is out of file.
So searching it from beginning of log file...
Phase 2 : Now process new records (Flush history on disk after 20000 hosts)...
Jumped lines in file: 0
Parsed lines in file: 354231
Found 0 dropped records,
Found 0 comments,
Found 0 blank records,
Found 319026 corrupted records,
Found 0 old records,
Found 35205 new qualified records.
Code language: Bash (bash)
corrupted recordsが31万もあるけど、なんだろう?
35万行のうち、新規追加されたのは3万行だけです。31万行は「corrupted records」となってしまいました。全体の90%です。
「corrupted records」とは、awstats.confのLogFormatでパースできなかった不正な行です。LogFormatは、いわゆるCombined Log Formatです。
LogFormat="%host %other %logname %time1 %methodurl %code %bytesd %refererquot %uaquot"
Code language: Bash (bash)
どんなサーバのログでも1%ぐらいは「corrupted records」になるそうですが、90%は多すぎます。
アクセスログを調べてみると、リファラーがあるときは「"https://www.google.com"」のようにダブルクォート囲みでした。リファラーがないときはダブルクォートのない「-」でした。
試しに数行のアクセスログを作り、リファラーを「"-"」に編集しました。集計してみると、その行は集計されて「new qualified records.」にカウントされました。
つまり、AWStatsのLogFormatの%refererquotは、「"-"」を想定していて、「-」は不正扱いするようです。
App Engineのアクセスログの書式がおかしいってこと?
それともAWStatsのバグ?
どちらも考えにくいわ。
でもそれらしいawstatasの設定オプションは見つからないし、
9割のリクエストを集計できるような、いい方法はないかしら
集計前に、アクセスログのリファラーの「-」を「"-"」に置換してしまいましょう。
ここでは、sedコマンドを使いました。
adjust_logformat.sh
#!/bin/bash -uex
# HTTP/1.1" 204 6430 - "Mozil...
# HTTP/1.1" 204 6430 "-" "Mozil...
src=$1
dst=$2
cat $src \
| sed -e "s/\(HTTP\/[0-9]\+[.][0-9]\+\" [0-9]\+ [0-9]\+\) - /\1 \"-\" /g" \
>$dst
Code language: Bash (bash)
次のように使います。
$ ./adjust_logformat.sh awstats/logs/2020-04-07-01-15-49.log awstats/logs/2020-04-07-01-15-49.log.tmp
Code language: Bash (bash)
集計処理
awstats/results/awstats*.txt を削除して、集計しなおします。
$ container_name=awstats.jpostal_log.docker
$ logfile=/var/local/log/2020-04-07-01-15-49.log.tmp
$ cd jpostal_log.docker
$ sudo docker exec $container_name /usr/lib/awstats/cgi-bin/awstats.pl -update -config=default -LogFile="$logfile"
Create/Update database for config "/etc/awstats/awstats.conf" by AWStats version 7.7 (build 20180105)
From data in log file "/var/local/log/2020-04-07-01-15-49.log.tmp"...
Phase 1 : First bypass old records, searching new record...
Searching new records from beginning of log file...
Phase 2 : Now process new records (Flush history on disk after 20000 hosts)...
Flush history file on disk (unique hosts reach flush limit of 20000)
Jumped lines in file: 0
Parsed lines in file: 354231
Found 0 dropped records,
Found 0 comments,
Found 0 blank records,
Found 234 corrupted records,
Found 0 old records,
Found 353997 new qualified records.
Code language: JavaScript (javascript)
ほぼ全ての行を集計できました。まだ234行が不正な書式で集計できませんでしたが、これぐらいは許容範囲とします。
集計済みのログファイルは削除していいのかな?
何回でもやり直せるから、とっておいたほうがいいわよ。
gzipで圧縮して、アーカイブ用のディレクトリに移動しておいて。