
杉嵜 諒吾です。戸籍の振り仮名は問題ありませんでした。
今年の5月よりLambdaのログ出力に仕様変更がありました。料金計算の際に Vended Logs として計上されるようになったほか、Vended Logs として S3 や Data Firehose へ出力できるようになりました。CloudWatch Logs 以外でのログ管理がしやすくなった他、S3 や Firehose へログ出力する際は料金面でも優遇されます。
ローンチ時のブログ記事では AWS コンソール上での設定方法を説明されていますが、Lambda 関数を AWS SAM で作っている身としては、できれば SAM テンプレートでまとめて設定しておきたいところです。今回ドキュメントを探したり、AWS Japan 様に問い合わせたりして作れるようにはなりましたが、自分の備忘も兼ねて記事にまとめることにしました。
今回変わったこと
今まで通りにLambda関数を作成した場合、ログはこれまで通りにCloudWatch Logsで取込・保存され、参照もCloudWatch Logsの機能で行うことになります。ログ運用を変える予定が無い場合は、今回のローンチ以降も変更すべきことはありません。
一方、CloudWatch Logsに取り込まれたログをS3へファイル出力したい場合、従来はAWSコンソールなどから手動でエクスポートするか、Data Firehose を使う必要がありました。これが今回のローンチ以降、Lambda から取り込むログを CloudWatch Logs で取り込んだ後、S3 バケットに直接出力することが可能になりました。
また Lambda から取り込まれるログは Vended Logs に分類されるようになったため、 S3 や Data Firehose への出力に変更する場合は、CloudWatch Logs のログ取込料金が大幅に安くなります。
CloudWatch Logs の料金
1GBあたりの料金(USD、2025年8月現在の東京リージョン)
| 通常のログ (標準クラス) |
Vended Logs | Vended Logs S3 出力 |
Vended Logs Firehose 出力 |
|
|---|---|---|---|---|
| 取込 (~10TB/月) | 0.760 | 0.760 | 0.380 | 0.380 |
| 取込 (10~30TB/月) | 0.760 | 0.380 | 0.228 | 0.228 |
| 取込 (30~50TB/月) | 0.760 | 0.152 | 0.114 | 0.114 |
| 取込 (50TB以降/月) | 0.760 | 0.076 | 0.076 | 0.076 |
| 保存 (月あたり)*1 | 0.033 | 0.033 | (S3 料金) | - |
CloudWatch Logs の料金で支配的になりやすいのはログの取込料金ですが、Vended Logs に分類されるサービスのログ取込では、毎月 10TB 以降の取込料金にボリュームディスカウントがあります。加えて、Vended Logs で S3 や Firehose 出力にした場合、毎月 50TB までの取込料金が大幅に安くなります。50TB 以降は Logs 出力と S3 / Firehose 出力で取込料金が同じになりますが、東京リージョンの場合は 50TB までの累計で 7,600 USD の差が出ることになります。
なお従来より VPC フローログや Route 53 のクエリログ、AWS WAF のログなども Vended Logs に分類されており、ボリュームディスカウントはそれらのデータ量の合計を元に適用されます。そのため、AWS Lambda 単体で毎月 10 TB に満たない場合でもボリュームディスカウントが適用されることがあります。
取込料金の一例(クリックで展開)
単位 : USD / 月
| 通常のログ (標準クラス) |
Vended Logs | Vended Logs S3 / Firehose 出力 |
|
|---|---|---|---|
| 10 TB/月 | 7,600 | 7,600 | 3,800 |
| 30 TB/月 | 22,800 | 15,200 | 8,360 |
| 50 TB/月 | 38,000 | 18,240 | 10,640 |
| 100 TB/月 | 76,000 | 22,040 | 14,440 |
S3出力にする場合の構築
AWSのドキュメントでは、コマンドで作る方法が書かれています。
Sending Lambda function logs to Amazon S3 - AWS Lambda
Lambda のログが Vended Logs になった際、CloudWatch Logs ロググループのログクラスに "Delivery" が追加されました。これは現状、Lambda からログを取り込んで S3 や Data Firehose に出力する専用のログクラスです。今回の構築は、Lambdaからログを取り込むロググループをログクラス Delivery で作り、サブスクリプションフィルターで S3 への出力設定をすることになります。
Log classes - Amazon CloudWatch Logs
なおロググループのログクラスは後から変更できないため、既存の Lambda 関数のログをS3出力に変更する際は、ロググループを新たに作ることになります。
SAMテンプレート例
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > test of vended logs delivery from lambda functions Globals: Function: Timeout: 3 MemorySize: 128 Resources: VendedLogsBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub "${AWS::StackName}-vended-logs" VersioningConfiguration: Status: Enabled AccessControl: Private HelloWorldFunction: Type: AWS::Serverless::Function Properties: CodeUri: hello_world/ Handler: app.lambda_handler Runtime: python3.13 Architectures: - x86_64 LoggingConfig: LogFormat: Text LogGroup: !Ref HelloWorldFunctionLogGroup # ログクラス DELIVERY でロググループを作る HelloWorldFunctionLogGroup: Type: AWS::Logs::LogGroup DeletionPolicy: Retain Properties: LogGroupClass: "DELIVERY" LogGroupName: !Sub "${AWS::StackName}-vended-logs" # DestinationArn に S3 バケットを指定 SubscriptionFilter: Type: AWS::Logs::SubscriptionFilter Properties: FilterPattern: "" Distribution: "ByLogStream" LogGroupName: !Ref HelloWorldFunctionLogGroup ApplyOnTransformedLogs: false FilterName: "lambda-logs-delivery" DestinationArn: !GetAtt VendedLogsBucket.Arn RoleArn: !GetAtt SubscriptionFilterRole.Arn SubscriptionFilterRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: logs.amazonaws.com Condition: StringLike: aws:SourceArn: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*" Action: sts:AssumeRole Policies: - PolicyName: "AllowS3Write" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - s3:PutObject Resource: !Sub "${VendedLogsBucket.Arn}/*"
ロググループの保持期間は明記せずとも2日に設定されるようです。あくまでロググループで管理してるログストリームなどが消えるもので、S3 バケットに出力したログが消えるわけではありません。バケット内の古いログを削除したい場合はライフサイクルルールを設定しましょう。
動作確認
設定後にLambda関数を実行するとログストリームが作成されますが、CloudWatch Logs でのログイベント参照はできません。

S3 へのログ出力はログストリームごとに Zstandard 形式で圧縮して保存されます。ロググループの名前やアカウントIDなどでフォルダが分かれるので、複数のロググループから同じ S3 バケットに出力することもできます。出力した後のログは、例えば Amazon Athena で日時やロググループ名を指定して参照できます。


終わりに
今回のローンチにより、AWS Lambda を中心に構築されたシステムでのログ管理の選択肢が増える形となりました。単に CloudWatch Logs の料金を抑えられるというのもありますが、1つの S3 バケットにログを集約して一元管理する、Data Firehose 経由で Redshift やサードパーティ製のデータウェアハウスに送るなどの大規模なログの分析・管理を、Lambda のログでやりやすくなったと言えるでしょう。
*1:取込後に圧縮されるため、料金計算に使われるデータ量は取込時より小さくなります。CloudWatch Logsの料金ページでは圧縮率 0.15 が目安として示されていますが、実際にはログの内容などに依存します。