下記ログ形式で出力されるログに出会い、フィルターや統計処理の方法に悩みましたので、解決策について共有いたします。
time,2023/9/1-00:00,2023/9/1-00:01,2023/9/1-00:02,2023/9/1-00:03,… send,0,1000,2000,3000,… receive,0,100,200,300,… flag,0,1,2,3,…
上記のログは、send、 receive、 flagといった各行に各データポイントの結果がoutputされており、データポイントごとにコンマ区切りで記録されます。
最終的に整形し出力したい表形式は下記です。
この形式にすることでsend、 recieve、 flagの値をフィルタリングしたり、統計処理することが可能です。
この記事では、次の2つの方法をご紹介します。
i) transposeコマンドを使用して、行と列を入れ替える
ii) rexコマンドを使用してフィールドを抽出し、各イベントごとに整形する
データの準備
いずれの方法もはじめにデータを準備します。
| makeresults | eval _raw = "time;2023/9/1-00:00;2023/9/1-00:01;2023/9/1-00:02;2023/9/1-00:03; send;0;1000;2000;3000; receive;0;100;200;300; flag;0;1;2;3; "
i) transposeコマンドを使用して、行と列を入れ替える
大まかな流れは次のとおりです。
- “time”の行をフィールド名として認識させTable化 (multikvコマンド)
- 行と列を入れ替える (transposeコマンド)
手順は次のとおりです。
- multikvコマンドを用いて、_rawフィールドをテーブルに展開します
multikvコマンドについては公式docをご確認ください。
“forceheader=”で何行目をフィールド名として認識させるか指定できます。
- fieldsコマンドを用い、不要なフィールドを省きます。transposeコマンドを用い、行と列を反転します
transposeコマンドについては公式docをご確認ください。
- renameコマンドを用いて、列の名称を変更します
ii) rexコマンドを使用してフィールドを抽出し、各イベントごとに整形する
手順は次のとおりです。ポイントはmvexpandをするタイミングです。
- rexコマンドを用いて、各フィールドを抽出します
- fieldsコマンドを用いて、不要なフィールドを省きます
- splitコマンドを用いて、シングルバリューをマルチバリューにします
splitコマンドについては公式docをご確認ください。
- mvzipコマンドを用いて、各フィールドを結合したtemporaryフィールドを作成します
mvzipコマンドについては公式docをご確認ください。
- Temporaryフィールド以外を省き、mvexpandコマンドを用いて、各行に展開します
mvexpandコマンドについては公式docをご確認ください。
- rexコマンドを用いて、各フィールドを抽出します
fieldsコマンドを用いて列を並び替えます
終わりに
ii)のやり方は少し手間に思えますが、ログの形式によっては柔軟に活用できる方法ですので、このやり方もぜひ覚えてみてください。