使用适用于 Python 中间件的 X-Ray 开发工具包跟踪传入请求 - Amazon X-Ray
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

使用适用于 Python 中间件的 X-Ray 开发工具包跟踪传入请求

在您将中间件添加到应用程序并配置分段名称时,适用于 Python 的 X-Ray 开发工具包会为每个采样请求创建一个分段。此分段包括 HTTP 请求的计时、方法和处置。其他检测会在此分段上创建子分段。

适用于 Python 的 X-Ray 开发工具包支持以下中间件来检测传入的 HTTP 请求:

  • Django

  • Flask

  • Bottle

注意

如果使用的是 Amazon Lambda 函数,Lambda 会为每个采样的请求创建一个分段。参阅 Amazon Lambda 和 Amazon X-Ray 了解更多信息。

有关在 Lambda 中检测过的示例 Python 函数,请参阅工作线程

对于其他框架上的脚本或 Python 应用程序,您可以手动创建分段

每个分段都有一个名称,用于在服务映射中标识您的应用程序。可以静态命名分段,也可以将开发工具包配置为根据传入请求中的主机标头对其进行动态命名。动态命名允许根据请求中的域名对跟踪进行分组,并且在名称不匹配预期模式时(例如,如果主机标头是伪造的)应用默认名称。

转发的请求

如果负载均衡器或其他中间将请求转发到您的应用程序,X-Ray 会提取请求 X-Forwarded-For 标头中的客户端 IP 而非 IP 数据包中的源 IP。由于转发的请求记录的客户端 IP 可以伪造,因此不应信任。

在转发请求时,开发工具包在分段中设置附加字段来指示此行为。如果分段包含设置为 x_forwarded_for 的字段 true,则从 HTTP 请求的 X-Forwarded-For 标头获取客户端 IP。

中间件使用包含以下信息的 http 块为每个传入请求创建一个分段:

  • HTTP 方法 - GET、POST、PUT、DELETE 等。

  • 客户端地址 - 发送请求的客户端的 IP 地址。

  • 响应代码 - 已完成请求的 HTTP 响应代码。

  • 时间 - 开始时间(收到请求时)和结束时间(发送响应时)。

  • 用户代理 - 请求中的 user-agent

  • 内容长度 - 响应中的 content-length

将中间件添加到应用程序 (Django)

将中间件添加到 MIDDLEWARE 文件中的 settings.py 列表。X-Ray 中间件应位于 settings.py 文件中的第一行,以确保在其他中间件失败的请求得到记录。

例 settings.py - 适用于 Python 中间件的 X-Ray 开发工具包
MIDDLEWARE = [ 'aws_xray_sdk.ext.django.middleware.XRayMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware' ]

将 X-Ray 开发工具包 Django 添加到 settings.py 文件中的 INSTALLED_APPS 列表。这将允许在应用程序启动期间配置 X-Ray 记录器。

例 settings.py - 适用于 Python Django 应用的 X-Ray 开发工具包
INSTALLED_APPS = [ 'aws_xray_sdk.ext.django', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]

settings.py 文件中配置分段名称。

例 settings.py - 分段名称
XRAY_RECORDER = { 'AWS_XRAY_TRACING_NAME': 'My application', 'PLUGINS': ('EC2Plugin',), }

这告知 X-Ray 记录器使用默认采样率跟踪您的 Django 应用程序处理的请求。您可以在您的 Django 设置文件中配置记录器,以便应用自定义采样规则或更改其他设置。

注意

由于 plugins 是作为元组传入的,因此请确保包含指定单一插件尾随的 ,。例如 plugins = ('EC2Plugin',)

将中间件添加到应用程序 (Flask)

要检测您的 Flask 应用程序,请先在 xray_recorder 上配置分段名称。然后,在代码中使用 XRayMiddleware 函数来修补您的 Flask 应用程序。

例 app.py
from aws_xray_sdk.core import xray_recorder from aws_xray_sdk.ext.flask.middleware import XRayMiddleware app = Flask(__name__) xray_recorder.configure(service='My application') XRayMiddleware(app, xray_recorder)

这告知 X-Ray 记录器使用默认采样率跟踪您的 Flask 应用程序处理的请求。您可以在代码中配置记录器,以便应用自定义采样规则或更改其他设置。

将中间件添加到应用程序 (Bottle)

要检测您的 Bottle 应用程序,请先在 xray_recorder 上配置分段名称。然后,在代码中使用 XRayMiddleware 函数来修补您的 Bottle 应用程序。

例 app.py
from aws_xray_sdk.core import xray_recorder from aws_xray_sdk.ext.bottle.middleware import XRayMiddleware app = Bottle() xray_recorder.configure(service='fallback_name', dynamic_naming='My application') app.install(XRayMiddleware(xray_recorder))

这告知 X-Ray 记录器使用默认采样率跟踪您的 Bottle 应用程序处理的请求。您可以在代码中配置记录器,以便应用自定义采样规则或更改其他设置。

手动检测 Python 代码

如果您不使用 Django 或 Flask,则可以手动创建分段。您可以为每个传入请求创建一个分段,或围绕经修补的 HTTP 或 Amazon 开发工具包客户端创建分段以便为记录器提供上下文来添加子分段。

例 main.py - 手动检测
from aws_xray_sdk.core import xray_recorder # Start a segment segment = xray_recorder.begin_segment('segment_name') # Start a subsegment subsegment = xray_recorder.begin_subsegment('subsegment_name') # Add metadata and annotations segment.put_metadata('key', dict, 'namespace') subsegment.put_annotation('key', 'value') # Close the subsegment and segment xray_recorder.end_subsegment() xray_recorder.end_segment()

配置分段命名策略

Amazon X-Ray 使用服务名称来识别应用程序并将其与其他应用程序数据库、外部 API 和应用程序使用的 Amazon 资源区别开。当 X-Ray 开发工具包为传入请求生成分段时,会将应用程序的服务名称记录在分段的名称字段中。

X-Ray 开发工具包可以用在 HTTP 请求标头中的 hostname 来命名分段。不过,此标头可以伪造,会导致服务地图中出现意料之外的节点。为防止开发工具包由于包含伪造的主机标头的请求而错误地命名分段,必须为传入请求指定一个默认名称。

如果应用程序为多个域的请求提供服务,则可以将开发工具包配置为使用动态命名策略以在分段名称中反映出这一点。动态命名策略允许开发工具包将主机名用于符合预期模式的请求,并将默认名称应用于不符合预期模式的请求。

例如,可能有一款应用程序为发送到三个子域的请求提供服务,分别为 www.example.comapi.example.comstatic.example.com。可以使用格式 *.example.com 的动态命名策略以识别包含不同名称的子域的分段,服务地图上因此会显示三个服务节点。如果应用程序收到包含与该格式不匹配的 hostname 的请求,您将会在服务地图上看到第四个节点,以及您指定的回退名称。

要对所有请求分段使用相同名称,请在配置记录器时指定应用程序的名称,如前几节所示。

动态命名策略定义一个主机名应匹配的模式和一个在 HTTP 请求中的主机名与该模式不匹配时要使用的默认名称。要在 Django 中动态命名分段,请将 DYNAMIC_NAMING 设置添加到您的 settings.py 文件。

例 settings.py - 动态命名
XRAY_RECORDER = { 'AUTO_INSTRUMENT': True, 'AWS_XRAY_TRACING_NAME': 'My application', 'DYNAMIC_NAMING': '*.example.com', 'PLUGINS': ('ElasticBeanstalkPlugin', 'EC2Plugin') }

您可以在模式中使用“*”来匹配任何字符串,或使用“?”来匹配任意单个字符。对于 Flask,在代码中配置记录器

例 main.py - 分段名称
from aws_xray_sdk.core import xray_recorder xray_recorder.configure(service='My application') xray_recorder.configure(dynamic_naming='*.example.com')
注意

您可以使用 AWS_XRAY_TRACING_NAME 环境变量覆盖您在代码中定义的默认服务名称。