2017年8月17日木曜日

簡単なコマンドでのApacheアクセス解析


ツールや仕組みを入れるほどじゃないけど、
Apacheのアクセスログ解析をちょろっとやるときのコマンドメモ。



前提のログフォーマット
"%h [%{X-Forwarded-For}i] %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D"
※ユーザーアクセスがNATされる環境で実施しているため「X-Forwarded-For」ヘッダーを見ています。
不要な場合は読み替える。
※末尾に%Dで応答マイクロ秒が出力されるようにしている。

アクセス数と平均応答時間、ステータスコード毎のアクセス数


1日のログを1時間毎にPV数、ステータスコード毎のPV数、アクセスの平均応答秒を集計。
#!/bin/bash
EXCLUDE_URL01=".css\|.jpg\|.js\|.gif\|.png\|.ico\|HTTP/1.1\" 30\|HTTP/1.1\" 40\|HTTP/1.1\" 50"
EXCLUDE_URL02=".css\|.jpg\|.js\|.gif\|.png\|.ico"

echo "-DATE- -PV- -300- -400- -500- -平均応答時間[ms]-"
COUNT=0
MAX_COUNT=10
while [ $COUNT -lt $MAX_COUNT ]
do
COUNT_PV=$(grep "$DATE_YEAR:0$COUNT:" "$APACHE_LOG" |grep -vc "$EXCLUDE_URL01")
COUNT_300=$(grep "$DATE_YEAR:0$COUNT:" "$APACHE_LOG" |grep -v "$EXCLUDE_URL02" |grep -c "HTTP/1.1\" 30")
COUNT_400=$(grep "$DATE_YEAR:0$COUNT:" "$APACHE_LOG" |grep -v "$EXCLUDE_URL02" |grep -c "HTTP/1.1\" 40")
COUNT_500=$(grep "$DATE_YEAR:0$COUNT:" "$APACHE_LOG" |grep -v "$EXCLUDE_URL02" |grep -c "HTTP/1.1\" 50")
AVARAGE_SPEED=$(grep "$DATE_YEAR:0$COUNT:" "$APACHE_LOG" |awk '{m+=$NF} END{print m/'"$COUNT_PV"'}')

echo "$DATE_DAY:0$COUNT $COUNT_PV $COUNT_300 $COUNT_400 $COUNT_500 $AVARAGE_SPEED"

COUNT=$(( COUNT + 1 ))
done

COUNT=10
MAX_COUNT=24
while [ $COUNT -lt $MAX_COUNT ]
do
COUNT_PV=$(grep "$DATE_YEAR:$COUNT:" "$APACHE_LOG" |grep -vc "$EXCLUDE_URL01")
COUNT_300=$(grep "$DATE_YEAR:$COUNT:" "$APACHE_LOG" |grep -v "$EXCLUDE_URL02" |grep -c "HTTP/1.1\" 30")
COUNT_400=$(grep "$DATE_YEAR:$COUNT:" "$APACHE_LOG" |grep -v "$EXCLUDE_URL02" |grep -c "HTTP/1.1\" 40")
COUNT_500=$(grep "$DATE_YEAR:$COUNT:" "$APACHE_LOG" |grep -v "$EXCLUDE_URL02" |grep -c "HTTP/1.1\" 50")
AVARAGE_SPEED=$(grep "$DATE_YEAR:$COUNT:" "$APACHE_LOG" |awk '{m+=$NF} END{print m/'"$COUNT_PV"'}')

echo "$DATE_DAY:$COUNT $COUNT_PV $COUNT_300 $COUNT_400 $COUNT_500 $AVARAGE_SPEED"

COUNT=$(( COUNT + 1 ))
done

アクセスIPの統計情報


アクセスログのクライアントIPを集計してTOP10を表示。可能なら逆引きもする。
#!/bin/bash
EXCLUDE_URL01=".css\|.jpg\|.js\|.gif\|.png\|.ico\|HTTP/1.1\" 30\|HTTP/1.1\" 40\|HTTP/1.1\" 50"
EXCLUDE_URL02=".css\|.jpg\|.js\|.gif\|.png\|.ico"

COUNT_IP=$(grep -v "$EXCLUDE_URL02" "$APACHE_LOG" |awk '{print $1}' |sort |uniq -c |sort -nr |head -n"$COUNT_TOP")
{
echo "-count- -FromIP- -PTR-"
echo "$COUNT_IP" | while read -r line
do
FROM_COUNT=$(echo "$line" |awk '{print $1}')
FROM_IP=$(echo "$line" |awk '{print $2}')
LOOCKUP_IP=$(nslookup "$FROM_IP" |awk '/name \=/{ print $NF}'|head -n1 )
echo "$FROM_COUNT $FROM_IP $LOOCKUP_IP"
done
※クライアントIPをX-Forwarded-Forヘッダーから取得しているため、多少不恰好。

アクセスの多いURLを集計


アクセスの多いURL TOP10を集計。エラーアクセスを除く。
#!/bin/bash
EXCLUDE_URL01=".css\|.jpg\|.js\|.gif\|.png\|.ico\|HTTP/1.1\" 30\|HTTP/1.1\" 40\|HTTP/1.1\" 50"
EXCLUDE_URL02=".css\|.jpg\|.js\|.gif\|.png\|.ico"

grep -v "$EXCLUDE_URL01" "$APACHE_LOG" |awk '{print $7}' |sort |uniq -c |sort -nr |head -n"$COUNT_TOP"

遅延URLの集計


応答時間が遅いURL TOP10を集計。
#!/bin/bash
awk '{print $NF,$1,$4,$7}' "$APACHE_LOG" |sort -nr |head -n"$COUNT_TOP"

クライアントUserAgentを集計


クライアントUserAgent Top10を集計。エラー含まない。
#!/bin/bash
#!/bin/bash
EXCLUDE_URL01=".css\|.jpg\|.js\|.gif\|.png\|.ico\|HTTP/1.1\" 30\|HTTP/1.1\" 40\|HTTP/1.1\" 50"
EXCLUDE_URL02=".css\|.jpg\|.js\|.gif\|.png\|.ico"

grep -v "$EXCLUDE_URL01" "$APACHE_LOG" |awk -F\" '{print $6}' |sort |uniq -c |sort -nr |head -n"$COUNT_TOP"

なぜシェルでやってるかって?それしか出来ないからさ!

0 コメント:

コメントを投稿