

# 将 Lambda 函数日志发送到 Amazon S3
<a name="logging-with-s3"></a>

您可以使用 Lambda 控制台配置 Lambda 函数，以将日志直接发送到 Amazon S3。此功能为长期日志存储提供了经济高效的解决方案，并使用 Athena 等服务实现了强大的分析选项。

**注意**  
您可以使用 Lambda 控制台、AWS CLI、AWS CloudFormation 和所有 AWS SDK 将 Lambda 函数日志配置为发送到 Amazon S3。

## 定价
<a name="logging-s3-pricing"></a>

有关定价详细信息，请参阅 [Amazon CloudWatch 定价](https://aws.amazon.com/cloudwatch/pricing/#Vended_Logs)。

## Amazon S3 日志目标所需的权限
<a name="logging-s3-permissions"></a>

使用 Lambda 控制台将 Amazon S3 配置为函数的日志目标时，您需要：

1. 将 CloudWatch Logs 与 Lambda 结合使用[所需的 IAM 权限](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-prereqs)。

1. [设置 CloudWatch Logs 订阅筛选条件以将 Lambda 函数日志发送到 Amazon S3](#using-cwl-subscription-filter-lambda-s3)。此筛选条件定义将哪些日志事件传送到 Amazon S3 存储桶。

## 设置 CloudWatch Logs 订阅筛选条件以将 Lambda 函数日志发送到 Amazon S3
<a name="using-cwl-subscription-filter-lambda-s3"></a>

要将日志从 CloudWatch Logs 发送到 Amazon S3，您需要创建一个订阅筛选条件。此筛选条件定义将哪些日志事件传送到 Amazon S3 存储桶。您的 Amazon S3 存储桶必须与您的日志组位于同一区域。

### 为 Amazon S3 创建订阅筛选条件
<a name="create-subscription-filter-s3"></a>

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

   运行以下命令，将占位符区域替换为您想使用的区域：

   ```
   aws s3api create-bucket --bucket amzn-s3-demo-bucket2 --create-bucket-configuration LocationConstraint=region
   ```
**注意**  
`amzn-s3-demo-bucket2` 是示例 Amazon S3 存储桶名称。它是*预留的*。要使此过程生效，您必须将其替换为唯一的 Amazon S3 存储桶名称。

   下面是示例输出：

   ```
   {
       "Location": "/amzn-s3-demo-bucket2"
   }
   ```

1. 创建 IAM 角色，该角色将授予 CloudWatch Logs 将数据放入 Amazon S3 存储桶的权限。此策略包括 aws:SourceArn 全局条件上下文密钥，有助于避免出现混淆代理安全问题。有关更多信息，请参阅 [Confused deputy prevention](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Subscriptions-confused-deputy.html)。

   1. 使用文本编辑器在文件 `~/TrustPolicyForCWL.json` 中创建一个信任策略，具体如下所示：

      ```
      {
          "Statement": {
              "Effect": "Allow",
              "Principal": { "Service": "logs.amazonaws.com" },
              "Condition": { 
                  "StringLike": {
                      "aws:SourceArn": "arn:aws:logs:region:123456789012:*"
                  } 
               },
              "Action": "sts:AssumeRole"
          } 
      }
      ```

   1. 使用 create-role 命令创建 IAM 角色，并指定信任策略文件。请记下返回的 Role.Arn 值，因为后面的步骤中将会用到它：

      ```
      aws iam create-role \
       --role-name CWLtoS3Role \
       --assume-role-policy-document file://~/TrustPolicyForCWL.json
      {
          "Role": {
              "AssumeRolePolicyDocument": {
                  "Statement": {
                      "Action": "sts:AssumeRole",
                      "Effect": "Allow",
                      "Principal": {
                          "Service": "logs.amazonaws.com"
                      },
                      "Condition": { 
                          "StringLike": {
                              "aws:SourceArn": "arn:aws:logs:region:123456789012:*"
                          } 
                      }
                  }
              },
              "RoleId": "AAOIIAH450GAB4HC5F431",
              "CreateDate": "2015-05-29T13:46:29.431Z",
              "RoleName": "CWLtoS3Role",
              "Path": "/",
              "Arn": "arn:aws:iam::123456789012:role/CWLtoS3Role"
          }
      }
      ```

1. 创建权限策略以定义可对您的账户执行的 CloudWatch Logs 操作。首先，使用文本编辑器在文件 `~/PermissionsForCWL.json` 中创建权限策略：

   ```
   {
     "Statement": [
       {
         "Effect": "Allow",
         "Action": ["s3:PutObject"],
         "Resource": ["arn:aws:s3:::amzn-s3-demo-bucket2/*"]
       }
     ]
   }
   ```

   使用以下 `put-role-policy` 命令，将权限策略与角色关联：

   ```
   aws iam put-role-policy --role-name CWLtoS3Role --policy-name Permissions-Policy-For-S3 --policy-document file://~/PermissionsForCWL.json
   ```

1. 创建 `Delivery` 日志组或使用现有的 `Delivery` 日志组。

   ```
   aws logs create-log-group --log-group-name my-logs --log-group-class DELIVERY --region REGION_NAME
   ```

1. `PutSubscriptionFilter` 用于设置目标

   ```
   aws logs put-subscription-filter
   --log-group-name my-logs
   --filter-name my-lambda-delivery
   --filter-pattern ""
   --destination-arn arn:aws:s3:::amzn-s3-demo-bucket2
   --role-arn arn:aws:iam::123456789012:role/CWLtoS3Role
   --region REGION_NAME
   ```

## 将 Lambda 函数日志发送到 Amazon S3
<a name="logging-s3-setup"></a>

在 Lambda 控制台中，您可以在创建新函数后将函数日志直接发送到 Amazon S3。为此，请完成以下步骤：

1. 登录 AWS 管理控制台，然后打开 Lambda 控制台。

1. 选择您的函数名称。

1. 选择**配置**选项卡。

1. 选择**监控和操作工具**选项卡。

1. 在“日志记录配置”部分中，选择**编辑**。

1. 在“日志内容”部分，选择一种日志格式。

1. 在“日志目标”部分中，完成以下步骤：

   1. 选择目标服务。

   1. 选择**创建新的日志组**或使用**现有日志组**。
**注意**  
如果为 Amazon S3 目标选择现有日志组，请确保您选择的日志组是 `Delivery` 日志组类型。

   1. 选择 Amazon S3 存储桶作为函数日志的目标。

   1. 将出现 CloudWatch `Delivery` 日志组。

1. 选择**保存**。

**注意**  
如果控制台中提供的 IAM 角色没有所需的权限，则目标设置将失败。要解决此问题，请参阅 [Amazon S3 日志目标所需的权限](#logging-s3-permissions)。

## 跨账户日志记录
<a name="cross-account-logging-s3"></a>

您可以将 Lambda 为使用不同 AWS 账户向 Amazon S3 存储桶发送日志。这需要设置目标，并在两个账户中配置适当的权限。

有关设置跨账户日志记录的详细说明，包括所需的 IAM 角色和策略，请参阅 CloudWatch Logs 文档中的 [Setting up a new cross-account subscription](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CrossAccountSubscriptions.html)。