

# 使用服务器访问日志记录来记录请求
<a name="ServerLogs"></a>

服务器访问日志记录详细地记录对存储桶提出的各种请求。对于许多应用程序而言，服务器访问日志很有用。例如，访问日志信息可能在安全和访问权限审核方面很有用。此信息还有助于您了解客户群以及您的 Amazon S3 账单。

**注意**  
服务器访问日志不会记录 2019 年 3 月 20 日之后发布的区域的不正确区域重定向错误的相关信息。在存储桶所在区域的外部发出对象或存储桶的请求时，会发生不正确区域重定向错误。

## 如何启用日志传送？
<a name="server-access-logging-overview"></a>

要启用日志传输，请执行以下基本步骤。有关更多信息，请参阅 [启用 Amazon S3 服务器访问日志记录](enable-server-access-logging.md)。

1. **提供目的地存储桶**（也称为*目标存储桶*）的名称。此存储桶是您希望 Amazon S3 用于将访问日志保存为对象的位置。源存储桶和目标存储桶必须位于同一个 AWS 区域，并且由同一个账户拥有。目标存储桶不得具有 S3 对象锁定默认保留期配置。目标存储桶也不得启用申请方付款。

   您可以让日志传输至您拥有的且与源存储桶位于同一区域中的任何存储桶，包括源存储桶本身。不过，为了更方便地管理日志，我们建议您将访问日志保存在不同的存储桶中。

   当源存储桶和目标存储桶是同一存储桶时，将为写入该存储桶的日志创建额外的日志，从而形成日志的无限循环。我们不建议这样做，因为它会导致您的存储账单金额小幅增加。此外，有关日志的额外日志可能会导致更难以找到您所查找的日志。

   如果您选择将访问日志保存在源存储桶中，建议您为所有日志对象键指定目的地前缀（也称为*目标前缀*）。指定前缀时，所有日志对象名称都以公共字符串开头，从而使日志对象更易识别。

1. **（可选）将一个目标前缀分配给所有 Amazon S3 日志对象键。**利用目的地前缀（也称作*目标前缀*），可更轻松地找到日志对象。例如，如果您指定前缀值 `logs/`，则 Amazon S3 创建的每个日志对象的键均以 `logs/` 前缀开头，例如：

   ```
   logs/2013-11-01-21-32-16-E568B2907131C0C0
   ```

   如果指定前缀值 `logs`，则日志对象如下所示：

   ```
   logs2013-11-01-21-32-16-E568B2907131C0C0
   ```

   当同一目标存储桶有多个存储桶日志时，[键前缀](https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#keyprefix)也可用于区分源存储桶。

   当您删除日志时，此前缀也很有用。例如，您可以设置一个生命周期配置规则，让 Amazon S3 删除具有特定前缀的对象。有关更多信息，请参阅 [删除 Amazon S3 日志文件](deleting-log-files-lifecycle.md)。

1. **（可选）设置权限**以使其他人能够访问生成的日志。**默认情况下，仅存储桶拥有者始终拥有日志对象的完全访问权限。如果您的目标存储桶使用 S3 对象所有权的强制存储桶拥有者设置来禁用访问控制列表（ACL），则无法在使用 ACL 的目的地授权（也称作*目标授权*）中授予权限。但是，您可以更新目标存储桶的存储桶策略以向其他存储桶授予访问权限。有关更多信息，请参阅[Amazon S3 的身份和访问管理](security-iam.md)和[日志传输的权限](enable-server-access-logging.md#grant-log-delivery-permissions-general)。

1. **（可选）为日志文件设置日志对象键格式。**对于日志对象键格式（也称为*目标对象键格式*），有两个选项：
   + **非基于日期的分区** - 这是原始日志对象键格式。如果选择此格式，则日志文件键格式如下所示：

     ```
     [DestinationPrefix][YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]
     ```

     例如，如果您指定 `logs/` 作为前缀，则日志对象将按以下方式命名：

     ```
     logs/2013-11-01-21-32-16-E568B2907131C0C0
     ```
   + **基于日期的分区** - 如果选择基于日期的分区，则可以选择日志文件的事件时间或传输时间作为日志格式中使用的日期源。此格式让查询日志变得更轻松。

     如果选择基于日期的分区，则日志文件键格式如下所示：

     ```
     [DestinationPrefix][SourceAccountId]/[SourceRegion]/[SourceBucket]/[YYYY]/[MM]/[DD]/[YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]
     ```

     例如，如果您指定 `logs/` 作为目标前缀，则日志对象将按以下方式命名：

     ```
     logs/123456789012/us-west-2/amzn-s3-demo-source-bucket/2023/03/01/2023-03-01-21-32-16-E568B2907131C0C0
     ```

     对于传输时间传送，日志文件名中的时间与日志文件的传输时间对应。

     对于事件时间传送，年、月和日对应于事件的发生日期，小时、分钟和秒设置为键中的 `00`。这些日志文件中传送的日志仅针对特定日期。

   

   如果您通过 AWS Command Line Interface（AWS CLI）、AWS SDK 或 Amazon S3 REST API 配置日志，请使用 `TargetObjectKeyFormat` 指定日志对象键格式。要指定非基于日期的分区，请使用 `SimplePrefix`。要指定基于日期的分区，请使用 `PartitionedPrefix`。如果使用 `PartitionedPrefix`，则使用 `PartitionDateSource` 来指定 `EventTime` 或 `DeliveryTime`。

   对于 `SimplePrefix`，日志文件键格式如下所示：

   ```
   [TargetPrefix][YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]
   ```

   对于带事件时间或传输时间的 `PartitionedPrefix`，日志文件键格式如下所示：

   ```
   [TargetPrefix][SourceAccountId]/[SourceRegion]/[SourceBucket]/[YYYY]/[MM]/[DD]/[YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]
   ```

## 日志对象键格式
<a name="server-log-keyname-format"></a>

Amazon S3 将以下对象键格式用于在目标存储桶中上传的日志对象：
+ **非基于日期的分区** - 这是原始日志对象键格式。如果选择此格式，则日志文件键格式如下所示：

  ```
  [DestinationPrefix][YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]
  ```
+ **基于日期的分区** - 如果选择基于日期的分区，则可以选择日志文件的事件时间或传输时间作为日志格式中使用的日期源。此格式让查询日志变得更轻松。

  如果选择基于日期的分区，则日志文件键格式如下所示：

  ```
  [DestinationPrefix][SourceAccountId]/[SourceRegion]/[SourceBucket]/[YYYY]/[MM]/[DD]/[YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]
  ```

在日志对象键中，`YYYY`、`MM`、`DD`、`hh`、`mm` 和 `ss` 分别是表示年、月、日、小时、分钟和秒的数字。这些日期和时间采用协调世界时 (UTC)。

在特定时间传输的日志文件可包含在该时间前的任何时刻编写的记录。无法知道是否已传输特定时间间隔内的所有日志记录。

键的 `UniqueString` 部分用于防止覆盖文件。它没有意义，日志处理软件应忽略它。

## 如何传输日志？
<a name="how-logs-delivered"></a>

Amazon S3 定期收集访问日志记录，在日志文件中整合这些记录，然后将日志文件作为日志对象上传到目标存储桶。如果多个启用了日志记录的源存储桶使用相同的目标存储桶，此目标存储桶中将保留所有这些源存储桶的访问日志。但是，每个日志对象只会报告特定源存储桶的访问日志记录。

Amazon S3 使用特殊的日志传输账户写入服务器访问日志。这些写入受常规的访问控制限制。我们建议您更新目标存储桶上的存储桶策略，以授予对日志记录服务主体（`logging.s3.amazonaws.com`）的访问权限来进行访问日志传输。您也可以通过存储桶访问控制列表（ACL）向 S3 日志传输组授予访问日志传输的访问权限。但是，建议不要使用存储桶 ACL 授予对 S3 日志传输组的访问权限。

当您启用服务器访问日志记录并通过目标存储桶策略授予访问日志传输的访问权限时，您必须更新该策略，以允许日志记录服务主体访问 `s3:PutObject`。如果您使用 Amazon S3 控制台启用服务器访问日志录入，该控制台会自动更新目标存储桶策略，以便将这些权限授予日志记录服务主体。有关授予服务器访问日志传输的权限的更多信息，请参阅 [日志传输的权限](enable-server-access-logging.md#grant-log-delivery-permissions-general)。

**注意**  
对于 VPC 端点策略拒绝的 VPC 端点请求，或者对于在评估 VPC 策略之前失败的请求，S3 不支持向请求者或存储桶拥有者传输 CloudTrail 日志或服务器访问日志。

**S3 对象所有权的强制存储桶拥有者设置**  
如果目标存储桶使用对象所有权的强制存储桶拥有者设置，ACL 将被禁用，并且不再影响权限。您必须更新目标存储桶上的存储桶策略，以授予对日志记录服务主体的访问权。有关对象所有权的更多信息，请参阅[为服务器访问日志记录授予对 S3 日志传输组的访问权限](object-ownership-migrating-acls-prerequisites.md#object-ownership-server-access-logs)。

## 最大努力服务器日志传输
<a name="LogDeliveryBestEffort"></a>

服务器访问日志记录会以最大努力进行传输。针对已正确配置了日志记录的存储桶的大多数请求会导致传输一条日志记录。大多数日志记录将在记录后的几小时内传输，但可以更频繁地传输这些记录。

因此不能保证服务器日志记录的完整性和即时性。特殊请求的日志记录可能会在实际处理了请求之后进行传输，也可能*根本不会传输*。您甚至可能会看到日志记录的副本。服务器日志的用途在于向您提供有关存储桶流量性质方面的信息。虽然日志记录丢失或重复的情况十分少见，但请注意，服务器日志记录并不旨在完整记录所有请求。

由于服务器日志记录特征的最大努力性质，使用情况报告中可能有一个或多个访问请求不会出现在传输的服务器日志中。您可以在 AWS 账单与成本管理 控制台的**成本和使用情况报告**下找到这些使用情况报告。

## 存储桶日志记录状态更改将逐渐生效
<a name="BucketLoggingStatusChanges"></a>

存储桶日志记录状态的更改需要一定时间才能实际影响日志文件的传输。例如，如果您为某个存储桶启用了日志记录，那么将记录在以下时间内发送的请求，而不会记录其他请求。假定您将日志记录的目标存储桶从存储桶 A 更改为存储桶 B，则在接下来的一个小时里仍可能有一些日志传输到存储桶 A，但其他日志则会传输到新的目标存储桶 B。无论如何，新的设置将最终生效，并且您无需执行任何操作。

有关日志记录和日志文件的更多信息，请参阅以下各部分：

**Topics**
+ [如何启用日志传送？](#server-access-logging-overview)
+ [日志对象键格式](#server-log-keyname-format)
+ [如何传输日志？](#how-logs-delivered)
+ [最大努力服务器日志传输](#LogDeliveryBestEffort)
+ [存储桶日志记录状态更改将逐渐生效](#BucketLoggingStatusChanges)
+ [启用 Amazon S3 服务器访问日志记录](enable-server-access-logging.md)
+ [Amazon S3 服务器访问日志格式](LogFormat.md)
+ [删除 Amazon S3 日志文件](deleting-log-files-lifecycle.md)
+ [使用 Amazon S3 服务器访问日志来确定请求](using-s3-access-logs-to-identify-requests.md)
+ [排查服务器访问日志记录问题](troubleshooting-server-access-logging.md)

# 启用 Amazon S3 服务器访问日志记录
<a name="enable-server-access-logging"></a>

服务器访问日志记录详细地记录对 Amazon S3 存储桶提出的各种请求。对于许多应用程序而言，服务器访问日志很有用。例如，访问日志信息可能在安全和访问权限审核方面很有用。此信息还有助于您了解客户群以及您的 Amazon S3 账单。

默认情况下，Amazon S3 不会收集服务器访问日志。在您启用日志记录后，Amazon S3 会将源存储桶的访问日志传输到您选择的目的地存储桶（也称作*目标存储桶*）。目标存储桶必须位于源存储桶所在的 AWS 区域和 AWS 账户中。

访问日志记录包含有关对存储桶做出的请求的详细信息。这些信息可能包括请求类型、请求中指定的资源以及处理请求的时间和日期。有关日志记录基本知识的更多信息，请参阅 [使用服务器访问日志记录来记录请求](ServerLogs.md)。

**重要**  
在 Amazon S3 存储桶上启用服务器访问日志记录不收取额外费用。但是，系统提交给您的任何日志文件都会产生普通存储费用。(您可以随时删除日志文件。) 我们不会估计传输日志文件的数据传输费，但会按正常数据传输费率对访问日志文件收费。
您的目标存储桶不应启用服务器访问日志记录。您可以让日志传输至您拥有的且与源存储桶位于同一区域中的任何存储桶，包括源存储桶本身。但是，将日志传输到源存储桶会导致日志的无限循环，因此不建议这样做。为了更方便地管理日志，我们建议您将访问日志保存在不同的存储桶中。有关更多信息，请参阅 [如何启用日志传送？](ServerLogs.md#server-access-logging-overview)。
已启用 S3 对象锁定的 S3 存储桶不能用作服务器访问日志的目标存储桶。目标存储桶不得具有默认保留期配置。
目标存储桶不得启用“申请方付款”。

您可以使用 Amazon S3 控制台、Amazon S3 API、AWS Command Line Interface（AWS CLI）或 AWS SDK 启用或禁用服务器访问日志记录。

## 日志传输的权限
<a name="grant-log-delivery-permissions-general"></a>

Amazon S3 使用特殊的日志传输账户写入服务器访问日志。这些写入受常规的访问控制限制。对于访问日志传输，您必须向日志记录服务主体（`logging.s3.amazonaws.com`）授予对目标存储桶的访问权限。

要向 Amazon S3 授予日志传输权限，您可以使用存储桶策略或存储桶访问控制列表（ACL），具体取决于目标存储桶的 S3 对象所有权设置。但是，建议您使用存储桶策略，而不是 ACL。

**S3 对象所有权的强制存储桶拥有者设置**  
如果目标存储桶使用对象所有权的强制存储桶拥有者设置，ACL 将被禁用，并且不再影响权限。在这种情况下，您必须更新目标存储桶的存储桶策略，以向日志记录服务主体授予访问权限。您无法更新存储桶 ACL 以授予对 S3 日志传输组的访问权限。您也无法在 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLogging.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLogging.html) 配置中包含目的地授权（也称为*目标授权*）。

有关将现有存储桶 ACL 以便将访问日志传输迁移到存储桶策略的信息，请参阅 [为服务器访问日志记录授予对 S3 日志传输组的访问权限](object-ownership-migrating-acls-prerequisites.md#object-ownership-server-access-logs)。有关对象所有权的更多信息，请参阅[为您的存储桶控制对象所有权和禁用 ACL。](about-object-ownership.md)。当您创建新存储桶时，默认情况下 ACL 处于禁用状态。

**使用存储桶策略授予访问权限**  
要使用目标存储桶的存储桶策略授予访问权限，请更新存储桶策略以向日志记录服务主体授予 `s3:PutObject` 权限。如果您使用 Amazon S3 控制台启用服务器访问日志记录，该控制台会自动更新目标存储桶的存储桶策略，以便将此权限授予日志记录服务主体。如果以编程方式启用服务器访问日志记录，则必须手动更新目标存储桶的存储桶策略以向日志记录服务主体授予访问权限。

有关向日志服务主体授予访问权限的存储桶策略示例，请参阅[使用存储桶策略向日志记录服务主体授予权限](#grant-log-delivery-permissions-bucket-policy)。

**使用存储桶 ACL 授予访问权限**  
您也可以使用存储桶 ACL 授予访问日志传输的访问权限。您可以在存储桶 ACL 中添加一个授予条目，以授予对 S3 日志传输组的 `WRITE` 和 `READ_ACP` 权限。但是，不建议使用存储桶 ACL 授予对 S3 日志传输组的访问权限。有关更多信息，请参阅 [为您的存储桶控制对象所有权和禁用 ACL。](about-object-ownership.md)。有关将现有存储桶 ACL 以便将访问日志传输迁移到存储桶策略的信息，请参阅 [为服务器访问日志记录授予对 S3 日志传输组的访问权限](object-ownership-migrating-acls-prerequisites.md#object-ownership-server-access-logs)。有关向日志记录服务主体授予访问权限的示例 ACL，请参阅[使用存储桶 ACL 向日志传输组授予权限](#grant-log-delivery-permissions-acl)。

### 使用存储桶策略向日志记录服务主体授予权限
<a name="grant-log-delivery-permissions-bucket-policy"></a>

此示例存储桶策略向日志记录服务主体（`logging.s3.amazonaws.com`）授予 `s3:PutObject` 权限。要使用这一存储桶策略，请将 `user input placeholders` 替换为您自己的信息。在以下策略中，`amzn-s3-demo-destination-bucket` 是将服务器访问日志传输到的目标存储桶，`amzn-s3-demo-source-bucket` 是源存储桶。`EXAMPLE-LOGGING-PREFIX` 是要用于日志对象的可选目的地前缀（也称为*目标前缀*）。`SOURCE-ACCOUNT-ID` 是拥有源存储桶的 AWS 账户。

**注意**  
如果存储桶策略中有 `Deny` 语句，请确保这些语句不会阻止 Amazon S3 传输访问日志。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "S3ServerAccessLogsPolicy",
            "Effect": "Allow",
            "Principal": {
                "Service": "logging.s3.amazonaws.com"
            },
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::amzn-s3-demo-destination-bucket/EXAMPLE-LOGGING-PREFIX*",
            "Condition": {
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:s3:::amzn-s3-demo-source-bucket"
                },
                "StringEquals": {
                    "aws:SourceAccount": "SOURCE-ACCOUNT-ID"
                }
            }
        }
    ]
}
```

------

### 使用存储桶 ACL 向日志传输组授予权限
<a name="grant-log-delivery-permissions-acl"></a>

**注意**  
作为安全最佳实践，默认情况下，Amazon S3 在所有新存储桶中禁用访问控制列表（ACL）。有关使用 Amazon S3 控制台 ACL 权限的更多信息，请参阅 [配置 ACL](managing-acls.md)。

我们建议您不要使用此方法，而是使用存储桶 ACL 向日志传输组授予权限。但是，如果目标存储桶使用对象所有权的强制存储桶拥有者设置，则无法设置存储桶或对象 ACL。您也无法在 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLogging.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLogging.html) 配置中包含目的地授权（也称为*目标授权*）。而是必须使用存储桶策略向日志记录服务主体（`logging.s3.amazonaws.com`）授予访问权限。有关更多信息，请参阅 [日志传输的权限](#grant-log-delivery-permissions-general)。

在存储桶 ACL 中，日志传输组通过以下 URL 表示：

```
1. http://acs.amazonaws.com/groups/s3/LogDelivery
```

要授予 `WRITE` 和 `READ_ACP`（ACL 读取）权限，请将以下授权添加到目标存储桶 ACL：

```
 1. <Grant>
 2.     <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:type="Group">
 3.         <URI>http://acs.amazonaws.com/groups/s3/LogDelivery</URI> 
 4.     </Grantee>
 5.     <Permission>WRITE</Permission>
 6. </Grant>
 7. <Grant>
 8.     <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:type="Group">
 9.         <URI>http://acs.amazonaws.com/groups/s3/LogDelivery</URI> 
10.     </Grantee>
11.     <Permission>READ_ACP</Permission>
12. </Grant>
```

有关以编程方式添加 ACL 授权的示例，请参阅 [配置 ACL](managing-acls.md)。

**重要**  
当您对存储桶使用 AWS CloudFormation 来启用 Amazon S3 服务器访问日志记录，并使用 ACL 向 S3 日志传输组授予访问权限时，您还必须向 CloudFormation 模板添加 "`AccessControl": "LogDeliveryWrite"`。这样做非常重要，因为您只能通过为存储桶创建 ACL 来授予这些权限，而无法在 CloudFormation 中为存储桶创建自定义 ACL。您只能将标准 ACL 与 CloudFormation 结合使用。

## 要启用服务器访问日志记录
<a name="enable-server-logging"></a>

要使用 Amazon S3 控制台、Amazon S3 REST API、AWS SDK 和 AWS CLI 启用服务器访问日志记录，请使用以下过程。

### 使用 S3 控制台
<a name="server-access-logging"></a>

1. 登录到 AWS 管理控制台，然后通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)。

1. 在左侧导航窗格中，选择**通用存储桶**。

1. 在存储桶列表中，选择要为其启用服务器访问日志记录的存储桶的名称。

1. 选择 **Properties (属性)**。

1. 在 **Server access logging (服务器访问日志记录)** 部分中，请选择 **Edit (编辑)**。

1. 在**服务器访问日志记录**下，选择**启用**。

1. 在**目标存储桶**下，指定存储桶和可选前缀。如果您指定前缀，建议您在前缀后面加上正斜杠（`/`），以便更轻松地查找日志。
**注意**  
通过斜杠（`/`）指定前缀可让您更轻松地查找日志对象。例如，如果您指定前缀值 `logs/`，则 Amazon S3 创建的每个日志对象的键均以 `logs/` 前缀开头，如下所示：  

   ```
   logs/2013-11-01-21-32-16-E568B2907131C0C0
   ```
如果指定前缀值 `logs`，则日志对象如下所示：  

   ```
   logs2013-11-01-21-32-16-E568B2907131C0C0
   ```

1. 在**日志对象件格式**下，执行下列操作之一：
   + 要选择非基于日期的分区，请选择 **[DestinationPrefix][YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]**。
   + 要选择基于日期的分区，请选择 **[DestinationPrefix][SourceAccountId]/[SourceRegion]/[SourceBucket]/[YYYY]/[MM]/[DD]/[YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]**，然后选择 **S3 事件时间**或**日志文件传输时间**。

1. 选择**保存更改**。

   当您在存储桶上启用服务器访问日志记录时，控制台会在源存储桶上启用日志记录并更新目标存储桶的存储桶策略，以便向日志记录服务主体（`logging.s3.amazonaws.com`）授予 `s3:PutObject` 权限。有关存储桶策略的更多信息，请参阅 [使用存储桶策略向日志记录服务主体授予权限](#grant-log-delivery-permissions-bucket-policy)。

   您可以查看目标存储桶中的日志。启用服务器访问日志记录后，可能需要数小时，日志才会传输到目标存储桶。有关如何以及何时传输日志的更多信息，请参阅[如何传输日志？](ServerLogs.md#how-logs-delivered)。

有关更多信息，请参阅 [查看 S3 通用存储桶的属性](view-bucket-properties.md)。

### 使用 REST API
<a name="enable-logging-rest"></a>

要启用日志记录，请提交 [https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html) 请求，以在源存储桶上添加日志记录配置。该请求指定目的地存储桶（也称作*目标存储桶*），并（可选）指定要用于所有日志对象键的前缀。

以下示例将 `amzn-s3-demo-destination-bucket` 标识为目标存储桶，将 *`logs/`* 标识为前缀。

```
1. <BucketLoggingStatus xmlns="http://doc.s3.amazonaws.com/2006-03-01">
2.   <LoggingEnabled>
3.     <TargetBucket>amzn-s3-demo-destination-bucket</TargetBucket>
4.     <TargetPrefix>logs/</TargetPrefix>
5.   </LoggingEnabled>
6. </BucketLoggingStatus>
```

以下示例将 `amzn-s3-demo-destination-bucket` 标识为目标存储桶，将 *`logs/`* 标识为前缀，并将 `EventTime` 标识为日志对象键格式。

```
 1. <BucketLoggingStatus xmlns="http://doc.s3.amazonaws.com/2006-03-01">
 2.   <LoggingEnabled>
 3.     <TargetBucket>amzn-s3-demo-destination-bucket</TargetBucket>
 4.     <TargetPrefix>logs/</TargetPrefix>
 5.     <TargetObjectKeyFormat>
 6.       <PartitionedPrefix>
 7.          <PartitionDateSource>EventTime</PartitionDateSource>
 8.       </PartitionedPrefix>
 9.   </TargetObjectKeyFormat>
10.   </LoggingEnabled>
11. </BucketLoggingStatus>
```

日志对象由 S3 日志传递账户编写并拥有，存储桶拥有者对日志对象授予完全权限。您可以选择性地使用目的地授权（也称作*目标授权*）向其他用户授予权限，以便他们能够访问日志。有关更多信息，请参阅 [https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlogging.html)。

**注意**  
如果目标存储桶使用对象所有权的强制存储桶拥有者设置，则您无法使用目标授权向其他用户授予权限。要向其他用户授予权限，您可以更新目标存储桶的存储桶策略。有关更多信息，请参阅 [日志传输的权限](#grant-log-delivery-permissions-general)。

要检索存储桶上的日志记录配置，请使用 [https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlogging.html](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlogging.html) API 操作。

要删除日志记录配置，请发送带空白 `BucketLoggingStatus` 的 `PutBucketLogging` 请求：

```
1. <BucketLoggingStatus xmlns="http://doc.s3.amazonaws.com/2006-03-01">
2. </BucketLoggingStatus>
```

要对存储桶启用日志记录，您可以使用 Amazon S3 API 或 AWS SDK 包装程序库。

### 使用 AWS SDK
<a name="enable-logging-sdk"></a>

以下示例对存储桶启用日志记录。您必须创建两个存储桶，即一个源存储桶和一个目的地（目标）存储桶。这些示例首先更新目标存储桶上的存储桶 ACL。之后，向日志传输组授予向目标存储桶写入日志所需的权限，然后在源存储桶上启用日志记录。

这些示例不适用于使用对象所有权的强制存储桶拥有者设置的目标存储桶。

如果目的地（目标）存储桶使用对象所有权的强制存储桶拥有者设置，则无法设置存储桶或对象 ACL。您也不能将目的地（目标）授权包含在 [PutBucketLogging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLogging.html) 配置中。您必须使用存储桶策略向日志服务主体（`logging.s3.amazonaws.com`）授予访问权限。有关更多信息，请参阅 [日志传输的权限](#grant-log-delivery-permissions-general)。

------
#### [ .NET ]

**适用于 .NET 的 SDK**  
 查看 GitHub，了解更多信息。在 [AWS 代码示例存储库](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/S3#code-examples)中查找完整示例，了解如何进行设置和运行。

```
    using System;
    using System.IO;
    using System.Threading.Tasks;
    using Amazon.S3;
    using Amazon.S3.Model;
    using Microsoft.Extensions.Configuration;

    /// <summary>
    /// This example shows how to enable logging on an Amazon Simple Storage
    /// Service (Amazon S3) bucket. You need to have two Amazon S3 buckets for
    /// this example. The first is the bucket for which you wish to enable
    /// logging, and the second is the location where you want to store the
    /// logs.
    /// </summary>
    public class ServerAccessLogging
    {
        private static IConfiguration _configuration = null!;

        public static async Task Main()
        {
            LoadConfig();

            string bucketName = _configuration["BucketName"];
            string logBucketName = _configuration["LogBucketName"];
            string logObjectKeyPrefix = _configuration["LogObjectKeyPrefix"];
            string accountId = _configuration["AccountId"];

            // If the AWS Region defined for your default user is different
            // from the Region where your Amazon S3 bucket is located,
            // pass the Region name to the Amazon S3 client object's constructor.
            // For example: RegionEndpoint.USWest2 or RegionEndpoint.USEast2.
            IAmazonS3 client = new AmazonS3Client();

            try
            {
                // Update bucket policy for target bucket to allow delivery of logs to it.
                await SetBucketPolicyToAllowLogDelivery(
                    client,
                    bucketName,
                    logBucketName,
                    logObjectKeyPrefix,
                    accountId);

                // Enable logging on the source bucket.
                await EnableLoggingAsync(
                    client,
                    bucketName,
                    logBucketName,
                    logObjectKeyPrefix);
            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine($"Error: {e.Message}");
            }
        }

        /// <summary>
        /// This method grants appropriate permissions for logging to the
        /// Amazon S3 bucket where the logs will be stored.
        /// </summary>
        /// <param name="client">The initialized Amazon S3 client which will be used
        /// to apply the bucket policy.</param>
        /// <param name="sourceBucketName">The name of the source bucket.</param>
        /// <param name="logBucketName">The name of the bucket where logging
        /// information will be stored.</param>
        /// <param name="logPrefix">The logging prefix where the logs should be delivered.</param>
        /// <param name="accountId">The account id of the account where the source bucket exists.</param>
        /// <returns>Async task.</returns>
        public static async Task SetBucketPolicyToAllowLogDelivery(
            IAmazonS3 client,
            string sourceBucketName,
            string logBucketName,
            string logPrefix,
            string accountId)
        {
            var resourceArn = @"""arn:aws:s3:::" + logBucketName + "/" + logPrefix + @"*""";

            var newPolicy = @"{
                                ""Statement"":[{
                                ""Sid"": ""S3ServerAccessLogsPolicy"",
                                ""Effect"": ""Allow"",
                                ""Principal"": { ""Service"": ""logging.s3.amazonaws.com"" },
                                ""Action"": [""s3:PutObject""],
                                ""Resource"": [" + resourceArn + @"],
                                ""Condition"": {
                                ""ArnLike"": { ""aws:SourceArn"": ""arn:aws:s3:::" + sourceBucketName + @""" },
                                ""StringEquals"": { ""aws:SourceAccount"": """ + accountId + @""" }
                                        }
                                    }]
                                }";
            Console.WriteLine($"The policy to apply to bucket {logBucketName} to enable logging:");
            Console.WriteLine(newPolicy);

            PutBucketPolicyRequest putRequest = new PutBucketPolicyRequest
            {
                BucketName = logBucketName,
                Policy = newPolicy,
            };
            await client.PutBucketPolicyAsync(putRequest);
            Console.WriteLine("Policy applied.");
        }

        /// <summary>
        /// This method enables logging for an Amazon S3 bucket. Logs will be stored
        /// in the bucket you selected for logging. Selected prefix
        /// will be prepended to each log object.
        /// </summary>
        /// <param name="client">The initialized Amazon S3 client which will be used
        /// to configure and apply logging to the selected Amazon S3 bucket.</param>
        /// <param name="bucketName">The name of the Amazon S3 bucket for which you
        /// wish to enable logging.</param>
        /// <param name="logBucketName">The name of the Amazon S3 bucket where logging
        /// information will be stored.</param>
        /// <param name="logObjectKeyPrefix">The prefix to prepend to each
        /// object key.</param>
        /// <returns>Async task.</returns>
        public static async Task EnableLoggingAsync(
            IAmazonS3 client,
            string bucketName,
            string logBucketName,
            string logObjectKeyPrefix)
        {
            Console.WriteLine($"Enabling logging for bucket {bucketName}.");
            var loggingConfig = new S3BucketLoggingConfig
            {
                TargetBucketName = logBucketName,
                TargetPrefix = logObjectKeyPrefix,
            };

            var putBucketLoggingRequest = new PutBucketLoggingRequest
            {
                BucketName = bucketName,
                LoggingConfig = loggingConfig,
            };
            await client.PutBucketLoggingAsync(putBucketLoggingRequest);
            Console.WriteLine($"Logging enabled.");
        }

        /// <summary>
        /// Loads configuration from settings files.
        /// </summary>
        public static void LoadConfig()
        {
            _configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("settings.json") // Load settings from .json file.
                .AddJsonFile("settings.local.json", true) // Optionally, load local settings.
                .Build();
        }
    }
```
+  有关更多信息，请参阅《适用于 .NET 的 AWS SDK API 参考》**中的 [PutBucketLogging](https://docs.aws.amazon.com/goto/DotNetSDKV3/s3-2006-03-01/PutBucketLogging)。

------
#### [ Java ]

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.BucketLoggingStatus;
import software.amazon.awssdk.services.s3.model.LoggingEnabled;
import software.amazon.awssdk.services.s3.model.PartitionedPrefix;
import software.amazon.awssdk.services.s3.model.PutBucketLoggingRequest;
import software.amazon.awssdk.services.s3.model.TargetObjectKeyFormat;

// Class to set a bucket policy on a target S3 bucket and enable server access logging on a source S3 bucket.
public class ServerAccessLogging {
    private static S3Client s3Client;

    public static void main(String[] args) {
        String sourceBucketName = "SOURCE-BUCKET";
        String targetBucketName = "TARGET-BUCKET";
        String sourceAccountId = "123456789012";
        String targetPrefix = "logs/";

        // Create S3 Client.
        s3Client = S3Client.builder().
                region(Region.US_EAST_2)
                .build();

        // Set a bucket policy on the target S3 bucket to enable server access logging by granting the
        // logging.s3.amazonaws.com principal permission to use the PutObject operation.
        ServerAccessLogging serverAccessLogging = new ServerAccessLogging();
        serverAccessLogging.setTargetBucketPolicy(sourceAccountId, sourceBucketName, targetBucketName);

        // Enable server access logging on the source S3 bucket.
        serverAccessLogging.enableServerAccessLogging(sourceBucketName, targetBucketName,
                targetPrefix);

    }

    // Function to set a bucket policy on the target S3 bucket to enable server access logging by granting the
    // logging.s3.amazonaws.com principal permission to use the PutObject operation.
    public void setTargetBucketPolicy(String sourceAccountId, String sourceBucketName, String targetBucketName) {
        String policy = "{\n" +
                "    \"Version\": \"2012-10-17\",\n" +
                "    \"Statement\": [\n" +
                "        {\n" +
                "            \"Sid\": \"S3ServerAccessLogsPolicy\",\n" +
                "            \"Effect\": \"Allow\",\n" +
                "            \"Principal\": {\"Service\": \"logging.s3.amazonaws.com\"},\n" +
                "            \"Action\": [\n" +
                "                \"s3:PutObject\"\n" +
                "            ],\n" +
                "            \"Resource\": \"arn:aws:s3:::" + targetBucketName + "/*\",\n" +
                "            \"Condition\": {\n" +
                "                \"ArnLike\": {\n" +
                "                    \"aws:SourceArn\": \"arn:aws:s3:::" + sourceBucketName + "\"\n" +
                "                },\n" +
                "                \"StringEquals\": {\n" +
                "                    \"aws:SourceAccount\": \"" + sourceAccountId + "\"\n" +
                "                }\n" +
                "            }\n" +
                "        }\n" +
                "    ]\n" +
                "}";
        s3Client.putBucketPolicy(b -> b.bucket(targetBucketName).policy(policy));
    }

    // Function to enable server access logging on the source S3 bucket.
    public void enableServerAccessLogging(String sourceBucketName, String targetBucketName,
            String targetPrefix) {
        TargetObjectKeyFormat targetObjectKeyFormat = TargetObjectKeyFormat.builder()
                .partitionedPrefix(PartitionedPrefix.builder().partitionDateSource("EventTime").build())
                .build();
        LoggingEnabled loggingEnabled = LoggingEnabled.builder()
                .targetBucket(targetBucketName)
                .targetPrefix(targetPrefix)
                .targetObjectKeyFormat(targetObjectKeyFormat)
                .build();
        BucketLoggingStatus bucketLoggingStatus = BucketLoggingStatus.builder()
                .loggingEnabled(loggingEnabled)
                .build();
        s3Client.putBucketLogging(PutBucketLoggingRequest.builder()
                .bucket(sourceBucketName)
                .bucketLoggingStatus(bucketLoggingStatus)
                .build());
    }

}
```

------

### 使用 AWS CLI
<a name="enabling-s3-access-logs-for-requests"></a>

我们建议您在其中放置 S3 存储桶的每个 AWS 区域 中都创建一个专用日志记录存储桶。然后，将 Amazon S3 访问日志传输到该 S3 存储桶。有关更多信息和示例，请参阅《AWS CLI 参考》**中的 [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-bucket-logging.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-bucket-logging.html)。

如果目的地（目标）存储桶使用对象所有权的强制存储桶拥有者设置，则无法设置存储桶或对象 ACL。您也不能将目的地（目标）授权包含在 [PutBucketLogging](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLogging.html) 配置中。您必须使用存储桶策略向日志服务主体（`logging.s3.amazonaws.com`）授予访问权限。有关更多信息，请参阅 [日志传输的权限](#grant-log-delivery-permissions-general)。

**Example — 为跨两个区域的五个存储桶启用访问日志**  
在本示例中，您有以下 5 个存储桶：  
+ `amzn-s3-demo-source-bucket-us-east-1`
+ `amzn-s3-demo-source-bucket1-us-east-1`
+ `amzn-s3-demo-source-bucket2-us-east-1`
+ `amzn-s3-demo-bucket1-us-west-2`
+ `amzn-s3-demo-bucket2-us-west-2`
**注意**  
以下过程的最后一步提供了示例 bash 脚本，可使用这些脚本来创建日志记录存储桶，并在这些存储桶上启用服务器访问日志记录。要使用这些脚本，必须创建 `policy.json` 和 `logging.json` 文件，如以下过程所述。

1. 在美国西部（俄勒冈州）和美国东部（弗吉尼亚州北部）区域创建两个日志记录存储桶，并为其指定以下名称：
   + `amzn-s3-demo-destination-bucket-logs-us-east-1`
   + `amzn-s3-demo-destination-bucket1-logs-us-west-2`

1. 稍后，在这些步骤中，您将启用服务器访问日志记录，如下所示：
   + `amzn-s3-demo-source-bucket-us-east-1` 记录到带有前缀 `amzn-s3-demo-source-bucket-us-east-1` 的 S3 存储桶 `amzn-s3-demo-destination-bucket-logs-us-east-1`
   + `amzn-s3-demo-source-bucket1-us-east-1` 记录到带有前缀 `amzn-s3-demo-source-bucket1-us-east-1` 的 S3 存储桶 `amzn-s3-demo-destination-bucket-logs-us-east-1`
   + `amzn-s3-demo-source-bucket2-us-east-1` 记录到带有前缀 `amzn-s3-demo-source-bucket2-us-east-1` 的 S3 存储桶 `amzn-s3-demo-destination-bucket-logs-us-east-1`
   + `amzn-s3-demo-bucket1-us-west-2` 记录到带有前缀 `amzn-s3-demo-bucket1-us-west-2` 的 S3 存储桶 `amzn-s3-demo-destination-bucket1-logs-us-west-2`
   + `amzn-s3-demo-bucket2-us-west-2` 记录到带有前缀 `amzn-s3-demo-bucket2-us-west-2` 的 S3 存储桶 `amzn-s3-demo-destination-bucket1-logs-us-west-2`

1. 对于每个目标日志记录存储桶，使用存储桶 ACL *或*存储桶策略授予服务器访问日志传输的权限：
   + **更新存储桶策略**（建议）– 要向日志记录服务主体授予权限，请使用以下 `put-bucket-policy` 命令：将 `amzn-s3-demo-destination-bucket-logs` 替换为您的目标桶的名称。

     ```
     1. aws s3api put-bucket-policy --bucket amzn-s3-demo-destination-bucket-logs --policy file://policy.json
     ```

     `Policy.json` 是当前文件夹中包含以下存储桶策略的 JSON 文档。要使用这一存储桶策略，请将 `user input placeholders` 替换为您自己的信息。在以下策略中，*`amzn-s3-demo-destination-bucket-logs`* 是要将服务器访问日志传输到的目标存储桶，`amzn-s3-demo-source-bucket` 是源存储桶。`SOURCE-ACCOUNT-ID` 是拥有源存储桶的 AWS 账户。

------
#### [ JSON ]

****  

     ```
     {
         "Version":"2012-10-17",		 	 	 
         "Statement": [
             {
                 "Sid": "S3ServerAccessLogsPolicy",
                 "Effect": "Allow",
                 "Principal": {
                     "Service": "logging.s3.amazonaws.com"
                 },
                 "Action": [
                     "s3:PutObject"
                 ],
                 "Resource": "arn:aws:s3:::amzn-s3-demo-destination-bucket-logs/*",
                 "Condition": {
                     "ArnLike": {
                         "aws:SourceArn": "arn:aws:s3:::amzn-s3-demo-source-bucket"
                     },
                     "StringEquals": {
                         "aws:SourceAccount": "SOURCE-ACCOUNT-ID"
                     }
                 }
             }
         ]
     }
     ```

------
   + **更新存储桶 ACL** –要向 S3 日志传输组授予权限，请使用以下 `put-bucket-acl` 命令。将 *`amzn-s3-demo-destination-bucket-logs`* 替换为您的目的地（目标）存储桶的名称。

     ```
     1. aws s3api put-bucket-acl --bucket amzn-s3-demo-destination-bucket-logs  --grant-write URI=http://acs.amazonaws.com/groups/s3/LogDelivery --grant-read-acp URI=http://acs.amazonaws.com/groups/s3/LogDelivery 
     ```

1. 然后，创建一个包含日志记录配置的 `logging.json` 文件（基于以下三个示例之一）。创建 `logging.json` 文件后，可以使用以下 `put-bucket-logging` 命令应用日志记录配置。将 *`amzn-s3-demo-destination-bucket-logs`* 替换为您的目的地（目标）存储桶的名称。

   ```
   1. aws s3api put-bucket-logging --bucket amzn-s3-demo-destination-bucket-logs --bucket-logging-status file://logging.json 
   ```
**注意**  
您可以使用下一步中提供的 bash 脚本之一，而不是使用此 `put-bucket-logging` 命令在每个目标存储桶上应用日志记录配置。要使用这些脚本，您必须创建 `policy.json` 和 `logging.json` 文件，如该过程所述。

   `logging.json` 文件是当前文件夹中包含日志记录配置的 JSON 文档。如果目标存储桶使用对象所有权的强制存储桶拥有者设置，则您的日志记录配置不能包含目的地（目标）授权。有关更多信息，请参阅 [日志传输的权限](#grant-log-delivery-permissions-general)。  
**Example – `logging.json`，不带目的地（目标）授权**  

   以下示例 `logging.json` 文件不包含目的地（目标）授权。因此，您可以将此配置应用于使用对象所有权的强制存储桶拥有者设置的目的地（目标）存储桶。

   ```
     {
         "LoggingEnabled": {
             "TargetBucket": "amzn-s3-demo-destination-bucket-logs",
             "TargetPrefix": "amzn-s3-demo-destination-bucket/"
          }
      }
   ```  
**Example – `logging.json`，带目的地（目标）授权**  

   以下示例 `logging.json` 文件包含目的地（目标）授权。

   如果目标存储桶使用对象所有权的强制存储桶拥有者设置，则您无法在 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLogging.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLogging.html) 配置中包含目的地（目标）授权。有关更多信息，请参阅 [日志传输的权限](#grant-log-delivery-permissions-general)。

   ```
     {
         "LoggingEnabled": {
             "TargetBucket": "amzn-s3-demo-destination-bucket-logs",
             "TargetPrefix": "amzn-s3-demo-destination-bucket/",
             "TargetGrants": [
                  {
                     "Grantee": {
                         "Type": "CanonicalUser",
                         "ID": "79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be"
                      },
                     "Permission": "FULL_CONTROL"
                  }
              ]
          }
      }
   ```

**被授权者值**  
您可以通过以下方式（使用请求元素）指定要向其分配访问权限的人员（被授权者）：
   + 按人员的 ID：

     ```
     {
       "Grantee": {
         "Type": "CanonicalUser",
         "ID": "ID"
       }
     }
     ```
   + 按 URI：

     ```
     {
       "Grantee": {
         "Type": "Group",
         "URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers"
       }
     }
     ```  
**Example – `logging.json`，日志对象键格式设置为 S3 事件时间**  

   以下 `logging.json` 文件将日志对象键格式更改为 S3 事件时间。有关设置日志对象键格式的更多信息，请参阅[如何启用日志传送？](ServerLogs.md#server-access-logging-overview)

   ```
     { 
       "LoggingEnabled": {
           "TargetBucket": "amzn-s3-demo-destination-bucket-logs",
           "TargetPrefix": "amzn-s3-demo-destination-bucket/",
           "TargetObjectKeyFormat": { 
               "PartitionedPrefix": { 
                   "PartitionDateSource": "EventTime" 
               }
            }
       }
   }
   ```

1. 使用下列 bash 脚本之一为您账户中的所有存储桶添加访问日志记录。将 *`amzn-s3-demo-destination-bucket-logs`* 替换为目的地（目标）存储桶的名称，并将 `us-west-2` 替换为存储桶所在的区域的名称。
**注意**  
此脚本仅在所有存储桶均位于同一区域中时有用。如果您在多个区域中有存储桶，则必须调整该脚本。  
**Example — 使用存储桶策略授予访问权限并为账户中的存储桶添加日志记录**  

   ```
     loggingBucket='amzn-s3-demo-destination-bucket-logs'
     region='us-west-2'
     
     
     # Create the logging bucket.
     aws s3 mb s3://$loggingBucket --region $region
     
     aws s3api put-bucket-policy --bucket $loggingBucket --policy file://policy.json
     
     # List the buckets in this account.
     buckets="$(aws s3 ls | awk '{print $3}')"
     
     # Put a bucket logging configuration on each bucket.
     for bucket in $buckets
         do 
           # This if statement excludes the logging bucket.
           if [ "$bucket" == "$loggingBucket" ] ; then
               continue;
           fi
           printf '{
             "LoggingEnabled": {
               "TargetBucket": "%s",
               "TargetPrefix": "%s/"
           }
         }' "$loggingBucket" "$bucket"  > logging.json
         aws s3api put-bucket-logging --bucket $bucket --bucket-logging-status file://logging.json
         echo "$bucket done"
     done
     
     rm logging.json
     
     echo "Complete"
   ```  
**Example — 使用存储桶 ACL 授予访问权限并为账户中的存储桶添加日志记录**  

   ```
     loggingBucket='amzn-s3-demo-destination-bucket-logs'
     region='us-west-2'
     
     
     # Create the logging bucket.
     aws s3 mb s3://$loggingBucket --region $region
     
     aws s3api put-bucket-acl --bucket $loggingBucket --grant-write URI=http://acs.amazonaws.com/groups/s3/LogDelivery --grant-read-acp URI=http://acs.amazonaws.com/groups/s3/LogDelivery
     
     # List the buckets in this account.
     buckets="$(aws s3 ls | awk '{print $3}')"
     
     # Put a bucket logging configuration on each bucket.
     for bucket in $buckets
         do 
           # This if statement excludes the logging bucket.
           if [ "$bucket" == "$loggingBucket" ] ; then
               continue;
           fi
           printf '{
             "LoggingEnabled": {
               "TargetBucket": "%s",
               "TargetPrefix": "%s/"
           }
         }' "$loggingBucket" "$bucket"  > logging.json
         aws s3api put-bucket-logging --bucket $bucket --bucket-logging-status file://logging.json
         echo "$bucket done"
     done
     
     rm logging.json
     
     echo "Complete"
   ```

## 验证服务器访问日志设置
<a name="verify-access-logs"></a>

启用服务器访问日志记录后，请完成以下步骤：
+ 访问目标存储桶并验证是否正在传输日志文件。设置访问日志后，Amazon S3 会立即开始捕获请求并记录这些请求。但是，日志会在数小时后传输到目标存储桶。有关更多信息，请参阅[存储桶日志记录状态更改将逐渐生效](ServerLogs.md#BucketLoggingStatusChanges)和[最大努力服务器日志传输](ServerLogs.md#LogDeliveryBestEffort)。

  还可以通过使用 Amazon S3 请求指标并为这些指标设置 Amazon CloudWatch 警报，来自动验证日志传输。有关更多信息，请参阅 [使用 Amazon CloudWatch 监控指标](cloudwatch-monitoring.md)。
+ 验证您是否能够打开和读取日志文件的内容。

有关服务器访问日志记录故障排除信息，请参阅[排查服务器访问日志记录问题](troubleshooting-server-access-logging.md)。

# Amazon S3 服务器访问日志格式
<a name="LogFormat"></a>

服务器访问日志记录详细地记录对 Amazon S3 存储桶提出的各种请求。您可以将服务器访问日志用于以下目的：
+ 进行安全和访问审计
+ 了解您的客户群
+ 了解您的 Amazon S3 账单

本节介绍了有关 Amazon S3 服务器访问日志文件的格式和其他详细信息。

服务器访问日志文件由一系列的换行分隔日志记录组成。每个日志记录表示一个请求并由空格分隔的字段组成。

以下是含有五份日志记录的示例日志。

**注意**  
任何字段都可以设置为 `-` 以指示数据未知或不可用，或者该字段不适用于此请求。

```
79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be amzn-s3-demo-bucket1 [06/Feb/2019:00:00:38 +0000] 192.0.2.3 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be 3E57427F3EXAMPLE REST.GET.VERSIONING - "GET /amzn-s3-demo-bucket1?versioning HTTP/1.1" 200 - 113 - 7 - "-" "S3Console/0.4" - s9lzHYrFp76ZVxRcpX9+5cjAnEH2ROuNkd2BHfIa6UkFVdtjf5mKR3/eTPFvsiP/XV/VLi31234= SigV4 ECDHE-RSA-AES128-GCM-SHA256 AuthHeader amzn-s3-demo-bucket1.s3.us-west-1.amazonaws.com TLSV1.2 arn:aws:s3:us-west-1:123456789012:accesspoint/example-AP Yes us-east-1
79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be amzn-s3-demo-bucket1 [06/Feb/2019:00:00:38 +0000] 192.0.2.3 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be 891CE47D2EXAMPLE REST.GET.LOGGING_STATUS - "GET /amzn-s3-demo-bucket1?logging HTTP/1.1" 200 - 242 - 11 - "-" "S3Console/0.4" - 9vKBE6vMhrNiWHZmb2L0mXOcqPGzQOI5XLnCtZNPxev+Hf+7tpT6sxDwDty4LHBUOZJG96N1234= SigV4 ECDHE-RSA-AES128-GCM-SHA256 AuthHeader amzn-s3-demo-bucket1.s3.us-west-1.amazonaws.com TLSV1.2 - - us-east-1
79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be amzn-s3-demo-bucket1 [06/Feb/2019:00:00:38 +0000] 192.0.2.3 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be A1206F460EXAMPLE REST.GET.BUCKETPOLICY - "GET /amzn-s3-demo-bucket1?policy HTTP/1.1" 404 NoSuchBucketPolicy 297 - 38 - "-" "S3Console/0.4" - BNaBsXZQQDbssi6xMBdBU2sLt+Yf5kZDmeBUP35sFoKa3sLLeMC78iwEIWxs99CRUrbS4n11234= SigV4 ECDHE-RSA-AES128-GCM-SHA256 AuthHeader amzn-s3-demo-bucket1.s3.us-west-1.amazonaws.com TLSV1.2 - Yes us-east-1
79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be amzn-s3-demo-bucket1 [06/Feb/2019:00:01:00 +0000] 192.0.2.3 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be 7B4A0FABBEXAMPLE REST.GET.VERSIONING - "GET /amzn-s3-demo-bucket1?versioning HTTP/1.1" 200 - 113 - 33 - "-" "S3Console/0.4" - Ke1bUcazaN1jWuUlPJaxF64cQVpUEhoZKEG/hmy/gijN/I1DeWqDfFvnpybfEseEME/u7ME1234= SigV4 ECDHE-RSA-AES128-GCM-SHA256 AuthHeader amzn-s3-demo-bucket1.s3.us-west-1.amazonaws.com TLSV1.2 - - us-east-1
79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be amzn-s3-demo-bucket1 [06/Feb/2019:00:01:57 +0000] 192.0.2.3 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be DD6CC733AEXAMPLE REST.PUT.OBJECT s3-dg.pdf "PUT /amzn-s3-demo-bucket1/s3-dg.pdf HTTP/1.1" 200 - - 4406583 41754 28 "-" "S3Console/0.4" - 10S62Zv81kBW7BB6SX4XJ48o6kpcl6LPwEoizZQQxJd5qDSCTLX0TgS37kYUBKQW3+bPdrg1234= SigV4 ECDHE-RSA-AES128-SHA AuthHeader amzn-s3-demo-bucket1.s3.us-west-1.amazonaws.com TLSV1.2 - Yes us-east-1
```

以下是**计算校验和**操作的示例日志记录：

```
7cd47ef2be amzn-s3-demo-bucket [06/Feb/2019:00:00:38 +0000] - 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be e5042925-b524-4b3b-a869-f3881e78ff3a S3.COMPUTE.OBJECT.CHECKSUM example-object - - - - 1048576 - - - - - bPf7qjG4XwYdPgDQTl72GW/uotRhdPz2UryEyAFLDSRmKrakUkJCYLtAw6fdANcrsUYc1M/kIulXM1u5vZQT5g== - - - - - - - -
```

**Topics**
+ [日志记录字段](#log-record-fields)
+ [复制操作的其他日志记录](#AdditionalLoggingforCopyOperations)
+ [自定义访问日志信息](#LogFormatCustom)
+ [可扩展服务器访问日志格式的编程注意事项](#LogFormatExtensible)

## 日志记录字段
<a name="log-record-fields"></a>

以下列表介绍了日志记录字段。

**存储桶拥有者**  
源存储桶拥有者的规范用户 ID。规范用户 ID 是另一种形式的 AWS 账户 ID。有关规范用户 ID 的更多信息，请参阅《AWS 一般参考》**中的 [AWS 账户 标识符](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html)。有关如何查找您的账户的规范用户 ID 的信息，请参阅[查找 AWS 账户 的规范用户 ID](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-identifiers.html#FindCanonicalId)。  
**示例条目**  

```
79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be
```

**存储桶**  
请求处理的存储桶的名称。如果系统收到格式错误的请求且无法确定存储桶，则请求不会显示在任何的服务器访问日志中。  
**示例条目**  

```
amzn-s3-demo-bucket1
```

**Time**  
收到请求的时间；这些日期和时间采用协调世界时 (UTC)。使用 `strftime()` 术语的格式如下所示：`[%d/%b/%Y:%H:%M:%S %z]`  
**示例条目**  

```
[06/Feb/2019:00:00:38 +0000]
```

**远程 IP**  
请求者的显式 IP 地址。中间代理和防火墙可能会隐藏发出请求的计算机的实际 IP 地址。  
**示例条目**  

```
192.0.2.3
```

**请求者**  
请求者的规范用户 ID 或用于未经验证请求的 `-`。如果请求者是 IAM 用户，此字段会返回请求者的 IAM 用户名以及该 IAM 用户所属的 AWS 账户。此标识符与用于访问控制目的的标识符是相同的。  
**示例条目**  

```
79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be
```
如果请求者使用代入的角色，则此字段返回代入的 IAM 角色。  
**示例条目**  

```
arn:aws:sts::123456789012:assumed-role/roleName/test-role
```

**请求 ID**  
由 Amazon S3 生成的字符串，可用于唯一地标识每个请求。对于**计算校验和**任务请求，**请求 ID** 字段显示关联的任务 ID。有关更多信息，请参阅 [计算校验和](batch-ops-compute-checksums.md)。  
**示例条目**  

```
3E57427F33A59F07
```

**操作**  
此处列出的操作将声明为 `SOAP.operation`、`REST.HTTP_method.resource_type`、`WEBSITE.HTTP_method.resource_type` 或 `BATCH.DELETE.OBJECT`，或者 `S3.action.resource_type` 的 [S3 生命周期和日志记录](lifecycle-and-other-bucket-config.md#lifecycle-general-considerations-logging)。对于 [https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-compute-checksums.html](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-compute-checksums.html) 任务请求，该操作列为 `S3.COMPUTE.OBJECT.CHECKSUM`。  
**示例条目**  

```
REST.PUT.OBJECT
S3.COMPUTE.OBJECT.CHECKSUM
```

**Key**  
请求的密钥（对象名称）部分。  
**示例条目**  

```
/photos/2019/08/puppy.jpg
```

**Request-URI**  
HTTP 请求消息的 `Request-URI` 部分。此字段可能包含用户输入中未转义的引号。  
**示例条目**  

```
"GET /amzn-s3-demo-bucket1/photos/2019/08/puppy.jpg?x-foo=bar HTTP/1.1"
```

**HTTP 状态**  
响应的数字 HTTP 状态代码。  
**示例条目**  

```
200
```

**错误代码**  
Amazon S3 [Error responses](https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html) 或 `-`（如果没有发生错误）。  
**示例条目**  

```
NoSuchBucket
```

**发送的字节数**  
发送的响应字节数（不包括 HTTP 协议支出），或 `-`（如果为零)。  
**示例条目**  

```
2662992
```

**对象大小**  
所涉及的对象的总大小。  
**示例条目**  

```
3462992
```

**总时间**  
从服务器的角度传输请求的毫秒数。该值计算从收到请求到发送响应的最后一个字节的时间。由于网络延迟，从客户端计算出的时间可能会更长。  
**示例条目**  

```
70
```

**周转时间**  
Amazon S3 处理您的请求所花费的毫秒数。该值计算从收到您的请求的最后一个字节到发出响应的第一个字节的时间。  
**示例条目**  

```
10
```

**Referer**  
HTTP `Referer` 标头的值（如果存在）。发送请求时，HTTP 用户代理（例如，浏览器）通常会将此标头设置为链接的 URL 或嵌入页面。此字段可能包含用户输入中未转义的引号。  
**示例条目**  

```
"http://www.example.com/webservices"
```

**User-Agent**  
HTTP `User-Agent` 标头的值。此字段可能包含用户输入中未转义的引号。  
**示例条目**  

```
"curl/7.15.1"
```

**版本 ID**  
请求中的版本 ID；如果操作没有使用 `versionId` 参数，则为 `-`。  
**示例条目**  

```
3HL4kqtJvjVBH40Nrjfkd
```

**主机 ID**  
`x-amz-id-2` 或 Amazon S3 扩展请求 ID。  
**示例条目**  

```
s9lzHYrFp76ZVxRcpX9+5cjAnEH2ROuNkd2BHfIa6UkFVdtjf5mKR3/eTPFvsiP/XV/VLi31234=
```

**签名版本**  
签名版本，用于对请求进行身份验证的 `SigV2` 或 `SigV4`，或未经身份验证的请求的 `-`。  
**示例条目**  

```
SigV2
```

**密码套件**  
协商用于处理 HTTPS 请求的传输层安全性协议（TLS）密码，或者，对于 HTTP 为 `-`。  
**示例条目**  

```
ECDHE-RSA-AES128-GCM-SHA256
```

**身份验证类型**  
所使用的请求身份验证的类型：身份验证标头使用 `AuthHeader`，查询字符串（预签名 URL）使用 `QueryString`，未经身份验证的请求使用 `-`。  
**示例条目**  

```
AuthHeader
```

**主机标头**  
用于连接到 Amazon S3 的端点。  
**示例条目**  

```
s3.us-west-2.amazonaws.com
```
某些较早的区域支持传统的端点。您可能会在服务器访问日志或 AWS CloudTrail 日志中看到这些端点。有关更多信息，请参阅 [传统终端节点](VirtualHosting.md#s3-legacy-endpoints)。有关 Amazon S3 区域和端点的完整列表，请参阅《Amazon Web Services 一般参考》**中的 [Amazon S3 端点和限额](https://docs.aws.amazon.com/general/latest/gr/s3.html)。

**TLS 版本**  
客户端协商的传输层安全性（TLS）版本。此值为以下值之一：`TLSv1.1`、`TLSv1.2`、`TLSv1.3`；如果不使用 TLS，则为 `-`。  
**示例条目**  

```
TLSv1.2
```

**接入点 ARN**  
请求接入点的 Amazon Resource Name（ARN）。如果接入点的 ARN 格式不正确或未使用，则该字段将包含 `-`。有关接入点的更多信息，请参阅 [使用通用存储桶的 Amazon S3 接入点](using-access-points.md)。有关 ARN 的更多信息，请参阅《AWS 参考指南》**中的 [Amazon 资源名称（ARN）](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)。  
**示例条目**  

```
arn:aws:s3:us-east-1:123456789012:accesspoint/example-AP
```

**aclRequired**  
一个字符串，用于指示请求是否需要访问控制列表（ACL）以进行授权。如果请求需要 ACL 进行授权，则字符串为 `Yes`。如果不需要 ACL，则字符串为 `-`。有关 ACL 的更多信息，请参阅 [访问控制列表 (ACL) 概述](acl-overview.md)。有关使用 `aclRequired` 字段禁用 ACL 的更多信息，请参阅[为您的存储桶控制对象所有权和禁用 ACL。](about-object-ownership.md)。  
**示例条目**  

```
Yes
```

**源区域**  
从中发出请求的 AWS 区域。当无法确定源区域 [例如 PrivateLink 连接、Direct Connect 连接、自带 IP 地址（BYOIP）或非 AWS IP 地址] 时，或者当日志由根据客户设置的策略或操作（例如生命周期和校验和）触发的操作而生成时，此字段会显示破折号 (`-`)。  
**示例条目**  

```
us-east-1
```

## 复制操作的其他日志记录
<a name="AdditionalLoggingforCopyOperations"></a>

复制操作包括 `GET` 和 `PUT`。出于该原因，我们会在执行复制操作时记录两份记录。前面的部分描述了与操作的 `PUT` 部分相关的字段。以下列表描述了记录中与复制操作的 `GET` 部分相关的字段。

**存储桶拥有者**  
用于存储将复制的对象的存储桶的规范用户 ID。规范用户 ID 是另一种形式的 AWS 账户 ID。有关规范用户 ID 的更多信息，请参阅《AWS 一般参考》**中的 [AWS 账户 标识符](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html)。有关如何查找您的账户的规范用户 ID 的信息，请参阅[查找 AWS 账户 的规范用户 ID](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-identifiers.html#FindCanonicalId)。  
**示例条目**  

```
79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be
```

**存储桶**  
用于存储被复制对象的存储桶的名称。  
**示例条目**  

```
amzn-s3-demo-bucket1
```

**Time**  
收到请求的时间；这些日期和时间采用协调世界时 (UTC)。使用 `strftime()` 术语的格式如下所示：`[%d/%B/%Y:%H:%M:%S %z]`  
**示例条目**  

```
[06/Feb/2019:00:00:38 +0000]
```

**远程 IP**  
请求者的显式 IP 地址。中间代理和防火墙可能会隐藏发出请求的计算机的实际 IP 地址。  
**示例条目**  

```
192.0.2.3
```

**请求者**  
请求者的规范用户 ID 或用于未经验证请求的 `-`。如果请求者是 IAM 用户，此字段将返回请求者的 IAM 用户名以及该 IAM 用户所属的 AWS 账户根用户。此标识符与用于访问控制目的的标识符是相同的。  
**示例条目**  

```
79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be
```
如果请求者使用代入的角色，则此字段返回代入的 IAM 角色。  
**示例条目**  

```
arn:aws:sts::123456789012:assumed-role/roleName/test-role
```

**请求 ID**  
由 Amazon S3 生成的字符串，可用于唯一地标识每个请求。对于**计算校验和**任务请求，**请求 ID** 字段显示关联的任务 ID。有关更多信息，请参阅 [计算校验和](batch-ops-compute-checksums.md)。  
**示例条目**  

```
3E57427F33A59F07
```

**操作**  
此处列出的操作将声明为 `SOAP.operation`、`REST.HTTP_method.resource_type`、`WEBSITE.HTTP_method.resource_type` 或 `BATCH.DELETE.OBJECT`。  
**示例条目**  

```
REST.COPY.OBJECT_GET
```

**Key**  
被复制对象的键（对象名称）；或者，如果操作没有使用键参数，则为 `-`。  
**示例条目**  

```
/photos/2019/08/puppy.jpg
```

**Request-URI**  
HTTP 请求消息的 `Request-URI` 部分。此字段可能包含用户输入中未转义的引号。  
**示例条目**  

```
"GET /amzn-s3-demo-bucket1/photos/2019/08/puppy.jpg?x-foo=bar"
```

**HTTP 状态**  
复制操作的 `GET` 部分的数字 HTTP 状态代码。  
**示例条目**  

```
200
```

**错误代码**  
复制操作的 `GET` 部分的 Amazon S3 [Error responses](https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html) 或 `-`（如果没有发生错误）。  
**示例条目**  

```
NoSuchBucket
```

**发送的字节数**  
发送的响应字节数（不包括 HTTP 协议支出）；或者，如果为零，则为 `-`。  
**示例条目**  

```
2662992
```

**对象大小**  
所涉及的对象的总大小。  
**示例条目**  

```
3462992
```

**总时间**  
从服务器的角度传输请求的毫秒数。该值计算从收到请求到发送响应的最后一个字节的时间。由于网络延迟，从客户端计算出的时间可能会更长。  
**示例条目**  

```
70
```

**周转时间**  
Amazon S3 处理您的请求所花费的毫秒数。该值计算从收到您的请求的最后一个字节到发出响应的第一个字节的时间。  
**示例条目**  

```
10
```

**Referer**  
HTTP `Referer` 标头的值（如果存在）。发送请求时，HTTP 用户代理（例如，浏览器）通常会将此标头设置为链接的 URL 或嵌入页面。此字段可能包含用户输入中未转义的引号。  
**示例条目**  

```
"http://www.example.com/webservices"
```

**User-Agent**  
HTTP `User-Agent` 标头的值。此字段可能包含用户输入中未转义的引号。  
**示例条目**  

```
"curl/7.15.1"
```

**版本 ID**  
被复制对象的版本 ID，或者，如果 `x-amz-copy-source` 标头没有将 `versionId` 参数指定为复制源的一部分，则为 `-`。  
**示例条目**  

```
3HL4kqtJvjVBH40Nrjfkd
```

**主机 ID**  
`x-amz-id-2` 或 Amazon S3 扩展请求 ID。  
**示例条目**  

```
s9lzHYrFp76ZVxRcpX9+5cjAnEH2ROuNkd2BHfIa6UkFVdtjf5mKR3/eTPFvsiP/XV/VLi31234=
```

**签名版本**  
签名版本 `SigV2` 或 `SigV4`，用于对请求进行身份验证；或者，对于未经身份验证的请求，则为 `-`。  
**示例条目**  

```
SigV4
```

**密码套件**  
协商用于处理 HTTPS 请求的传输层安全性协议（TLS）密码，或者，对于 HTTP 为 `-`。  
**示例条目**  

```
ECDHE-RSA-AES128-GCM-SHA256
```

**身份验证类型**  
所使用的请求身份验证的类型：身份验证标头使用 `AuthHeader`，查询字符串（预签名 URL）使用 `QueryString`，未经身份验证的请求使用 `-`。  
**示例条目**  

```
AuthHeader
```

**主机标头**  
用于连接到 Amazon S3 的端点。  
**示例条目**  

```
s3.us-west-2.amazonaws.com
```
某些较早的区域支持传统的端点。您可能会在服务器访问日志或 AWS CloudTrail 日志中看到这些端点。有关更多信息，请参阅 [传统终端节点](VirtualHosting.md#s3-legacy-endpoints)。有关 Amazon S3 区域和端点的完整列表，请参阅《Amazon Web Services 一般参考》**中的 [Amazon S3 端点和限额](https://docs.aws.amazon.com/general/latest/gr/s3.html)。

**TLS 版本**  
客户端协商的传输层安全性（TLS）版本。此值为以下值之一：`TLSv1.1`、`TLSv1.2`、`TLSv1.3`；如果不使用 TLS，则为 `-`。  
**示例条目**  

```
TLSv1.2
```

**接入点 ARN**  
请求接入点的 Amazon Resource Name（ARN）。如果接入点的 ARN 格式不正确或未使用，则该字段将包含 `-`。有关接入点的更多信息，请参阅 [使用通用存储桶的 Amazon S3 接入点](using-access-points.md)。有关 ARN 的更多信息，请参阅《AWS 参考指南》**中的 [Amazon 资源名称（ARN）](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)。  
**示例条目**  

```
arn:aws:s3:us-east-1:123456789012:accesspoint/example-AP
```

**aclRequired**  
一个字符串，用于指示请求是否需要访问控制列表（ACL）以进行授权。如果请求需要 ACL 进行授权，则字符串为 `Yes`。如果不需要 ACL，则字符串为 `-`。有关 ACL 的更多信息，请参阅 [访问控制列表 (ACL) 概述](acl-overview.md)。有关使用 `aclRequired` 字段禁用 ACL 的更多信息，请参阅[为您的存储桶控制对象所有权和禁用 ACL。](about-object-ownership.md)。  
**示例条目**  

```
Yes
```

**源区域**  
从中发出请求的 AWS 区域。当无法确定源区域 [例如 PrivateLink 连接、Direct Connect 连接、自带 IP 地址（BYOIP）或非 AWS IP 地址] 时，或者当日志由根据客户设置的策略或操作（例如生命周期和校验和）触发的操作而生成时，此字段会显示破折号 (`-`)。  
**示例条目**  

```
us-east-1
```

## 自定义访问日志信息
<a name="LogFormatCustom"></a>

您可以包含要存储在请求的访问日志记录中的自定义信息。为此，请将自定义查询字符串参数添加到请求的 URL 中。Amazon S3 忽略以 `x-` 开头的查询字符串参数，但是会将这些参数包含在请求的访问日志记录中，以作为日志记录的 `Request-URI` 字段的一部分。

例如，`GET` 的 `"s3.amazonaws.com/amzn-s3-demo-bucket1/photos/2019/08/puppy.jpg?x-user=johndoe"` 请求工作方式与 `"s3.amazonaws.com/amzn-s3-demo-bucket1/photos/2019/08/puppy.jpg"` 的请求的相同，只是 `"x-user=johndoe"` 字符串包含在关联日志记录的 `Request-URI` 字段中。此功能仅在 REST 界面中可用。

## 可扩展服务器访问日志格式的编程注意事项
<a name="LogFormatExtensible"></a>

有时，我们可能会通过向每一行的末尾添加新字段来扩展访问日志记录格式。因此，请确保用于解析服务器访问日志的任何代码都可以处理它后续可能不理解的字段。

# 删除 Amazon S3 日志文件
<a name="deleting-log-files-lifecycle"></a>

一个已启用服务器访问日志记录的 Amazon S3 存储桶可能会随时间推移积累许多服务器日志对象。您的应用程序可能在创建之后的特定时间段内需要这些访问日志，在此之后，您可能希望删除它们。您可以使用 Amazon S3 生命周期配置来设置规则，以便 Amazon S3 可自动对这些对象进行排队，从而在其生命周期结束时进行删除。

您可以使用共享前缀为 S3 存储桶中的对象子集定义生命周期配置。如果您在服务器访问日志记录配置中指定了前缀，则可以设置生命周期配置规则，以删除具有该前缀的日志对象。

例如，假定您的日志对象具有前缀 `logs/`。您可以设置生命周期配置规则，以便在指定的时间段后删除存储桶中具有 `logs/` 前缀的所有对象。

有关生命周期配置的更多信息，请参阅 [管理对象的生命周期](object-lifecycle-mgmt.md)。

有关服务器访问日志记录的一般信息，请参阅 [使用服务器访问日志记录来记录请求](ServerLogs.md)。

# 使用 Amazon S3 服务器访问日志来确定请求
<a name="using-s3-access-logs-to-identify-requests"></a>

您可以使用 Amazon S3 服务器访问日志来确定 Amazon S3 请求。

**注意**  
要确定 Amazon S3 请求，建议您使用 AWS CloudTrail 数据事件而不是 Amazon S3 服务器访问日志。CloudTrail 数据事件更易于设置并包含更多信息。有关更多信息，请参阅 [使用 CloudTrail 识别 Amazon S3 请求](cloudtrail-request-identification.md)。
根据您获得的访问请求数量，与使用 CloudTrail 数据事件相比，分析日志使用的资源或时间可能会更多。

**Topics**
+ [使用 Amazon Athena 查询访问日志中的请求](#querying-s3-access-logs-for-requests)
+ [使用 Amazon S3 访问日志确定签名版本 2 请求](#using-s3-access-logs-to-identify-sigv2-requests)
+ [使用 Amazon S3 访问日志确定对象访问请求](#using-s3-access-logs-to-identify-objects-access)

## 使用 Amazon Athena 查询访问日志中的请求
<a name="querying-s3-access-logs-for-requests"></a>

您可以使用 Amazon Athena 查询 Amazon S3 访问日志以确定 Amazon S3 请求。

Amazon S3 将服务器访问日志作为对象存储在 S3 存储桶中。使用可以分析 Amazon S3 中的日志的工具通常会更轻松。Athena 支持分析 S3 对象，并且可用于查询 Amazon S3 访问日志。

**Example**  
以下示例说明了如何在 Amazon Athena 中查询 Amazon S3 服务器访问日志。将以下示例中使用的 `user input placeholders` 替换为您自己的信息。  
要在 Athena 查询中指定 Amazon S3 位置，您必须提供将日志传输到的存储桶的 S3 URI。此 URI 必须包含以下格式的存储桶名称和前缀：`s3://amzn-s3-demo-bucket1-logs/prefix/`

1. 从 [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home) 打开 Athena 控制台。

1. 在查询编辑器中，运行类似如下的命令。将 `s3_access_logs_db` 替换为要为数据库指定的名称。

   ```
   CREATE DATABASE s3_access_logs_db
   ```
**注意**  
最佳实践是在与 S3 存储桶所在相同的 AWS 区域中创建数据库。

1. 在查询编辑器中，运行类似如下的命令以便在步骤 2 中创建的数据库中创建一个表架构。将 `s3_access_logs_db.mybucket_logs` 替换为要为表指定的名称。`STRING` 和 `BIGINT` 数据类型值是访问日志属性。您可以在 Athena 中查询这些属性。对于 `LOCATION`，输入之前记下的 S3 存储桶和前缀。

------
#### [ Date-based partitioning ]

   ```
   CREATE EXTERNAL TABLE s3_access_logs_db.mybucket_logs( 
    `bucketowner` STRING, 
    `bucket_name` STRING, 
    `requestdatetime` STRING, 
    `remoteip` STRING, 
    `requester` STRING, 
    `requestid` STRING, 
    `operation` STRING, 
    `key` STRING, 
    `request_uri` STRING, 
    `httpstatus` STRING, 
    `errorcode` STRING, 
    `bytessent` BIGINT, 
    `objectsize` BIGINT, 
    `totaltime` STRING, 
    `turnaroundtime` STRING, 
    `referrer` STRING, 
    `useragent` STRING, 
    `versionid` STRING, 
    `hostid` STRING, 
    `sigv` STRING, 
    `ciphersuite` STRING, 
    `authtype` STRING, 
    `endpoint` STRING, 
    `tlsversion` STRING,
    `accesspointarn` STRING,
    `aclrequired` STRING,
    `sourceregion` STRING)
    PARTITIONED BY (
      `timestamp` string)
   ROW FORMAT SERDE 
    'org.apache.hadoop.hive.serde2.RegexSerDe' 
   WITH SERDEPROPERTIES ( 
    'input.regex'='([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) ([^ ]*)(?: ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*))?.*$') 
   STORED AS INPUTFORMAT 
    'org.apache.hadoop.mapred.TextInputFormat' 
   OUTPUTFORMAT 
    'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
   LOCATION
    's3://bucket-name/prefix-name/account-id/region/source-bucket-name/'
    TBLPROPERTIES (
     'projection.enabled'='true', 
     'projection.timestamp.format'='yyyy/MM/dd', 
     'projection.timestamp.interval'='1', 
     'projection.timestamp.interval.unit'='DAYS', 
     'projection.timestamp.range'='2024/01/01,NOW', 
     'projection.timestamp.type'='date', 
     'storage.location.template'='s3://bucket-name/prefix-name/account-id/region/source-bucket-name/${timestamp}')
   ```

------
#### [ Non-date-based partitioning ]

   ```
   CREATE EXTERNAL TABLE `s3_access_logs_db.mybucket_logs`(
     `bucketowner` STRING, 
     `bucket_name` STRING, 
     `requestdatetime` STRING, 
     `remoteip` STRING, 
     `requester` STRING, 
     `requestid` STRING, 
     `operation` STRING, 
     `key` STRING, 
     `request_uri` STRING, 
     `httpstatus` STRING, 
     `errorcode` STRING, 
     `bytessent` BIGINT, 
     `objectsize` BIGINT, 
     `totaltime` STRING, 
     `turnaroundtime` STRING, 
     `referrer` STRING, 
     `useragent` STRING, 
     `versionid` STRING, 
     `hostid` STRING, 
     `sigv` STRING, 
     `ciphersuite` STRING, 
     `authtype` STRING, 
     `endpoint` STRING, 
     `tlsversion` STRING,
     `accesspointarn` STRING,
     `aclrequired` STRING,
     `sourceregion` STRING)
   ROW FORMAT SERDE 
     'org.apache.hadoop.hive.serde2.RegexSerDe' 
   WITH SERDEPROPERTIES ( 
     'input.regex'='([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) ([^ ]*)(?: ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*))?.*$') 
   STORED AS INPUTFORMAT 
     'org.apache.hadoop.mapred.TextInputFormat' 
   OUTPUTFORMAT 
     'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
   LOCATION
     's3://amzn-s3-demo-bucket1-logs/prefix/'
   ```

------

1. 在导航窗格中，在 **Database (数据库)** 下，请选择您的数据库。

1. 在 **Tables (表)** 下，请选择表名称旁边的 **Preview table (预览表)**。

   在 **Results (结果)** 窗格中，您应看到来自服务器访问日志中的数据，如 `bucketowner`、`bucket`、`requestdatetime` 等。这表示您成功创建了 Athena 表。您现在可以查询 Amazon S3 服务器访问日志。

**Example — 显示已删除对象的人员和时间（时间戳、IP 地址和 IAM 用户）**  

```
SELECT requestdatetime, remoteip, requester, key 
FROM s3_access_logs_db.mybucket_logs 
WHERE key = 'images/picture.jpg' AND operation like '%DELETE%';
```

**Example — 显示 IAM 用户执行的所有操作**  

```
SELECT * 
FROM s3_access_logs_db.mybucket_logs 
WHERE requester='arn:aws:iam::123456789123:user/user_name';
```

**Example — 显示在特定时间段内对对象执行的所有操作**  

```
SELECT *
FROM s3_access_logs_db.mybucket_logs
WHERE Key='prefix/images/picture.jpg' 
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2017-02-18:07:00:00','yyyy-MM-dd:HH:mm:ss')
AND parse_datetime('2017-02-18:08:00:00','yyyy-MM-dd:HH:mm:ss');
```

**Example — 显示在特定时间段内传输到特定 IP 地址的数据量**  

```
SELECT coalesce(SUM(bytessent), 0) AS bytessenttotal
FROM s3_access_logs_db.mybucket_logs
WHERE remoteip='192.0.2.1'
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2022-06-01','yyyy-MM-dd')
AND parse_datetime('2022-07-01','yyyy-MM-dd');
```

**Example — 查找特定时间段内 HTTP 5xx 错误的请求 ID**  

```
SELECT requestdatetime, key, httpstatus, errorcode, requestid, hostid 
FROM s3_access_logs_db.mybucket_logs
WHERE httpstatus like '5%' AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'
```

**注意**  
要减少保留日志的时间，您可以为服务器访问日志存储桶创建 S3 生命周期配置。创建生命周期配置规则以定期删除日志文件。这样做可以减少 Athena 为每个查询分析的数据量。有关更多信息，请参阅 [在存储桶上设置 S3 生命周期配置](how-to-set-lifecycle-configuration-intro.md)。

## 使用 Amazon S3 访问日志确定签名版本 2 请求
<a name="using-s3-access-logs-to-identify-sigv2-requests"></a>

对 Signature Version 2 的 Amazon S3 支持将会关闭（弃用）。之后，Amazon S3 将不再接受使用 Signature Version 2 的请求，并且所有请求必须使用 Signature Version 4 进行签署。您可以使用 Amazon S3 访问日志确定签名版本 2 访问请求。

**注意**  
要确定签名版本 2 请求，建议您使用 AWS CloudTrail 数据事件而不是 Amazon S3 服务器访问日志。CloudTrail 数据事件更易于设置，并且包含比服务器访问日志更多的信息。有关更多信息，请参阅 [使用 CloudTrail 识别 Amazon S3 签名版本 2 请求](cloudtrail-request-identification.md#cloudtrail-identification-sigv2-requests)。

**Example — 显示发送签名版本 2 流量的所有请求者**  

```
SELECT requester, sigv, Count(sigv) as sigcount 
FROM s3_access_logs_db.mybucket_logs
GROUP BY requester, sigv;
```

## 使用 Amazon S3 访问日志确定对象访问请求
<a name="using-s3-access-logs-to-identify-objects-access"></a>

对于诸如 `GET`、`PUT` 和 `DELETE` 等操作，您可以对 Amazon S3 服务访问日志使用查询以确定 Amazon S3 对象访问请求，并发现有关这些请求的进一步信息。

以下 Amazon Athena 查询示例说明如何从服务器访问日志中获取 Amazon S3 的所有 `PUT` 对象请求。

**Example — 显示在特定时段内正在发送 `PUT` 对象请求的所有请求者**  

```
SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE operation='REST.PUT.OBJECT' 
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z') 
BETWEEN parse_datetime('2019-07-01:00:42:42',yyyy-MM-dd:HH:mm:ss')
AND parse_datetime('2019-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')
```

以下 Amazon Athena 查询示例说明了如何从服务器访问日志中获取 Amazon S3 的所有 `GET` 对象请求。

**Example — 显示在特定时段内正在发送 `GET` 对象请求的所有请求者**  

```
SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE operation='REST.GET.OBJECT' 
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z') 
BETWEEN parse_datetime('2019-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND parse_datetime('2019-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')
```

以下 Amazon Athena 查询示例说明了如何从服务器访问日志中获取向 S3 存储桶发出的所有匿名请求。

**Example — 显示在特定时段内向存储桶发出请求的所有匿名请求者**  

```
SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE requester IS NULL 
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z') 
BETWEEN parse_datetime('2019-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND parse_datetime('2019-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')
```

以下 Amazon Athena 查询说明如何识别向 S3 存储桶发出的所有请求，这些请求需要访问控制列表（ACL）进行授权。您可以使用此信息将这些 ACL 权限迁移到相应的存储桶策略并禁用 ACL。创建这些存储桶策略后，您可以对这些存储桶禁用 ACL。有关禁用 ACL 的更多信息，请参阅[禁用 ACL 的先决条件](object-ownership-migrating-acls-prerequisites.md)。

**Example — 识别所有需要 ACL 进行授权的请求**  

```
SELECT bucket_name, requester, key, operation, aclrequired, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE aclrequired = 'Yes' 
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2022-05-10:00:00:00','yyyy-MM-dd:HH:mm:ss')
AND parse_datetime('2022-08-10:00:00:00','yyyy-MM-dd:HH:mm:ss')
```

**注意**  
您可以修改日期范围以满足您的需要。
也可以使用这些查询示例进行安全监控。您可以查看意外或未经授权的 IP 地址或请求者发出的 `PutObject` 或 `GetObject` 调用的结果，以及确定向存储桶发出的任何匿名请求。
此查询仅从启用了日志记录的时间检索信息。
如果您使用 AWS CloudTrail 日志，请参阅 [使用 CloudTrail 识别对 S3 对象的访问权限](cloudtrail-request-identification.md#cloudtrail-identification-object-access)。

# 排查服务器访问日志记录问题
<a name="troubleshooting-server-access-logging"></a>

以下主题可以帮助您排查在使用 Amazon S3 设置日志记录时可能遇到的问题。

**Topics**
+ [设置日志记录时的常见错误消息](#common-errors)
+ [排查传输失败问题](#delivery-failures)

## 设置日志记录时的常见错误消息
<a name="common-errors"></a>

当您通过 AWS Command Line Interface（AWS CLI）和 AWS SDK 启用日志记录功能时，可能会出现以下常见错误消息：

错误：不允许进行跨 S3 位置日志记录

如果目的地存储桶（也称为*目标存储桶*）与源存储桶位于不同的区域，则会出现不允许跨 S3 位置日志记录错误。要解决此错误，请确保配置为接收访问日志的目标存储桶与源存储桶位于相同的 AWS 区域和 AWS 账户中。

错误：要记录的存储桶的拥有者与目标存储桶的拥有者必须相同

启用服务器访问日志记录时，如果指定的目标存储桶属于其他账户，则会出现此错误。要解决此错误，请确保目标存储桶与源存储桶位于相同 AWS 账户中。

**注意**  
我们建议您选择不同于源存储桶的目的地存储桶。当源存储桶和目标存储桶相同时，将为写入存储桶的日志创建额外的日志，这会增加您的存储费用。这些关于日志的额外日志也可能使您难以找到您正在寻找的特定日志。为了更方便地管理日志，我们建议将访问日志保存在不同的存储桶中。有关更多信息，请参阅 [如何启用日志传送？](ServerLogs.md#server-access-logging-overview)。

错误：用于日志记录的目标存储桶不存在

在设置配置之前，目标存储桶必须已存在。此错误表示目标存储桶不存在或找不到目标存储桶。确保存储桶名称拼写正确，然后重试。

错误：不允许对强制存储桶拥有者的存储存储桶进行目标授权

此错误表明目标存储桶为 S3 对象所有权使用“强制存储桶拥有者”设置。“强制存储桶拥有者”设置不支持目的地（目标）存储桶。有关更多信息，请参阅 [日志传输的权限](enable-server-access-logging.md#grant-log-delivery-permissions-general)。

## 排查传输失败问题
<a name="delivery-failures"></a>

为避免出现服务器访问日志记录问题，请确保遵循以下最佳实践：
+ **S3 日志传输组具有对目的地存储桶的写入权限** – S3 日志传输组将服务器访问日志传输到目的地存储桶。存储桶策略或存储桶访问控制列表（ACL）可用于授予对目标存储桶的写入权限。但是，我们建议您使用存储桶策略，而不是 ACL。有关如何授予对目标存储桶的写入权限的更多信息，请参阅[日志传输的权限](enable-server-access-logging.md#grant-log-delivery-permissions-general)。
**注意**  
如果目标存储桶为对象所有权使用“强制存储桶拥有者”设置，请注意以下几点：  
ACL 已禁用，不再影响权限。这意味着，您无法更新存储桶 ACL 以授予对 S3 日志传输组的访问权限。相反，要授予对日志记录服务主体的访问权限，您必须更新目标存储桶的存储桶策略。
您不能将目标授权包含在 `PutBucketLogging` 配置中。
+ **目标存储桶的存储桶策略允许访问日志** – 检查目标存储桶的存储桶策略。在存储桶策略中搜索包含 `"Effect": "Deny"` 的所有语句。然后，验证 `Deny` 语句不会阻止将访问日志写入存储桶中。
+ **未对目标存储桶启用 S3 对象锁定** – 检查目标存储桶是否启用了对象锁定。对象锁定阻止服务器访问日志传输。您必须选择未启用对象锁定的目标存储桶。
+ **如果在目标存储桶上启用了默认加密，则选择 Amazon S3 托管密钥（SSE-S3）**– 仅当使用具有 Amazon S3 托管式密钥的服务器端加密（SSE-S3）时，才能对目标存储桶使用默认存储桶加密。服务器访问日志记录目标存储桶不支持采用 AWS Key Management Service（AWS KMS）密钥的默认服务器端加密（SSE-KMS）。有关如何启用默认加密的更多信息，请参阅[配置默认加密](default-bucket-encryption.md)。
+ **目标存储桶未启用申请方付款** – 不支持将申请方付款存储桶用作服务器访问日志记录的目标存储桶。要允许传输服务器访问日志，请对目标存储桶禁用申请方付款选项。
+ **查看您的 AWS Organizations 服务控制策略（SCP）和资源控制策略（RCP）**- 当使用 AWS Organizations 时，请检查服务控制策略和资源控制策略以确保允许 Amazon S3 访问。这些策略指定了受影响账户中的主体和资源的最大权限。在策略中搜索任何包含 `"Effect": "Deny"` 的语句，并验证 `Deny` 语句不会阻止将任何访问日志写入存储桶中。有关更多信息，请参阅《AWS Organizations User Guide》**中的 [Authorization policies in AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_authorization_policies.html)。
+ **等待一段时间让最近的日志记录配置更改生效** – 首次启用服务器访问日志记录或更改日志的目标存储桶时，需要一定的时间才能完全生效。要正确记录和传输所有请求，可能需要一个多小时的时间。

  要检查日志传输失败，请在 Amazon CloudWatch 中启用请求指标。如果日志在几个小时内未传输，请查找 `4xxErrors` 指标，该指标可能表明日志传输失败。有关启用请求指标的更多信息，请参阅[为存储桶中的所有对象创建 CloudWatch 指标配置](configure-request-metrics-bucket.md)。