目的
- ECSコンテナ(Fargate)から出力されるアプリケーションログをS3へ出力したい。
- アプリケーションログはJSON形式なので、FireLens(fluentbit)でパースをしたい。
やってみた
システム構成は下記のイメージですが、FargateやS3の構築の方法や設定ついては省略しています。
ここでは、JSON形式のログをパースして出力する方法と、設定値による出力の違いを記載します。
なお、fluentbitの設定方法は2パターンあります。さらにカスタム設定ファイルを読み込む方法も2パターンあります。
- Fargateのタスク定義のオプションに設定する
- カスタム設定ファイルに設定する
ⅰ. S3に配置したカスタム設定ファイルを読み込む
ⅱ. コンテナイメージビルド時にカスタム設定ファイルをイメージにコピーする
今回は「ⅰ. S3に配置したカスタム設定ファイルを読み込む」パターンで検証しています。
参考手順)
JSON形式のログをパースして出力する
アプリケーションコンテナから出力されるJSONを以下として、どのように出力されるか見てみます。
{"key1":"value1", "key2":"value2", "key3":"value3", "key4":"value4", "key5":"value5"}
まず、パースをしないで出力した例です。log
にパースされていない状態で出力されています。
{
"date": "2023-12-28T05:44:21.333117Z",
"container_name": "side-car",
"source": "stdout",
"log": "{\"key1\":\"value1\", \"key2\":\"value2\", \"key3\":\"value3\", \"key4\":\"value4\", \"key5\":\"value5\"}",
"container_id": "20fd58957fe14e6ba5ac7d5a5d9c54a8-159383053",
"ecs_cluster": "test_ecs_cluster",
"ecs_task_arn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/test_ecs_cluster/20fd58957fe14e6ba5ac7d5a5d9c54a8",
"ecs_task_definition": "test_ecs_task_definition:9"
}
JSONをパースしたい場合は、fluentbitのコンテナイメージにパーサー設定ファイルが用意されているため、[SERVICE]
で読み込みます。[FILTER]
にパースする設定を記載します。
[SERVICE]
Parsers_File /fluent-bit/parsers/parsers.conf
[FILTER]
Name parser
Match *
Key_Name log
Parser json
Preserve_Key False
Reserve_Data False
[FILTER]の設定値について
キー | 設定値 | 説明 |
---|---|---|
Name | parser | フィルタープラグインの名前。今回は parser というプラグインを指定。 |
Match | * | 受信レコードのタグに対してマッチするパターン。大文字と小文字を区別し、ワイルドカードとしてスター (*) 文字をサポートします。 |
Key_Name | log | 解析するレコードのフィールド名を指定します。 |
Parser | json | フィールドを解釈するパーサーを指定する。事前に用意されたjsonというパーサー。自作したパーサーも設定可。 |
Preserve_Key | False | 解析された結果に元のKey_Nameフィールドを残す。false の場合、フィールドは削除されます。 デフォルトはfalse |
Reserve_Data | False | パースされた結果に他のすべてのオリジナル・フィールドを残す。falseの場合、他のすべてのオリジナルフィールドは削除されます。デフォルトはfalse |
参考)FILTER
参考)parser
Preserve_Key と Reserve_Data の挙動
設定値のうち、Preserve_Key
とReserve_Data
の設定による違いがよくわからなかったので、違いを比べてみます。
- どちらもFalse(デフォルトと同じ)
パースされたlog
のデータとdate
が出力されます。
{
"date": "2023-12-28T03:18:42.950209Z",
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
"key5": "value5"
}
- どちらもOnにした場合
container_id
やcontainer_name
、パースされていないままのlog
もそのまま出力されています。
{
"date": "2023-12-28T05:08:21.979872Z",
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
"key5": "value5",
"container_name": "side-car",
"source": "stdout",
"log": "{\"key1\":\"value1\", \"key2\":\"value2\", \"key3\":\"value3\", \"key4\":\"value4\", \"key5\":\"value5\"}",
"container_id": "edc63f4367784d408944b56f4967546a-159383053",
"ecs_cluster": "test_ecs_cluster",
"ecs_task_arn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/test_ecs_cluster/edc63f4367784d408944b56f4967546a",
"ecs_task_definition": "test_ecs_task_definition:9"
}
-
Preserve_Key
だけOnの場合の出力結果
パースされていないlog
のデータが出力されると思ったんですが出力されずでした。どちらもfalseの時と同じ結果。(もしかしたら設定方法が良くなかったかも)
{
"date": "2023-12-28T02:59:34.892455Z",
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
"key5": "value5"
}
-
Reserve_Data
だけOnの場合の出力結果
container_id
やcontainer_name
などが追加されて出力されています。
{
"date": "2023-12-28T02:49:00.524241Z",
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4",
"key5": "value5",
"container_id": "75cfcc2b4f914ea09103bd2c26c566e8-159383053",
"container_name": "side-car",
"source": "stdout",
"ecs_cluster": "test_ecs_cluster",
"ecs_task_arn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task/test_ecs_cluster/75cfcc2b4f914ea09103bd2c26c566e8",
"ecs_task_definition": "test_ecs_task_definition:9"
}
まとめ
- JSONパーサーは用意されているので、それを使うことができる
- パースされた結果、トップレベルのオブジェクトとして出力される
- パース前だとlogの下に出力されているが、トップレベルで出力される
- logの下に出力して欲しいケースもありそう
- parseの設定値について
- Preserve_Key
- デフォルトはFalse
- もともとのlogもパースされてない状態でそのまま出力される
- Reserve_Data
- デフォルトはFalse
- Trueにすると
container_id
やcontainer_name
など ECS 関連のメタデータが出力できる。
- Preserve_Key
その他参考