以前業務でMySQLのRDSのスロークエリをCloudWatch Logs サブスクリプションフィルター+LambdaでAmazon ES(現OpenSearch)に集めるやつを作った。
似たようなものをPostgreSQLのRDSで作ったのだが、今回の要件ではクロスアカウントでログを集計する必要があったため、Kinesis Firehoseを経由する必要があった。
cf. Kinesis Data Firehose を使用したクロスアカウントログデータ共有 - Amazon CloudWatch Logs
※ちなみにサブスクリプションフィルター+クロスアカウントのCloudWatch Logsはできそうな雰囲気がありそうでできなかった(たぶん現状Kinesisしか対応していないと思う)
Kinesis FirehoseでLambdaを使ってCloudWatch Logsのデータ変換を行おうと思うとのが、CloudWatch Logsが1レコード内に複数イベント詰めてくるのに対して、データ変換後のOpenSearchへの出力は1レコード・1イベントにする必要があり、無理矢理複数イベントを詰め込むとエラーになる。
公式にはマルチレコードに対応していない雰囲気なのだがハックがあった。
複数データの途中にインデックスのアクションを挟むことにより、OpenSearchが複数レコードをインポートしてくれる。 ※先頭にはアクションは付けない
{"foo":"bar","request_logged_at":"2017-02-07T15:13:01.39256Z"} { "index" : { "_index" : "my-index" } } {"foo":"bar","request_logged_at":"2017-02-07T15:13:01.39256Z"} { "index" : { "_index" : "my-index" } } {"foo":"bar","request_logged_at":"2017-02-07T15:13:01.39256Z"}
ということで、冒頭のlambdaのコードは一応、元気に動いている。
あと、GoでのKinesis Firehose+Lambdaのデータ変換は以下のブログが参考になった。