はじめに
業務でnginx等のログを分析する必要があり、その際に使用したawkコマンドのまとめ
オプション
-F:区切り文字の指定
-F" " //スペース区切り
-F"\t" //タブ区切り
-F"," //カンマ区切り
一般的なユースケース
ログのn列目を出力する
nには実施は$14のように数値を入れる。
awk -F" " '{print $n}' access.log
eg.スペース区切りのログの14列目を出力する
awk -F" " '{print $14}' access.log
特定の条件を満たす場合のみ出力する
awk -F" " '{if(条件式) print 出力内容}' access.log
eg.14列目の数値の大きさが0.2を越える時のみ、その列を出力する
awk -F" " '{if($14>0.2) print $14 }' access.log
各行の先頭にカウントを付けて出力する
$0は全列表示
awk -F" " '{count++;print count " " $0 }' access.log
出力の最後に行数を出力する
awk -F" " '{count++} END{ print count }' access.log
特定の日時範囲のログを出力する
awk -F" " '{
date = $日付情報を持つ列の番号
if ( date >= $開始時刻 && date <= $終了時刻) {
print $0
}
}' access.log
- ログ上で日付と時刻が別の列に出力されている場合
awk -F" " '{
date = $日付の列番号" "$時刻の列番号
if ( date >= $開始時刻 && date <= $終了時刻) {
print $0
}
}' access.log
- 時刻にミリ秒が含まれるがHH: mm:ssにしたい時(例 14:09:23,187)
awk -F" " '{
split($時刻の列番号, arr, ",") #時刻を指定した区切り文字で分割して配列arrに格納する
date = $日付の列番号" "arr[1]
if ( date >= $開始時刻 && date <= $終了時刻) {
print $0
}
}' access.log
eg.YYYY-MM-DD HH: mm:ss形式で日付範囲を指定した時
awk -F" " '{
split($2, arr, ",")
date = $1" "arr[1]
if ( date >= "2021-09-03 14:09:00" && date <= "2021-09-04 00:00:00") {
print $0
}
}' sample.log
nginx特化のユースケース
アクセスログのrequest_timeが特定の値を越えている時のみ、行数カウント付きでtailして出力する.(今回は200ms)
※nginx.confで設定されている出力項目の数によってrequest_timeが何列目になるかは変わるので注意。自分の場合は14列目
request_timeは秒単位で出力されるため、200msは0.2。
$4は今回は日付列を指定している。
tail -F /var2/log/nginx/access.log | awk -F" " '{if($14>0.2) {count++;print count " " $4 " " $14 "s"}} END { print count }'