シンプルなレポートの作成
最後のタスクとして、ログファイルから重要な情報を要約したシンプルな HTML レポートを作成しましょう。この複雑な操作のために、別のファイルに保存された AWK スクリプトを使用します。
このステップでは、これまでのセクションで学んだいくつかの AWK のアイデアを組み合わせます。
total++ のようなカウンター
ip_count[$3]++ のような配列
- 最終的な要約を出力する
END ブロック
スクリプトが長く見えるかもしれませんが、一度に 1 つのブロックに集中してください。実行する前にファイル全体を暗記する必要はありません。
まず、以下の内容で log_report.awk という名前のファイルを作成します。
ヒント:以下の内容をコピーしてターミナルに貼り付け、ファイルを作成してください。
cat << 'EOF' > log_report.awk
BEGIN {
print "<html><body>"
print "<h1>Server Log Summary</h1>"
total = 0
errors = 0
}
{
total++
if ($6 >= 400) errors++
ip_count[$3]++
resource_count[$5]++
}
END {
print "<p>Total requests: " total "</p>"
print "<p>Error rate: " (errors/total) * 100 "%</p>"
print "<h2>Top 5 IP Addresses</h2>"
print "<ul>"
for (ip in ip_count) {
top_ips[ip] = ip_count[ip]
}
n = asort(top_ips, sorted_ips, "@val_num_desc")
for (i = 1; i <= 5 && i <= n; i++) {
for (ip in ip_count) {
if (ip_count[ip] == sorted_ips[i]) {
print "<li>" ip ": " ip_count[ip] " requests</li>"
break
}
}
}
print "</ul>"
print "<h2>Top 5 Requested Resources</h2>"
print "<ul>"
for (resource in resource_count) {
top_resources[resource] = resource_count[resource]
}
n = asort(top_resources, sorted_resources, "@val_num_desc")
for (i = 1; i <= 5 && i <= n; i++) {
for (resource in resource_count) {
if (resource_count[resource] == sorted_resources[i]) {
print "<li>" resource ": " resource_count[resource] " requests</li>"
break
}
}
}
print "</ul>"
print "</body></html>"
}
EOF
この AWK スクリプトをセクションごとに理解しましょう。
-
BEGIN ブロック: 入力行を処理する前に実行されます。
BEGIN {
print "<html><body>" ## HTML 構造の開始
print "<h1>Server Log Summary</h1>"
total = 0 ## 合計リクエスト数のカウンターを初期化
errors = 0 ## エラーリクエスト数のカウンターを初期化
}
-
メイン処理ブロック: 入力ファイルの各行に対して実行されます。
{
total++ ## 合計リクエストカウンターをインクリメント
if ($6 >= 400) errors++ ## エラーレスポンスをカウント(ステータスコード 400 以上)
ip_count[$3]++ ## IP アドレスごとのリクエストをカウント(フィールド 3)
resource_count[$5]++ ## リソースごとのリクエストをカウント(フィールド 5)
}
-
END ブロック: すべての入力行を処理した後に実行されます。
END {
## 要約統計を出力
print "<p>Total requests: " total "</p>"
print "<p>Error rate: " (errors/total) * 100 "%</p>"
## 上位5つのIPアドレスを処理して出力
## ...
## 上位5つのリクエストリソースを処理して出力
## ...
print "</body></html>" ## HTML構造の終了
}
次に進む前に、全体的な流れを確認してください。
BEGIN が HTML の開始タグを出力し、カウンターを初期化します。
- 中間のブロックが各ログ行を処理し、合計を更新します。
END がすべての行を分析した後、最終レポートを出力します。
上位 IP のソートロジックを確認しましょう(リソースセクションも同様に機能します)。
## ソートのためにカウントを新しい配列にコピー
for (ip in ip_count) {
top_ips[ip] = ip_count[ip]
}
## 値に基づいて降順で配列をソート
n = asort(top_ips, sorted_ips, "@val_num_desc")
## 上位5つのエントリを出力
for (i = 1; i <= 5 && i <= n; i++) {
## このカウントに一致する元のIPを見つける
for (ip in ip_count) {
if (ip_count[ip] == sorted_ips[i]) {
print "<li>" ip ": " ip_count[ip] " requests</li>"
break
}
}
}
このスクリプトでは:
asort() 関数が配列をソートします。
"@val_num_desc" は、値を数値として降順でソートするように指示する特別な引数です。
- ネストされたループが上位 5 つのエントリを見つけて出力します。
ネストされたループは次のように考えることができます。
- 最初のループが、どのカウントが上位 5 つに入るかを決定します。
- 2 番目のループが、どの IP アドレスまたはリソースがそのカウントを生み出したかを見つけます。
この検索パターンはこれまでのステップよりも高度なため、ここが実験の中で初めて「スクリプトを書いている」と感じる部分であっても正常です。
それでは、AWK スクリプトを実行してレポートを生成しましょう。
awk -f log_report.awk server_logs.txt > log_report.html
-f オプションは、指定されたファイルからスクリプトを読み込むように AWK に指示します。
-f log_report.awk - log_report.awk ファイルから AWK スクリプトを読み込みます。
server_logs.txt - このファイルをスクリプトを使用して処理します。
> log_report.html - 出力を log_report.html ファイルにリダイレクトします。
cat コマンドを使用してレポートの内容を確認できます。
cat log_report.html
HTML 出力がターミナルで確認しにくい場合は、最初の部分だけをプレビューしてください。
head -n 15 log_report.html
このレポートは、合計リクエスト数、エラー率、上位 5 つの IP アドレス、上位 5 つのリクエストリソースの要約を提供します。実際のシナリオでは、この HTML ファイルを Web ブラウザで開いて整形されたビューを確認できます。
このスクリプトで使用したアプローチは、AWK がより複雑なデータ分析タスクにどのように使用できるかを示しています。このスクリプトを拡張して、特定のニーズに基づいて追加の統計や異なる視覚化を含めることができます。