在 Amazon Lambda 中检测 Python 代码 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

在 Amazon Lambda 中检测 Python 代码

Lambda 与 Amazon X-Ray 集成,以帮助您跟踪、调试和优化 Lambda 应用程序。您可以在某个请求遍历应用程序中的资源(其中可能包括 Lambda 函数和其他 Amazon 服务)时,使用 X-Ray 跟踪该请求。

要将跟踪数据发送到 X-Ray,您可以使用以下三个开发工具包库之一:

每个开发工具包均提供了将遥测数据发送到 X-Ray 服务的方法。然后,您可以使用 X-Ray 查看、筛选和获得对应用程序性能指标的洞察,从而发现问题和优化机会。

重要

X-Ray 和 Powertools for Amazon Lambda SDK 是 Amazon 提供的紧密集成的分析解决方案的一部分。ADOT Lambda Layers 是全行业通用的跟踪分析标准的一部分,该标准通常会收集更多数据,但可能不适用于所有使用案例。您可以使用任一解决方案在 X-Ray 中实现 end-to-end 跟踪。要了解有关如何在两者之间进行选择的更多信息,请参阅在 Amazon Distro for Open Telemetry 和 X-Ray 开发工具包之间进行选择

将 Powertools for Amazon Lambda(Python)和 Amazon SAM 用于跟踪

请按照以下步骤使用 Amazon SAM,通过集成的 Powertools for Amazon Lambda(Python)模块来下载、构建和部署示例 Hello World Python 应用程序。此应用程序实现了基本的 API 后端,并使用 Powertools 发送日志、指标和跟踪。它由 Amazon API Gateway 端点和 Lambda 函数组成。当您向 API Gateway 终端节点发送 GET 请求时,Lambda 函数会调用、使用嵌入式指标格式向其发送日志和指标 CloudWatch,并将跟踪发送到。Amazon X-Ray该函数将返回一条 hello world 消息。

先决条件

要完成本节中的步骤,您必须满足以下条件:

部署示例 Amazon SAM 应用程序
  1. 使用 Hello World Python 模板初始化该应用程序。

    sam init --app-template hello-world-powertools-python --name sam-app --package-type Zip --runtime python3.9 --no-tracing
  2. 构建应用程序。

    cd sam-app && sam build
  3. 部署应用程序。

    sam deploy --guided
  4. 按照屏幕上的提示操作。要在交互式体验中接受提供的默认选项,请按 Enter

    注意

    因为HelloWorldFunction 可能没有定义授权,这样可以吗? ,请务必输入y

  5. 获取已部署应用程序的 URL:

    aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
  6. 调用 API 端点:

    curl -X GET <URL_FROM_PREVIOUS_STEP>

    如果成功,您将会看到如下响应:

    {"message":"hello world"}
  7. 要获取该函数的跟踪信息,请运行 sam traces

    sam traces

    该跟踪输出类似于以下示例:

    New XRay Service Graph Start time: 2023-02-03 14:59:50+00:00 End time: 2023-02-03 14:59:50+00:00 Reference Id: 0 - (Root) AWS::Lambda - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [1] Summary_statistics: - total requests: 1 - ok count(2XX): 1 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0.924 Reference Id: 1 - AWS::Lambda::Function - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [] Summary_statistics: - total requests: 1 - ok count(2XX): 1 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0.016 Reference Id: 2 - client - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [0] Summary_statistics: - total requests: 0 - ok count(2XX): 0 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0 XRay Event [revision 1] at (2023-02-03T14:59:50.204000) with id (1-63dd2166-434a12c22e1307ff2114f299) and duration (0.924s) - 0.924s - sam-app-HelloWorldFunction-YBg8yfYtOc9j [HTTP: 200] - 0.016s - sam-app-HelloWorldFunction-YBg8yfYtOc9j - 0.739s - Initialization - 0.016s - Invocation - 0.013s - ## lambda_handler - 0.000s - ## app.hello - 0.000s - Overhead
  8. 这是一个可以通过互联网访问的公有 API 端点。我们建议您在测试后删除该端点。

    sam delete

X-Ray 无法跟踪对应用程序的所有请求。X-Ray 将应用采样算法确保跟踪有效,同时仍会提供所有请求的一个代表性样本。采样率是每秒 1 个请求和 5% 的其他请求。

注意

您无法为您的函数配置此 X-Ray 采样率。

将 Powertools for Amazon Lambda(Python)和 Amazon CDK 用于跟踪

请按照以下步骤使用 Amazon CDK,通过集成的 Powertools for Amazon Lambda(Python)模块来下载、构建和部署示例 Hello World Python 应用程序。此应用程序实现了基本的 API 后端,并使用 Powertools 发送日志、指标和跟踪。它由 Amazon API Gateway 端点和 Lambda 函数组成。当您向 API Gateway 终端节点发送 GET 请求时,Lambda 函数会调用、使用嵌入式指标格式向其发送日志和指标 CloudWatch,并将跟踪发送到。Amazon X-Ray该函数将返回一条 hello world 消息。

先决条件

要完成本节中的步骤,您必须满足以下条件:

部署示例 Amazon CDK 应用程序
  1. 为您的新应用程序创建一个项目目录。

    mkdir hello-world cd hello-world
  2. 初始化该应用程序。

    cdk init app --language python
  3. 安装 Python 依赖项。

    pip install -r requirements.txt
  4. 在根文件夹下创建目录 lambda_function

    mkdir lambda_function cd lambda_function
  5. 创建文件 app.py 并将以下代码添加到该文件中。这是适用于 Lambda 函数的代码。

    from aws_lambda_powertools.event_handler import APIGatewayRestResolver from aws_lambda_powertools.utilities.typing import LambdaContext from aws_lambda_powertools.logging import correlation_paths from aws_lambda_powertools import Logger from aws_lambda_powertools import Tracer from aws_lambda_powertools import Metrics from aws_lambda_powertools.metrics import MetricUnit app = APIGatewayRestResolver() tracer = Tracer() logger = Logger() metrics = Metrics(namespace="PowertoolsSample") @app.get("/hello") @tracer.capture_method def hello(): # adding custom metrics # See: https://docs.powertools.aws.dev/lambda-python/latest/core/metrics/ metrics.add_metric(name="HelloWorldInvocations", unit=MetricUnit.Count, value=1) # structured log # See: https://docs.powertools.aws.dev/lambda-python/latest/core/logger/ logger.info("Hello world API - HTTP 200") return {"message": "hello world"} # Enrich logging with contextual information from Lambda @logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST) # Adding tracer # See: https://docs.powertools.aws.dev/lambda-python/latest/core/tracer/ @tracer.capture_lambda_handler # ensures metrics are flushed upon request completion/failure and capturing ColdStart metric @metrics.log_metrics(capture_cold_start_metric=True) def lambda_handler(event: dict, context: LambdaContext) -> dict: return app.resolve(event, context)
  6. 打开 hello_world 目录。您应该会看到一个名为 hello_world_stack.py 的文件。

    cd .. cd hello_world
  7. 打开 hello_world_stack.py,然后将以下代码添加到该文件中。它包含 Lambda 构造函数,它创建 Lambda 函数,为 Powertools 配置环境变量并将日志保留时间设置为一周,以及创建 REST API 的 ApiGatewayv1 构造函数

    from aws_cdk import ( Stack, aws_apigateway as apigwv1, aws_lambda as lambda_, CfnOutput, Duration ) from constructs import Construct class HelloWorldStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Powertools Lambda Layer powertools_layer = lambda_.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", # At the moment we wrote this example, the aws_lambda_python_alpha CDK constructor is in Alpha, o we use layer to make the example simpler # See https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_lambda_python_alpha/README.html # Check all Powertools layers versions here: https://docs.powertools.aws.dev/lambda-python/latest/#lambda-layer layer_version_arn=f"arn:aws:lambda:{self.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:21" ) function = lambda_.Function(self, 'sample-app-lambda', runtime=lambda_.Runtime.PYTHON_3_9, layers=[powertools_layer], code = lambda_.Code.from_asset("./lambda_function/"), handler="app.lambda_handler", memory_size=128, timeout=Duration.seconds(3), architecture=lambda_.Architecture.X86_64, environment={ "POWERTOOLS_SERVICE_NAME": "PowertoolsHelloWorld", "POWERTOOLS_METRICS_NAMESPACE": "PowertoolsSample", "LOG_LEVEL": "INFO" } ) apigw = apigwv1.RestApi(self, "PowertoolsAPI", deploy_options=apigwv1.StageOptions(stage_name="dev")) hello_api = apigw.root.add_resource("hello") hello_api.add_method("GET", apigwv1.LambdaIntegration(function, proxy=True)) CfnOutput(self, "apiUrl", value=f"{apigw.url}hello")
  8. 部署您的应用程序。

    cd .. cdk deploy
  9. 获取已部署应用程序的 URL:

    aws cloudformation describe-stacks --stack-name HelloWorldStack --query 'Stacks[0].Outputs[?OutputKey==`apiUrl`].OutputValue' --output text
  10. 调用 API 端点:

    curl -X GET <URL_FROM_PREVIOUS_STEP>

    如果成功,您将会看到如下响应:

    {"message":"hello world"}
  11. 要获取该函数的跟踪信息,请运行 sam traces

    sam traces

    该跟踪输出类似于以下示例:

    New XRay Service Graph Start time: 2023-02-03 14:59:50+00:00 End time: 2023-02-03 14:59:50+00:00 Reference Id: 0 - (Root) AWS::Lambda - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [1] Summary_statistics: - total requests: 1 - ok count(2XX): 1 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0.924 Reference Id: 1 - AWS::Lambda::Function - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [] Summary_statistics: - total requests: 1 - ok count(2XX): 1 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0.016 Reference Id: 2 - client - sam-app-HelloWorldFunction-YBg8yfYtOc9j - Edges: [0] Summary_statistics: - total requests: 0 - ok count(2XX): 0 - error count(4XX): 0 - fault count(5XX): 0 - total response time: 0 XRay Event [revision 1] at (2023-02-03T14:59:50.204000) with id (1-63dd2166-434a12c22e1307ff2114f299) and duration (0.924s) - 0.924s - sam-app-HelloWorldFunction-YBg8yfYtOc9j [HTTP: 200] - 0.016s - sam-app-HelloWorldFunction-YBg8yfYtOc9j - 0.739s - Initialization - 0.016s - Invocation - 0.013s - ## lambda_handler - 0.000s - ## app.hello - 0.000s - Overhead
  12. 这是一个可以通过互联网访问的公有 API 端点。我们建议您在测试后删除该端点。

    cdk destroy

使用 ADOT 分析您的 Python 函数

ADOT 提供完全托管式 Lambda ,这些层使用 OTel SDK,将收集遥测数据所需的一切内容打包起来。通过使用此层,您可以在不必修改任何函数代码的情况下,对您的 Lambda 函数进行分析。您还可以将您的层配置为对 OTel 进行自定义初始化。有关更多信息,请参阅 ADOT 文档中的适用于 Lambda 上的 ADOT 收集器的自定义配置

对于 Python 运行时,可以添加 Amazon适用于 ADOT Python 的托管 Lambda 层以自动分析您的函数。此层适用于 arm64 和 x86_64 架构。有关如何添加此层的详细说明,请参阅 ADOT 文档中的 Lam Amazonb OpenTelemetry da Support 发行版 Python 支持

使用 X-Ray SDK 分析您的 Python 函数

要记录有关您的 Lambda 函数对应用程序中的其他资源进行调用的详细信息,您还可以使用 Amazon X-Ray SDK for Python。要获取开发工具包,请将 aws-xray-sdk 包添加到应用程序的依赖项中。

requirements.txt
jsonpickle==1.3 aws-xray-sdk==2.4.3

在函数代码中,可以通过使用 aws_xray_sdk.core 模块修补 boto3 库来分析 Amazon SDK 客户端。

函数 – 跟踪 Amazon SDK 客户端
import boto3 from aws_xray_sdk.core import xray_recorder from aws_xray_sdk.core import patch_all logger = logging.getLogger() logger.setLevel(logging.INFO) patch_all() client = boto3.client('lambda') client.get_account_settings() def lambda_handler(event, context): logger.info('## ENVIRONMENT VARIABLES\r' + jsonpickle.encode(dict(**os.environ))) ...

在添加正确的依赖项并进行必要的代码更改后,请通过 Lambda 控制台或 API 激活函数配置中的跟踪。

使用 Lambda 控制台激活跟踪

要使用控制台切换 Lambda 函数的活动跟踪,请按照以下步骤操作:

打开活跃跟踪
  1. 打开 Lamba 控制台的 Functions(函数)页面。

  2. 选择函数。

  3. 选择 Configuration(配置),然后选择 Monitoring and operations tools(监控和操作工具)。

  4. 选择编辑

  5. X-Ray 下方,开启 Active tracing(活动跟踪)。

  6. 选择保存

使用 Lambda API 激活跟踪

借助 Amazon CLI 或 Amazon SDK 在 Lambda 函数上配置跟踪,请使用以下 API 操作:

以下示例 Amazon CLI 命令对名为 my-function 的函数启用活跃跟踪。

aws lambda update-function-configuration --function-name my-function \ --tracing-config Mode=Active

跟踪模式是发布函数版本时版本特定配置的一部分。您无法更改已发布版本上的跟踪模式。

使用 Amazon CloudFormation 激活跟踪

要对 Amazon CloudFormation 模板中的 AWS::Lambda::Function 资源激活跟踪,请使用 TracingConfig 属性。

function-inline.yml – 跟踪配置
Resources: function: Type: AWS::Lambda::Function Properties: TracingConfig: Mode: Active ...

对于 Amazon Serverless Application Model (Amazon SAM) AWS::Serverless::Function 资源,请使用 Tracing 属性。

template.yml – 跟踪配置
Resources: function: Type: AWS::Serverless::Function Properties: Tracing: Active ...

解释 X-Ray 跟踪

您的函数需要权限才能将跟踪数据上载到 X-Ray。在 Lambda 控制台中激活跟踪后,Lambda 会将所需权限添加到函数的执行角色。否则,请将AWSXRayDaemonWriteAccess策略添加到执行角色。

在配置活跃跟踪后,您可以通过应用程序观察特定请求。X-Ray 服务图将显示有关应用程序及其所有组件的信息。来自错误处理器示例应用程序的以下示例显示了具有两个函数的应用程序。主函数处理事件,有时会返回错误。顶部的第二个函数处理第一个日志组中出现的错误,并使用软件开发工具包调用 X-Ray、Amazon Amazon Simple Storage Service (Amazon S3) 和 Amazon CloudWatch Logs。


        一幅显示 X-Ray 中两个独立应用程序及其各自服务地图的图

X-Ray 无法跟踪对应用程序的所有请求。X-Ray 将应用采样算法确保跟踪有效,同时仍会提供所有请求的一个代表性样本。采样率是每秒 1 个请求和 5% 的其他请求。

注意

您无法为您的函数配置此 X-Ray 采样率。

使用活动跟踪时,Lambda 会每个跟踪记录 2 个分段,这些分段将在服务图上创建两个节点。下图突出显示了错误处理程序示例应用程序中的主函数的这两个节点。


      具有单个函数的 X-Ray 服务地图。

位于左侧的第一个节点表示接收调用请求的 Lambda 服务。第二个节点表示特定的 Lambda 函数。以下示例显示了一个包含这 2 个分段的跟踪。两者都命名为 my-function,但其中一个函数具有 AWS::Lambda 源,另一个则具有 AWS::Lambda::Function 源。


        一个 X-Ray 跟踪,它将显示特定 Lambda 调用的每个子分段的延迟。

此示例将展开函数分段,以显示其三个子分段。

  • 初始化 – 表示加载函数和运行初始化代码所花费的时间。此子分段仅对由您的函数的每个实例处理的第一个事件显示。

  • 调用 – 表示执行处理程序代码花费的时间。

  • 开销 – 表示 Lambda 运行时为准备处理下一个事件而花费的时间。

您还可以分析 HTTP 客户端、记录 SQL 查询以及使用注释和元数据创建自定义子段。有关更多信息,请参阅 Amazon X-Ray 开发人员指南中的 Amazon X-Ray SDK for Python

定价

作为 Amazon 免费套餐的组成部分,您可以每月免费使用 X-Ray 跟踪,但不能超过一定限制。超出该阈值后,X-Ray 会对跟踪存储和检索进行收费。有关更多信息,请参阅 Amazon X-Ray 定价

在层中存储运行时依赖项 (X-Ray SDK)

如果您使用 X-Ray 开发工具包来分析Amazon开发工具包客户端和您的函数代码,则您的部署程序包可能会变得相当大。为了避免每次更新函数代码时上载运行时依赖项,请将 X-Ray SDK 打包到 Lambda 层中。

以下示例显示存储 Amazon X-Ray SDK for Python 的 AWS::Serverless::LayerVersion 资源。

template.yml – 依赖项层
Resources: function: Type: AWS::Serverless::Function Properties: CodeUri: function/. Tracing: Active Layers: - !Ref libs ... libs: Type: AWS::Serverless::LayerVersion Properties: LayerName: blank-python-lib Description: Dependencies for the blank-python sample app. ContentUri: package/. CompatibleRuntimes: - python3.8

使用此配置,仅在更改运行时依赖项时您才会更新库层。由于函数部署软件包仅包含您的代码,因此可以帮助缩短上传时间。

为依赖项创建层需要更改构建才能在部署之前生成层存档。有关工作示例,请参阅 blank-python 示例应用程序。