Nginxのログをシェルスクリプトで解析・集計する方法です。
Nginxアクセスログ解析ワンライナー
Nginxのアクセスログから集計したい項目を抽出するワンライナーです。
以下のシェルスクリプトでアクセスログから、集計したい項目を抽出・集計して表示させることができます。
sudo zgrep -h "\[日/月" /var/log/nginx/access.log* | awk '($7 !~ /(除外対象1|除外対象2|除外対象3)/)' | awk '{print $集計したい項目番号 }' | sort | uniq -c | sort -rn | head -n 表示行数
集計する日付は「zgrep -h "\[日/月"」で指定することができ、以下が指定例となります。
- 月日を指定: zgrep -h "\[28/Mar"
- 月を指定: zgrep -h "\[*/Mar"
- 10日単位で指定: zgrep -h "\[1./Mar" # 10〜19日の指定例
- 複数日を指定: zgrep -h -E "\[01|02|03/Mar" # -Eオプションを追加し|で区切り指定
実行例
以下の項目についての集計例を記載していきます。
- アクセスされたページと回数
- アクセス元IPアドレスと回数
- 参照元URLと回数
集計したい項目番号は、ログ内のスペースを区切り文字として分解して集計したい項目が何番目にあるのかを指定します。
アクセスされたページと回数
アクセスされたページは7番目の項目に記載されているので、「awk '{print $7 }'」と指定することで、アクセスされたページと回数を集計することが出来ます。
$ sudo zgrep -h "\[28/Mar" /var/log/nginx/vpslife_access.log* | awk '($7 !~ /(jpg|woff|svg|png|css|js|gif|php|ico|ttf|txt)/)' | awk '{print $7 }' | sort | uniq -c | sort -rn | head -5 188 /feed/ 144 /package_uninstall/ 120 /ubuntu_reboot_shutdown/ 80 /apt-list-installed/ 58 /ubuntu_deluser_userdel/
アクセス元IPアドレスと回数
アクセス元(クライアント)のIPアドレスは、1番目の項目に記載されているので、「awk '{print $1 }'」と指定することで、アクセス元(クライアント)のIPアドレスとアクセス数を集計することが出来ます。
$ sudo zgrep -h "\[28/Mar" /var/log/nginx/vpslife_access.log* | awk '($7 !~ /(jpg|woff|svg|png|css|js|gif|php|ico|ttf|txt)/)' | awk '{print $1 }' | sort | uniq -c | sort -rn | head -5 218 xxx.xxx.xxx.205 92 xxx.xxx.xxx.26 79 xxx.xxx.xxx.25 44 xxx.xxx.xxx.177 42 xxx.xxx.xxx.171
※IPアドレスはマスクしています。
参照元URLと回数
参照元のURLと回数は、11番目の項目に記載されているので、「awk '{print $11 }'」と指定することで、参照元のURLと回数を集計することが出来ます。
$ sudo zgrep -h "\[28/Mar" /var/log/nginx/vpslife_access.log* | awk '($7 !~ /(jpg|woff|svg|png|css|js|gif|php|ico|ttf|txt)/)' | awk '{print $11 }' | sort | uniq -c | sort -rn | head -5 1218 "-" 769 "https://www.google.com/" 101 "https://www.bing.com/" 56 "https://vpslife.server-memo.net/dmarc-record_setting/" 47 "https://www.google.co.jp/"
Nginxのログについて説明
今回紹介したシェルクリプトは、Nginxのログフォーマット「main」で出力されるものを解析するためのものです。
Nginxのログフォーマット「main」で出力されるログは以下のよう設定されています。
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
実際のログの出力例を見てみましょう。
xxx.xxx.xxx.xxx - - [27/Mar/2025:20:58:21 +0900] "GET /ubuntu_munin_install/ HTTP/1.1" 200 423440 "https://www.google.com/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" "-"
※各項目に表示されている内容については、以下のページで説明を行っています。
https://vpslife.server-memo.net/nginx_access_log/
このログをawkコマンドでログを解析するので、区切り文字であるスペースごとに改行して分解してみます。
- xxx.xxx.xxx.xxx
- -
- -
- [27/Mar/2025:20:58:21
- +0900]
- "GET
- /ubuntu_munin_install/
- HTTP/1.1"
- 200
- 423440
- "https://www.google.com/"
- "Mozilla/5.0
- (X11;
- Linux x86_64)
- AppleWebKit/537.36
- (KHTML,
- like
- Gecko)
- Chrome/134.0.0.0
- Safari/537.36"
- "-"
ここから、集計したい項目を「awk '{print $集計したい項目番号 }'」の部分で指定します。
保存されているログにについて
私の環境では、以下のようにnginxのログは圧縮されてながらローテションしています。
圧縮されているログがあるため「zgrep」を使用して、圧縮されたログについても日付で検索出来るようにしています。
$ ls -lt /var/log/nginx/access.log* | head -n 5 -rw-r----- 1 nginx adm 748969 Mar 28 16:06 /var/log/nginx/access.log -rw-r----- 1 nginx adm 747435 Mar 27 23:55 /var/log/nginx/access.log.1 -rw-r----- 1 nginx adm 58125 Mar 27 00:00 /var/log/nginx/access.log.2.gz -rw-r----- 1 nginx adm 54426 Mar 26 00:00 /var/log/nginx/access.log.3.gz -rw-r----- 1 nginx adm 50631 Mar 25 00:00 /var/log/nginx/access.log.4.gz
シェルスクリプトの説明
シェルスクリプトについて説明します。
sudo zgrep -h "\[日/月" /var/log/nginx/access.log* | awk '($7 !~ /(除外対象1|除外対象2|除外対象3)/)' | awk '{print $集計したい項目番号 }' | sort | uniq -c | sort -rn | head -n 表示行数
zgrep -h "\[日/月" /var/log/nginx/access.log*
gzipで圧縮されたファイルも検索できる「zgrep」を使って集計する月日を検索し、-hオプションで検索した文字が含まれているログファイル名を非表示にしています。
awk '( !~ /(除外対象1|除外対象2|除外対象3)/)'
集計対象から除外したいファイルの拡張子を指定しています。
私は、以下の種類にファイルについては集計に必要ないので除外していますが、この部分はご自分の環境に合わせて適宜調整を行って下さい。
- jpg
- woff
- svg
- png
- css
- js
- gif
- php
- ico
- ttf
- txt
awk '{print $集計したい項目番号 }'
集計したい項目を指定しています。
私が良く使うのは以下の項目ですが、こちらも集計したい項目にあわせて適宜変更してください。
- アクセス元IPアドレスと回数 1番目
- アクセスされたページと回数 7番目
- 参照元URLと回数 11番目
sort
「awk '{print $集計したい項目番号 }'」で抽出した項目を並び替えます。
uniq -c
並べ替えられた項目で、重複しているものを1行にまとめて、重複している数を左側に表示します。
sort -rn
重複している数が多い順に並べ替えます。
head -n 表示行数
表示する行数を指定します。
コメント