[アップデート] CloudWatch Logs のロググループに2つのサブスクリプションフィルタを設定できるようになりました!

2020.10.06

こんにちは。コンサル部@大阪オフィスのYui(@MayForBlue)です。

タイトルの通り、CloudWatch Logs のロググループに2つのサブスクリプションフィルタを設定できるようになりました〜!!!

公式アナウンスはこちら。
Amazon CloudWatch Logs now supports two subscription filters per log group

何が嬉しいのか

CloudWatch Logs のサブスクリプションフィルタは、CloudWatch Logs に出力されたログをリアルタイムに検知して特定の文字列を含むデータや全データをKinesis データストリーム、Kinesis Data Firehose、Lambdaなどに連携できる機能です。

これまでは1つのロググループに対してサブスクリプションフィルタを1つしか設定できなかったので、連携が単一サービスのみに限られていました。
今回2つ設定できるようになったことで Kinesis Data Firehose と Lambda など2つのサービスに連携したり、Kinesis Data Firehose 経由で異なるS3バケットにログを出力したりできるようになりました。

早速試してみる

構成

今回は CloudWatch Logs から Kinesis Data Firehose 経由で S3 にログを出力します。

2つのサブスクリプションフィルタがそれぞれ機能していることを確認したいので、Kinesis Data Firehose を 2つ用意し、S3 の同一バケット内の別プレフィックス配下にそれぞれログが出力されるようにしてみます。
検知文字列はそれぞれ test1test2とします。

事前準備

事前に以下を用意しておきました。

  • CloudWatch Logs
    • ロググループ:TestLogGroup
    • TestLogGroup内のログストリーム:TestLogStream1
  • Kinesis Data Firehose
    • teststream-for-subscription-1
    • teststream-for-subscription-2
  • S3
    • バケット: testbucket-for-subscription
  • IAMロール
    • CWLtoKinesisFirehoseRole (CloudWatchLogs から Kinesis Data Firehose へのログデータの転送を許可するロール)

CWLtoKinesisFirehoseRoleの詳細については以下ドキュメントをご参照ください。
CloudWatch Logs サブスクリプションフィルタの使用

手順

サブスクリプションフィルタの作成は AWS CLI で行う必要があります。
aws logs put-subscription-filterコマンドを使ってサブスクリプションフィルタを作成します。
このコマンドで必要なオプションは以下です。

  • --log-group-name: 作成済みのCloudWatch Logs ロググループ名
  • --filter-name: サブスクリプションフィルタ名
  • --filter-pattern: 検知する文字列
  • --destination-arn: 作成済みの Kinesis Data Firehose のARN
  • --role-arn: ロググループに紐づける作成済みのIAMロール

aws logs put-subscription-filter

サブスクリプションフィルタの作成

TestLogGrouptest1の文字列を含むログが出力された場合にteststream-for-subscription-1の Kinesis Data Firehose 配信ストリームにログを転送させるためのサブスクリプションフィルタを作成します。

$ aws logs put-subscription-filter \
    --log-group-name "TestLogGroup" \
    --filter-name "TestSubscriptionFilter-1" \
    --filter-pattern "test1" \
    --destination-arn "arn:aws:firehose:ap-northeast-1:【AWSアカウントID】:deliverystream/teststream-for-subscription-1" \
    --role-arn "arn:aws:iam::【AWSアカウントID】:role/CWLtoKinesisFirehoseRole"

TestLogGrouptest2の文字列を含むログが出力された場合にteststream-for-subscription-2の Kinesis Data Firehose 配信ストリームにログを転送させるためのサブスクリプションフィルタを作成します。

$ aws logs put-subscription-filter \
    --log-group-name "TestLogGroup" \
    --filter-name "TestSubscriptionFilter-2" \
    --filter-pattern "test2" \
    --destination-arn "arn:aws:firehose:ap-northeast-1:【AWSアカウントID】:deliverystream/teststream-for-subscription-2" \
    --role-arn "arn:aws:iam::【AWSアカウントID】:role/CWLtoKinesisFirehoseRole"

TestLogGroupのサブスクリプションフィルタを一覧すると2つのサブスクリプションフィルタが適用されていることが確認できます。

$ aws logs describe-subscription-filters --log-group-name TestLogGroup
{
    "subscriptionFilters": [
        {
            "filterName": "TestSubscriptionFilter-1",
            "logGroupName": "TestLogGroup",
            "filterPattern": "test1",
            "destinationArn": "arn:aws:firehose:ap-northeast-1:【AWSアカウントID】:deliverystream/teststream-for-subscription-1",
            "roleArn": "arn:aws:iam::【AWSアカウントID】:role/CWLtoKinesisFirehoseRole",
            "distribution": "ByLogStream",
            "creationTime": 1601890337619
        },
        {
            "filterName": "TestSubscriptionFilter-2",
            "logGroupName": "TestLogGroup",
            "filterPattern": "test2",
            "destinationArn": "arn:aws:firehose:ap-northeast-1:【AWSアカウントID】:deliverystream/teststream-for-subscription-2",
            "roleArn": "arn:aws:iam::【AWSアカウントID】:role/CWLtoKinesisFirehoseRole",
            "distribution": "ByLogStream",
            "creationTime": 1601890412601
        }
    ]
}

また、詳細は確認できませんが、マネジメントコンソールからもサブスクリプションフィルタが2つ紐づいていることが確認できます。

動作確認

マネジメントコンソールから、テスト用のログメッセージを push して以下を確認します。  

  • test1の文字列を含むログメッセージがteststream-for-subscriptionバケットのtest1プレフィックス配下に出力されること
  • test2の文字列を含むログメッセージがteststream-for-subscriptionバケットのtest2プレフィックス配下に出力されること

マネジメントコンソールでTestLogGroupグループのTestLogStream1を選択して「アクション」の「Create Log event」をクリックします。

test1 messageというログメッセージを作成します。

test2 messageも同じように作成しました。

しばらく待つと、バケットのそれぞれのプレフィックス配下にオブジェクトが出力されていることが確認できました。
testbucket-for-subscription/test1/

testbucket-for-subscription/test2/

それぞれのプレフィックス配下のログの内容を確認すると、サブスクリプションフィルタで設定した通りにログが配信されていることを確認できました!

testbucket-for-subscription/test1/配下のログ

{"messageType":"DATA_MESSAGE","owner":"【AWSアカウントID】","logGroup":"TestLogGroup","logStream":"TestLogStream1","subscriptionFilters":["TestSubscriptionFilter-1"],"logEvents":[{"id":"012345678900123456789001234567890","timestamp":1601890626756,"message":"test1 message"}]}

testbucket-for-subscription/test2/配下のログ

{"messageType":"DATA_MESSAGE","owner":"【AWSアカウントID】","logGroup":"TestLogGroup","logStream":"TestLogStream1","subscriptionFilters":["TestSubscriptionFilter-2"],"logEvents":[{"id":"012345678900123456789001234567890","timestamp":1601890638050,"message":"test2 message"}]}

最後に

今回のアップデートでログの連携がより柔軟に行えるようになりました。
この記事がどなたかのお役に立てば幸いです。

以上、コンサル部@大阪オフィスのYui(@MayForBlue)でした。

参考リンク

Amazon CloudWatch Logs now supports two subscription filters per log group
CloudWatch Logs サブスクリプションフィルタの使用
aws logs put-subscription-filter