LFCS — Linux Foundation認定システム管理者
ログを加工して集計する
目標
自分で作ったログをgrep・sed・awk・cut・tr・sort・uniqで加工し、jqとyqで構造化されたデータから値を取り出します。
なぜ重要なのか
LFCSのテキスト処理の問題は、「正解の1行を知っているか」ではなく、フィールド単位で考えているかを見ています。行全体を正規表現で走査すると、バイト数の列の500のようなものまで引っかかります。そのため、ステータスコードは4番目のフィールドであるという構造を先に押さえ、その上にツールを載せる必要があります。集計も同じです。sort | uniq -c | sort -rnは定番の書き方ですが、なぜ先に1回並べ替える必要があるのか(uniqは隣接する重複だけを消す)を知らないと、状況が少し変わっただけで崩れます。最後の2つのステップは、最近の運用の現実です。設定の多くはJSONやYAMLで、値1つを取り出すためにPythonを起動する代わりに、jqとyqで済ませられる手が必要です。
ステップ
/root/lfcs-text/access.logを、下の12行のとおりに作成してください。フィールドは空白1つで区切り、<IP> <메서드> <경로> <상태코드> <바이트>の順です(プレースホルダーはIP以外は順に、メソッド、パス、ステータスコード、バイト数です)。
10.0.0.117 GET /api/users 200 512
10.0.0.118 POST /api/users 201 128
10.0.0.117 GET /api/orders 500 64
10.0.0.120 GET /healthz 200 12
10.0.0.117 GET /api/users 200 512
10.0.0.116 DELETE /api/users 403 96
10.0.0.118 GET /api/orders 500 64
10.0.0.117 POST /api/orders 201 256
10.0.0.120 GET /healthz 200 12
10.0.0.117 GET /api/users 404 32
10.0.0.115 GET /api/orders 200 1024
10.0.0.118 GET /healthz 200 12
- ステータスコードが5で始まる行だけを、元の順序のまま
/root/lfcs-text/errors.txtに入れてください。 - IPごとのバイト数の合計を、
/root/lfcs-text/bytes_by_ip.txtに<IP> <합계>の形式で、合計の降順に書いてください(プレースホルダーは順にIP、合計です)。 - 最も多く登場したIPを、
/root/lfcs-text/top_ip.txtに<횟수> <IP>の1行で書いてください(プレースホルダーは順に、回数、IPです)。 - 2番目のフィールド(HTTPメソッド)を取り出して小文字に変え、重複をなくしたあと、辞書順に並べ替えて、
/root/lfcs-text/methods.txtに書いてください。 access.logを/root/lfcs-text/access-v2.logにコピーしたあと、そのコピーで、パスの/api/を/v2/api/に変更してください。編集前の内容は/root/lfcs-text/access-v2.log.bakとして残っている必要があり、access.logの元のファイルはそのままである必要があります。/root/lfcs-text/services.jsonを下の内容で作成し、tierがbackendであるサービスのreplicasの合計を、/root/lfcs-text/jq_out.txtに数字1つで書いてください。
{
"cluster": "homelab",
"services": [
{"name": "api", "replicas": 3, "tier": "backend"},
{"name": "web", "replicas": 5, "tier": "frontend"},
{"name": "worker", "replicas": 2, "tier": "backend"}
]
}
/root/lfcs-text/deploy.yamlを下の内容で作成し、/root/lfcs-text/yq_out.txtに、replicas=<값>とimage=<값>の2行を書いてください(プレースホルダーは値です)。
apiVersion: apps/v1
kind: Deployment
metadata:
name: lfcs-web
namespace: lfcs
spec:
replicas: 4
template:
spec:
containers:
- name: web
image: nginx:1.27
参考
awkは、フィールドを$1、$2のように番号で指します。合計は連想配列に集めると、一度で終わります。sort -k2,2nrは、2番目のフィールドを数値基準の降順で並べ替えます。uniqは隣接する重複だけを処理します。必ず先に並べ替えてください。- よくある間違い: 置換対象にスラッシュが入る場合は、区切り文字を
#などに変えるほうが安全です。
分析するログファイルの作成
/root/lfcs-text/access.logを下の12行のとおりに作成してください。フィールドは空白1つで区切り、<IP> <메서드> <경로> <상태코드> <바이트>の順です(プレースホルダーはIP以外は順に、メソッド、パス、ステータスコード、バイト数です)。
指示文の12行をそのまま作成すればよいです。フィールドの区切りは空白1つで、行の順序もそのままである必要があり、そうでないと後のステップの結果が合いません。
5xxのレスポンスだけを抜き出す
ステータスコードが5で始まる行だけを、元の順序のまま/root/lfcs-text/errors.txtに入れてください。
ステータスコードは4番目のフィールドです。行全体から500を探すと、バイト数に500が入った行まで引っかかることがあるので、フィールドを指定して判断してください。
IPごとのバイト数の合計
IPごとのバイト数の合計を、/root/lfcs-text/bytes_by_ip.txtに<IP> <합계>の形式で、合計の降順に書いてください(プレースホルダーは順にIP、合計です)。
awkの連想配列にIPをキーとして置き、5番目のフィールドを足していけばよいです。最後に配列を巡回して出力し、数値基準の降順で並べ替えてください。
最も多く登場したIP
最も多く登場したIPを、/root/lfcs-text/top_ip.txtに<횟수> <IP>の1行で書いてください(プレースホルダーは順に、回数、IPです)。
重複を数えるには、まず並べ替える必要があります。個数を付けてくれるツールの出力は「個数 値」の順だという点を、そのまま活用してください。
メソッド一覧の正規化
2番目のフィールド(HTTPメソッド)を取り出して小文字に変え、重複をなくしたあと、辞書順に並べ替えて、/root/lfcs-text/methods.txtに書いてください。
フィールドを切り出すツールと、文字を変えるツールをつなぎます。重複の除去は、並べ替えツールのオプションでもできます。
元を守って置換する
access.logを/root/lfcs-text/access-v2.logにコピーしたあと、そのコピーで、パスの/api/を/v2/api/に変更してください。編集前の内容は/root/lfcs-text/access-v2.log.bakとして残っている必要があり、access.logの元のファイルはそのままである必要があります。
その場編集のオプションに接尾辞を付けると、編集前の内容がその名前で残ります。置換の区切り文字は、スラッシュ以外の文字に変えてもかまいません。
JSONの集計
/root/lfcs-text/services.jsonを下の内容で作成し、tierがbackendであるサービスのreplicasの合計を、/root/lfcs-text/jq_out.txtに数字1つで書いてください。
配列を条件で絞り込み、欲しいフィールドだけを集めて配列にして、その配列を合計する関数を使えば、1行で終わります。
YAMLの値の抽出
/root/lfcs-text/deploy.yamlを下の内容で作成し、/root/lfcs-text/yq_out.txtに、replicas=<값>とimage=<값>の2行を書いてください(プレースホルダーは値です)。
パス式はjqとほぼ同じです。配列の要素はインデックスでアクセスし、実装によっては引用符が付いて出力されることがあるので、結果を目で確認してください。