Memo

メモ > サーバ > 各論: コマンド > 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分以内のログを表示
#!/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
■メモ あなたはだんだん、ファイルを読むのに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

Advertisement