本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用AWS SDK for Java 2.x 为 AWS Lambda 函数发布 SDK 指标
由于 Lambda 函数的执行时间通常为几毫秒到几分钟,而使用 CloudWatchMetricPublisher 发送指标存在延迟,这种延迟可能导致指标数据丢失。
EmfMetricLoggingPublisher 提供了一种更合适的方法,该方法会立即以 CloudWatch 嵌入式指标格式(EMF)将指标写成结构化日志条目。EmfMetricLoggingPublisher 适用于与 Amazon CloudWatch Logs 内置集成的执行环境,例如 AWS Lambda 和 Amazon Elastic Container Service。
设置
先完成以下步骤,然后才能使用 EmfMetricLoggingPublisher 来启用和使用指标。
步骤 1:添加所需的依赖项
将项目依赖项(例如,在您的 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</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:配置所需的权限
为指标发布者使用的 IAM 身份启用 logs:PutLogEvents 权限,以允许适用于 Java 的 SDK 编写 EMF 格式的日志。
步骤 3:设置日志记录
为确保正确收集指标,请将您的日志记录配置为以 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 文件的更多信息,请参阅本指南中的日志记录主题。
配置和使用 EmfMetricLoggingPublisher。
以下 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 日志流。
例如,如果您向 GameHandler Lambda 函数发送以下事件,并且之前日志记录按如下所示进行配置:
{ "id": "23456" }
函数处理事件后,您会看到两个与以下示例类似的日志事件。第二个事件中的 JSON 对象包含 DynamoDB PutItem 操作的 Java SDK 指标数据。
当 CloudWatch 收到 EMF 格式的日志事件时,它会自动解析结构化的 JSON 以提取指标数据。然后,CloudWatch 会创建相应的指标,同时将原始日志条目存储在 CloudWatch Logs 中。
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 文档
您还可以为单个请求启用 EMF 指标日志记录,如 CloudWatchMetricPublisher 所示。
后续步骤:对于长时间运行的应用程序,请参阅从长时间运行的应用程序发布 SDK 指标,了解基于 CloudWatch 的指标发布。