以前、GoAccessをインストールしてアクセスログを解析する方法を紹介しました。
今回は、GoAccessの集計結果を定期的に自動更新する方法を紹介します。
集計結果を残すためのディレクトリを作成
GoAccessがサイトのアクセスログを解析し、その集計データを永続化(保存)するためのディレクトリを作成します。
今回はconv.server-me今回は「conv.server-memo.net」のアクセスログを解析するため、以下のような名前でディレクトリを作成します。
$ sudo mkdir -p /var/lib/goaccess/conv
複数のサイトを解析する場合は、サイトごとにディレクトリを分けて作成しておくと管理が便利です。
HTML形式のレポートを保存するディレクトリを作成
GoAccessが解析した結果を、Webブラウザで閲覧できるHTML形式のレポートとして保存するためのディレクトリを作成します。
$ sudo mkdir -p /usr/share/nginx/goaccess
こちらは、レポートの名前をサイトごこちらは、レポートのファイル名をサイトごとに別名で指定できるため、ディレクトリは1つ共通のままでも問題ありません。
ログ解析コマンドとに指定することが可能なため、ディレクトリは1つでも問題ありません。 ログ解析コマンドの基本と使用例
GoAccessでは、「--persist」オプションをオプションを指定することで、Nginxのアクセスログを解析した集計データを指定したディレクトリに保存(蓄積)できます。
sudo goaccess 解析対象のログファイル \ --log-format=ログフォーマット \ --persist \ --db-path=集計結果の保存先ディレクトリ \ -o HTMLレポートの出力先パス
具体的な使用例
実際に「conv.server-memo.net」のアクセスログを解析して、集計結果を保存するコマンドは以下のようになります。
$ sudo goaccess /var/log/nginx/conv_access.log \ --log-format=COMBINED \ --persist \ --db-path=/var/lib/goaccess/conv \ -o /usr/share/nginx/goaccess/conv_report.html
コマンド実行後、「/var/lib/goaccess/conv」ディレクトリに集計データが保存され、「/usr/share/nginx/goaccess/conv_report.html」にHTML形式のレポートが出力されていることを確認してください。
シェルスクリプトの作成
手動でのコマンド実行に問題がなければ、定期実行の際に呼び出せるようにシェルスクリプト化しておきます。
毎回長いコマンドを入力する手間も省けます。
$ sudo vi /usr/local/bin/update_goaccess.sh
実行したコマンドの内容を元に、以下のようなシェルスクリプトを作成します。
#!/bin/bash DB_PATH="/var/lib/goaccess/conv" LOG_FILE="/var/log/nginx/conv_access.log" REPORT_FILE="/usr/share/nginx/goaccess/conv_report.html" /usr/bin/goaccess $LOG_FILE \ --log-format=COMBINED \ --persist \ --db-path=$DB_PATH \ -o $REPORT_FILE
スクリプトを保存したら、実行権限を付与します。
$ chmod 755 /usr/local/bin/update_goaccess.sh
権限付与の完了後、シェルスクリプトを手動で実行してみて、アクセスログの解析と集計結果の更新が正常に行われるか確認してください。
systemd.timer機能で定期実行
GoAccessの集計結果を定期的に更新するために、今回はcronではなく、Ubuntuで標準的な「systemd」 の 「timer」機能を使用してみます。
そのために、以下の2つのファイルを作成します。
- /etc/systemd/system/update_goaccess.service
- /etc/systemd/system/update_goaccess.timer
update_goaccess.serviceの作成
先ほど作成したシェルスクリプトを実行するためのサービスファイルです。
$ sudo vi /etc/systemd/system/update_goaccess.service
以下の内容を記述します。
[Unit] Description=Update GoAccess Report [Service] Type=oneshot ExecStart=/usr/local/bin/update_goaccess.sh
update_goaccess.timerの作成
こちらは、サービスをどのくらいの時間間隔で実行するかを設定するファイルです。
$ sudo vi /etc/systemd/system/update_goaccess.timer
[Timer]セクションの「OnCalendar」で「hourly(毎時)」を設定し、「Unit」で先ほど作成した「update_goaccess.service」を指定します。
[Unit] Description=Update GoAccess Report Hourly Timer [Timer] OnCalendar=hourly Unit=update_goaccess.service [Install] WantedBy=timers.target
systemdへの登録と起動
作成した2つのファイルをsystemdに認識させます。
$ sudo systemctl daemon-reload
タイマーの自動起動設定(有効化)と、タイマーの開始を行います。
$ sudo systemctl enable update_goaccess.timer $ sudo systemctl start update_goaccess.timer
以下のコマンドを実行し、タイマーが正常に登録され、次回実行までの時間が正しく表示されているか確認します。
$ systemctl list-timers update_goaccess.timer NEXT LEFT LAST PASSED UNIT ACTIVATES Thu 2026-05-21 17:00:00 JST 53min Thu 2026-05-21 16:00:02 JST 6min ago update_goaccess.timer update_goaccess.service 1 timers listed.
「NEXT」部分に次回の実行予定日時が表示されていれば成功です。
これで、1時間ごとにアクセスログが自動で解析され、HTMLレポートが更新されるようになりました。
logrotateの設定(データの取りこぼし対策)
Nginxのログがローテーションされる場合、古いログファイルが削除される前にgoaccessでログの内容解析・集計する必要があります。
Nginxのログがローテーション(日次などで新しいファイルに切り替わる動作)される場合、古いログファイルが処理される直前にもGoAccessを動かす必要があります。
これをしないと、「最後に1時間おきの定期実行をしてから、ログローテーションが行われるまでの間」のアクセスデータが集計に反映されず、消失してしまうためです。
そのため、Nginxのlogrotate設定ファイルに、ログをローテションする直前にGoAccessの解析スクリプトを実行する設定(prerotate)を追加します。
$ sudo vi /etc/logrotate.d/nginx
私の環境では、以下のように赤字部分の設定を追加しました。
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
prerotate
/usr/local/bin/update_goaccess.sh
endscript
postrotate
if [ -f /run/nginx.pid ]; then
kill -USR1 `cat /run/nginx.pid`
fi
endscript
}
これで、定期実行のタイミングだけでなく、ログが切り替わる瞬間も漏れなく集計されるようになり、正確なアクセスレポートを維持できるようになります。


コメント