メモ > サーバ > 各論: コマンド > Apacheのログをコマンドで解析
Apacheのログをコマンドで解析
※可能なら、最初からcatではなくgrepを使う方が高速。計測方法は「コマンドの実行時間を表示」を参照。
※SSL経由のアクセスの場合、ログは /var/log/httpd/ssl_access_log に記録されるので注意。
※コマンド以外だと、例えば以下のようなソフトがある。
ApacheLogViewerソフトでログからアクセス解析 [DokuWikiで情報発信]
https://dokuwiki.oreda.net/access/apachelogviewer.html
sedでこういう時はどう書く? - Qiita
https://qiita.com/hirohiro77/items/7fe2f68781c41777e507
■各項目の参照(cut版とsed版)
IPアドレス。
# cat /var/log/httpd/access_log | cut -d ' ' -f 1
# cat /var/log/httpd/access_log | sed 's/ .*$//'
日時。
# cat /var/log/httpd/access_log | cut -d '[' -f 2 | cut -d ']' -f 1
# cat /var/log/httpd/access_log | sed 's/^.*\[\([^]]*\)\].*/\1/'
リクエスト。
# cat /var/log/httpd/access_log | cut -d ' ' -f 7
# cat /var/log/httpd/access_log | sed 's/^[^"]*"\([^"]*\)".*/\1/'
リファラー。
# cat /var/log/httpd/access_log | cut -d '"' -f 4
# cat /var/log/httpd/access_log | sed 's/.*"\([^"]*\)" .*$/\1/'
User Agent。
# cat /var/log/httpd/access_log | cut -d '"' -f 6
# cat /var/log/httpd/access_log | sed 's/.*"\([^"]*\)"$/\1/'
■変換
日時を時間に変換。
# cat /var/log/httpd/access_log | cut -d '[' -f 2 | cut -d ']' -f 1 | awk -F : '{print $2":"$3}'
■ソート
※IPアドレスを例に紹介。他の項目の場合も手順は同じ。
IPアドレス一覧。
# cat /var/log/httpd/access_log | cut -d ' ' -f 1
ソート。
# cat /var/log/httpd/access_log | cut -d ' ' -f 1 | sort
重複を除外して件数を表示。(重複を除外する前にソートが必要。)
# cat /var/log/httpd/access_log | cut -d ' ' -f 1 | sort | uniq -c
件数の降順にソート。
# cat /var/log/httpd/access_log | cut -d ' ' -f 1 | sort | uniq -c | sort -nr
上位10件。
# cat /var/log/httpd/access_log | cut -d ' ' -f 1 | sort | uniq -c | sort -nr | head -n 10
■除外
CSSや画像などへのアクセスを除外。
# cat /var/log/httpd/access_log | egrep -iv '(.css|.js|.gif|.jpeg|.jpg|.jpe|.png|.ico|.swf)'
さらにbotからのアクセスを除外。
# cat /var/log/httpd/access_log | egrep -iv '(.css|.js|.gif|.jpeg|.jpg|.jpe|.png|.ico|.swf|clawler|Googlebot|googlebot|DotBot|Slurp|msnbot|robots|spider|Wget|ScoutJet|mlbot)'
以下は旧版。grepよりもegrepの方が読みやすい。
# cat /var/log/httpd/access_log | grep -ive "\(\.css\|\.js\|\.gif\|\.jpeg\|\.jpg\|\.jpe\|\.png\|\.ico\|\.swf\)"
# cat /var/log/httpd/access_log | grep -ive "\(\.css\|\.js\|\.gif\|\.jpeg\|\.jpg\|\.jpe\|\.png\|\.ico\|\.swf\|clawler\|Googlebot\|googlebot\|DotBot\|Slurp\|msnbot\|robots\|spider\|Wget\|ScoutJet\|mlbot\)"
■絞り込み
特定ユーザの特定のアクセス。
# cat /var/log/httpd/access_log | grep '203.0.113.1' | grep '/mypage/profile'
2016年2月10日のみ。
# cat /var/log/httpd/access_log | grep '10/Feb/2016'
2016年2月10日15時のみ。
# cat /var/log/httpd/access_log | grep '10/Feb/2016:15'
2016年2月10日15時20〜29分のみ。
# cat /var/log/httpd/access_log | grep '10/Feb/2016:15:2'
2016年2月10日15時台の、リクエストが多かったページ上位10件。
# cat /var/log/httpd/access_log | grep '10/Feb/2016:15' | cut -d ' ' -f 7 | sort | uniq -c | sort -nr | head -n 10
直近の10件のみ。
# tail -n 10 /var/log/httpd/access_log
直近の1000件の、リクエストが多かったページ上位10件。
# tail -n 1000 /var/log/httpd/access_log | cut -d ' ' -f 7 | sort | uniq -c | sort -nr | head -n 10
MP4とPDFへのアクセスのみ。
# grep '01/Aug/2022:15' access_log | grep mp4
# grep '01/Aug/2022:15' access_log | grep pdf
# cat /var/log/httpd/access_log | egrep -i '(.mp4)'
# cat /var/log/httpd/access_log | egrep -i '(.pdf)'
# grep '01/Aug/2022:15' access_log | egrep -i '(.mp4|.pdf)'
巨大ファイル(10MB以上の重いファイル)へのアクセスのみ。
# cat /var/log/httpd/access_log | awk '($10 >= 10000000) {print $0}'
ファイル名を表示。
# cat /var/log/httpd/access_log | awk '($10 >= 10000000) {print $7}'
ファイルサイズとファイル名を表示。
# cat /var/log/httpd/access_log | awk '($10 >= 10000000) {print int($10/1024/1024)"MB:"$7}' | uniq | sort -nr
特定日時で絞り込んで巨大ファイルへのアクセスを確認。(「$(NF-2)」は「末尾から数えて3番目」の値。末尾は0なので単に「$NF」と書く。)
# cat /var/log/httpd/access_log | grep '27/Jun/2019:09:1[2-6]' | awk '($(NF-2) >= 10000000) {print $0}'
エラーのみ。
# cat /var/log/httpd/access_log | awk '($9 >= 400 || $7 >= 400) {print $0}'
エラーの比率。
# cat /var/log/httpd/access_log | awk '($9 < 400) {ok++} ($9 >= 400 || $7 >= 400) {ng++} END {print ng/(ok+ng)*100}'
■レスポンスタイム解析
以下のように、ログフォーマットに「%D」が記載されているものとする。(レスポンスタイムがマイクロ秒で記録される。)
LogFormat "%h %l %u %t \"%!414r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" combined
※末尾のデータは「$NF」で参照できるが、例えば末尾からn番目の場合は「$(NF-n)」で参照できる。
※1秒 = 1,000ミリ秒 = 1,000,000マイクロ秒。
レスポンスタイムを参照。
# cat /var/log/httpd/access_log | awk '{print $NF}'
1秒以上かかったレスポンス数。
# cat /var/log/httpd/access_log | awk '$NF > 1000000 {print $NF/1000, $7}' | wc -l
レスポンスの遅かったリクエストトップ10。
# cat /var/log/httpd/access_log | awk '{print $NF/1000, $7}' | sort -nr | head -n 10
平均レスポンスタイム(ミリ秒)。
# cat /var/log/httpd/access_log | awk '{sum += $NF; count++}; END{print (sum/count)/1000}'
2016年11月5日15時台の、平均レスポンスタイム(ミリ秒)。
# cat /var/log/httpd/access_log | grep '05/Nov/2016:15' | awk '{sum += $NF; count++}; END{print (sum/count)/1000}'
※例えば以下の形式(末尾から2つ目がレスポンスタイム)で記録されている場合、
LogFormat "%h %l %u %t \"%!414r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D %{X-Forwarded-For}i %{X-Forwarded-Proto}i" combined
以下のように $(NF-2) と指定すれば解析できる。
# cat /var/log/httpd/access_log | awk '{print $(NF-2)/1000, $7}' | sort -nr | head -n 10
# cat /var/log/httpd/access_log | awk '{sum += $(NF-2); count++}; END{print (sum/count)/1000}'
# cat /var/log/httpd/access_log | grep '05/Nov/2016:15' | awk '{sum += $(NF-2); count++}; END{print (sum/count)/1000}'
■5分以内のApacheログを表示
※月をまたぐと、余計なデータが表示されてしまう。
あらかじめ日でgrepしておくか。高速化にもなるかも。要検証。
grep '01/Jun/2018' /var/log/nginx/access.log | awk -F'\\[|\\]' '"01/Jun/2018:01:00:00" < $2'
# date … 現在の日時を表示。
# date "+%Y-%m-%d %H:%M:%S" … フォーマットして表示。(「+」に続けてフォーマットを指定。)
# LC_ALL=C date "+%d/%b/%Y:%H:%M:%S" … 日本語環境でも英語表記で表示。
# LC_ALL=C date -d '5 minutes ago' "+%d/%b/%Y:%H:%M:%S" … 5分前の日時を英語表記で表示。
# tail -n 10 /var/log/httpd/access_log | awk -F'\\[|\\]' '{ print $2 }' … Apacheログの日時を取得。
# tail -n 10 /var/log/nginx/access.log | awk -F'\\[|\\]' '{ print $2 }' … nginxログの日時を取得。
# awk -F'\\[|\\]' '"31/May/2018:19:30:00" < $2' /var/log/httpd/access_log … 特定日時以降のApacheログを表示。
# awk -F'\\[|\\]' '"31/May/2018:19:30:00" < $2' /var/log/nginx/access.log … 特定日時以降のnginxログを表示。
$ vi get_access_log.sh … 5分以内のログを表示。
■メモ
あなたはだんだん、ファイルを読むのにlessコマンドを使いたくなる
http://qiita.com/marrontan619/items/95e954972706f32be255
Apache ログを awk と uniq だけで集計する
https://qiita.com/bezeklik/items/f5c292c4360cde140bef
アクセスログからピーク時の分間hit数を割り出す
https://hacknote.jp/archives/11938/
Apacheのログからエラーアクセスだけ抽出
http://hole.sugutsukaeru.jp/archives/625
Apacheのレスポンス分析に必要なスクリプトまとめ
http://koduki.hatenablog.com/entry/2012/11/24/171534
Apacheのログから応答速度分布やエラー状況を分析する(原始的な方法)
http://www.teradas.net/archives/5298/
突然のTwitter砲にもなんとか耐えたさくらVPSに感謝する
https://blog.riywo.com/2011/02/07/162154/
awkで末尾から数えてn番目のフィールドを取り出す。
http://qiita.com/koitatu3/items/3d746c7e292908c6167e
ログ分析に使えるLinuxコマンド6選 - Qiita
https://qiita.com/moneymog/items/16d2f843c344a5ace51a
grepでAND検索とOR検索 #UNIX - Qiita
https://qiita.com/ritukiii/items/968f17f9c308743e85a7
date コマンド | コマンドの使い方(Linux) | hydroculのメモ
https://hydrocul.github.io/wiki/commands/date.html
"date" 日付・時刻の表示 @LCD -Linux Command Dictionary-|Replog!株式会社レップワンスタッフによるブログです
http://www.rep1.co.jp/staff/200vcxg/217rav/date_lcd_-linux_command_dictio_2.htm
特別なコマンド無しで「◯◯時からXX時までの間のログを抽出」というように、時間指定でログを抽出させる方法(awk,sed)
https://orebibou.com/2015/04/%E7%89%B9%E5%88%A5%E3%81%AA%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E7%84%A...
awkへシェルスクリプトの変数を渡す - Qiita
https://qiita.com/yamao2253/items/cf69b68447214036e914
俺の愛用ワンライナー、Web企業のエンジニア16人に聞きました - エンジニアHub|若手Webエンジニアのキャリアを考える!
https://employment.en-japan.com/engineerhub/entry/2018/05/08/110000
■Apacheのログをツールで解析
【Apache】アクセスログ解析ソフトの一覧
http://matome.naver.jp/odai/2142278136708605501
便利ツール(9)アクセスログ解析ソフト「ApacheLogViewer」
http://win.kororo.jp/weblog/2006/08/17/post_0808.php
「生ログ」を解析してみよう!
http://jugemstaff.jugem.jp/?eid=25#!/bin/bash
# 5分前の日時を取得
datetime=`LC_ALL=C date -d '5 minutes ago' "+%d/%b/%Y:%H:%M:%S"`
# 5分以内のApacheログを表示
awk -F'\\[|\\]' '"'"${datetime}"'" < $2' /var/log/httpd/access_log
# 5分以内のnginxログを表示
#awk -F'\\[|\\]' '"'"${datetime}"'" < $2' /var/log/nginx/access.log