nginxの一般的なaccess.logファイル
000.00.000.001 - - [28/Jun/2021:06:37:02 +0100] "POST /abc/cba/ HTTP/1.1" 429 1157 "data..."
000.00.000.002 - - [28/Jun/2021:06:37:02 +0100] "POST /abc/cba/ HTTP/1.1" 200 741 "-" "data..."
000.00.000.001 - - [28/Jun/2021:06:37:02 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
000.00.000.001 - - [28/Jun/2021:06:37:02 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
000.00.000.001 - - [28/Jun/2021:06:37:02 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
000.00.000.001 - - [28/Jun/2021:06:37:02 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
000.00.000.003 - - [28/Jun/2021:06:37:03 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
000.00.000.003 - - [28/Jun/2021:06:37:03 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
000.00.000.003 - - [28/Jun/2021:06:37:03 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
000.00.000.003 - - [28/Jun/2021:06:37:03 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
000.00.000.003 - - [28/Jun/2021:06:37:03 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
000.00.000.004 - - [28/Jun/2021:06:37:03 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
000.00.000.004 - - [28/Jun/2021:06:37:03 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
000.00.000.004 - - [28/Jun/2021:06:37:03 +0100] "POST /abc/cba/ HTTP/1.1" 429 741 "-" "data..."
問題は、応答コードが429で、いつでも1秒以内に生成されるすべてのIPアドレスをログファイルからどのように取得できるかということです。私はawkを使って解決策を見つけようとしていますが、誰かが私にヒントを与えることができれば、まだ成功していません。与えられた例の出力は次のとおりです。
28/Jun/2021:06:37:02:
000.00.000.001
28/Jun/2021:06:37:03:
000.00.000.003
- 5つ以上の要求を持つIPのみ
- 応答状態429があります
- 特定の秒以外の時間に表示される応答がある場合は、秒単位でグループ化
答え1
これはあなたがしたいことですか?
$ awk -F'[[ ]+' '$9==429{print $4, $1}' file | uniq -c | awk '$1>4{print $2 ":\n" $3}'
28/Jun/2021:06:37:02:
000.00.000.001
28/Jun/2021:06:37:03:
000.00.000.003
たとえば、最初の引用符セットの内容が、例の入力など、"POST /abc/cba/ HTTP/1.1"
常に3つのスペースで区切られた文字列で構成されていない場合は、次のように調整します。
$ awk -F'[[ ]+' '{sub(/"[^"]*"/,"")} $6==429{print $4, $1}' file | uniq -c | awk '$1>4{print $2 ":\n" $3}'
28/Jun/2021:06:37:02:
000.00.000.001
28/Jun/2021:06:37:03:
000.00.000.003
何らかの理由でawk専用ソリューションを好む場合:
$ awk -F'[[ ]+' '$9==429{cnt[$4":\n"$1]++} END{for (key in cnt) if (cnt[key]>4) print key}' file
28/Jun/2021:06:37:02:
000.00.000.001
28/Jun/2021:06:37:03:
000.00.000.003
上記のすべてのスクリプトは、すべてのUnixシステムのすべてのシェルで必須のPOSIXツールを使用して簡単に機能します。