基于 AWS Lambda 的无服务器可观测性与 OpenTelemetry
本指南涵盖了使用托管开源工具和技术配合 AWS 原生监控服务(如 AWS X-Ray 和 Amazon CloudWatch)为基于 Lambda 的无服务器应用程序配置可观测性的最佳实践。我们将介绍 AWS Distro for OpenTelemetry (ADOT)、AWS X-Ray 和 Amazon Managed Service for Prometheus (AMP) 等工具,以及如何使用这些工具获取无服务器应用程序的可操作洞察、排查问题和优化应用程序性能。
涵盖的关键主题
在可观测性最佳实践指南的这一部分中,我们将深入探讨以下主题:
- AWS Distro for OpenTelemetry (ADOT) 和 ADOT Lambda Layer 简介
- 使用 ADOT Lambda Layer 自动插桩 Lambda 函数
- ADOT Collector 的自定义配置支持
- 与 Amazon Managed Service for Prometheus (AMP) 的集成
- 使用 ADOT Lambda Layer 的优缺点
- 使用 ADOT 时管理冷启动延迟
AWS Distro for OpenTelemetry (ADOT) 简介
AWS Distro for OpenTelemetry (ADOT) 是由 AWS 支持的安全、可用于生产环境的 Cloud Native Computing Foundation (CNCF) OpenTelemetry (OTel) 项目发行版。使用 ADOT,您只需对应用程序进行一次插桩,即可将关联的 metrics 和 traces 发送到多个监控解决方案。
AWS 托管的 OpenTelemetry Lambda Layer 利用 OpenTelemetry Lambda Layer 来导出遥测数据。它通过包装 AWS Lambda 函数,并打包 OpenTelemetry 运行时特定的 SDK、精简版 ADOT collector 以及用于自动插桩 AWS Lambda 函数的开箱即用配置,提供即插即用的用户体验。ADOT Lambda Layer collector 组件(如 Receivers、Exporters 和 Extensions)支持与 Amazon CloudWatch、Amazon OpenSearch Service、Amazon Managed Service for Prometheus、AWS X-Ray 等的集成。完整列表请参见此处。ADOT 还支持与合作伙伴解决方案的集成。
ADOT Lambda Layer 支持自动插桩(适用于 Python、NodeJS 和 Java)以及针对任何特定库和 SDK 集的自定义插桩。对于自动插桩,默认情况下 Lambda Layer 配置为将 traces 导出到 AWS X-Ray。对于自定义插桩,您需要从相应的 OpenTelemetry 运行时插桩仓库 中包含对应的库插桩,并修改代码以在函数中初始化它。
使用 ADOT Lambda Layer 与 AWS Lambda 进行自动插桩
您可以轻松地使用 ADOT Lambda Layer 启用 Lambda 函数的自动插桩,无需任何代码更改。让我们以将 ADOT Lambda Layer 添加到现有的基于 Java 的 Lambda 函数并在 CloudWatch 中查看执行日志和 traces 为例。
- 根据文档,基于
runtime、region和arch type选择 Lambda Layer 的 ARN。确保使用与 Lambda 函数相同区域的 Lambda Layer。例如,用于 Java 自动插桩的 Lambda Layer 为arn:aws:lambda:us-east-1:901920570463:layer:aws-otel-java-agent-x86_64-ver-1-28-1:1 - 通过控制台或您选择的 IaC 将 Layer 添加到 Lambda 函数。
- 使用 AWS 控制台时,按照说明将 Layer 添加到 Lambda 函数。在"指定 ARN"下粘贴上面选择的 Layer ARN。
- 使用 IaC 选项时,Lambda 函数的 SAM 模板如下所示:
Layers:
- !Sub arn:aws:lambda:${AWS::Region}:901920570463:layer:aws-otel-java-agent-arm64-ver-1-28-1:1 - 向 Lambda 函数添加环境变量,Node.js 或 Java 使用
AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-handler,Python 使用AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument。 - 为 Lambda 函数启用主动追踪。
注意默认情况下,Layer 配置为将 traces 导出到 AWS X-Ray。确保 Lambda 函数的执行角色具有所需的 AWS X-Ray 权限。有关 AWS Lambda 的 AWS X-Ray 权限的更多信息,请参阅 AWS Lambda 文档。Tracing: Active
- 包含 Lambda Layer 配置、环境变量和 X-Ray 追踪的示例 SAM 模板如下所示:
Resources:
ListBucketsFunction:
Type: AWS::Serverless::Function
Properties:
Handler: com.example.App::handleRequest
...
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: 1
Policies:
- AWSXrayWriteOnlyAccess
- AmazonS3ReadOnlyAccess
Environment:
Variables:
AWS_LAMBDA_EXEC_WRAPPER: /opt/otel-handler
Tracing: Active
Layers:
- !Sub arn:aws:lambda:${AWS::Region}:901920570463:layer:aws-otel-java-agent-amd64-ver-1-28-1:1
Events:
HelloWorld:
Type: Api
Properties:
Path: /listBuckets
Method: get
- 在 AWS X-Ray 中测试和可视化 traces
直接或通过 API(如果配置了 API 触发器)调用 Lambda 函数。例如,通过 API(使用
curl)调用 Lambda 函数将生成如下日志:
curl -X GET https://XXXXXX.execute-api.us-east-1.amazonaws.com/Prod/listBuckets
Lambda 函数日志:
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
[otel.javaagent 2023-09-24 15:28:16:862 +0000] [main] INFO io.opentelemetry.javaagent.tooling.VersionLogger - opentelemetry-javaagent - version: 1.28.0-adot-lambda1-aws
EXTENSION Name: collector State: Ready Events: [INVOKE, SHUTDOWN]
START RequestId: ed8f8444-3c29-40fe-a4a1-aca7af8cd940 Version: 3
...
END RequestId: ed8f8444-3c29-40fe-a4a1-aca7af8cd940
REPORT RequestId: ed8f8444-3c29-40fe-a4a1-aca7af8cd940 Duration: 5144.38 ms Billed Duration: 5145 ms Memory Size: 1024 MB Max Memory Used: 345 MB Init Duration: 27769.64 ms
XRAY TraceId: 1-65105691-384f7da75714148655fa631b SegmentId: 2c52a147021ebd20 Sampled: true
从日志中可以看到,OpenTelemetry Lambda 扩展开始使用 opentelemetry-javaagent 监听和插桩 Lambda 函数,并在 AWS X-Ray 中生成 traces。
要查看上述 Lambda 函数调用的 traces,请导航到 AWS X-Ray 控制台,并在 Traces 下选择 trace id。您应该会看到如下所示的 Trace Map 和 Segments Timeline:

ADOT Collector 的自定义配置支持
ADOT Lambda Layer 结合了 OpenTelemetry SDK 和 ADOT Collector 组件。ADOT Collector 的配置遵循 OpenTelemetry 标准。默认情况下,ADOT Lambda Layer 使用 config.yaml 将遥测数据导出到 AWS X-Ray。但是,ADOT Lambda Layer 也支持其他 exporters,使您能够将 metrics 和 traces 发送到其他目的地。自定义配置支持的可用组件完整列表请参见此处。
与 Amazon Managed Service for Prometheus (AMP) 的集成
您可以使用自定义 collector 配置将 Lambda 函数的 metrics 导出到 Amazon Managed Prometheus (AMP)。
- 按照上面自动插桩的步骤,配置 Lambda Layer,设置环境变量
AWS_LAMBDA_EXEC_WRAPPER。 - 按照说明在您的 AWS 账户中创建 Amazon Managed Prometheus 工作空间,Lambda 函数将向其发送 metrics。记下 AMP 工作空间中的
Endpoint - remote write URL。您需要将其配置在 ADOT collector 配置中。 - 在 Lambda 函数的根目录中创建一个自定义 ADOT collector 配置文件(例如
collector.yaml),其中包含上一步中 AMP endpoint remote write URL 的详细信息。您也可以从 S3 存储桶加载配置文件。 示例 ADOT collector 配置文件:
#collector.yaml in the root directory
#Set an environemnt variable 'OPENTELEMETRY_COLLECTOR_CONFIG_FILE' to '/var/task/collector.yaml'
extensions:
sigv4auth:
service: "aps"
region: "<workspace_region>"
receivers:
otlp:
protocols:
grpc:
http:
exporters:
logging:
prometheusremotewrite:
endpoint: "<workspace_remote_write_url>"
namespace: test
auth:
authenticator: sigv4auth
service:
extensions: [sigv4auth]
pipelines:
traces:
receivers: [otlp]
exporters: [awsxray]
metrics:
receivers: [otlp]
exporters: [logging, prometheusremotewrite]
Prometheus Remote Write Exporter 还可以配置 retry 和 timeout 设置。更多信息请参阅文档。注意 sigv4auth 扩展的 Service 值应为 aps(Amazon Prometheus Service)。另外,确保 Lambda 函数执行角色具有所需的 AMP 权限。有关 AWS Lambda 所需的 AMP 权限和策略的更多信息,请参阅 Amazon Managed Service for Prometheus 文档。
- 添加环境变量
OPENTELEMETRY_COLLECTOR_CONFIG_FILE并将值设置为配置文件的路径。例如 /var/task/<path to config file>.yaml。这将告诉 Lambda Layer 扩展在哪里找到 collector 配置。
Function:
Type: AWS::Serverless::Function
Properties:
...
Environment:
Variables:
OPENTELEMETRY_COLLECTOR_CONFIG_FILE: /var/task/collector.yaml