

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在中配置可观测性功能 AWS SDK for Java 2.x
<a name="observability"></a>

遥测是自动收集和传输来自远程来源的数据，使您能够监控和分析系统的行为。

Java SDK for Java 2.x 中的可观察性 AWS 服务 通过捕获完整请求生命周期的丰富遥测数据，让开发人员全面了解其 Java 应用程序是如何与之交互的。这些功能使您能够收集、分析和可视化遥测信号，例如指标、日志和跟踪，从而使您能够监控请求模式、识别瓶颈并优化应用程序的 AWS 交互以提高可靠性和性能。

**Topics**
+ [指标](metrics.md)
+ [监控](monitoring-overview.md)
+ [日志记录](logging-slf4j.md)

# 从中发布 SDK 指标 AWS SDK for Java 2.x
<a name="metrics"></a>

借助， AWS SDK for Java 2.x 您可以收集有关应用程序中服务客户端和请求的指标，分析 Amazon CloudWatch Logs 中的输出，然后对其采取行动。

默认情况下，SDK 中的指标收集处于禁用状态。本主题可帮助您启用和配置指标收集。

## SDK 指标入门
<a name="getting-started-with-metrics"></a>

要在应用程序中启用指标收集，请根据您的使用案例选择适当的 `[MetricPublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/metrics/MetricPublisher.html)` 接口实现，并按照详细的设置说明进行操作：

**对于长时间运行的应用程序：**
+ 使用 `[CloudWatchMetricPublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/metrics/publishers/cloudwatch/CloudWatchMetricPublisher.html)`
+ 有关完整的设置说明、代码示例和配置选项，请参阅[从长时间运行的应用程序发布 SDK 指标](metric-pub-impl-cwmp.md)。

**对于 AWS Lambda 函数：**
+ 使用 `[EmfMetricLoggingPublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/metrics/publishers/emf/EmfMetricLoggingPublisher.html)`
+ 有关完整的设置说明、依赖关系和特定于 Lambda 的配置，请参阅[发布 SDK AWS Lambda 函数指标](metric-pub-impl-emf.md)。

**对于故障排除和控制台输出：**
+ 使用 `[LoggingMetricPublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/metrics/LoggingMetricPublisher.html)`
+ 有关本地开发和故障排除的设置说明、格式选项以及示例，请参阅[将 SDK 指标输出到控制台进行开发和调试](metric-pub-impl-logging.md)。

## 快速实施预览
<a name="quick-implementation-preview"></a>

以下是针对每个使用案例启用指标的具体示例：

**长时间运行的应用程序：**

```
MetricPublisher metricsPub = CloudWatchMetricPublisher.create();
DynamoDbClient ddb = DynamoDbClient.builder()
    .overrideConfiguration(c -> c.addMetricPublisher(metricsPub))
    .build();
```

**Lambda 函数：**

```
EmfMetricLoggingPublisher emfPublisher = EmfMetricLoggingPublisher.builder()
    .namespace("MyApp")
    .build();
DynamoDbClient dynamoDb = DynamoDbClient.builder()
    .overrideConfiguration(c -> c.addMetricPublisher(emfPublisher))
    .build();
```

**开发和调试：**

```
MetricPublisher loggingPublisher = LoggingMetricPublisher.create();
S3Client s3 = S3Client.builder()
    .overrideConfiguration(c -> c.addMetricPublisher(loggingPublisher))
    .build();
```

## 基于 AWS CRT 的 S3 客户端的指标限制
<a name="metrics-using-s3-crt-based-client"></a>

[基于AWS CRT 的 S3 客户端](crt-based-s3-client.md)目前不支持 SDK 指标收集。 AWS 基于 CRT 的 S3 客户端实例的构建器不提供配置指标发布者的方法。[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.html)

## 指标何时可用？
<a name="when-are-metrics-available"></a>

指标通常在 SDK for Java 发出它们后的 5-10 分钟内可用。要获得准确性和 up-to-date指标，请在从 Java 应用程序发出指标至少 10 分钟后查看 Cloudwatch。

## 收集哪些信息？
<a name="what-information-is-collected"></a>

指标收集包括以下内容：
+ API 请求的数量，包括请求成功还是失败
+ 有关 AWS 服务 您在 API 请求中调用的信息，包括返回的异常
+ 封送、签名和 HTTP 请求等各种操作的用时
+ HTTP 客户端指标，例如打开的连接数、待处理的请求数以及所使用的 HTTP 客户端的名称

**注意**  
可用指标因 HTTP 客户端而异。

有关完整列表，请参阅[服务客户端指标](metrics-list.md)。

## 我该如何使用这些信息？
<a name="how-can-i-use-this-information"></a>

您可以使用 SDK 收集的指标来监控应用程序中的服务客户端。您可以查看总体使用趋势、识别异常情况、查看返回的服务客户端异常，或者深入了解特定问题。使用 Ama CloudWatch zon Logs，您还可以创建警报，以便在应用程序达到您定义的条件时立即通知您。

有关更多信息，请参阅《[亚马逊 CloudWatch 日志用户指南》中的 “使用亚马逊 CloudWatch 日志指标](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/working_with_metrics.html) [[” 和 “使用亚马逊 CloudWatch 日志](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/)警报](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)”。

# 使用长时间运行的应用程序发布 SDK 指标 AWS SDK for Java 2.x
<a name="metric-pub-impl-cwmp"></a>

由于该`[CloudWatchMetricPublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/metrics/publishers/cloudwatch/CloudWatchMetricPublisher.html)`实施会汇总指标并将其定期上传到 Amazon CloudWatch ，因此其使用最适合长时间运行的应用程序。

指标发布者的默认设置旨在最大限度地减少内存使用量和 CloudWatch 成本，同时仍能为指标数据提供有用的见解。

## 设置
<a name="prerequisitesmetrics"></a>

先完成以下步骤，然后才能使用 `CloudWatchMetricPublisher` 来启用和使用指标。

### 步骤 1：添加所需的依赖项
<a name="cwmp-set-up-deps"></a>

将项目依赖项（例如，在您的 `pom.xml` 或 `build.gradle` 文件中）配置为使用 适用于 Java 的 AWS SDK版本 `2.14.0` 或更高版本。

在项目的依赖项中包括 artifactId `cloudwatch-metric-publisher`，并使用版本号 `2.14.0` 或更高版本号。

例如：

```
<project>
  <dependencyManagement>
   <dependencies>
      <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>bom</artifactId>
        <version>[2.30.11](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)</version>  <!-- Navigate the link to see the latest version. -->
        <type>pom</type>
        <scope>import</scope>
      </dependency>
   </dependencies>
  </dependencyManagement>
  <dependencies>
   <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>cloudwatch-metric-publisher</artifactId>
   </dependency>
  </dependencies>
</project>
```

### 步骤 2：配置所需的权限
<a name="cwmp-set-up-perms"></a>

为指标发布者使用的 IAM 身份启用 `cloudwatch:PutMetricData` 权限，以允许适用于 Java 的 SDK 编写指标。

## 为特定请求启用指标
<a name="enable-metrics-for-a-specific-request"></a>

以下课程展示了如何为向 Amazon DynamoDB 发出的请求启用 CloudWatch 指标发布者。该类使用默认的指标发布者配置。

```
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.metrics.publishers.cloudwatch.CloudWatchMetricPublisher;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest;

public class DefaultConfigForRequest {
    // Use one MetricPublisher for your application. It can be used with requests or service clients.
    static MetricPublisher metricsPub = CloudWatchMetricPublisher.create();

    public static void main(String[] args) {
        DynamoDbClient ddb = DynamoDbClient.create();
        // Publish metrics the for ListTables operation.
        ddb.listTables(ListTablesRequest.builder()
            .overrideConfiguration(c -> c.addMetricPublisher(metricsPub))
            .build());

        // Perform more work in your application.

        // A MetricsPublisher has its own lifecycle independent of any service client or request that uses it.
        // If you no longer need the publisher, close it to free up resources.
        metricsPub.close();  // All metrics stored in memory are flushed to CloudWatch.

        // Perform more work with the DynamoDbClient instance without publishing metrics.
        // Close the service client when you no longer need it.
        ddb.close();
    }
}
```

**重要**  
当服务客户端不再使用时，请确保您的应用程序在 `[MetricPublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/metrics/MetricPublisher.html)` 实例上调用 `close`。否则可能会导致线程泄漏或文件描述符泄漏。

## 为特定服务客户端启用摘要指标
<a name="enable-metrics-for-a-specific-service-client"></a>

以下代码片段显示了如何为服务客户端启用具有默认设置的 CloudWatch 指标发布者。

```
MetricPublisher metricsPub = CloudWatchMetricPublisher.create();

DynamoDbClient ddb = DynamoDbClient.builder()
          .overrideConfiguration(c -> c.addMetricPublisher(metricsPub))
          .build();
```

## 自定义 CloudWatch 指标发布者
<a name="customize-metrics-publisher"></a>

以下类演示如何为特定服务客户端的指标发布者设置自定义配置。自定义设置包括加载特定的配置文件、指定指标发布者向其发送请求的 AWS 区域，以及自定义发布者向其发送指标的频率。 CloudWatch

```
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.core.metrics.CoreMetric;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.metrics.publishers.cloudwatch.CloudWatchMetricPublisher;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cloudwatch.CloudWatchAsyncClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;

import java.time.Duration;

public class CustomConfigForDDBClient {
    // Use one MetricPublisher for your application. It can be used with requests or service clients.
    static MetricPublisher metricsPub = CloudWatchMetricPublisher.builder()
        .cloudWatchClient(CloudWatchAsyncClient.builder()
            .region(Region.US_WEST_2)
            .credentialsProvider(ProfileCredentialsProvider.create("cloudwatch"))
            .build())
        .uploadFrequency(Duration.ofMinutes(5))
        .maximumCallsPerUpload(100)
        .namespace("ExampleSDKV2Metrics")
        .detailedMetrics(CoreMetric.API_CALL_DURATION)
        .build();

    public static void main(String[] args) {
        DynamoDbClient ddb = DynamoDbClient.builder()
            .overrideConfiguration(c -> c.addMetricPublisher(metricsPub))
            .build();
        // Publish metrics for DynamoDB operations.
        ddb.listTables();
        ddb.describeEndpoints();
        ddb.describeLimits();
        // Perform more work in your application.

        // A MetricsPublisher has its own lifecycle independent of any service client or request that uses it.
        // If you no longer need the publisher, close it to free up resources.
        metricsPub.close();  // All metrics stored in memory are flushed to CloudWatch.


        // Perform more work with the DynamoDbClient instance without publishing metrics.
        // Close the service client when you no longer need it.
        ddb.close();
    }
}
```

上一个代码段中显示的自定义设置具有以下效果。
+ 该`cloudWatchClient`方法允许您自定义用于发送指标的 CloudWatch 客户端。在此示例中，我们使用与客户端发送指标的默认区域 *us-east-1* 不同的区域。我们还使用不同的命名配置文件 *cloudwatch*，其凭据将用于对请求进行 CloudWatch身份验证。这些凭证必须具有执行 `cloudwatch:PutMetricData` 操作的权限。
+ 该`uploadFrequency`方法允许您指定指标发布者上传指标的频率。 CloudWatch默认为一分钟一次。
+ `maximumCallsPerUpload` 方法限制每次上传的调用次数。默认为无限制。
+ 默认情况下，适用于 Java 的 SDK 2.x 将指标发布在命名空间 `AwsSdk/JavaSdk2` 下。您可以使用 `namespace` 方法来指定不同的值。
+ 默认情况下，SDK 发布摘要指标。摘要指标包括平均值、最小值、最大值、总计和样本数量。通过在 `detailedMetrics` 方法中指定一个或多个 SDK 指标，SDK 会为每个指标发布额外数据。这些附加数据支持百分位数统计信息，例如 p90 和 p99，供您查询。 CloudWatch详细指标对于延迟指标特别有用`APICallDuration`，例如衡量 SDK 客户端请求的 end-to-end延迟。您可以使用 `[CoreMetric](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/metrics/CoreMetric.html)` 类的字段来指定其他常用 SDK 指标。

**后续步骤：**如果您也在使用 Lambda 函数，请参阅[发布基于 EMF 的指标发布 AWS Lambda 函数的 SDK 指标](metric-pub-impl-emf.md)。

# 使用发布 AWS Lambda 函数的 SDK 指标 AWS SDK for Java 2.x
<a name="metric-pub-impl-emf"></a>

由于 Lambda 函数的执行时间通常为几毫秒到几分钟，而使用 `CloudWatchMetricPublisher` 发送指标存在延迟，这种延迟可能导致指标数据丢失。

`[EmfMetricLoggingPublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/metrics/publishers/emf/EmfMetricLoggingPublisher.html)`通过立即将指标写成[CloudWatch 嵌入式指标格式 (EMF)](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format.html) 的结构化日志条目，提供了一种更合适的方法。 `EmfMetricLoggingPublisher`适用于与 Amazon L CloudWatch ogs 内置集成的执行环境，例如 AWS Lambda 和亚马逊弹性容器服务。

## 设置
<a name="metric-pub-impl-emf-set-up"></a>

先完成以下步骤，然后才能使用 `EmfMetricLoggingPublisher` 来启用和使用指标。

### 步骤 1：添加所需的依赖项
<a name="metric-pub-impl-emf-set-up-deps"></a>

将项目依赖项（例如，在您的 `pom.xml` 或 `build.gradle` 文件中）配置为使用 适用于 Java 的 AWS SDK版本 `2.30.3` 或更高版本。

在项目的依赖项中包括 artifactId `emf-metric-logging-publisher`，并使用版本号 `2.30.3` 或更高版本号。

例如：

```
<project>
  <dependencyManagement>
   <dependencies>
      <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>bom</artifactId>
        <version>[2.30.11](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)</version>  <!-- Navigate the link to see the latest version. -->
        <type>pom</type>
        <scope>import</scope>
      </dependency>
   </dependencies>
  </dependencyManagement>
  <dependencies>
   <dependency>
      <groupId>software.amazon.awssdk</groupId>
      <artifactId>emf-metric-logging-publisher</artifactId>
   </dependency>
  </dependencies>
</project>
```

### 步骤 2：配置所需的权限
<a name="metric-pub-impl-emf-set-up-perm"></a>

为指标发布者使用的 IAM 身份启用 `logs:PutLogEvents` 权限，以允许适用于 Java 的 SDK 编写 EMF 格式的日志。

### 步骤 3：设置日志记录
<a name="metric-pub-impl-emf-set-up-logger"></a>

为确保正确收集指标，请将您的日志记录配置为以 `INFO` 级别或更低级别（例如 `DEBUG`）输出到控制台。在 `log4j2.xml` 文件中：

```
<Loggers>
  <Root level="WARN">
   <AppenderRef ref="ConsoleAppender"/>
  </Root>
  <Logger name="software.amazon.awssdk.metrics.publishers.emf.EmfMetricLoggingPublisher" level="INFO" />
</Loggers>
```

有关如何设置 `log4j2.xml` 文件的更多信息，请参阅本指南中的[日志记录主题](logging-slf4j.md)。

## 配置和使用 `EmfMetricLoggingPublisher`。
<a name="metric-pub-impl-emf-use"></a>

以下 Lambda 函数类先创建和配置 `EmfMetricLoggingPublisher` 实例，然后将其与 Amazon DynamoDB 服务客户端一起使用：

```
public class GameIdHandler implements RequestHandler<Map<String, String>, String> {
    private final EmfMetricLoggingPublisher emfPublisher;
    private final DynamoDbClient dynamoDb;

    public GameIdHandler() {
        // Build the publisher. 
        this.emfPublisher = EmfMetricLoggingPublisher.builder()
                .namespace("namespace")
                .dimensions(CoreMetric.SERVICE_ID,
                        CoreMetric.OPERATION_NAME)
                .build();
        // Add the publisher to the client.
        this.dynamoDb = DynamoDbClient.builder()
                .overrideConfiguration(c -> c.addMetricPublisher(emfPublisher))
                .region(Region.of(System.getenv("AWS_REGION")))
                .build();
    }

    @Override
    public String handleRequest(Map<String, String> event, Context context) {
        Map<String, AttributeValue> gameItem = new HashMap<>();

        gameItem.put("gameId", AttributeValue.builder().s(event.get("id")).build());

        PutItemRequest putItemRequest = PutItemRequest.builder()
                .tableName("games")
                .item(gameItem)
                .build();

        dynamoDb.putItem(putItemRequest);

        return "Request handled";
    }
}
```

当 DynamoDB 客户端执行`putItem`该方法时，它会自动以 EMF 格式将指标发布到日志 CloudWatch 流。

### EMF 日志事件的示例
<a name="emf-logged-output"></a>

例如，如果您将以下事件发送到 GameHandler Lambda 函数，且日志配置如前所示：

```
{
  "id": "23456"
}
```

函数处理事件后，您会看到两个与以下示例类似的日志事件。第二个事件中的 JSON 对象包含 DynamoDB `PutItem` 操作的 Java SDK 指标数据。

当 CloudWatch 收到 EMF 格式的日志事件时，它会自动解析结构化的 JSON 以提取指标数据。 CloudWatch 然后创建相应的指标，同时将原始日志条目存储在 CloudWatch 日志中。

```
2025-07-11 15:58:30 [main] INFO  org.example.GameIdHandler:39 - Received map: {id=23456}

2025-07-11 15:58:34 [main] INFO  software.amazon.awssdk.metrics.publishers.emf.EmfMetricLoggingPublisher:43 - 
{
    "_aws": {
        "Timestamp": 1752249513975,
        "LogGroupName": "/aws/lambda/GameId",
        "CloudWatchMetrics": [
            {
                "Namespace": "namespace",
                "Dimensions": [
                    [
                        "OperationName",
                        "ServiceId"
                    ]
                ],
                "Metrics": [
                    {
                        "Name": "AvailableConcurrency"
                    },
                    {
                        "Name": "PendingConcurrencyAcquires"
                    },
                    {
                        "Name": "ServiceCallDuration",
                        "Unit": "Milliseconds"
                    },
                    {
                        "Name": "EndpointResolveDuration",
                        "Unit": "Milliseconds"
                    },
                    {
                        "Name": "MaxConcurrency"
                    },
                    {
                        "Name": "BackoffDelayDuration",
                        "Unit": "Milliseconds"
                    },
                    {
                        "Name": "MarshallingDuration",
                        "Unit": "Milliseconds"
                    },
                    {
                        "Name": "LeasedConcurrency"
                    },
                    {
                        "Name": "SigningDuration",
                        "Unit": "Milliseconds"
                    },
                    {
                        "Name": "ConcurrencyAcquireDuration",
                        "Unit": "Milliseconds"
                    },
                    {
                        "Name": "ApiCallSuccessful"
                    },
                    {
                        "Name": "RetryCount"
                    },
                    {
                        "Name": "UnmarshallingDuration",
                        "Unit": "Milliseconds"
                    },
                    {
                        "Name": "ApiCallDuration",
                        "Unit": "Milliseconds"
                    },
                    {
                        "Name": "CredentialsFetchDuration",
                        "Unit": "Milliseconds"
                    }
                ]
            }
        ]
    },
    "AvailableConcurrency": 0,
    "PendingConcurrencyAcquires": 0,
    "OperationName": "PutItem",
    "ServiceCallDuration": 1339,
    "EndpointResolveDuration": 81,
    "MaxConcurrency": 50,
    "BackoffDelayDuration": 0,
    "ServiceId": "DynamoDB",
    "MarshallingDuration": 181,
    "LeasedConcurrency": 1,
    "SigningDuration": 184,
    "ConcurrencyAcquireDuration": 83,
    "ApiCallSuccessful": 1,
    "RetryCount": 0,
    "UnmarshallingDuration": 85,
    "ApiCallDuration": 1880,
    "CredentialsFetchDuration": 138
}
```

`EmfMetricLoggingPublisher.Builder` 的 [API 文档](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/metrics/publishers/emf/EmfMetricLoggingPublisher.Builder.html)显示了您可以使用的配置选项。

您也可以为单个请求启用 EMF 指标日志记录，如[所 CloudWatchMetricPublisher示](metric-pub-impl-cwmp.md#enable-metrics-for-a-specific-request)。

**后续步骤：**对于长时间运行的应用程序，请参阅[从长时间运行的应用程序发布 SDK 指标](metric-pub-impl-cwmp.md)以发布 CloudWatch基于基础的指标。

# 使用向控制台输出 SDK 指标 AWS SDK for Java 2.x
<a name="metric-pub-impl-logging"></a>

`[LoggingMetricPublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/metrics/LoggingMetricPublisher.html)` 实现将指标直接输出到应用程序的控制台或日志文件。这种方法非常适合开发、调试和了解 SDK 收集的指标，而无需像 Amazon 这样的外部服务 CloudWatch。

与 `CloudWatchMetricPublisher` 和 `EmfMetricLoggingPublisher` 不同，`LoggingMetricPublisher` 提供即时输出，没有延迟或外部依赖项。这使其非常适合用于本地开发和故障排除场景。

## 何时使用 LoggingMetricPublisher
<a name="logging-metric-publisher-when-to-use"></a>

在需要执行以下操作时使用 `LoggingMetricPublisher`：
+ 在开发过程中调试指标收集
+ 了解 SDK 为您的运营收集了哪些指标
+ 在本地排查性能问题
+ 在没有外部服务依赖项的情况下测试指标收集
+ 立即在控制台或日志文件中查看指标

**注意**  
不建议将 `LoggingMetricPublisher` 用于需要持久指标存储和分析功能的生产环境中。

## 为指标设置控制台日志记录
<a name="logging-metric-publisher-setup"></a>

要查看 `LoggingMetricPublisher` 输出，请将您的日志记录框架配置为显示 `INFO` 级别消息。以下 `log4j2.xml` 配置可确保指标显示在控制台中：

```
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="ConsoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="ConsoleAppender"/>
        </Root>
        <!-- Ensure LoggingMetricPublisher output appears. -->
        <Logger name="software.amazon.awssdk.metrics.LoggingMetricPublisher" level="INFO" />
    </Loggers>
</Configuration>
```

此配置指示 SDK 在 `INFO` 级别将指标输出到控制台。`LoggingMetricPublisher` 记录器配置可确保即使根记录器使用更高的级别（如 `WARN` 或 `ERROR`），也能显示指标输出。

## 为服务客户端启用控制台指标
<a name="logging-metric-publisher-basic-usage"></a>

以下示例演示如何创建 `LoggingMetricPublisher` 并与 Amazon Simple Storage Service 客户端一起使用：

```
import software.amazon.awssdk.metrics.LoggingMetricPublisher;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;

// Create a LoggingMetricPublisher with default settings.
MetricPublisher metricPublisher = LoggingMetricPublisher.create();

// Add the publisher to your service client.
S3Client s3Client = S3Client.builder()
    .region(Region.US_EAST_1)
    .overrideConfiguration(config -> config.addMetricPublisher(metricPublisher))
    .build();

// Make requests - metrics will appear in your console.
s3Client.listBuckets();

// Clean up resources.
metricPublisher.close();
s3Client.close();
```

## 选择指标输出格式
<a name="logging-metric-publisher-formatting-options"></a>

`LoggingMetricPublisher` 支持两种输出格式：
+ **PLAIN 格式（默认）：**以紧凑的单行形式输出指标
+ **PRETTY 格式：**以多行、用户可读的格式输出指标

以下示例演示如何使用 PRETTY 格式，以便在开发过程中更轻松地读取输出：

```
import org.slf4j.event.Level;
import software.amazon.awssdk.metrics.LoggingMetricPublisher;

// Create a LoggingMetricPublisher with PRETTY format.
MetricPublisher prettyMetricPublisher = LoggingMetricPublisher.create(
    Level.INFO, 
    LoggingMetricPublisher.Format.PRETTY
);

// Use with your service client.
S3Client s3Client = S3Client.builder()
    .region(Region.US_EAST_1)
    .overrideConfiguration(config -> config.addMetricPublisher(prettyMetricPublisher))
    .build();
```

## 完整示例
<a name="logging-metric-publisher-complete-example"></a>

以下示例演示了通过两种方式来使用 `LoggingMetricPublisher`：
+ 在服务客户端级别
+ 对于单个请求

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
import software.amazon.awssdk.metrics.LoggingMetricPublisher;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.ListBucketsRequest;
import software.amazon.awssdk.services.s3.model.ListBucketsResponse;

/**
 * Demonstrates how to use LoggingMetricPublisher with AWS S3 SDK for Java 2.x.
 * <p>
 * This demo focuses on the S3 listBuckets operation to show how metrics are collected
 * and logged to the console for development and debugging purposes.
 * <p>
 * LoggingMetricPublisher is ideal for:
 * - Development and debugging
 * - Console output for troubleshooting
 * - Understanding what metrics are being collected
 * - Testing metric collection without external dependencies
 */
public class S3LoggingMetricPublisherDemo {

    private static final Logger logger = LoggerFactory.getLogger(S3LoggingMetricPublisherDemo.class);

    public static void main(String[] args) {
        S3LoggingMetricPublisherDemo demo = new S3LoggingMetricPublisherDemo();
        demo.demonstrateUsage();
    }

    /**
     * Demonstrates basic usage with S3Client and metrics enabled at the client level.
     */
    private void demonstrateUsage() {

        // Create a LoggingMetricPublisher with default settings. The SDK logs metrics as text in a single line.
        // The default settings are equivalent to using `LoggingMetricPublisher.Format.PLAIN`.

        MetricPublisher metricPublisher = LoggingMetricPublisher.create();

        // Create an S3 client with metrics enabled.
        try (S3Client s3Client = S3Client.builder()
                .region(Region.US_EAST_1)
                .overrideConfiguration(config -> config.addMetricPublisher(metricPublisher))
                .build()) {

            // Make the listBuckets request - metrics will be logged to console.
            ListBucketsResponse response = s3Client.listBuckets(ListBucketsRequest.builder().build());

            // The next block shows the using a different LoggingMetricPublisher with a `PRETTY` format.
            // Since the metric publisher is added to the request using the `overrideConfiguration`, this formatting
            // applies only to the one request.
            try {
                s3Client.listBuckets(ListBucketsRequest.builder()
                        .overrideConfiguration(config -> config
                                .addMetricPublisher(LoggingMetricPublisher.create(
                                        Level.INFO, LoggingMetricPublisher.Format.PRETTY)))
                        .build());
            } catch (Exception e) {
                logger.info("Request failed with metrics logged: {}", e.getMessage());
            }
            logger.info("Found {} buckets in your AWS account.", response.buckets().size());

        } catch (Exception e) {
            logger.error("Error during S3 operation: {}", e.getMessage());
            logger.info("Note: This is expected if AWS credentials are not configured.");
        }

        // Close the metric publisher to flush any remaining metrics.
        metricPublisher.close();
    }
}
```

该代码将以下内容记录到控制台：

```
INFO  LoggingMetricPublisher - Metrics published: MetricCollection(name=ApiCall, metrics=[MetricRecord(metric=MarshallingDuration, value=PT0.005409792S), MetricRecord(metric=RetryCount, value=0), MetricRecord(metric=ApiCallSuccessful, value=true), MetricRecord(metric=OperationName, value=ListBuckets), MetricRecord(metric=EndpointResolveDuration, value=PT0.000068S), MetricRecord(metric=ApiCallDuration, value=PT0.163802958S), MetricRecord(metric=CredentialsFetchDuration, value=PT0.145686542S), MetricRecord(metric=ServiceEndpoint, value=https://s3.amazonaws.com), MetricRecord(metric=ServiceId, value=S3)], children=[MetricCollection(name=ApiCallAttempt, metrics=[MetricRecord(metric=TimeToFirstByte, value=PT0.138816S), MetricRecord(metric=SigningDuration, value=PT0.007803459S), MetricRecord(metric=ReadThroughput, value=165153.96002660287), MetricRecord(metric=ServiceCallDuration, value=PT0.138816S), MetricRecord(metric=AwsExtendedRequestId, value=e13Swj3uwn0qP1Oz+m7II5OGq7jf8xxT8H18iDfRBCQmDg+gU4ek91Xrsl8XxRLROlIzCAPQtsQF0DAAWOb8ntuKCzX2AJdj), MetricRecord(metric=HttpStatusCode, value=200), MetricRecord(metric=BackoffDelayDuration, value=PT0S), MetricRecord(metric=TimeToLastByte, value=PT0.148915667S), MetricRecord(metric=AwsRequestId, value=78AW9BM7SWR6YMGB)], children=[MetricCollection(name=HttpClient, metrics=[MetricRecord(metric=MaxConcurrency, value=50), MetricRecord(metric=AvailableConcurrency, value=0), MetricRecord(metric=LeasedConcurrency, value=1), MetricRecord(metric=ConcurrencyAcquireDuration, value=PT0.002623S), MetricRecord(metric=PendingConcurrencyAcquires, value=0), MetricRecord(metric=HttpClientName, value=Apache)], children=[])])])
INFO  LoggingMetricPublisher - [4e6f2bb5] ApiCall
INFO  LoggingMetricPublisher - [4e6f2bb5] ┌──────────────────────────────────────────┐
INFO  LoggingMetricPublisher - [4e6f2bb5] │ MarshallingDuration=PT0.000063S          │
INFO  LoggingMetricPublisher - [4e6f2bb5] │ RetryCount=0                             │
INFO  LoggingMetricPublisher - [4e6f2bb5] │ ApiCallSuccessful=true                   │
INFO  LoggingMetricPublisher - [4e6f2bb5] │ OperationName=ListBuckets                │
INFO  LoggingMetricPublisher - [4e6f2bb5] │ EndpointResolveDuration=PT0.000024375S   │
INFO  LoggingMetricPublisher - [4e6f2bb5] │ ApiCallDuration=PT0.018463083S           │
INFO  LoggingMetricPublisher - [4e6f2bb5] │ CredentialsFetchDuration=PT0.000022334S  │
INFO  LoggingMetricPublisher - [4e6f2bb5] │ ServiceEndpoint=https://s3.amazonaws.com │
INFO  LoggingMetricPublisher - [4e6f2bb5] │ ServiceId=S3                             │
INFO  LoggingMetricPublisher - [4e6f2bb5] └──────────────────────────────────────────┘
INFO  LoggingMetricPublisher - [4e6f2bb5]     ApiCallAttempt
INFO  LoggingMetricPublisher - [4e6f2bb5]     ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
INFO  LoggingMetricPublisher - [4e6f2bb5]     │ TimeToFirstByte=PT0.0165575S                                                                                          │
INFO  LoggingMetricPublisher - [4e6f2bb5]     │ SigningDuration=PT0.000301125S                                                                                        │
INFO  LoggingMetricPublisher - [4e6f2bb5]     │ ReadThroughput=1195591.792850103                                                                                      │
INFO  LoggingMetricPublisher - [4e6f2bb5]     │ ServiceCallDuration=PT0.0165575S                                                                                      │
INFO  LoggingMetricPublisher - [4e6f2bb5]     │ AwsExtendedRequestId=3QI1eenRuokdszWqZBmBMDUmko6FlSmHkM+CUMNMeLor7gJml4D4lv6QXUZ1zWoTgG+tHbr6yo2vHdz4h1P8PDovvtMFRCeB │
INFO  LoggingMetricPublisher - [4e6f2bb5]     │ HttpStatusCode=200                                                                                                    │
INFO  LoggingMetricPublisher - [4e6f2bb5]     │ BackoffDelayDuration=PT0S                                                                                             │
INFO  LoggingMetricPublisher - [4e6f2bb5]     │ TimeToLastByte=PT0.017952625S                                                                                         │
INFO  LoggingMetricPublisher - [4e6f2bb5]     │ AwsRequestId=78AVFAF795AAWAXH                                                                                         │
INFO  LoggingMetricPublisher - [4e6f2bb5]     └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
INFO  LoggingMetricPublisher - [4e6f2bb5]         HttpClient
INFO  LoggingMetricPublisher - [4e6f2bb5]         ┌───────────────────────────────────────┐
INFO  LoggingMetricPublisher - [4e6f2bb5]         │ MaxConcurrency=50                     │
INFO  LoggingMetricPublisher - [4e6f2bb5]         │ AvailableConcurrency=0                │
INFO  LoggingMetricPublisher - [4e6f2bb5]         │ LeasedConcurrency=1                   │
INFO  LoggingMetricPublisher - [4e6f2bb5]         │ ConcurrencyAcquireDuration=PT0.00004S │
INFO  LoggingMetricPublisher - [4e6f2bb5]         │ PendingConcurrencyAcquires=0          │
INFO  LoggingMetricPublisher - [4e6f2bb5]         │ HttpClientName=Apache                 │
INFO  LoggingMetricPublisher - [4e6f2bb5]         └───────────────────────────────────────┘
INFO  S3LoggingMetricPublisherDemo - Found 6 buckets in your AWS account.
```

### 该示例的其他构件
<a name="logging-metric-publisher-complete-example-artifacts"></a>

Maven `pom.xml` 文件

```
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>s3-logging-metric-publisher-demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>AWS S3 LoggingMetricPublisher Demo</name>
    <description>Demonstrates how to use LoggingMetricPublisher with AWS S3 SDK for Java 2.x</description>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <aws.java.sdk.version>2.31.66</aws.java.sdk.version>
        <log4j.version>2.24.3</log4j.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- AWS SDK BOM for dependency management -->
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${aws.java.sdk.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Log4j BOM for logging dependency management -->
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-bom</artifactId>
                <version>${log4j.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- AWS S3 SDK for demonstration -->
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
        </dependency>

        <!-- Log4j2 SLF4J implementation -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j2-impl</artifactId>
        </dependency>

        <!-- Log4j2 Core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.13.0</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

`Log4j2.xml` 配置文件

```
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="ConsoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="ConsoleAppender"/>
        </Root>
        <!-- Ensure LoggingMetricPublisher output appears. -->
        <Logger name="software.amazon.awssdk.metrics.LoggingMetricPublisher" level="INFO"/>
    </Loggers>
</Configuration>
```

这些指标包括计时信息、服务详细信息、操作名称和 HTTP 状态代码，可帮助您了解应用程序的 AWS API 使用模式。

## 后续步骤
<a name="logging-metric-publisher-next-steps"></a>

在使用 `LoggingMetricPublisher` 进行开发和调试之后，请考虑在生产环境中使用以下选项：
+ 对于长时间运行的应用程序，使用[CloudWatchMetricPublisher](metric-pub-impl-cwmp.md)向 Amazon 发送指标以 CloudWatch 供分析和提醒
+ 对于 AWS Lambda 函数，使用[EmfMetricLoggingPublisher](metric-pub-impl-emf.md)以 CloudWatch 嵌入式指标格式发布指标

# AWS SDK for Java 2.x：全面的指标参考
<a name="metrics-list"></a>

借助 AWS SDK for Java 2.x，您可以从应用程序中的服务客户端收集指标，然后将这些指标发布（输出）到 [Amazon CloudWatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html)。

这些表列出了您可以收集的指标以及任何 HTTP 客户端使用要求。

有关为 SDK 启用和配置指标的更多信息，请参阅[启用 SDK 指标](metrics.md)。

## 每次请求收集的指标
<a name="metrics-perrequest"></a>


| 指标名称 | 说明 | Type | 
| --- | --- | --- | 
|  ApiCallDuration  |  API 调用的持续时间。这包括所有已发起的调用尝试。  |  持续时间\$1  | 
|  ApiCallSuccessful  |  如果 API 调用成功则为 true，否则为 false。  |  布尔值  | 
|  CredentialsFetchDuration  |  获取 API 调用的签名凭证的持续时间。  |  持续时间\$1  | 
| EndpointResolveDuration | 解析 API 调用所用端点的持续时间。 | 持续时间\$1 | 
|  MarshallingDuration  |  将 SDK 请求封送到 HTTP 请求的持续时间。  |  持续时间\$1  | 
|  OperationName  |  所调用服务操作的名称。  |  字符串  | 
|  RetryCount  |  SDK 在执行请求时自动重试的次数。0 表示该请求第一次就成功了，没有进行任何重试。 有关配置重试行为的更多信息，请参阅[重试策略](retry-strategy.md#retry-strategies)。  |  整数  | 
|  ServiceId  |  服务的唯一 ID。  |  字符串  | 
|  ServiceEndpoint  |  服务的端点。  |  URI  | 
|  TokenFetchDuration  | 获取 API 调用的签名凭证的持续时间。 | 持续时间\$1 | 

\$1[java.time.Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html)。

## 为每次请求尝试收集的指标
<a name="metrics-perattempt"></a>

每个 API 调用可能需要多次尝试才能收到响应。每次尝试都会收集这些指标。

### 核心指标
<a name="metrics-perattempt-core"></a>


| 指标名称 | 说明 | Type | 
| --- | --- | --- | 
|  AwsExtendedRequestId  |  服务请求的扩展请求 ID。  |  字符串  | 
|  AwsRequestId  |  服务请求的请求 ID。  |  字符串  | 
|  BackoffDelayDuration  |  在这次 API 调用尝试之前 SDK 已等待的持续时间。该值基于客户端上 `[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/retries/api/BackoffStrategy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/retries/api/BackoffStrategy.html)` 设置。有关更多信息，请参阅本指南的[重试策略](retry-strategy.md#retry-strategies)部分。  |  持续时间\$1  | 
| ErrorType |  进行调用尝试时发生的错误类型。 以下是可能的值： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-java/latest/developer-guide/metrics-list.html)  | 字符串 | 
| ReadThroughput |  客户端的读取吞吐量，定义为 `NumberOfResponseBytesRead / (TTLB - TTFB)`。此值以每秒字节数为单位。 请注意，此指标仅测量从 `ResponseTransformer` 或 `AsyncResponseTransformer` 内读取的字节。计算中不包括在转换器外部读取的数据（例如，当响应流作为转换器的结果返回时）。  | 双精度 | 
| WriteThroughput |  客户端的写入吞吐量，定义为`RequestBytesWritten / (LastByteWrittenTime - FirstByteWrittenTime)`。此值以每秒字节数为单位。 该指标衡量 SDK 向 HTTP 客户端提供请求正文的速率。它不包括连接设置、TLS 握手时间和服务器处理时间。仅针对具有流媒体主体（例如 S3）的请求报告此指标 PutObject。 请注意，此指标未考虑 HTTP 客户端层中的缓冲情况。如果 HTTP 客户端在发送数据之前缓冲数据，则实际网络传输速率可能会更低。该指标代表网络吞吐量的上限。  | 双精度 | 
|  ServiceCallDuration  |  连接到服务（或从连接池中获取连接）、发送序列化请求和接收初始响应（例如 HTTP 状态码和标头）的持续时间。这不包括从服务中读取整个响应的时间。  |  持续时间\$1  | 
|  SigningDuration  |  签署 HTTP 请求的持续时间。  |  持续时间\$1  | 
| TimeToFirstByte | 从将 HTTP 请求发送到服务（包括获取连接），到接收响应中标头的第一个字节的持续时间。 | 持续时间\$1 | 
| TimeToLastByte |  从将 HTTP 请求发送到服务（包括获取连接），到接收响应的最后一个字节的持续时间。 请注意，对于 APIs 返回的流媒体响应，此指标跨越了直到`ResponseTransformer`或`AsyncResponseTransformer`完成的时间。  | 持续时间\$1 | 
|  UnmarshallingDuration  |  将 HTTP 响应解组到 SDK 响应的持续时间。 注意：对于流式操作，这不包括读取响应有效载荷的时间。  |  持续时间\$1  | 

\$1[java.time.Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html)。

### HTTP 指标
<a name="metrics-perattempt-http"></a>


| 指标名称 | 说明 | Type | 需要 HTTP 客户端\$1 | 
| --- | --- | --- | --- | 
|  AvailableConcurrency  |  在不与目标服务器建立新连接的情况下，HTTP 客户端支持的额外并发请求数。 对于 HTTP/1 操作，这等于与服务建立的空闲 TCP 连接的数量。对于 HTTP/2 操作，这等于空闲流的数量。 注意：此值因 HTTP 客户端实现而异： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-java/latest/developer-guide/metrics-list.html) 该值的范围限定于单个 HTTP 客户端实例，不包括同一 JVM 中其他 HTTP 客户端的并发。  |  整数  | Apache、Netty、CRT | 
|  ConcurrencyAcquireDuration  |  从连接池中获取通道的持续时间。 对于 HTTP/1 操作，通道等于 TCP 连接。对于 HTTP/2 操作，通道等于 HTTP/2 流通道。 获取新通道可能包括以下时间： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-java/latest/developer-guide/metrics-list.html)  |  持续时间\$1  |  Apache、Netty、CRT  | 
|  HttpClientName  |  用于请求的 HTTP 的名称。  |  字符串  |  Apache、Netty、CRT  | 
|  HttpStatusCode  |  HTTP 响应的状态代码。  |  整数  |  任何  | 
|  LeasedConcurrency  |  HTTP 客户端当前执行的请求数。 对于 HTTP/1 操作，这等于与服务建立的活跃 TCP 连接的数量（不包括空闲连接）。对于 HTTP/2 操作，这等于服务的活动 HTTP 流的数量（不包括空闲流容量）。 注意：此值因 HTTP 客户端实现而异： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-java/latest/developer-guide/metrics-list.html) 该值的范围限定于单个 HTTP 客户端实例，不包括同一 JVM 中其他 HTTP 客户端的并发。  |  整数  |  Apache、Netty、CRT  | 
|  LocalStreamWindowSize  |  执行此请求的流的本地 HTTP/2 窗口大小（以字节为单位）。  |  整数  |  Netty  | 
|  MaxConcurrency  |  HTTP 客户端支持的最大并发请求数。 对于 HTTP/1 操作，这等于 HTTP 客户端可以汇集的最大 TCP 连接数。对于 HTTP/2 操作，这等于 HTTP 客户端可以汇集的最大流数。 注意：此值因 HTTP 客户端实现而异： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-java/latest/developer-guide/metrics-list.html) 该值的范围限定于单个 HTTP 客户端实例，不包括同一 JVM 中其他 HTTP 客户端的并发。  |  整数  |  Apache、Netty、CRT  | 
|  PendingConcurrencyAcquires  |  等待 HTTP 客户端并发的请求数。 对于 HTTP/1 操作，这等于等待 TCP 连接建立或从连接池返回的请求数。对于 HTTP/2 操作，这等于等待来自连接池的新流（可能还有新 HTTP/2 连接）的请求数。 注意：此值因 HTTP 客户端实现而异： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-java/latest/developer-guide/metrics-list.html) 该值的范围限定于单个 HTTP 客户端实例，不包括同一 JVM 中其他 HTTP 客户端的并发。  |  整数  |  Apache、Netty、CRT  | 
|  RemoteStreamWindowSize  |  执行此请求的流的远程 HTTP/2 窗口大小（以字节为单位）。  |  整数  |  Netty  | 

\$1[java.time.Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html)。

列中所用术语解释：
+ Apache：基于 Apache 的 HTTP 客户端（`[ApacheHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/apache/ApacheHttpClient.html)`）
+ Netty：基于 Netty 的 HTTP 客户端（`[NettyNioAsyncHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html)`）
+ CRT： AWS 基于 CRT 的 HTTP 客户端 () `[AwsCrtAsyncHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtAsyncHttpClient.html)`
+ 任意：指标数据的收集不依赖于 HTTP 客户端；这包括 URLConnection基于的 HTTP 客户端 (`[UrlConnectionHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html)`)

# 监控AWS SDK for Java 2.x 应用程序
<a name="monitoring-overview"></a>

使用AWS SDK for Java 2.x 时为了使应用程序保持可靠性、可用性和性能，监控是一个很重要的部分。AWS 提供了以下监控工具来监控适用于 Java 的 SDK 2.x、在出现错误时进行报告并适时自动采取措施：
+ *Amazon CloudWatch* 可实时监控您的 AWS 资源以及您在 AWS 上运行的应用程序。您可以收集和跟踪指标，创建自定义的控制平面，以及设置警报以在指定的指标达到您指定的阈值时通知您或采取措施。例如，您可以使用 CloudWatch 跟踪 Amazon EC2 实例的 CPU 使用率或其他指标并且在需要时自动启动新实例。有关更多信息，请参阅《Amazon CloudWatch 用户指南》[https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/)。
+ *Amazon CloudWatch Logs* 使您能够监控、存储和访问来自 Amazon EC2 实例、CloudTrail 和其他来源的日志文件。CloudWatch Logs 可以监控日志文件中的信息，并在达到特定阈值时通知您。您还可以在高持久性存储中检索您的日志数据。有关更多信息，请参阅 [Amazon CloudWatch Logs 用户指南](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/)。
+ *AWS CloudTrail* 捕获由您的 AWS 账户或代表该账户发出的 API 调用和相关事件，并将日志文件传输到您指定的 Amazon S3 存储桶。您可以标识哪些用户和账户调用了 AWS、发出调用的源 IP 地址以及调用的发生时间。有关更多信息，请参阅[《AWS CloudTrail 用户指南》](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/)。

# 使用适用于 Java 的 SDK 2.x 进行日志记录
<a name="logging-slf4j"></a>

 AWS SDK for Java 2.x 使用 [SLF4J](https://www.slf4j.org/manual.html)，这是一个抽象层，允许在运行时使用多个日志系统中的任何一个。

支持的日志记录系统包括 Java Logging Framework、Apache [Log4j 2](https://logging.apache.org/log4j/2.x/) 和其他系统。本主题向您展示如何将 Log4j 2 作为与 SDK 结合使用的日志记录系统。

## Log4j 2 配置文件
<a name="log4j-configuration-file"></a>

您通常是将一个名为 `log4j2.xml` 的配置文件与 Log4j 2 结合使用。配置文件示例如下所示。要了解有关配置文件中使用的值的更多信息，请参阅 [Log4j 配置手册](https://logging.apache.org/log4j/2.x/manual/configuration.html)。

应用程序启动时，该 `log4j2.xml` 文件必须位于类路径中。对于 Maven 项目，请将文件放在 `<project-dir>/src/main/resources` 目录中。

`log4j2.xml` 配置文件会指定[日志记录级别](https://logging.apache.org/log4j/2.x/manual/configuration.html#Loggers)、将日志记录输出发送到的位置（例如[发送到文件或控制台](https://logging.apache.org/log4j/2.x/manual/appenders.html)）和[输出格式](https://logging.apache.org/log4j/2.x/manual/layouts.html)等属性。日志级别指定 Log4j 2 输出的详细级别。Log4j 2 支持多个日志记录[https://logging.apache.org/log4j/2.x/manual/architecture.html#](https://logging.apache.org/log4j/2.x/manual/architecture.html#) 的概念。可以为每级层次结构单独设置日志记录级别。与一起使用的主日志层次结构 AWS SDK for Java 2.x 是`software.amazon.awssdk`。

## 添加日志记录依赖项
<a name="sdk-java-logging-classpath"></a>

要在生成文件中为 J 配置 Log4 SLF4 j 2 绑定，请使用以下命令。

------
#### [ Maven ]

在 `pom.xml` 文件中添加以下元素：

```
...
<dependency>
   <groupId>org.apache.logging.log4j</groupId>
   <artifactId>log4j-slf4j2-impl</artifactId>
   <version>VERSION</version>
</dependency>
...
```

------
#### [ Gradle–Kotlin DSL ]

在 `build.gradle.kts` 文件中添加以下内容。

```
...
dependencies {
    ...
    implementation("org.apache.logging.log4j:log4j-slf4j2-impl:VERSION")
    ...
}
...
```

------

对于 `log4j-slf4j2-impl` 构件的最低版本，请使用 `2.20.0`。要获取最新版本，请使用发布到 [Maven central](https://central.sonatype.com/artifact/org.apache.logging.log4j/log4j-slf4j2-impl) 的版本。*VERSION*替换为你将要使用的版本。

## 特定于 SDK 的错误消息和警告
<a name="sdk-java-logging-service"></a>

建议始终将“software.amazon.awssdk”记录器层次结构设置为“WARN”，以保证不会错过来自 SDK 客户端库的任何重要消息。例如，如果 Amazon S3 客户端检测到应用程序没有正确关闭 `InputStream` 而且可能会泄漏资源，那么 S3 客户端将通过向日志中记录警告消息来进行报告。另外，由此可确保客户端在处理请求或响应遇到任何问题时会记录相应消息。

以下 `log4j2.xml` 文件将 `rootLogger` 设置为 “WARN”，这会导致输出来自应用程序中所有记录器的警告和错误级别消息，*包括*“software.amazon.awssdk”层次结构中的记录器。如果使用 `<Root level="ERROR">`，也可将“software.amazon.awssdk”记录器层次结构显式设置为 WARN。

**Log4j2.xml 配置文件示例**

此配置会将所有记录器层次结构的“ERROR”和“WARN”级别的消息记录到控制台。

```
<Configuration status="WARN">
 <Appenders>
  <Console name="ConsoleAppender" target="SYSTEM_OUT">
   <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
  </Console>
 </Appenders>

 <Loggers>
  <Root level="WARN">
   <AppenderRef ref="ConsoleAppender"/>
  </Root>
 </Loggers>
</Configuration>
```

## 请求/响应摘要日志记录
<a name="sdk-java-logging-request-response"></a>

对的每个请求都会 AWS 服务 生成一个唯一的 AWS 请求 ID，如果您在如何处理请求时遇到问题， AWS 服务 这会很有用。 AWS 对于任何失败的服务调用，都可以通过软件开发工具包中的[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html#requestId()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html#requestId())对象以编程方式访问请求 IDs ，也可以通过 “software.amazon.awssdk.request” 记录器的 “调试” 日志级别报告请求。

以下 `log4j2.xml` 文件将启用请求和响应的摘要。

```
<Configuration status="WARN">
 <Appenders>
  <Console name="ConsoleAppender" target="SYSTEM_OUT">
   <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
  </Console>
 </Appenders>

 <Loggers>
  <Root level="ERROR">
   <AppenderRef ref="ConsoleAppender"/>
  </Root>
  <Logger name="software.amazon.awssdk" level="WARN" />
  <Logger name="software.amazon.awssdk.request" level="DEBUG" />
 </Loggers>
</Configuration>
```

以下是日志输出的示例：

```
2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Sending Request: DefaultSdkHttpFullRequest(httpMethod=POST, protocol=https, host=dynamodb.us-east-1.amazonaws.com, encodedPath=/, headers=[amz-sdk-invocation-id, Content-Length, Content-Type, User-Agent, X-Amz-Target], queryParameters=[])
2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Received successful response: 200, Request ID: QS9DUMME2NHEDH8TGT9N5V53OJVV4KQNSO5AEMVJF66Q9ASUAAJG, Extended Request ID: not available
```

如果您只对请求编号感兴趣，请使用 `<Logger name="software.amazon.awssdk.requestId" level="DEBUG" />`。

## 调试级别 SDK 日志记录
<a name="sdk-debug-level-logging"></a>

如果您需要更详细地了解 SDK 正在做什么，可以将 `software.amazon.awssdk` 记录器的日志记录级别设置为 `DEBUG`。在此级别，SDK 会输出大量细节，因此我们建议您设置此级别以使用集成测试来解决错误。

在此日志记录级别，SDK 会记录有关配置、凭证解析、执行拦截器、高级 TLS 活动、请求签名等方面的信息。

以下是 SDK 在 `S3Client#listBuckets()` 调用的 `DEBUG` 级别输出的语句示例。

```
DEBUG s.a.a.r.p.AwsRegionProviderChain:57 - Unable to load region from software.amazon.awssdk.regions.providers.SystemSettingsRegionProvider@324dcd31:Unable to load region from system settings. Region must be specified either via environment variable (AWS_REGION) or  system property (aws.region).
DEBUG s.a.a.c.i.h.l.ClasspathSdkHttpServiceProvider:85 - The HTTP implementation loaded is software.amazon.awssdk.http.apache.ApacheSdkHttpService@a23a01d
DEBUG s.a.a.c.i.ExecutionInterceptorChain:85 - Creating an interceptor chain that will apply interceptors in the following order: [software.amazon.awssdk.core.internal.interceptor.HttpChecksumValidationInterceptor@69b2f8e5, software.amazon.awssdk.awscore.interceptor.HelpfulUnknownHostExceptionInterceptor@6331250e, software.amazon.awssdk.awscore.eventstream.EventStreamInitialRequestInterceptor@a10c1b5, software.amazon.awssdk.awscore.interceptor.TraceIdExecutionInterceptor@644abb8f, software.amazon.awssdk.services.s3.auth.scheme.internal.S3AuthSchemeInterceptor@1a411233, software.amazon.awssdk.services.s3.endpoints.internal.S3ResolveEndpointInterceptor@70325d20, software.amazon.awssdk.services.s3.endpoints.internal.S3RequestSetEndpointInterceptor@7c2327fa, software.amazon.awssdk.services.s3.internal.handlers.StreamingRequestInterceptor@4d847d32, software.amazon.awssdk.services.s3.internal.handlers.CreateBucketInterceptor@5f462e3b, software.amazon.awssdk.services.s3.internal.handlers.CreateMultipartUploadRequestInterceptor@3d7fa3ae, software.amazon.awssdk.services.s3.internal.handlers.DecodeUrlEncodedResponseInterceptor@58065f0c, software.amazon.awssdk.services.s3.internal.handlers.GetBucketPolicyInterceptor@3605c4d3, software.amazon.awssdk.services.s3.internal.handlers.S3ExpressChecksumInterceptor@585c13de, software.amazon.awssdk.services.s3.internal.handlers.AsyncChecksumValidationInterceptor@187eb9a8, software.amazon.awssdk.services.s3.internal.handlers.SyncChecksumValidationInterceptor@726a6b94, software.amazon.awssdk.services.s3.internal.handlers.EnableTrailingChecksumInterceptor@6ad11a56, software.amazon.awssdk.services.s3.internal.handlers.ExceptionTranslationInterceptor@522b2631, software.amazon.awssdk.services.s3.internal.handlers.GetObjectInterceptor@3ff57625, software.amazon.awssdk.services.s3.internal.handlers.CopySourceInterceptor@1ee29c84, software.amazon.awssdk.services.s3.internal.handlers.ObjectMetadataInterceptor@7c8326a4]
DEBUG s.a.a.u.c.CachedSupplier:85 - (SsoOidcTokenProvider()) Cached value is stale and will be refreshed.
...
DEBUG s.a.a.c.i.ExecutionInterceptorChain:85 - Creating an interceptor chain that will apply interceptors in the following order: [software.amazon.awssdk.core.internal.interceptor.HttpChecksumValidationInterceptor@51351f28, software.amazon.awssdk.awscore.interceptor.HelpfulUnknownHostExceptionInterceptor@21618fa7, software.amazon.awssdk.awscore.eventstream.EventStreamInitialRequestInterceptor@15f2eda3, software.amazon.awssdk.awscore.interceptor.TraceIdExecutionInterceptor@34cf294c, software.amazon.awssdk.services.sso.auth.scheme.internal.SsoAuthSchemeInterceptor@4d7aaca2, software.amazon.awssdk.services.sso.endpoints.internal.SsoResolveEndpointInterceptor@604b1e1d, software.amazon.awssdk.services.sso.endpoints.internal.SsoRequestSetEndpointInterceptor@62566842]
...
DEBUG s.a.a.request:85 - Sending Request: DefaultSdkHttpFullRequest(httpMethod=GET, protocol=https, host=portal.sso.us-east-1.amazonaws.com, encodedPath=/federation/credentials, headers=[amz-sdk-invocation-id, User-Agent, x-amz-sso_bearer_token], queryParameters=[role_name, account_id])
DEBUG s.a.a.c.i.h.p.s.SigningStage:85 - Using SelectedAuthScheme: smithy.api#noAuth
DEBUG s.a.a.h.a.i.c.SdkTlsSocketFactory:366 - Connecting socket to portal.sso.us-east-1.amazonaws.com/18.235.195.183:443 with timeout 2000
...
DEBUG s.a.a.requestId:85 - Received successful response: 200, Request ID: bb4f40f4-e920-4b5c-8648-58f26e7e08cd, Extended Request ID: not available
DEBUG s.a.a.request:85 - Received successful response: 200, Request ID: bb4f40f4-e920-4b5c-8648-58f26e7e08cd, Extended Request ID: not available
DEBUG s.a.a.u.c.CachedSupplier:85 - (software.amazon.awssdk.services.sso.auth.SsoCredentialsProvider@b965857) Successfully refreshed cached value. Next Prefetch Time: 2024-04-25T22:03:10.097Z. Next Stale Time: 2024-04-25T22:05:30Z
DEBUG s.a.a.c.i.ExecutionInterceptorChain:85 - Interceptor 'software.amazon.awssdk.services.s3.endpoints.internal.S3RequestSetEndpointInterceptor@7c2327fa' modified the message with its modifyHttpRequest method.
...
DEBUG s.a.a.c.i.h.p.s.SigningStage:85 - Using SelectedAuthScheme: aws.auth#sigv4
...
DEBUG s.a.a.a.s.Aws4Signer:85 - AWS4 Canonical Request: GET
...
DEBUG s.a.a.h.a.a.i.s.DefaultV4RequestSigner:85 - AWS4 String to sign: AWS4-HMAC-SHA256
20240425T210631Z
20240425/us-east-1/s3/aws4_request
aafb7784627fa7a49584256cb746279751c48c2076f813259ef767ecce304d64
DEBUG s.a.a.h.a.i.c.SdkTlsSocketFactory:366 - Connecting socket to s3.us-east-1.amazonaws.com/52.217.41.86:443 with timeout 2000
...
```

以下 `log4j2.xml` 文件配置了之前的输出。

```
<Configuration status="WARN">
    <Appenders>
        <Console name="ConsoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="%-5p %c{1.}:%L - %m%n" />
        </Console>
    </Appenders>

    <Loggers>
        <Root level="WARN">
            <AppenderRef ref="ConsoleAppender"/>
        </Root>
        <Logger name="software.amazon.awssdk" level="DEBUG" />
    </Loggers>
</Configuration>
```

## 启用线路日志记录
<a name="sdk-java-logging-verbose"></a>

查看适用于 Java 的 SDK 2.x 发送和接收的确切请求和响应可能很有用。如果您需要访问这些信息，可以根据服务客户端使用的 HTTP 客户端，通过添加必要的配置来临时启用它。

默认情况下，同步服务客户端（例如 [S3Client）使用底层 Apache HttpClient，而异步服务客户端](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html)（例如 [S3](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html)）使用 Netty 非阻AsyncClient塞 HTTP 客户端。

以下是可用于这两类服务客户端的 HTTP 客户端的细分：


| 同步 HTTP 客户端 | 异步 HTTP 客户端 | 
| --- | --- | 
| [ApacheHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/apache/ApacheHttpClient.html)（默认值） | [NettyNioAsyncHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html)（默认值） | 
| [UrlConnectionHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html) | [AwsCrtAsyncHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtAsyncHttpClient.html) | 
| [AwsCrtHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtHttpClient.html) |  | 
| [Apache5 HttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/apache5/Apache5HttpClient.html)  | 

请参阅下面的相应标签，了解需要根据底层 HTTP 客户端添加的配置设置。

**警告**  
我们建议只出于调试目的使用线路日志记录。由于线路日志记录可能记录敏感数据，因此应在您的生产环境中禁用它。它会记录完整的请求或响应而不加密，即使对于 HTTPS 调用也是如此。对于大型请求（例如，将文件上传到 Amazon S3）或响应，详细的线路记录也会显著影响应用程序的性能。

------
#### [ ApacheHttpClient ]

将“org.apache.http.wire”记录器添加到 `log4j2.xml` 配置文件中，并将级别设置为“DEBUG”。

以下`log4j2.xml`文件开启了 Apache HttpClient 的完整线路记录。

```
<Configuration status="WARN">
 <Appenders>
  <Console name="ConsoleAppender" target="SYSTEM_OUT">
   <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
  </Console>
 </Appenders>

 <Loggers>
  <Root level="WARN">
   <AppenderRef ref="ConsoleAppender"/>
  </Root>
  <Logger name="software.amazon.awssdk" level="WARN" />
  <Logger name="software.amazon.awssdk.request" level="DEBUG" />
  <Logger name="org.apache.http.wire" level="DEBUG" />
 </Loggers>
</Configuration>
```

使用 Apache 进行线路日志记录需要对 `log4j-1.2-api` 构件的额外 Maven 依赖项，因为它在后台使用 1.2。

以下构建文件片段显示了 log4j 2 的全套 Maven 依赖项，包括 Apache HTTP 客户端的线路日志记录。

**Maven**

```
...
<dependencyManagement>
    ...
    <dependencies>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-bom</artifactId>
            <version>VERSION</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
     </dependencies>
</dependencyManagement>
...
<!-- The following is needed for Log4j2 with SLF4J -->
<dependency>
   <groupId>org.apache.logging.log4j</groupId>
   <artifactId>log4j-slf4j2-impl</artifactId>
</dependency>

<!-- The following is needed for Apache HttpClient wire logging -->
<dependency>
   <groupId>org.apache.logging.log4j</groupId>
   <artifactId>log4j-1.2-api</artifactId>
</dependency>
...
```

**Gradle–Kotlin DSL**

```
...
dependencies {
    ...
    implementation(platform("org.apache.logging.log4j:log4j-bom:VERSION"))
    implementation("org.apache.logging.log4j:log4j-slf4j2-impl")
    implementation("org.apache.logging.log4j:log4j-1.2-api")
}
...
```

对于 `log4j-bom` 构件的最低版本，请使用 `2.20.0`。要获取最新版本，请使用发布到 [Maven central](https://central.sonatype.com/artifact/org.apache.logging.log4j/log4j-bom) 的版本。*VERSION*替换为你将要使用的版本。

------
#### [ Apache5HttpClient ]

将 “org.apache.hc.client5.http.wire” 记录器添加到配置文件中，并将级别设置为 “DEBUG”。`log4j2.xml`

以下`log4j2.xml`文件开启了 Apache HttpClient 5 的完整线路记录。

```
<Configuration status="WARN">
 <Appenders>
  <Console name="ConsoleAppender" target="SYSTEM_OUT">
   <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
  </Console>
 </Appenders>

 <Loggers>
  <Root level="WARN">
   <AppenderRef ref="ConsoleAppender"/>
  </Root>
  <Logger name="software.amazon.awssdk" level="WARN" />
  <Logger name="software.amazon.awssdk.request" level="DEBUG" />
  <Logger name="org.apache.hc.client5.http.wire" level="DEBUG" />
 </Loggers>
</Configuration>
```

------
#### [ UrlConnectionHttpClient ]

要记录使用 `UrlConnectionHttpClient` 的服务客户端的详细信息，请先创建一个包含以下内容的 `logging.properties` 文件：

```
handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINEST
sun.net.www.protocol.http.HttpURLConnection.level=ALL
```

使用 `logging.properties` 的完整路径设置以下 JVM 系统属性：

```
-Djava.util.logging.config.file=/full/path/to/logging.properties
```

此配置将仅记录请求和响应的标头，例如：

```
<Request>  FINE: sun.net.www.MessageHeader@35a9782c11 pairs: {GET /fileuploadtest HTTP/1.1: null}{amz-sdk-invocation-id: 5f7e707e-4ac5-bef5-ba62-00d71034ffdc}{amz-sdk-request: attempt=1; max=4}{Authorization: AWS4-HMAC-SHA256 Credential=<deleted>/20220927/us-east-1/s3/aws4_request, SignedHeaders=amz-sdk-invocation-id;amz-sdk-request;host;x-amz-content-sha256;x-amz-date;x-amz-te, Signature=e367fa0bc217a6a65675bb743e1280cf12fbe8d566196a816d948fdf0b42ca1a}{User-Agent: aws-sdk-java/2.17.230 Mac_OS_X/12.5 OpenJDK_64-Bit_Server_VM/25.332-b08 Java/1.8.0_332 vendor/Amazon.com_Inc. io/sync http/UrlConnection cfg/retry-mode/legacy}{x-amz-content-sha256: UNSIGNED-PAYLOAD}{X-Amz-Date: 20220927T133955Z}{x-amz-te: append-md5}{Host: tkhill-test1.s3.amazonaws.com}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}
<Response> FINE: sun.net.www.MessageHeader@70a36a6611 pairs: {null: HTTP/1.1 200 OK}{x-amz-id-2: sAFeZDOKdUMsBbkdjyDZw7P0oocb4C9KbiuzfJ6TWKQsGXHM/dFuOvr2tUb7Y1wEHGdJ3DSIxq0=}{x-amz-request-id: P9QW9SMZ97FKZ9X7}{Date: Tue, 27 Sep 2022 13:39:57 GMT}{Last-Modified: Tue, 13 Sep 2022 14:38:12 GMT}{ETag: "2cbe5ad4a064cedec33b452bebf48032"}{x-amz-transfer-encoding: append-md5}{Accept-Ranges: bytes}{Content-Type: text/plain}{Server: AmazonS3}{Content-Length: 67}
```

要查看主 request/response 体，请添加`-Djavax.net.debug=all`到 JVM 属性中。此附加属性记录了大量信息，包括所有 SSL 信息。

在日志控制台或日志文件中，搜索 `"GET"` 或 `"POST"` 以快速转到包含实际请求和响应的日志部分。使用 `"Plaintext before ENCRYPTION"` 搜索请求，使用 `"Plaintext after DECRYPTION"` 搜索响应，以查看标头和正文的全文。

------
#### [ NettyNioAsyncHttpClient ]

如果您的异步服务客户端使用默认值 `NettyNioAsyncHttpClient`，请在 `log4j2.xml` 文件中再添加两个记录器来记录 HTTP 标头和请求/响应正文。

```
<Logger name="io.netty.handler.logging" level="DEBUG" />
<Logger name="io.netty.handler.codec.http2.Http2FrameLogger" level="DEBUG" />
```

以下是完整 `log4j2.xml` 示例：

```
<Configuration status="WARN">
    <Appenders>
        <Console name="ConsoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
        </Console>
    </Appenders>

    <Loggers>
        <Root level="WARN">
            <AppenderRef ref="ConsoleAppender"/>
        </Root>
        <Logger name="software.amazon.awssdk" level="WARN" />
        <Logger name="software.amazon.awssdk.request" level="DEBUG" />
        <Logger name="io.netty.handler.logging" level="DEBUG" />
        <Logger name="io.netty.handler.codec.http2.Http2FrameLogger" level="DEBUG" />
    </Loggers>
</Configuration>
```

这些设置会记录所有标题的详细信息和正 request/response 文。

------
#### [ AwsCrtAsyncHttpClient/AwsCrtHttpClient ]

如果您已将服务客户端配置为使用基于 AWS CRT 的 HTTP 客户端的实例，则可以通过设置 JVM 系统属性或使用编程方式记录详细信息。


|  | 
| --- |
|  Log to a file at "Debug" level  | 
|  使用系统属性： <pre>-Daws.crt.log.level=Trace <br />-Daws.crt.log.destination=File <br />-Daws.crt.log.filename=<path to file></pre>  |  使用编程方式： <pre>import software.amazon.awssdk.crt.Log;<br /><br />// Execute this statement before constructing the SDK service client.<br />Log.initLoggingToFile(Log.LogLevel.Trace, "<path to file>");</pre>  | 
|  Log to the console at "Debug" level  | 
|  使用系统属性： <pre>-Daws.crt.log.level=Trace <br />-Daws.crt.log.destination=Stdout</pre>  |  使用编程方式： <pre>import software.amazon.awssdk.crt.Log;<br /><br />// Execute this statement before constructing the SDK service client.<br />Log.initLoggingToStdout(Log.LogLevel.Trace);</pre>  | 

出于安全考虑，在 “跟踪” 级别， AWS 基于 CRT 的 HTTP 客户端仅记录响应标头。不记录请求标头、请求正文和响应正文。

------