ksaitoの日記

日々試したことの覚え書き

大量のログを分析する

特定の時間帯で障害が起こった時に、該当時間帯のログを見る必要があります。
ディタでも開くことができないくらい大きいログファイルというケースも多々あります。
大量のログから特定の時間だけを取り出す方法です。

日付や時間帯で切り出す

awkで日付や時間を指定して特定の日付、時間、分でログを切り出せます。
ポイントは、タイムスタンプの区切り位置と日付をパターンで指定することと、[]や/といった文字をエスケープすることです。
下記は、2011/12/4 6:38台のログを抽出した結果です。

$ zcat access.log.52.gz | awk '$4 ~ /\[04\/Dec\/2011:06:38/ { print }'
127.0.0.1 - - [04/Dec/2011:06:38:11 +0900] "GET /server-status HTTP/1.1" 200 5069 "-" "-"
127.0.0.1 - - [04/Dec/2011:06:38:11 +0900] "GET /server-status HTTP/1.1" 200 5065 "-" "-"
127.0.0.1 - - [04/Dec/2011:06:38:11 +0900] "GET /server-status HTTP/1.1" 200 5065 "-" "-"
127.0.0.1 - - [04/Dec/2011:06:38:11 +0900] "GET /server-status HTTP/1.1" 200 5059 "-" "-"
127.0.0.1 - - [04/Dec/2011:06:38:11 +0900] "GET /server-status HTTP/1.1" 200 5059 "-" "-"
127.0.0.1 - - [04/Dec/2011:06:38:11 +0900] "GET /server-status HTTP/1.1" 200 5055 "-" "-"
127.0.0.1 - - [04/Dec/2011:06:38:11 +0900] "GET /server-status HTTP/1.1" 200 5055 "-" "-"
127.0.0.1 - - [04/Dec/2011:06:38:11 +0900] "GET /server-status HTTP/1.1" 200 5057 "-" "-"
127.0.0.1 - - [04/Dec/2011:06:38:11 +0900] "GET /server-status HTTP/1.1" 200 5055 "-" "-"
127.0.0.1 - - [04/Dec/2011:06:38:11 +0900] "GET /server-status HTTP/1.1" 200 5035 "-" "-"
$

タイムスタンプがないログも取り出す

Apacheアクセスログのように1行単位でタイムスタンプが付いている行儀の良いログであれば良いのですがログが複数行で、先頭の行にしかタイムスタンプがないログもあります。
タイムスタンプでログの行番号を絞って取り出します。
ポイントは、cat -nで行番号に連番を付与して行数を特定することです。
例えば、2011/12/4 7時台のログを取り出したい場合、最初に7時のログの開始位置を調べます。

$ zcat access.log.52.gz | cat -n | awk '$5 ~ /\[04\/Dec\/2011:07/ { print }' | head -1
   130  127.0.0.1 - - [04/Dec/2011:07:00:11 +0900] "GET /server-status HTTP/1.1" 200 5030 "-" "-"
$ 

次に終わりの位置を調べます。

$ zcat access.log.52.gz | cat -n | awk '$5 ~ /\[04\/Dec\/2011:07/ { print }' | tail -1
   551  192.168.2.100 - - [04/Dec/2011:07:59:32 +0900] "GET /zabbix/config.php HTTP/1.1" 200 14352 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)"
$ 

130行目から551行目までを取り出します。

$ zcat access.log.52.gz | cat -n | head -n 551 | tail -n +130 | wc -l
422
$