如何让AWS CDK REST API每5分钟内的日志条目归入同一日志流?
解决API Gateway日志流频繁创建的方案
要实现每5分钟的日志归入同一CloudWatch日志流,不能直接让API Gateway写入CloudWatch,得通过Kinesis Data Firehose做中间层——它支持设置缓冲周期,把一段时间内的日志批量转发到CloudWatch,自然就能合并日志流。
具体CDK实现步骤
- 创建目标CloudWatch日志组(和你原来的配置一致,需确保Firehose有写入权限)
- 配置Kinesis Data Firehose,设置缓冲间隔为5分钟,目标指向日志组
- 将API Gateway的访问日志目标改为Firehose
以下是完整的CDK代码:
import * as cdk from 'aws-cdk-lib'; import * as apigw from 'aws-cdk-lib/aws-apigateway'; import * as logs from 'aws-cdk-lib/aws-logs'; import * as firehose from 'aws-cdk-lib/aws-kinesisfirehose'; import * as iam from 'aws-cdk-lib/aws-iam'; export class ApiLogStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const apiName = 'YourApiName'; // 1. 创建目标CloudWatch日志组 const apiLogGroup = new logs.LogGroup(this, `${apiName}-logGroup`, { retention: logs.RetentionDays.ONE_MONTH, logGroupName: `/aws/apigateway/${apiName}`, }); // 2. 创建Firehose所需的IAM角色(允许Firehose写入CloudWatch日志组) const firehoseRole = new iam.Role(this, `${apiName}-firehose-role`, { assumedBy: new iam.ServicePrincipal('firehose.amazonaws.com'), }); apiLogGroup.grantWrite(firehoseRole); // 3. 创建Kinesis Data Firehose Delivery Stream const firehoseStream = new firehose.CfnDeliveryStream(this, `${apiName}-log-firehose`, { deliveryStreamType: 'DirectPut', cloudWatchLogDestinationConfiguration: { logGroupName: apiLogGroup.logGroupName, roleArn: firehoseRole.roleArn, }, // 设置缓冲配置:5分钟(300秒),或5MB(满足任一条件就发送) bufferingHints: { intervalInSeconds: 300, sizeInMBs: 5, }, }); // 4. 创建API Gateway的Firehose日志目标 const accessLogDestination = new apigw.FirehoseLogDestination(firehoseStream); // 5. 配置API Gateway的访问日志格式(和你原来的一致) const accessLogFormat = apigw.AccessLogFormat.custom( JSON.stringify({ requestId: apigw.AccessLogField.contextRequestId(), email: apigw.AccessLogField.contextAuthorizer('email'), path: apigw.AccessLogField.contextResourcePath(), method: apigw.AccessLogField.contextHttpMethod(), }) ); // 6. 创建REST API并配置部署选项 new apigw.RestApi(this, apiName, { deployOptions: { accessLogDestination, accessLogFormat, }, }); // 给API Gateway添加向Firehose发送日志的权限 firehoseStream.addToResourcePolicy(new iam.PolicyStatement({ actions: ['firehose:PutRecord', 'firehose:PutRecordBatch'], principals: [new iam.ServicePrincipal('apigateway.amazonaws.com')], resources: [firehoseStream.attrArn], })); } }
原理说明
- API Gateway直接写入CloudWatch时,日志流的创建逻辑由AWS控制,无法自定义合并规则,导致单请求生成单流。
- 通过Firehose的缓冲机制,它会收集5分钟内的所有API日志,批量发送到CloudWatch,此时CloudWatch会将这些批量日志写入同一个日志流,直到缓冲周期结束,从而实现你需要的5分钟一个流的需求。
内容的提问来源于stack exchange,提问作者benito_h
相关产品推荐
相关产品推荐

