はじめに
apacheログで「特定のURLパス」の「時間帯」ごとのレスポンス速度を集計する際に、シェルスクリプトのawkコマンドを使って、2列のgroup by集計が必要になったので、やり方を備忘録として残します。
結論
group byしたい2列を文字列結合して集計するだけ。
(※あとで更に修正しやすいように、集計後に再度列を分割して出力を推奨)
例
下記のようなログデータがあるとする。
20231218-112000 /users 2
20231218-113000 /categories 3
20231218-114000 /users 5
20231218-115000 /categories 1
20231218-121000 /categories 4
20231218-122000 /users 8
20231218-123000 /users 2
20231218-124000 /categories 7
※日時 URLパス レスポンス時間(秒)
※日時は20231218-112000 = 2023年12月18日11時20分00秒の意味
このデータをもとに、下記のような「各パス」の「時間帯」ごとの「平均レスポンス時間(秒)」を集計したい。
/categories 11 2 ※11時台は平均2秒のレスポンス時間
/categories 12 5.5
/users 11 3.5
/users 12 5
ステップ1
group byしたい2列を文字列結合して出力。
#!bin/zsh
cat apache.log |
awk '{print substr($1, 10, 2)$2, $3}' # $1:日時, $2:URLパス, $3:レスポンス時間(秒)
# ↓出力結果
11/users 2
11/categories 3
11/users 5
11/categories 1
12/categories 4
12/users 8
12/users 2
12/categories 7
awk '{print $1$2}'
と、カンマで区切らず書くことで、列を文字列結合できる。
上記例では、「時間帯」だけ必要だったので、substr($1, 10, 2)
で時間を抽出したうえで$2
(パス)と結合させている
ステップ2
ステップ1の出力をもとに集計する。
#!bin/zsh
cat apache.log |
awk '{print substr($1, 10, 2)$2, $3}' | # $1:日時, $2:URLパス, $3:レスポンス時間(秒)
awk '{count[$1]++; sum[$1]+=$2} END{for(i in count) print i, sum[i]/count[i]}' # $1:時間+URLパス, $2:レスポンス時間(秒)
# ↓出力結果
11/categories 2
12/users 5
12/categories 5.5
11/users 3.5
ステップ3
使いやすい&見やすいように、列を分割、列の並び順を整理し、行もソートする。
#!bin/zsh
cat apache.log |
awk '{print substr($1, 10, 2)$2, $3}' |
awk '{count[$1]++; sum[$1]+=$2} END{for(i in count) print i, sum[i]/count[i]}' |
awk '{print substr($1, 3), substr($1, 1, 2), $2}' |
sort -k1 -k2 # 1列目、2列目でソート
# ↓出力結果
/categories 11 2
/categories 12 5.5
/users 11 3.5
/users 12 5
完成🎉🎉🎉
ステップ4(おまけ)
スプレッドシートなどに貼り付けやすいように加工する。
#!bin/zsh
cat apache.log |
awk '{print substr($1, 10, 2)$2, $3}' |
awk '{count[$1]++; sum[$1]+=$2} END{for(i in count) print i, sum[i]/count[i]}' |
awk '{print substr($1, 3)"\t", substr($1, 1, 2)"\t", $2}' |
sort -k1 -k2 | tee >(pbcopy)
# ↓出力結果
/categories 11 2
/categories 12 5.5
/users 11 3.5
/users 12 5
"\t"
を挟んで、タブ区切りにする。
tee >(pbcopy)
で標準出力を確認しつつ、クリップボードにもコピー。
コピーされた内容をスプレッドシートにそのまま貼り付けると、表として綺麗に貼り付けできる(下図)
おわりに
awkコマンドを活用することで、テキストログから有用な情報を抽出できます。
是非活用してみてください!!