Webサーバーのアクセス解析

siteadministrator2020/07/05(日) - 14:37 に投稿

Nginxのアクセスログ解析を行う。

GoAccessを利用する。パッケージをインストールする。

apt install goaccess

Nginxでの初期値はcombinedらしい。

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

combinedフォーマットを前提とする。

vi /etc/goaccess.conf

time-format %H:%M:%S
date-format %d/%b/%Y
log-format COMBINED

Nginx再起動する。

service nginx restart

goaccess -f /var/log/nginx/access.log

リアルタイム解析はWebSockを利用することとなるらしいが、ファイアーウォールに穴を開けるのが嫌なので、今回は、Cronで回すこととする。

HTML出力は、以下の通り。ヴァーチャルホスト毎に解析したい場合には、Nginxのログ出力先をそれぞれに設定し、GoAccessもそれぞれに実行する。

静的出力

goaccess /var/log/nginx/access.log -o report.html --log-format=COMBINED

リアルタイム出力

goaccess /var/log/nginx/access.log -o report.html --log-format=COMBINED --real-time-html

Apache2でも基本同じ。

combinedではないフォーマットを利用する。

主にログデータのフォーマットとしての利用が想定されているLTSVはLabeled Tab-separated Valuesの略で、コロンで区切られたラベルと値の組み合わせ(key:value)をタブ区切りで表現したフォーマットである。

vi /etc/nginx/conf.d/log.conf

log_format  ltsv  "host:$remote_addr"
                  "\tuser:$remote_user"
                  "\ttime:$time_local"
                  "\treq:$request"
                  "\tstatus:$status"
                  "\tsize:$body_bytes_sent"
                  "\treferer:$http_referer"
                  "\tua:$http_user_agent"
                  "\tforwardedfor:$http_x_forwarded_for"
                  "\treqtime:$request_time"
                  "\tapptime:$upstream_response_time";

vi /etc/goaccess.conf

date_format %d/%b/%Y
time_format %H:%M:%S
log_format host:%h\tuser:%^\ttime:%d:%t %^\treq:%r\tstatus:%s\tsize:%b\treferer:%R\tua:%u\tforwardedfor:%^\treqtime:%T\tapptime:%^

vi /etc/nginx/sites-available/設定ファイル
server {
              ・・・・
         
     access_log /var/log/nginx/access.log ltsv;
              ・・・・・
}

Rsyslogでリモート転送ログの場合

Rsyslogで転送すると、転送先では本来のログの先頭にヘッダー(Tag)が付く。このタグは、複数種類のログファイルが1ファイルになった場合には、切り分けには便利であるが、goaccessの様なログ解析ツールではフォーマットエラーが出る。フォーマットを新たに定義しても良いが、複数フォーマットが1ファイルになっている場合には、かなり面倒になる。

そこで、sedやawkを使ってログを切り分け、パイプでgoaccessに渡すのが簡単である。

awk -F'nginx: ' '{print $2}' ログファイル | goaccess -o 出力先ファイル -

パイプを使う場合には、最後の"-"を忘れないように!