你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
本文介绍如何将函数应用配置为以 OpenTelemetry 格式导出日志和跟踪数据。 Azure Functions 生成在 Functions 主机进程和运行函数代码的特定语言工作进程中对函数执行的遥测数据。 默认情况下,此遥测数据使用 Application Insights SDK 发送到 Application Insights。 但是,可以选择使用 OpenTelemetry 语义导出此数据。 虽然仍可以使用 OpenTelemetry 格式将数据发送到 Application Insights,但现在可以将相同的数据导出到任何其他符合 OpenTelemetry 的终结点。
通过在函数应用中启用 OpenTelemetry,可以获得这些优势:
- 在主机和应用程序代码中生成跟踪和日志之间的关联数据。
- 启用一致的、基于标准的可导出遥测数据生成。
- 与其他可以使用 OpenTelemetry 兼容数据的提供程序集成。
使用本文时,请记住以下注意事项:
试用 OpenTelemetry 教程,旨在帮助你快速开始使用 OpenTelemetry 和 Azure Functions。 本文使用 Azure Developer CLI(
azd)创建和部署使用 OpenTelemetry 集成进行分布式跟踪的函数应用。由于本文针对的是你所选择的开发语言,因此请记住在文章顶部选择正确的语言。
- C# 进程内应用目前不受 OpenTelemetry 的支持。
- 在主机配置 (
host.json) 和代码项目中的函数应用级别均启用了 OpenTelemetry。 Functions 还提供客户端优化体验,用于从在特定于语言的工作进程中运行的函数代码导出 OpenTelemetry 数据。
在 Functions 主机中启用 OpenTelemetry
在函数应用的 host.json 文件中启用 OpenTelemetry 输出时,主机会导出 OpenTelemetry 输出,而不考虑应用使用的语言堆栈。
若要从 Functions 主机启用 OpenTelemetry 输出,请在代码项目中更新 host.json文件,以将 "telemetryMode": "OpenTelemetry" 元素添加到根集合。 启用 OpenTelemetry 后,host.json 文件可能如下所示:
{
"version": "2.0",
"telemetryMode": "OpenTelemetry",
...
}
配置应用程序设置
启用 host.json 文件中的 OpenTelemetry 时,应用的环境变量会根据可用的 OpenTelemetry 支持的应用程序设置来确定数据发送的终结点。
基于 OpenTelemetry 输出目标在函数应用中创建特定的应用程序设置。 为 Application Insights 和 OpenTelemetry 协议 (OTLP) 导出程序提供连接设置时,OpenTelemetry 数据将发送到这两个终结点。
APPLICATIONINSIGHTS_CONNECTION_STRING:Application Insights 工作区的连接字符串。 如果存在此设置,OpenTelemetry 数据将发送到该工作区。 使用相同的设置连接到未启用 OpenTelemetry 功能的 Application Insights。 如果应用还没有此设置,则可能需要启用 Application Insights 集成。
JAVA_APPLICATIONINSIGHTS_ENABLE_TELEMETRY:设置为 true,以便 Functions 主机允许Java工作进程直接流式传输 OpenTelemetry 日志,从而阻止重复的主机级条目。
PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY:设置为 true,以便 Functions 主机允许Python工作进程直接流式传输 OpenTelemetry 日志,从而阻止重复的主机级条目。
在应用中启用 OpenTelemetry
将 Functions 主机配置为使用 OpenTelemetry 后,更新应用程序代码以输出 OpenTelemetry 数据。 在主机和应用程序代码中启用 OpenTelemetry 时,可以在 Functions 主机进程和语言工作进程发出的跟踪和日志之间获得更好的关联。
检测应用程序以使用 OpenTelemetry 的方式取决于目标 OpenTelemetry 终结点:
本文中的示例假定应用程序使用 IHostApplicationBuilder,该功能在 Microsoft.Azure.Functions.Worker 的 2.x 版本及更高版本中可用。 有关详细信息,请参阅 C# 独立辅助角色模型指南中的 版本 2.x 。
运行以下命令,以在应用中安装所需的程序集:
注释
从版本 3.0 开始,
Microsoft.ApplicationInsights.WorkerService包利用 Azure Monitor 导出程序。 可以使用此包在内部使用 Azure Monitor 管道(包括 OpenTelemetry 导出程序)来维护现有的 Application Insights 配置行为。 可以使用Microsoft.ApplicationInsights.WorkerService包(v3.0 或更高版本),而不是Azure.Monitor.OpenTelemetry.Exporter包,如以下示例所示。dotnet add package Microsoft.Azure.Functions.Worker.OpenTelemetry dotnet add package OpenTelemetry.Extensions.Hosting dotnet add package Azure.Monitor.OpenTelemetry.Exporter在 Program.cs 项目文件中,添加此
using语句:using Azure.Monitor.OpenTelemetry.Exporter;根据项目启动是使用
IHostBuilder还是IHostApplicationBuilder来配置 OpenTelemetry。 后者是在 .NET 隔离工作者模型扩展功能的 v2.x 中引入的。在program.cs中,在
ConfigureFunctionsWebApplication之后添加此代码行:builder.Services.AddOpenTelemetry() .UseFunctionsWorkerDefaults() .UseAzureMonitorExporter();可以从同一应用导出到两个 OpenTelemetry 终结点。
将所需的库添加到应用。 添加库的方式取决于是使用 Maven 还是 Kotlin 进行部署,以及是否还要将数据发送到 Application Insights。
<dependency> <groupId>com.microsoft.azure.functions</groupId> <artifactId>azure-functions-java-opentelemetry</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>com.azure</groupId> <artifactId>azure-monitor-opentelemetry-autoconfigure</artifactId> <version>1.2.0</version> </dependency>(可选)添加此代码以创建自定义范围:
import com.microsoft.azure.functions.opentelemetry.FunctionsOpenTelemetry; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.context.Scope; Span span = FunctionsOpenTelemetry.startSpan( "com.contoso.PaymentFunction", // tracer name "validateCharge", // span name null, // parent = current context SpanKind.INTERNAL); try (Scope ignored = span.makeCurrent()) { // business logic here } finally { span.end(); }
在项目中安装以下 npm 包:
npm install @opentelemetry/api npm install @opentelemetry/auto-instrumentations-node npm install @azure/monitor-opentelemetry-exporter npm install @azure/functions-opentelemetry-instrumentation
在项目中创建代码文件,将此新文件中复制并粘贴以下代码,并将该文件另存为
src/index.js:const { AzureFunctionsInstrumentation } = require('@azure/functions-opentelemetry-instrumentation'); const { AzureMonitorLogExporter, AzureMonitorTraceExporter } = require('@azure/monitor-opentelemetry-exporter'); const { getNodeAutoInstrumentations, getResourceDetectors } = require('@opentelemetry/auto-instrumentations-node'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const { detectResourcesSync } = require('@opentelemetry/resources'); const { LoggerProvider, SimpleLogRecordProcessor } = require('@opentelemetry/sdk-logs'); const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node'); const resource = detectResourcesSync({ detectors: getResourceDetectors() }); const tracerProvider = new NodeTracerProvider({ resource }); tracerProvider.addSpanProcessor(new SimpleSpanProcessor(new AzureMonitorTraceExporter())); tracerProvider.register(); const loggerProvider = new LoggerProvider({ resource }); loggerProvider.addLogRecordProcessor(new SimpleLogRecordProcessor(new AzureMonitorLogExporter())); registerInstrumentations({ tracerProvider, loggerProvider, instrumentations: [getNodeAutoInstrumentations(), new AzureFunctionsInstrumentation()], });请在 package.json 文件中更新
main字段,以包含新src/index.js文件。 例如:"main": "src/{index.js,functions/*.js}"
在项目中创建代码文件,将此新文件中复制并粘贴以下代码,并将该文件另存为
src/index.ts:import { AzureFunctionsInstrumentation } from '@azure/functions-opentelemetry-instrumentation'; import { AzureMonitorLogExporter, AzureMonitorTraceExporter } from '@azure/monitor-opentelemetry-exporter'; import { getNodeAutoInstrumentations, getResourceDetectors } from '@opentelemetry/auto-instrumentations-node'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { detectResourcesSync } from '@opentelemetry/resources'; import { LoggerProvider, SimpleLogRecordProcessor } from '@opentelemetry/sdk-logs'; import { NodeTracerProvider, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node'; const resource = detectResourcesSync({ detectors: getResourceDetectors() }); const tracerProvider = new NodeTracerProvider({ resource }); tracerProvider.addSpanProcessor(new SimpleSpanProcessor(new AzureMonitorTraceExporter())); tracerProvider.register(); const loggerProvider = new LoggerProvider({ resource }); loggerProvider.addLogRecordProcessor(new SimpleLogRecordProcessor(new AzureMonitorLogExporter())); registerInstrumentations({ tracerProvider, loggerProvider, instrumentations: [getNodeAutoInstrumentations(), new AzureFunctionsInstrumentation()], });更新 package.json 文件中的
main字段以包含此新src/index.ts文件的输出,如下所示:"main": "dist/src/{index.js,functions/*.js}"
重要说明
PowerShell 应用目前不支持从语言辅助角色将 OpenTelemetry 输出输出到 Application Insights。 你可能想要使用 OTLP 导出器终结点。 将主机配置为 OpenTelemetry 输出到 Application Insights 时,PowerShell 工作进程生成的日志仍会转发,但目前不支持分布式跟踪。
这些说明仅适用于 OTLP 导出程序:
添加名为
OTEL_FUNCTIONS_WORKER_ENABLED的应用程序设置,其值为True。在应用的根目录中创建应用级
Modules文件夹并运行以下命令:Save-Module -Name AzureFunctions.PowerShell.OpenTelemetry.SDK此命令直接在应用中安装所需的
AzureFunctions.PowerShell.OpenTelemetry.SDK模块。 无法使用requirements.psd1文件自动安装此依赖项,因为 Flex Consumption 计划预览版目前不支持托管依赖项。将此代码添加到 profile.ps1 文件:
Import-Module AzureFunctions.PowerShell.OpenTelemetry.SDK -Force -ErrorAction Stop Initialize-FunctionsOpenTelemetry
请确保这些库位于
requirements.txt文件中,无论是取消注释还是自行添加:azure-monitor-opentelemetry将此代码添加到
function_app.py主入口点文件:如果已在应用程序设置中添加
PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY=true,则可以跳过此步骤。 若要在不自动检测的情况下手动启用 Application Insights 集合,请将以下代码添加到应用:from azure.monitor.opentelemetry import configure_azure_monitor configure_azure_monitor()查看 Azure 监视发行版使用情况文档,获取有关如何进一步配置 SDK 的选项。
OpenTelemetry 注意事项
使用 OpenTelemetry 导出数据时,请记住这些注意事项。
仅当遥测被发送到 Azure Monitor 时,Azure 门户才支持
Recent function invocation追踪。将主机配置为使用 OpenTelemetry 时,Azure门户不支持日志流式处理。
如果将
telemetryMode设置为OpenTelemetry,则 host.json 部分中的logging.applicationInsights配置将不适用。
自定义范围会自动包括所有资源属性,并使用应用中配置的导出程序。
当应用在Azure外部运行(包括在本地开发期间)时,资源检测器默认将
service.name属性设置为java-function-app。可以使用这些Java虚拟机(JVM)标志在本地进行单元测试时禁用遥测:
-Dotel.traces.exporter=none-Dotel.metrics.exporter=none-Dotel.logs.exporter=none
- 无需手动注册中间件,Java工作线程会自动发现
OpenTelemetryInvocationMiddleware。
资源检测器和语义约定
在Azure Functions中,资源属性描述函数应用进程及其环境。 Span 属性描述单个调用。
默认行为(无需执行任何操作)
在应用服务的Azure Functions中,资源检测器通常会自动填充常见属性,包括:
-
service.name(默认为函数应用名称) - Azure云属性,例如
cloud.provider、cloud.region和cloud.resource_id
在大多数情况下,这些默认值足以用于正确的应用程序映射分组和Azure上下文。
重写 service.name(云角色名称)的时机
仅当在 Application Insights(应用程序映射分组)中需要一个不同且稳定的节点名称时才进行重写,例如要在不同的槽位或环境中标准化命名。
将OTEL_SERVICE_NAME设置为覆盖已检测的值:
export OTEL_SERVICE_NAME="my-function-app"
调用范围属性(通常为自动)
除非要创建自定义调用范围,否则无需手动设置这些设置。
-
faas.name(函数名称) -
faas.trigger(例如http,servicebus)eventhubs -
faas.execution(调用/执行标识符)
重要说明
函数应用可以在一个进程中托管多个函数。 不要在资源上放置特定于函数的值。 将每次调用的标识置于区段上。
注释
在本地运行(Functions Core Tools)或在Azure元数据不可用的容器化/自承载环境中时,service.name可能默认为泛型值。 在本地设置 OTEL_SERVICE_NAME 以匹配生产命名。
Troubleshooting
使用 OpenTelemetry 导出数据时,请记住这些常见问题和解决方案。
日志筛选
若要在函数应用中正确配置日志筛选,需要了解主机进程与工作进程之间的差异。
宿主进程是 Azure Functions 运行时,它管理触发器、扩展,并发出系统级遥测信息,例如初始化日志、请求跟踪和运行时健康信息。
工作进程特定于语言,执行函数代码,并独立生成应用程序日志和遥测。
重要说明
host.json 中定义的筛选器仅适用于主机进程生成的日志。 必须使用针对语言的 OpenTelemetry 设置来筛选工作进程中的日志。
示例:筛选 host.json中所有提供程序的主机日志
使用此方法可为主机托管的所有提供程序设置全局日志级别:
{
"version": "2.0",
"telemetryMode": "OpenTelemetry",
"logging": {
"logLevel": {
"default": "Warning"
}
}
}
示例:仅筛选与 OpenTelemetry 日志记录器提供程序相关的日志
使用此方法仅针对 OpenTelemetry 日志记录器提供程序,不影响其他提供程序(如控制台或文件日志)。
{
"version": "2.0",
"telemetryMode": "OpenTelemetry",
"logging": {
"OpenTelemetry": {
"logLevel": {
"default": "Warning"
}
}
}
}
控制台日志输出
Functions 主机会自动捕获写入 stdout 或 stderr 的任何内容,并将其转发到遥测管道。 如果你在代码中使用 ConsoleExporter 或直接写入控制台,则遥测数据中可能会出现重复日志。
注释
为了避免重复的遥测条目,请勿在生产代码中添加 ConsoleExporter 或输出到控制台。
Microsoft Entra身份验证
在 OpenTelemetry 中使用Microsoft Entra身份验证时,必须为主机进程和辅助进程单独配置身份验证。
若要为主机进程配置身份验证,请参阅 要求Microsoft Entra身份验证。
若要为工作进程配置身份验证,请参阅 启用 Microsoft Entra 身份验证。
资源属性支持
Azure Monitor中的资源属性支持目前为预览版。 若要启用此功能,请将 OTEL_DOTNET_AZURE_MONITOR_ENABLE_RESOURCE_METRICS 环境变量设置为 true。 此设置将资源属性引入到自定义指标表中。
重复的请求遥测
主机进程会自动发送请求遥测数据。 如果工作进程也使用用于请求跟踪的库(例如 .NET 中的 AspNetCoreInstrumentation)进行检测,那么同一个请求会被报告两次。
注释
由于 Azure Monitor 发行版通常在 .NET 中包括 AspNetCoreInstrumentation,并在其他语言中具有类似的工具,请避免在工作进程中使用 Azure Monitor 发行版,以防止遥测数据重复。
不包括日志记录范围
默认情况下,工作进程不在其日志中包括作用域。 若要启用授权范围,您必须在工作线程中显式配置此设置。 以下示例演示如何在 .NET Isolated 中启用作用域:
builder.Logging.AddOpenTelemetry(b => b.IncludeScopes = true);
缺少请求遥测
HTTP、服务总线 和事件中心等触发器依赖于分布式跟踪的上下文传播。 默认情况下,使用基于父级的采样。当传入请求或消息未被采样时,不会生成请求遥测数据。
重复 OperationId
在 Azure Functions 中,用于关联遥测的 OperationId 直接来自传入请求或消息中的 traceparent 值。 如果多个调用重复使用相同的 traceparent 值,则它们都获得相同的 OperationId值。
使用环境变量配置 OpenTelemetry
可以使用其标准环境变量来配置 OpenTelemetry 行为。 这些变量提供一致的方式来控制不同语言和运行时的行为。 可以调整采样策略、导出程序设置和资源属性。 有关支持的环境变量的详细信息,请参阅 OpenTelemetry 文档。
使用诊断工具排查监控问题
在 Azure 门户中的 Azure Functions 诊断 是用来检测和诊断潜在监视相关问题的有用资源。
若要访问应用中的诊断,请按以下步骤操作:
在 Azure 门户中,导航到您的函数应用资源。
在左窗格中选择“诊断并解决问题”,然后搜索“函数应用缺少遥测 Application Insights 或 OpenTelemetry”工作流。
选择此工作流,选择引入方法,然后选择“ 下一步”。
查看疑难解答提供的指南和任何建议。
后续步骤
详细了解 OpenTelemetry 和监视Azure Functions:
- 监控 Azure Functions 使用 OpenTelemetry 分布式跟踪
- Monitor Azure Functions