ECS がログを Firelens で出力するときにタスクが止まってハマったときのメモ。
ECS がログを Firelens で出力するときにタスクが止まった
ECS は CDK で構築していてログは awslogs ログドライバーで CloudWatch に出力してるんだけど、awsfirelens ログドライバーで S3 に出力するように変えて CFn スタックを更新したらタスクが止まって上がらなくなったときのことをメモしておく。
事象
ECS は CDK で構築していてログは awslogs ログドライバーで CloudWatch に出力してるのを awsfirelens ログドライバーで S3 に出力するように変えて CFn スタックを更新したら AWS::ECS::Service
が UPDATE_PROGRESS
のままでしばらく待っても更新が終わらない。
ECS のサービスとタスクの状態を見てみるとタスクが止まって上がらなくなっているよう。さらにタスクの状態を見てみるとタスクが止まる => 新しくタスクを作成 => 新しく作成したタスクが止まる => さらに新しくタスクを作成 => ... みたいな感じでタスクの作成と止まるのが繰り返している。
なにが駄目だったか
Unable to generate firelens config file: unable to generate firelens config: unable to apply log options of container <コンテナ名> to firelens config: missing output key Name which is required for firelens configuration of type fluentbit
STOPPED
になってるタスクの停止理由を確認したらこんな感じになってるんだけど Firelens でログを出力するのは初めてじゃないし Name
フィールドは指定してるはず……と思ったけどコードを見たらたしかに Name
フィールドは指定してなかった。
そのときのコードはこうなってた。
Name
を指定するところが name
に typo してたのが原因だった。
logging: ecs.LogDrivers.firelens({ options: { name: "firehose", region: this.region, delivery_stream: "my-stream", }, }),
name
=> Name
にして CFn スタックを更新したらちゃんと ECS のタスクとサービスが上がってきてログが S3 に流れるようになった。
結論: typo ダメ絶対。
logging: ecs.LogDrivers.firelens({ options: { Name: "firehose", region: this.region, delivery_stream: "my-stream", }, }),
typo がエラーにならなかったのはなぜか
CDK は TypeScript で書いててフィールド名を typo したらコンパイルエラーになるんだけど FireLensLogDriverProps.options
は Name
じゃなくて name
と書いてもコンパイルエラーにはならない。
ドキュメント を見直したら FireLensLogDriverProps.options
の型は普通に Map<string, string>
になってて typo しようがなかった。
ちなみに FireLensLogDriverProps.options
のコードはこうなってる。
Name
は必須のフィールドだから明示的に定義しといてもいいんじゃないかって気はする。
結論: ドキュメントはちゃんと読む。
/** * Specifies the firelens log driver configuration options. */ export interface FireLensLogDriverProps extends BaseLogDriverProps { /** * The configuration options to send to the log driver. * @default - the log driver options */ readonly options?: { [key: string]: string; }; }