为 Python 应用程序设置 Azure Monitor
Azure Monitor 支持对 Python 应用程序进行分布式跟踪、指标收集和日志记录。
Microsoft 支持的用于跟踪和导出 Python 应用程序数据的解决方案是通过 OpenCensus Python SDK 借助 Azure Monitor 导出程序完成的。
Microsoft 不建议将任何其他适用于 Python 的遥测 SDK 用作遥测解决方案,因为它们不受支持。
OpenCensus 正在聚合到 OpenTelemetry 中。 我们继续推荐使用 OpenCensus,虽然 OpenTelemetry 不断变得成熟。
先决条件
需要一个 Azure 订阅。 如果没有 Azure 订阅,请在开始之前创建一个免费帐户。
OpenCensus Python SDK 简介
OpenCensus 是一组开放源代码库,用于收集分布式跟踪、指标和日志记录遥测数据。 通过使用 Azure Monitor 导出程序,可将收集的遥测数据发送到 Application Insights。 本文分步介绍设置为 Python 设置 OpenCensus for Python 和 Azure Monitor 导出程序并将监视数据发送到 Azure Monitor 的过程。
使用 Azure Monitor 导出程序检测 OpenCensus Python SDK
安装 OpenCensus Azure Monitor 导出程序:
python -m pip install opencensus-ext-azure
SDK 使用三个 Azure Monitor 导出程序将不同类型的遥测数据发送到 Azure Monitor。 它们是 trace
、metrics
和 logs
。 有关这些遥测类型的详细信息,请参阅数据平台概述。 按照以下说明通过三个导出程序发送这些遥测类型。
遥测类型映射
OpenCensus 将以下导出程序映射到可在 Azure Monitor 中显示的遥测类型。
可观测性的支柱 | Azure Monitor 中的遥测类型 | 说明 |
---|---|---|
日志 | Traces、exceptions、customEvents | 日志遥测、异常遥测、事件遥测 |
指标 | customMetrics、performanceCounters | 自定义指标、性能计数器 |
跟踪 | 请求依赖项 | 传入的请求数、传出的请求数 |
日志
首先,让我们生成一些本地日志数据。
import logging logger = logging.getLogger(__name__) def main(): """Generate random log data.""" for num in range(5): logger.warning(f"Log Entry - {num}") if __name__ == "__main__": main()
为范围中的每个数字发出一个日志条目。
Log Entry - 0 Log Entry - 1 Log Entry - 2 Log Entry - 3 Log Entry - 4
我们希望在 Azure Monitor 中查看此日志数据。 你可以在环境变量
APPLICATIONINSIGHTS_CONNECTION_STRING
中指定它。 还可以将 connection_string 直接传递到AzureLogHandler
中,但不应将连接字符串添加到版本控制。APPLICATIONINSIGHTS_CONNECTION_STRING=<appinsights-connection-string>
建议使用连接字符串实例化用于向 Application Insights 发送遥测数据的导出程序。 根据以下代码示例,修改上一步中的代码:
import logging from opencensus.ext.azure.log_exporter import AzureLogHandler logger = logging.getLogger(__name__) logger.addHandler(AzureLogHandler()) # Alternatively manually pass in the connection_string # logger.addHandler(AzureLogHandler(connection_string=<appinsights-connection-string>)) """Generate random log data.""" for num in range(5): logger.warning(f"Log Entry - {num}")
导出程序会将日志数据发送到 Azure Monitor。 可在
traces
下找到数据。在此上下文中,
traces
与tracing
不同。 此处,traces
是指使用AzureLogHandler
时 Azure Monitor 中会出现的遥测类型。 但tracing
是指 OpenCensus 中的一种概念,与分布式跟踪相关。注意
根记录器配置为
warning
级别。 这意味着如果所发送的任何日志的严重性低于此级别,则其将被忽略,不会发送到 Azure Monitor。 有关详细信息,请参阅日志记录文档。还可以在
extra
关键字参数中通过使用custom_dimensions
字段向日志消息添加自定义属性。 这些属性会显示为 Azure Monitor 的customDimensions
中的键值对。注意
若要使此功能正常运行,需要将字典传递给
custom_dimensions
字段。 如果传递任何其他类型的参数,记录器会忽略它们。import logging from opencensus.ext.azure.log_exporter import AzureLogHandler logger = logging.getLogger(__name__) logger.addHandler(AzureLogHandler()) # Alternatively manually pass in the connection_string # logger.addHandler(AzureLogHandler(connection_string=<appinsights-connection-string>)) properties = {'custom_dimensions': {'key_1': 'value_1', 'key_2': 'value_2'}} # Use properties in logging statements logger.warning('action', extra=properties)
注意
在使用 Application Insights 检测的过程中,我们会收集诊断数据并将其发送给 Microsoft。 这些数据可帮助我们运行和改进 Application Insights。 可以选择禁用非基本数据的收集。 若要了解详细信息,请参阅 Application Insights 中的 Statsbeat。
配置 Django 应用程序的日志记录
可以按照上文所述在应用程序代码中为 Django 应用程序显式配置日志记录,也可以在 Django 的日志记录配置中指定日志记录。 此代码可以包含在用于 Django 站点的设置配置的任何文件中,通常是 settings.py
。
有关如何配置 Django 设置的信息,请参阅 Django 设置。 有关如何配置日志记录的详细信息,请参阅 Django 设置。
LOGGING = {
"handlers": {
"azure": {
"level": "DEBUG",
"class": "opencensus.ext.azure.log_exporter.AzureLogHandler",
"connection_string": "<appinsights-connection-string>",
},
"console": {
"level": "DEBUG",
"class": "logging.StreamHandler",
"stream": sys.stdout,
},
},
"loggers": {
"logger_name": {"handlers": ["azure", "console"]},
},
}
请确保所用记录器的名称与在配置中指定的名称相同。
# views.py
import logging
from django.shortcuts import request
logger = logging.getLogger("logger_name")
logger.warning("this will be tracked")
发送异常
OpenCensus Python 不会自动跟踪和发送 exception
遥测。 借助 Python 日志记录库使用异常,可通过 AzureLogHandler
发送它。 可以像处理普通日志记录一样添加自定义属性。
import logging
from opencensus.ext.azure.log_exporter import AzureLogHandler
logger = logging.getLogger(__name__)
logger.addHandler(AzureLogHandler())
# Alternatively, manually pass in the connection_string
# logger.addHandler(AzureLogHandler(connection_string=<appinsights-connection-string>))
properties = {'custom_dimensions': {'key_1': 'value_1', 'key_2': 'value_2'}}
# Use properties in exception logs
try:
result = 1 / 0 # generate a ZeroDivisionError
except Exception:
logger.exception('Captured an exception.', extra=properties)
由于必须显式记录异常,这取决于你如何记录未处理的异常。 OpenCensus 对如何执行此日志记录没有限制,但是你必须显式记录异常遥测。
发送事件
可以使用与发送 trace
遥测完全相同的方式来发送 customEvent
遥测,只是后者应该使用 AzureEventHandler
。
import logging
from opencensus.ext.azure.log_exporter import AzureEventHandler
logger = logging.getLogger(__name__)
logger.addHandler(AzureEventHandler())
# Alternatively manually pass in the connection_string
# logger.addHandler(AzureEventHandler(connection_string=<appinsights-connection-string>))
logger.setLevel(logging.INFO)
logger.info('Hello, World!')
采样
有关在 OpenCensus 中采样的信息,请参阅 OpenCensus 中的采样。
日志关联
有关如何使用跟踪上下文数据扩充日志的信息,请参阅 OpenCensus Python 日志集成。
修改遥测
如需了解将跟踪的遥测发送到 Azure Monitor 之前如何对其进行修改,请参阅 OpenCensus Python 遥测处理器。
指标
OpenCensus.stats 支持四种聚合方法,但提供对 Azure Monitor 的部分支持:
- Count:度量点数的计数。 此值为累积值,只能增加,且在重启时重置为 0。
- Sum:度量点的总和。 此值为累积值,只能增加,且在重启时重置为 0。
- LastValue:保留最后记录的值,并删除所有其他值。
- 分布:Azure 导出程序不支持测量点的直方图分布。
Count 聚合示例
首先,让我们生成一些本地指标数据。 我们将创建一个指标,用于跟踪用户选择 Enter 键的次数。
from datetime import datetime from opencensus.stats import aggregation as aggregation_module from opencensus.stats import measure as measure_module from opencensus.stats import stats as stats_module from opencensus.stats import view as view_module from opencensus.tags import tag_map as tag_map_module stats = stats_module.stats view_manager = stats.view_manager stats_recorder = stats.stats_recorder prompt_measure = measure_module.MeasureInt("prompts", "number of prompts", "prompts") prompt_view = view_module.View("prompt view", "number of prompts", [], prompt_measure, aggregation_module.CountAggregation()) view_manager.register_view(prompt_view) mmap = stats_recorder.new_measurement_map() tmap = tag_map_module.TagMap() def main(): for _ in range(4): mmap.measure_int_put(prompt_measure, 1) mmap.record(tmap) metrics = list(mmap.measure_to_view_map.get_metrics(datetime.utcnow())) print(metrics[0].time_series[0].points[0]) if __name__ == "__main__": main()
创建指标以跟踪次数。 每次输入都会递增值,并且指标信息将显示在控制台中。 该信息包括指标更新时的当前值和当前时间戳。
Point(value=ValueLong(5), timestamp=2019-10-09 20:58:04.930426) Point(value=ValueLong(6), timestamp=2019-10-09 20:58:05.170167) Point(value=ValueLong(7), timestamp=2019-10-09 20:58:05.438614) Point(value=ValueLong(7), timestamp=2019-10-09 20:58:05.834216)
输入值有助于演示,但我们希望向 Azure Monitor 发出指标数据。 将连接字符串直接传递到导出程序。 也可以在环境变量
APPLICATIONINSIGHTS_CONNECTION_STRING
中指定它。 建议使用连接字符串实例化用于向 Application Insights 发送遥测数据的导出程序。 根据以下代码示例,修改上一步中的代码:from datetime import datetime from opencensus.ext.azure import metrics_exporter from opencensus.stats import aggregation as aggregation_module from opencensus.stats import measure as measure_module from opencensus.stats import stats as stats_module from opencensus.stats import view as view_module from opencensus.tags import tag_map as tag_map_module stats = stats_module.stats view_manager = stats.view_manager stats_recorder = stats.stats_recorder prompt_measure = measure_module.MeasureInt("prompts", "number of prompts", "prompts") prompt_view = view_module.View("prompt view", "number of prompts", [], prompt_measure, aggregation_module.CountAggregation()) view_manager.register_view(prompt_view) mmap = stats_recorder.new_measurement_map() tmap = tag_map_module.TagMap() exporter = metrics_exporter.new_metrics_exporter() # Alternatively manually pass in the connection_string # exporter = metrics_exporter.new_metrics_exporter(connection_string='<appinsights-connection-string>') view_manager.register_exporter(exporter) def main(): for _ in range(10): input("Press enter.") mmap.measure_int_put(prompt_measure, 1) mmap.record(tmap) metrics = list(mmap.measure_to_view_map.get_metrics(datetime.utcnow())) print(metrics[0].time_series[0].points[0]) if __name__ == "__main__": main()
导出程序按固定的间隔将指标数据发送到 Azure Monitor。 必须将此值设置为 60 秒,因为 Application Insights 后端会假定以 60 秒的时间间隔聚合指标点。 我们正在跟踪单个指标,因此,在每个间隔将会发送此指标数据及其包含的任何值和时间戳。 此数据为累积值,只能增加,且在重启时重置为 0。
可在
customMetrics
下找到数据,但是customMetrics
属性valueCount
、valueSum
、valueMin
、valueMax
和valueStdDev
未得到有效使用。
在指标中设置自定义维度
OpenCensus Python SDK 允许你通过使用 tags
(类似于键值对的字典)向指标遥测添加自定义维度。
将想要使用的标记插入到标记映射中。 标记映射的作用就像一种“池塘”,包含所有可用的标记。
... tmap = tag_map_module.TagMap() tmap.insert("url", "http://example.com") ...
对于特定
View
,请通过标记键来指定你在使用该视图记录指标时要使用的标记。... prompt_view = view_module.View("prompt view", "number of prompts", ["url"], # <-- A sequence of tag keys used to specify which tag key/value to use from the tag map prompt_measure, aggregation_module.CountAggregation()) ...
在度量映射中记录时,请务必使用标记映射。 在
View
中指定的标记键必须能在用于记录的标记映射中找到。... mmap = stats_recorder.new_measurement_map() mmap.measure_int_put(prompt_measure, 1) mmap.record(tmap) # <-- pass the tag map in here ...
在
customMetrics
表下,使用prompt_view
发出的所有指标记录都将具有自定义维度{"url":"http://example.com"}
。若要使用相同的键生成具有不同值的标记,请为这些标记创建新的标记映射。
... tmap = tag_map_module.TagMap() tmap2 = tag_map_module.TagMap() tmap.insert("url", "http://example.com") tmap2.insert("url", "https://www.wikipedia.org/wiki/") ...
性能计数器
默认情况下,指标导出程序会向 Azure Monitor 发送一组性能计数器。 可通过在指标导出程序的构造函数中将 enable_standard_metrics
标志设置为 False
来禁用此功能。
...
exporter = metrics_exporter.new_metrics_exporter(
enable_standard_metrics=False,
)
...
当前已发送以下性能计数器:
- 可用内存(字节)
- CPU 处理器时间(百分比)
- 传入请求速率(每秒)
- 传入请求平均执行时间(毫秒)
- 进程 CPU 使用率(百分比)
- 进程专用字节数(字节)
你应该能够在 performanceCounters
中看到这些指标。 有关详细信息,请参阅性能计数器。
修改遥测
如需了解将跟踪的遥测发送到 Azure Monitor 之前如何对其进行修改,请参阅 OpenCensus Python 遥测处理器。
跟踪
注意
在 OpenCensus 中,tracing
指分布式跟踪。 AzureExporter
参数将 requests
和 dependency
遥测发送到 Azure Monitor。
首先,让我们在本地生成一些跟踪数据。 在 Python IDLE 或所选编辑器中,输入以下代码:
from opencensus.trace.samplers import ProbabilitySampler from opencensus.trace.tracer import Tracer tracer = Tracer(sampler=ProbabilitySampler(1.0)) def main(): with tracer.span(name="test") as span: for value in range(5): print(value) if __name__ == "__main__": main()
对于每个条目,值会打印到 shell。 OpenCensus Python 模块会生成相应的
SpanData
部分。 OpenCensus 项目将跟踪定义为 span 树。0 [SpanData(name='test', context=SpanContext(trace_id=8aa41bc469f1a705aed1bdb20c342603, span_id=None, trace_options=TraceOptions(enabled=True), tracestate=None), span_id='15ac5123ac1f6847', parent_span_id=None, attributes=BoundedDict({}, maxlen=32), start_time='2019-06-27T18:21:22.805429Z', end_time='2019-06-27T18:21:44.933405Z', child_span_count=0, stack_trace=None, annotations=BoundedList([], maxlen=32), message_events=BoundedList([], maxlen=128), links=BoundedList([], maxlen=32), status=None, same_process_as_parent_span=None, span_kind=0)] 1 [SpanData(name='test', context=SpanContext(trace_id=8aa41bc469f1a705aed1bdb20c342603, span_id=None, trace_options=TraceOptions(enabled=True), tracestate=None), span_id='2e512f846ba342de', parent_span_id=None, attributes=BoundedDict({}, maxlen=32), start_time='2019-06-27T18:21:44.933405Z', end_time='2019-06-27T18:21:46.156787Z', child_span_count=0, stack_trace=None, annotations=BoundedList([], maxlen=32), message_events=BoundedList([], maxlen=128), links=BoundedList([], maxlen=32), status=None, same_process_as_parent_span=None, span_kind=0)] 2 [SpanData(name='test', context=SpanContext(trace_id=8aa41bc469f1a705aed1bdb20c342603, span_id=None, trace_options=TraceOptions(enabled=True), tracestate=None), span_id='f3f9f9ee6db4740a', parent_span_id=None, attributes=BoundedDict({}, maxlen=32), start_time='2019-06-27T18:21:46.157732Z', end_time='2019-06-27T18:21:47.269583Z', child_span_count=0, stack_trace=None, annotations=BoundedList([], maxlen=32), message_events=BoundedList([], maxlen=128), links=BoundedList([], maxlen=32), status=None, same_process_as_parent_span=None, span_kind=0)]
查看输出有助于演示,但我们希望向 Azure Monitor 发出
SpanData
。 将连接字符串直接传递到导出程序。 也可以在环境变量APPLICATIONINSIGHTS_CONNECTION_STRING
中指定它。 建议使用连接字符串实例化用于向 Application Insights 发送遥测数据的导出程序。 根据以下代码示例,修改上一步中的代码:from opencensus.ext.azure.trace_exporter import AzureExporter from opencensus.trace.samplers import ProbabilitySampler from opencensus.trace.tracer import Tracer tracer = Tracer( exporter=AzureExporter(), sampler=ProbabilitySampler(1.0), ) # Alternatively manually pass in the connection_string # exporter = AzureExporter( # connection_string='<appinsights-connection-string>', # ... # ) def main(): with tracer.span(name="test") as span: for value in range(5): print(value) if __name__ == "__main__": main()
现在,在运行 Python 脚本时,shell 中仅打印值。 会将创建的
SpanData
发送到 Azure Monitor。 可在dependencies
下找到发出的 span 数据。有关传出请求的详细信息,请参阅 OpenCensus Python 依赖项。 有关传入请求的详细信息,请参阅 OpenCensus Python 请求。
采样
有关在 OpenCensus 中采样的信息,请参阅 OpenCensus 中的采样。
跟踪关联
有关跟踪数据中遥测关联的详细信息,请参阅 OpenCensus Python 遥测关联。
修改遥测
有关在将跟踪的遥测发送到 Azure Monitor 之前如何对其进行修改的详细信息,请参阅 OpenCensus Python 遥测处理器。
配置 Azure Monitor 导出程序
如图所示,有三个不同的 Azure Monitor 导出程序支持 OpenCensus。 每个导出程序都将不同类型的遥测发送到 Azure Monitor。 要查看每个导出程序发送的遥测类型,请参阅下表。
每个导出程序都接受通过构造函数传递的相同配置参数。 可在此处查看有关每个导出程序的信息:
导出程序遥测 | 说明 |
---|---|
connection_string |
用于连接到 Azure Monitor 资源的连接字符串。 其优先级高于 instrumentation_key 。 |
credential |
Azure Active Directory 身份验证使用的凭据类。 请参阅下面的“身份验证”部分。 |
enable_standard_metrics |
用于 AzureMetricsExporter 。 指示导出程序将性能计数器指标自动发送到 Azure Monitor。 默认为 True 。 |
export_interval |
用于指定导出频率(秒)。 默认为 15s 。 对于指标,必须将其设置为 60 秒,否则指标聚合在指标资源管理器中将没有意义。 |
grace_period |
用于指定关闭导出程序的超时时间(以秒为单位)。 默认为 5s 。 |
instrumentation_key |
用于连接到 Azure Monitor 资源的检测密钥。 |
logging_sampling_rate |
用于 AzureLogHandler 和 AzureEventHandler 。 为导出日志/事件提供采样率 [0,1.0]。 默认为 1.0 。 |
max_batch_size |
指定一次性导出的最大遥测大小。 |
proxies |
指定用于将数据发送到 Azure Monitor 的代理序列。 有关详细信息,请参阅代理。 |
storage_path |
指向本地存储文件夹(未发送的遥测)所在位置的路径。 自 opencensus-ext-azure v1.0.3 起,默认路径为 OS 临时目录 + opencensus-python + your-ikey 。 在 v1.0.3 之前,默认路径为 $USER + .opencensus + .azure + python-file-name 。 |
timeout |
指定将遥测数据发送到引入服务的网络超时时间(以秒为单位)。 默认为 10s 。 |
与 Azure Functions 相集成
若要在 Azure Functions 环境中捕获自定义遥测,请使用 OpenCensus Python Azure Functions 扩展。 有关详细信息,请参阅 Azure Functions Python 开发人员指南。
身份验证(预览版)
注意
从 opencensus-ext-azure
v1.1b0 开始提供身份验证功能。
每个 Azure Monitor 导出程序都支持以下配置:通过使用 Azure Active Directory 进行的 OAuth 身份验证来安全地发送遥测有效负载。 有关详细信息,请参阅身份验证文档。
使用查询查看数据
可以通过“日志(分析)”选项卡查看从应用程序发送的遥测数据。
在“活动”下的列表中:
- 对于使用 Azure Monitor 跟踪导出程序发送的遥测,传入请求在
requests
下显示。 传出或进程内请求在dependencies
下显示。 - 对于使用 Azure Monitor 指标导出程序发送的遥测,发送的指标在
customMetrics
下显示。 - 对于使用 Azure Monitor 日志导出程序发送的遥测,日志在
traces
下显示。 异常在exceptions
下显示。
有关如何使用查询和日志的详细信息,请参阅 Azure Monitor 中的日志。
配置和启用基于 Microsoft Entra ID 的身份验证
注意
Microsoft Entra 身份验证仅适用于 Python v2.7、v3.6 和 v3.7。 从 beta 版本 opencensus-ext-azure 1.1b0 开始,包含对 Application Insights OpenCensus Python SDK 中 Microsoft Entra ID 的支持。
注意
OpenCensus Python SDK 已弃用,但 Microsoft 会提供对它的支持,直至 2024 年 9 月 30 日停用它。 我们现在推荐基于 OpenTelemetry 的 Python 产品/服务并提供迁移指南。
构造适当的凭据,然后将其传递给 Azure Monitor 导出程序的构造函数。 请确保使用资源的检测密钥和引入终结点设置连接字符串。
OpenCensus
Azure Monitor 导出程序支持这些身份验证类型。 建议在生产环境中使用托管标识。
系统分配的托管标识
from azure.identity import ManagedIdentityCredential
from opencensus.ext.azure.trace_exporter import AzureExporter
from opencensus.trace.samplers import ProbabilitySampler
from opencensus.trace.tracer import Tracer
credential = ManagedIdentityCredential()
tracer = Tracer(
exporter=AzureExporter(credential=credential, connection_string="InstrumentationKey=<your-instrumentation-key>;IngestionEndpoint=<your-ingestion-endpoint>"),
sampler=ProbabilitySampler(1.0)
)
...
用户分配的托管标识
from azure.identity import ManagedIdentityCredential
from opencensus.ext.azure.trace_exporter import AzureExporter
from opencensus.trace.samplers import ProbabilitySampler
from opencensus.trace.tracer import Tracer
credential = ManagedIdentityCredential(client_id="<client-id>")
tracer = Tracer(
exporter=AzureExporter(credential=credential, connection_string="InstrumentationKey=<your-instrumentation-key>;IngestionEndpoint=<your-ingestion-endpoint>"),
sampler=ProbabilitySampler(1.0)
)
...
了解有关 OpenCensus for Python 的详细信息
疑难解答
测试应用程序主机与引入服务之间的连接性
Application Insights SDK 和代理发送遥测,将其作为 REST 调用引入到引入终结点。 可以使用原始 REST 客户端通过 PowerShell 或使用 curl 命令,测试从 Web 服务器或应用程序主机计算机到引入服务终结点的连接。 请参阅排查 Azure Monitor Application Insights 中缺失应用程序遥测的问题。
发行说明
有关最新发行说明,请参阅 Python Azure Monitor 导出程序
我们的服务更新还总结了 Application Insights 的主要改进。
后续步骤
- 若要开启使用体验,请启用 Web 或浏览器用户监视
- 跟踪传入请求。
- 跟踪传出请求。
- 查看应用程序映射。
- 了解如何执行端到端性能监视。