この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
大阪オフィスの小倉です。
Serverless Frameworkのプラグインであるserverless-plugin-log-subscription
を導入して、
サブスクリプションフィルターの管理がとても簡単になったので紹介します。
概要
Serverless Frameworkを使ってLambdaのCloudWatch Logsロググループに
サブスクリプションフィルターを設定する場合、
基本的には各ロググループに対して一つずつ設定を記述する必要があります。
serverless-plugin-log-subscriptionを使うことで、YAMLテンプレート内で管理する全てのLambdaに対して一括でサブスクリプションフィルターを設定することが出来ます。
やってみる
今回は以下の環境で検証しました。
環境 | バージョン |
---|---|
Serverless Framework | 3.21.0 |
serverless-plugin-log-subscription | 2.1.2 |
構成
今回の構成は以下の通りです。
アプリケーションLambdaがCloudWatchLogsに出力するログの中で、特定の文字を見つけたら、
サブスクリプションフィルターの機能で、通知実行用のLambda関数を呼び出します。
サブスクリプションフィルターを動作させるには、
- サブスクリプションフィルターの作成
- CloudWatchLogsからのLambda呼び出しを許可するリソースベースポリシーの作成
が必要となり、この部分をプラグインが支援してくれます。
※通知実行用Lambda−>SNS−>メール送信の部分については以下のブログを参照ください。
実装
ログの中に「ERROR」という文字列を見つけたらサブスクリプションフィルターが動く例です。
フィルターを設定したいLambdaに対して、logSuscription: true
を指定します。
通知実行用LambdaのArnは、 destinationArn
に指定します。
service: log-subscription-project
frameworkVersion: '3'
plugins:
- serverless-plugin-log-subscription
provider:
name: aws
runtime: python3.9
region: ap-northeast-1
custom:
logSubscription:
destinationArn: <通知実行用LambdaのArn>
filterPattern: 'ERROR' # ログの中にERRORという文字を見つけたら発動
functions:
hello:
handler: handler.hello
events:
- httpApi:
path: /
method: get
logSubscription: true # サブスクリプションフィルターの有効化
テンプレートに多数のLambdaが定義されている場合、custom
配下にenabled: true
を指定することで一括設定できます。
各Lambdaの定義でlogSubscription: false
を指定すると、個別にサブスクリプションフィルターを無効化出来ます。
custom:
logSubscription:
destinationArn: <通知実行用LambdaのArn>
filterPattern: 'ERROR' # ログの中にERRORという文字を見つけたら発動
enabled: true # サブスクリプションフィルターの一括有効化
functions:
hello:
handler: handler.hello
events:
- httpApi:
path: /
method: get
world:
handler: handler.hello
events:
- httpApi:
path: /world
method: get
logSubscription: false # 例外的にこのLambdaだけサブスクリプションフィルターを作らない
hoge:
handler: handler.hello
events:
- httpApi:
path: /hoge
method: get
Lambdaの数が多いと、通知実行用Lambdaに対して、リソースベースポリシーが大量に自動作成されてしまい、
Lambda関数リソースベースポリシーのサイズ上限(20KB)を超えてしまうおそれがあります。
この場合は以下のようなエラーになります。
The final policy size (20560) is bigger than the limit (20480).
このような場合は、予め自前で複数のロググループに対応できるようなポリシーを用意しておき、
custom:
logSubscription:
addLambdaPermission: false # リソースベースポリシーの自動生成を停止
とすることで、プラグインによるリソースベースポリシーの自動生成を停止することが出来ます。
まとめ
Serverless Frameworkを使いながらサブスクリプションフィルターを設定していると、テンプレートの記述量がどうしても増えてしまったり、
Lambda関数を追加した際にサブスクリプションフィルターを追加し忘れる事があって困っていました。
プラグインを導入することで設定が自動化され、テンプレートの記述量も大幅に削減することが出来たので、
同じ様な悩みがある方はぜひ使ってみてください。