Amazon CloudWatch Logs
用户指南
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。请点击 Amazon AWS 入门,可查看中国地区的具体差异

使用 CloudWatch Logs 订阅筛选器

可以对 Kinesis、Lambda 或 Kinesis Firehose 使用订阅筛选器。

示例 1:Kinesis 订阅筛选器

以下示例将订阅筛选器与包含 AWS CloudTrail 事件的日志组关联,以便将记录中由“根”AWS 凭证完成的每个活动传输到名为“RootAccess”的 Kinesis 流。有关如何将 AWS CloudTrail 事件发送到 CloudWatch Logs 的更多信息,请参阅 AWS CloudTrail User Guide 中的将 CloudTrail 事件发送到 CloudWatch Logs

为 Kinesis 创建订阅筛选器

  1. 使用以下命令创建目标 Kinesis 流:

    Copy
    $ C:\> aws kinesis create-stream --stream-name "RootAccess" --shard-count 1
  2. 请耐心等待,直到 Kinesis 流变为活动状态 (这可能需要一两分钟)。您可使用以下 Kinesis describe-stream 命令检查 StreamDescription.StreamStatus 属性。此外,请记下 StreamDescription.StreamARN 值,因为后面的步骤中将会用到它:

    Copy
    aws kinesis describe-stream --stream-name "RootAccess"

    下面是示例输出:

    Copy
    { "StreamDescription": { "StreamStatus": "ACTIVE", "StreamName": "RootAccess", "StreamARN": "arn:aws:kinesis:us-east-1:123456789012:stream/RootAccess", "Shards": [ { "ShardId": "shardId-000000000000", "HashKeyRange": { "EndingHashKey": "340282366920938463463374607431768211455", "StartingHashKey": "0" }, "SequenceNumberRange": { "StartingSequenceNumber": "49551135218688818456679503831981458784591352702181572610" } } ] } }
  3. 创建 IAM 角色,该角色将向 CloudWatch Logs 授予将数据放入 Kinesis 流的权限。首先,您需要在文件 (例如 ~/TrustPolicyForCWL.json) 中创建信任策略。使用文本编辑器创建此策略。请勿使用 IAM 控制台来创建策略。

    Copy
    { "Statement": { "Effect": "Allow", "Principal": { "Service": "logs.us-east-1.amazonaws.com" }, "Action": "sts:AssumeRole" } }
  4. 使用 create-role 命令创建 IAM 角色,并指定信任策略文件。请记下返回的 Role.Arn 值,因为后面的步骤中将会用到它:

    Copy
    aws iam create-role --role-name CWLtoKinesisRole --assume-role-policy-document file://~/TrustPolicyForCWL.json
    Copy
    { "Role": { "AssumeRolePolicyDocument": { "Statement": { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "logs.us-east-1.amazonaws.com" } } }, "RoleId": "AAOIIAH450GAB4HC5F431", "CreateDate": "2015-05-29T13:46:29.431Z", "RoleName": "CWLtoKinesisRole", "Path": "/", "Arn": "arn:aws:iam::123456789012:role/CWLtoKinesisRole" } }
  5. 创建权限策略以定义可对您的账户执行的 CloudWatch Logs 操作。首先,您将在文件 (例如 ~/PermissionsForCWL.json) 中创建权限策略。使用文本编辑器创建此策略。请勿使用 IAM 控制台来创建策略。

    Copy
    { "Statement": [ { "Effect": "Allow", "Action": "kinesis:PutRecord", "Resource": "arn:aws:kinesis:us-east-1:123456789012:stream/RootAccess" }, { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::123456789012:role/CWLtoKinesisRole" } ] }
  6. 使用以下 put-role-policy 命令将权限策略与角色关联:

    Copy
    aws iam put-role-policy --role-name CWLtoKinesisRole --policy-name Permissions-Policy-For-CWL --policy-document file://~/PermissionsForCWL.json
  7. 在 Kinesis 流进入 Active 状态并且您已创建 IAM 角色后,您便可以创建 CloudWatch Logs 订阅筛选器。订阅筛选器将立即让实时日志数据开始从所选日志组流动到您的 Kinesis 流:

    Copy
    aws logs put-subscription-filter \ --log-group-name "CloudTrail" \ --filter-name "RootAccess" \ --filter-pattern "{$.userIdentity.type = Root}" \ --destination-arn "arn:aws:kinesis:us-east-1:123456789012:stream/RootAccess" \ --role-arn "arn:aws:iam::123456789012:role/CWLtoKinesisRole"
  8. 设置订阅筛选器后,CloudWatch Logs 会将与筛选器模式匹配的所有传入事件日志转发到您的 Kinesis 流。您可以通过抓取 Kinesis 分片迭代器并使用 Kinesis get-records 命令获取一些 Kinesis 记录来验证此事件是否发生:

    Copy
    aws kinesis get-shard-iterator --stream-name RootAccess --shard-id shardId-000000000000 --shard-iterator-type TRIM_HORIZON
    Copy
    { "ShardIterator": "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiK2OSh0uP" }
    Copy
    aws kinesis get-records --limit 10 --shard-iterator "AAAAAAAAAAFGU/kLvNggvndHq2UIFOw5PZc6F01s3e3afsSscRM70JSbjIefg2ub07nk1y6CDxYR1UoGHJNP4m4NFUetzfL+wev+e2P4djJg4L9wmXKvQYoE+rMUiFq+p4Cn3IgvqOb5dRA0yybNdRcdzvnC35KQANoHzzahKdRGb9v4scv+3vaq+f+OIK8zM5My8ID+g6rMo7UKWeI4+IWiK2OSh0uP"

    请注意,您可能需要在 Kinesis 开始返回数据之前调用几次此命令。

    您将看到包含一组记录的响应。Kinesis 记录中的 Data 属性使用 gzip 格式进行了 Base64 编码和压缩。您可使用以下 Unix 命令检查命令行中的原始数据:

    Copy
    echo -n "<Content of Data>" | base64 -d | zcat

    Base64 解码和解压缩数据被格式化为 JSON 并具有以下结构:

    Copy
    { "owner": "111111111111", "logGroup": "CloudTrail", "logStream": "111111111111_CloudTrail_us-east-1", "subscriptionFilters": [ "Destination" ], "messageType": "DATA_MESSAGE", "logEvents": [ { "id": "31953106606966983378809025079804211143289615424298221568", "timestamp": 1432826855000, "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" }, { "id": "31953106606966983378809025079804211143289615424298221569", "timestamp": 1432826855000, "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" }, { "id": "31953106606966983378809025079804211143289615424298221570", "timestamp": 1432826855000, "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" } ] }

    上述数据架构中的关键元素如下:

    owner

    原始日志数据的 AWS 账户 ID。

    logGroup

    原始日志数据的日志组名称。

    logStream

    原始日志数据的日志流名称。

    subscriptionFilters

    与原始日志数据匹配的订阅筛选器名称的列表。

    messageType

    数据消息将使用“DATA_MESSAGE”类型。有时候,CloudWatch Logs 可能发出类型为“CONTROL_MESSAGE”的 Kinesis 记录,这主要是为了检查目标是否可访问。

    logEvents

    表示为一组日志事件记录的实际日志数据。“id”属性是每个日志事件的唯一标识符。

示例 2:AWS Lambda 订阅筛选器

此示例将创建一个 CloudWatch Logs 订阅筛选器,用于将日志数据发送到您的 AWS Lambda 函数。

为 Lambda 创建订阅筛选器

  1. 创建 AWS Lambda 函数。

    确保您已设置 Lambda 执行角色。有关详细信息,请参阅以下指南中的 步骤 2.2:创建 IAM 角色 (执行角色)AWS Lambda Developer Guide

  2. 打开文本编辑器,并用以下内容创建名为 helloWorld.js 的文件:

    Copy
    var zlib = require('zlib'); exports.handler = function(input, context) { var payload = new Buffer(input.awslogs.data, 'base64'); zlib.gunzip(payload, function(e, result) { if (e) { context.fail(e); } else { result = JSON.parse(result.toString('ascii')); console.log("Event Data:", JSON.stringify(result, null, 2)); context.succeed(); } }); };
  3. 压缩 helloWorld.js 文件,并用名称 helloWorld.zip 保存它。

  4. 使用以下命令,其中角色是您在第一步中设置的 Lambda 执行角色:

    Copy
    aws lambda create-function \ --function-name helloworld \ --zip-file file://file-path/helloWorld.zip \ --role lambda-execution-role-arn \ --handler helloWorld.handler \ --runtime nodejs4.3
  5. 授予 CloudWatch Logs 执行您的函数的权限。使用以下命令,将占位符账户替换为您自己的账户,将占位符日志组替换为要处理的日志组:

    Copy
    aws lambda add-permission \ --function-name "helloworld" \ --statement-id "helloworld" \ --principal "logs.us-east-1.amazonaws.com" \ --action "lambda:InvokeFunction" \ --source-arn "arn:aws:logs:us-east-1:123456789123:log-group:TestLambda:*" \ --source-account "123456789012"
  6. 使用以下命令创建订阅筛选器,将占位符账户替换为您自己的账户,将占位符日志组替换为要处理的日志组:

    Copy
    aws logs put-subscription-filter \ --log-group-name myLogGroup \ --filter-name demo \ --filter-pattern "" \ --destination-arn arn:aws:lambda:us-east-1:123456789123:function:helloworld
  7. (可选) 使用样本日志事件进行测试。在出现命令提示符时,运行以下命令,以将一条简单的日志消息放入已订阅的流中。

    要查看您的 Lambda 函数的输出,请导航至 Lambda 函数,在此处您可以查看 /aws/lambda/helloworld 中的输出:

    Copy
    aws logs put-log-events --log-group-name myLogGroup --log-stream-name stream1 --log-events "[{\"timestamp\":<CURRENT TIMESTAMP MILLIS> , \"message\": \"Simple Lambda Test\"}]"

    您将看到包含一组 Lambda 的响应。Lambda 记录中的 Data 属性采用 Base64 编码,并使用 gzip 格式进行压缩。Lambda 接收的实际负载采用以下格式:{ "awslogs": {"data": "BASE64ENCODED_GZIP_COMPRESSED_DATA"} }。您可以使用以下 Unix 命令检查命令行中的原始数据:

    Copy
    echo -n "<BASE64ENCODED_GZIP_COMPRESSED_DATA>" | base64 -d | zcat

    Base64 解码和解压缩数据被格式化为 JSON 并具有以下结构:

    Copy
    { "owner": "123456789012", "logGroup": "CloudTrail", "logStream": "123456789012_CloudTrail_us-east-1", "subscriptionFilters": [ "Destination" ], "messageType": "DATA_MESSAGE", "logEvents": [ { "id": "31953106606966983378809025079804211143289615424298221568", "timestamp": 1432826855000, "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" }, { "id": "31953106606966983378809025079804211143289615424298221569", "timestamp": 1432826855000, "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" }, { "id": "31953106606966983378809025079804211143289615424298221570", "timestamp": 1432826855000, "message": "{\"eventVersion\":\"1.03\",\"userIdentity\":{\"type\":\"Root\"}" } ] }

    上述数据架构中的关键元素如下:

    owner

    原始日志数据的 AWS 账户 ID。

    logGroup

    原始日志数据的日志组名称。

    logStream

    原始日志数据的日志流名称。

    subscriptionFilters

    与原始日志数据匹配的订阅筛选器名称的列表。

    messageType

    数据消息将使用“DATA_MESSAGE”类型。有时候,CloudWatch Logs 可能发出类型为“CONTROL_MESSAGE”的 Lambda 记录,这主要是为了检查目标是否可访问。

    logEvents

    表示为一组日志事件记录的实际日志数据。“id”属性是每个日志事件的唯一标识符。

示例 3:Amazon Kinesis Firehose 订阅筛选器

此示例将创建一个 CloudWatch Logs 订阅,用于将与所定义筛选器匹配的所有传入日志事件发送到您的 Amazon Kinesis Firehose 传输流。已经使用 gzip 6 级压缩对从 CloudWatch Logs 发送到 Amazon Kinesis Firehose 的数据进行压缩,因此您无需在 Kinesis Firehose 传输流中使用压缩。

为 Kinesis Firehose 创建订阅筛选器

  1. 创建一个 Amazon Simple Storage Service (Amazon S3) 存储桶。我们建议您使用专为 CloudWatch Logs 创建的存储桶。 但是,如果要使用现有存储桶,请跳至第 2 步。

    运行以下命令,将占用符区域替换为您想使用的区域:

    Copy
    aws s3api create-bucket --bucket my-bucket --create-bucket-configuration LocationConstraint=us-east-1

    下面是示例输出:

    Copy
    { "Location": "/my-bucket" }
  2. 创建 IAM 角色,该角色将向 Amazon Kinesis Firehose 授予将数据放入您的 Amazon S3 存储桶的权限。

    有关更多信息,请参阅 Amazon Kinesis Firehose 开发人员指南 中的使用 Amazon Kinesis Firehose 控制访问权限

    首先,如下所示使用文本编辑器在文件 ~/TrustPolicyForFirehose.json 中创建信任策略,将 account-id 替换为您的 AWS 账户 ID:

    Copy
    { "Statement": { "Effect": "Allow", "Principal": { "Service": "firehose.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId":"account-id" } } } }
  3. 使用 create-role 命令创建 IAM 角色,并指定信任策略文件。请记下返回的 Role.Arn 值,因为后面的步骤中将会用到它:

    Copy
    aws iam create-role \ --role-name FirehosetoS3Role \ --assume-role-policy-document file://~/TrustPolicyForFirehose.json { "Role": { "AssumeRolePolicyDocument": { "Statement": { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "logs.us-east-1.amazonaws.com" } } }, "RoleId": "AAOIIAH450GAB4HC5F431", "CreateDate": "2015-05-29T13:46:29.431Z", "RoleName": "FirehosetoS3Role", "Path": "/", "Arn": "arn:aws:iam::123456789012:role/FirehosetoS3Role" } }
  4. 创建权限策略以定义可对您的账户执行的 Kinesis Firehose 操作。首先,使用文本编辑器在文件 ~/PermissionsForFirehose.json 中创建权限策略:

    Copy
    { "Statement": [ { "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket", "s3:ListBucketMultipartUploads", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*" ] } ] }
  5. 使用以下 put-role-policy 命令将权限策略与角色关联:

    Copy
    aws iam put-role-policy --role-name FirehosetoS3Role --policy-name Permissions-Policy-For-Firehose --policy-document file://~/PermissionsForFirehose.json
  6. 如下所示创建目标 Kinesis Firehose 传输流,将 RoleARNBucketARN 的占位符值替换为创建的角色和存储桶 ARN:

    Copy
    aws firehose create-delivery-stream \ --delivery-stream-name 'my-delivery-stream' \ --s3-destination-configuration \ RoleARN='arn:aws:iam::123456789012:role/FirehosetoS3Role',BucketARN='arn:aws:s3:::my-bucket'

    请注意,Kinesis Firehose 对所传输的 Amazon S3 对象自动使用 YYYY/MM/DD/HH UTC 时间格式的前缀。您可以指定要添加在该时间格式前缀前面的额外前缀。如果前缀以正斜杠 (/) 结束,则在 Amazon S3 存储桶中显示为文件夹。

  7. 请耐心等待,直到流变为活动状态 (这可能需要几分钟时间)。您可以使用 Kinesis Firehose describe-delivery-stream 命令检查 DeliveryStreamDescription.DeliveryStreamStatus 属性。此外,请记下 DeliveryStreamDescription.DeliveryStreamARN 值,因为后面的步骤中将会用到它:

    Copy
    aws firehose describe-delivery-stream --delivery-stream-name "my-delivery-stream" { "DeliveryStreamDescription": { "HasMoreDestinations": false, "VersionId": "1", "CreateTimestamp": 1446075815.822, "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789012:deliverystream/my-delivery-stream", "DeliveryStreamStatus": "ACTIVE", "DeliveryStreamName": "my-delivery-stream", "Destinations": [ { "DestinationId": "destinationId-000000000001", "S3DestinationDescription": { "CompressionFormat": "UNCOMPRESSED", "EncryptionConfiguration": { "NoEncryptionConfig": "NoEncryption" }, "RoleARN": "delivery-stream-role", "BucketARN": "arn:aws:s3:::my-bucket", "BufferingHints": { "IntervalInSeconds": 300, "SizeInMBs": 5 } } } ] } }
  8. 创建 IAM 角色,该角色将向 CloudWatch Logs 授予将数据放入 Kinesis Firehose 传输流的权限。首先,使用文本编辑器在文件 ~/TrustPolicyForCWL.json 中创建信任策略:

    Copy
    { "Statement": { "Effect": "Allow", "Principal": { "Service": "logs.us-east-1.amazonaws.com" }, "Action": "sts:AssumeRole" } }
  9. 使用 create-role 命令创建 IAM 角色,并指定信任策略文件。请记下返回的 Role.Arn 值,因为后面的步骤中将会用到它:

    Copy
    aws iam create-role \ --role-name CWLtoKinesisFirehoseRole \ --assume-role-policy-document file://~/TrustPolicyForCWL.json { "Role": { "AssumeRolePolicyDocument": { "Statement": { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "logs.us-east-1.amazonaws.com" } } }, "RoleId": "AAOIIAH450GAB4HC5F431", "CreateDate": "2015-05-29T13:46:29.431Z", "RoleName": "CWLtoKinesisFirehoseRole", "Path": "/", "Arn": "arn:aws:iam::123456789012:role/CWLtoKinesisFirehoseRole" } }
  10. 创建权限策略以定义可对您的账户执行的 CloudWatch Logs 操作。首先,使用文本编辑器创建权限策略文件 (例如 ~/PermissionsForCWL.json):

    Copy
    { "Statement":[ { "Effect":"Allow", "Action":["firehose:*"], "Resource":["arn:aws:firehose:us-east-1:123456789012:*"] }, { "Effect":"Allow", "Action":["iam:PassRole"], "Resource":["arn:aws:iam::123456789012:role/CWLtoKinesisFirehoseRole"] } ] }
  11. 使用 put-role-policy 命令将权限策略与角色关联:

    Copy
    aws iam put-role-policy --role-name CWLtoKinesisFirehoseRole --policy-name Permissions-Policy-For-CWL --policy-document file://~/PermissionsForCWL.json
  12. 在 Amazon Kinesis Firehose 传输流进入活动状态并且您已创建 IAM 角色后,您便可以创建 CloudWatch Logs 订阅筛选器。订阅筛选器将立即启动从所选日志组到您的 Amazon Kinesis Firehose 传输流的实时日志数据流动:

    Copy
    aws logs put-subscription-filter \ --log-group-name "CloudTrail" \ --filter-name "Destination" \ --filter-pattern "{$.userIdentity.type = Root}" \ --destination-arn "arn:aws:firehose:us-east-1:123456789012:deliverystream/my-delivery-stream" \ --role-arn "arn:aws:iam::123456789012:role/CWLtoKinesisFirehoseRole"
  13. 当您设置订阅筛选器后,CloudWatch Logs 将与筛选器模式匹配的所有传入事件日志转发到您的 Amazon Kinesis Firehose 传输流。您的数据将开始根据您的 Amazon Kinesis Firehose 传输流上设置的时间缓冲间隔显示在 Amazon S3 中。经过足够的时间后,您可以通过检查您的 Amazon S3 存储桶验证您的数据。

    Copy
    aws s3api list-objects --bucket 'my-bucket' --prefix 'firehose/' { "Contents": [ { "LastModified": "2015-10-29T00:01:25.000Z", "ETag": "\"a14589f8897f4089d3264d9e2d1f1610\"", "StorageClass": "STANDARD", "Key": "firehose/2015/10/29/00/my-delivery-stream-2015-10-29-00-01-21-a188030a-62d2-49e6-b7c2-b11f1a7ba250", "Owner": { "DisplayName": "cloudwatch-logs", "ID": "1ec9cf700ef6be062b19584e0b7d84ecc19237f87b5" }, "Size": 593 }, { "LastModified": "2015-10-29T00:35:41.000Z", "ETag": "\"a7035b65872bb2161388ffb63dd1aec5\"", "StorageClass": "STANDARD", "Key": "firehose/2015/10/29/00/my-delivery-stream-2015-10-29-00-35-40-7cc92023-7e66-49bc-9fd4-fc9819cc8ed3", "Owner": { "DisplayName": "cloudwatch-logs", "ID": "1ec9cf700ef6be062b19584e0b7d84ecc19237f87b6" }, "Size": 5752 } ] }
    Copy
    aws s3api get-object --bucket 'my-bucket' --key 'firehose/2015/10/29/00/my-delivery-stream-2015-10-29-00-01-21-a188030a-62d2-49e6-b7c2-b11f1a7ba250' testfile.gz { "AcceptRanges": "bytes", "ContentType": "application/octet-stream", "LastModified": "Thu, 29 Oct 2015 00:07:06 GMT", "ContentLength": 593, "Metadata": {} }

    Amazon S3 对象中的数据以 gzip 格式压缩。您可以使用以下 Unix 命令检查命令行中的原始数据:

    Copy
    zcat testfile.gz