【2026年7月4日時点の情報です】
GoAccessで自宅サーバーのアクセスを集計すると、読者のアクセスのほかに、自分が記事を確かめたアクセスや、WordPressが裏で行っている通信も数えられます。このままだと、読者がどのくらい来ているのかが分かりにくくなります。
この記事では、このブログでレポートから除外しているものとその理由、除外したのにレポートから消えないときの切り分け方をまとめます。GoAccessの入れ方と毎時の自動更新は「Webアクセス解析(GoAccess)の設定」で紹介しています。
なお、Cloudflare Tunnelを使っていると、そのままではログのIPアドレスがすべて 127.0.0.1 になり、自分のアクセスをIPアドレスで除外できません。先に「Cloudflare Tunnel経由のアクセスログに読者のIPアドレスを残す(mod_remoteip)」の設定が必要です。
除外しているもの
| 除外するもの | 条件(正規表現) | 理由 |
|---|---|---|
| WordPressの管理画面 | /wp-admin/ | 記事を書いている間、自動保存などの通信が数十秒ごとに記録される |
| ログイン画面 | /wp-login\.php | 自分のログインと、ログインを試すボットのアクセス |
| 自宅のIPv6アドレス | ^2001:db8:1234:5678: | 自分で記事を確かめたアクセス(前半だけで比べる) |
| 自宅のIPv4アドレス | ^203\.0\.113\.10 | 同じく、IPv4でつながったときの自分のアクセス |
| ランダムな名前の .txt | [0-9a-f]{32}\.txt | 32文字の英数字の .txt へのアクセス。Cloudflare側の確認用と思われ、404の一覧を埋めてしまう |
| WordPressの定期処理 | /wp-cron\.php | 予約投稿などのために、WordPressが自分自身を呼び出す通信 |
IPアドレスは例です。自宅のIPアドレスをブログに載せるときは、説明用の 2001:db8: や 203.0.113.x に置き換えておくと安心です。
集計スクリプト
このブログでは、次のスクリプトを root の crontab で毎時動かしています(IPアドレスは例)。
#!/bin/bash
export LANG="ja_JP.UTF-8"
/usr/bin/zcat -f /var/log/httpd/access_log* \
| /usr/bin/grep -v -E '/wp-admin/|/wp-login\.php|^2001:db8:1234:5678:|^203\.0\.113\.10 |[0-9a-f]{32}\.txt|/wp-cron\.php' \
| /usr/bin/goaccess - -o /var/www/app/report.html --log-format=COMBINED実際のファイルでは1行で書いていますが、読みやすいように \ で改行しています。やっていることは次の3つです。
zcat -f /var/log/httpd/access_log*:今のログと、ローテーションで別ファイルになった過去のログをまとめて読む。-fを付けると、圧縮されていないファイルもそのまま読めるgrep -v -E '...':除外の条件に当てはまる行を取り除く(-vは「当てはまらない行だけ残す」)goaccess - -o ...:残った行を集計して、HTMLのレポートを書き出す(-は「前のコマンドの出力を読む」)
コマンドをフルパスで書いているのは、cron から動かすときは、ふだんのシェルとコマンドを探す場所(PATH)が違うことがあるためです。レポートの出力先は、外からそのまま見られない場所にしています(詳しくは GoAccess の設定の記事)。
自宅のIPアドレスは「行の先頭」で比べる
Apacheのログの1行は、アクセス元のIPアドレスから始まります。^ を付けて「行の先頭がこのIPアドレスの行」だけを除外すると、URLや参照元など、行の途中にたまたま同じ文字がある行まで消してしまうことを防げます。IPv4の最後に空白を入れているのは、203.0.113.10 で 203.0.113.100 まで消さないためです。また、. は正規表現では「任意の1文字」なので、\. と書いています。
除外したのにレポートから消えないとき
条件を足したのに、レポートに自分のIPアドレスなどが残っているときは、次の順に確かめます。
1. スクリプトが動いて、レポートが更新されているか
# レポートが最後に更新された時刻
ls -l /var/www/app/report.html
# cron からスクリプトが実行された記録(CMD の行)
sudo grep update_report /var/log/cron | tail -n 3時刻が古いままなら、スクリプトを手で実行して、エラーが出ないかを見ます。
sudo /root/update_report.sh2. ブラウザが古いレポートを表示していないか
レポートは、ふつうのHTMLファイルを毎時作り直しているだけです。ブラウザに前のファイルが残っていることがあるので、スーパーリロード(Windowsなら Ctrl + F5)で開き直します。
3. 古いログの分が残っていないか
このスクリプトは、過去のログもまとめて読んでいます。条件を足す前に記録された行も、同じ条件で除外されるはずですが、自宅のIPアドレスが変わっていると、古いアドレスの行は残ります。レポートに残っているIPアドレスが、今の自宅のものかどうかを確かめます。
自宅の今のIPアドレスは、家のパソコンで次のように確かめられます(外部の確認用サービスを使います)。
curl -s -4 https://ifconfig.me # IPv4
curl -s -6 https://ifconfig.me # IPv6変わっていたら、スクリプトの条件を新しいアドレスに直します。CloudflareのWAFで自宅を除外している場合は、そちらも直します。
4. 条件の書き方が合っているか
条件が本当に当てはまっているかは、除外したい行の数を数えると確かめられます。たとえば自宅のIPv6アドレスなら、次のようにします。
# ログ全体のうち、自宅のIPv6アドレスの行の数
sudo zcat -f /var/log/httpd/access_log* | grep -c -E '^2001:db8:1234:5678:'
# 除外したあとに残っている、自宅のIPv6アドレスの行の数(0になるはず)
sudo zcat -f /var/log/httpd/access_log* \
| grep -v -E '/wp-admin/|/wp-login\.php|^2001:db8:1234:5678:|^203\.0\.113\.10 |[0-9a-f]{32}\.txt|/wp-cron\.php' \
| grep -c -E '^2001:db8:1234:5678:'1つ目が0なら、条件のアドレスがログと合っていません(ログのIPアドレスが 127.0.0.1 のままなら、mod_remoteip の設定を確かめます)。2つ目が0より大きいなら、除外の条件の書き方が間違っています。
5. GoAccessが前の集計を引き継いでいないか
GoAccessは、初期設定では毎回ゼロから集計して、レポートを上書きします。ただし、設定で集計結果を保存して次回に引き継ぐ機能(persist と restore)を有効にしていると、前の集計が残ります。次のコマンドで何も表示されなければ、引き継ぎは使っていません。
grep -nE '^(persist|restore|db-path)' /etc/goaccess/goaccess.confログを消して作り直す必要はない
レポートをきれいにしたいときに、Apacheのアクセスログを空にする方法を見かけることがありますが、おすすめしません。このスクリプトは毎回ログを読み直してレポートを作るので、条件を直せば次の実行で反映されます。ログを消すと、怪しいアクセスをあとから調べる手がかりもなくなります。
まとめ
- レポートからは、管理画面・ログイン画面・自宅のIPアドレス・ランダムな .txt・WordPressの定期処理を除外している
- 自宅のIPアドレスで除外するには、先に mod_remoteip でログに読者のIPアドレスを残す必要がある
- 自宅のIPアドレスは行頭(
^)で比べる。IPv4は最後に空白を入れる - 消えないときは、スクリプトが動いているか、ブラウザの古い表示、自宅のIPアドレスの変化、条件の書き方、集計の引き継ぎの順に確かめる
- ログを消して作り直す必要はない



コメント