将 OpenTelemetry 与 Azure Functions 配合使用

重要

对 Azure Functions 的 OpenTelemetry 支持目前为预览版,应用必须托管在弹性消耗计划中,才能使用 OpenTelemetry。

本文介绍如何将函数应用配置为以 OpenTelemetry 格式导出日志和跟踪数据。 Azure Functions 从 Functions 主机进程和运行函数代码的语言特定的工作进程生成函数执行的遥测数据。 默认情况下,此遥测数据使用 Application Insights SDK 发送到 Application Insights。 但是,可以选择使用 OpenTelemetry 语义导出此数据。 虽然仍可以使用 OpenTelemetry 格式将数据发送到 Application Insights,但现在可以将相同的数据导出到任何其他符合 OpenTelemetry 的终结点。

提示

由于本文针对的是你所选择的开发语言,因此请记住在文章顶部选择正确的语言。

C # 进程内应用目前不支持 OpenTelemetry。

通过在函数应用中启用 OpenTelemetry,可以获得这些优势:

  • 跨在主机和应用程序代码中生成的跟踪和日志关联数据。
  • 启用一致的基于标准的可导出遥测数据生成。
  • 与能够处理 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,该应用在 2.x 版和更高版本的 Microsoft.Azure.Functions.Worker 中可用。 有关详细信息,请参阅 C# 独立辅助角色模型指南中的 版本 2.x

  1. 运行以下命令,以在应用中安装所需的程序集:

    dotnet add package Microsoft.Azure.Functions.Worker.OpenTelemetry --version  1.1.0-preview6
    dotnet add package OpenTelemetry.Extensions.Hosting 
    dotnet add package Azure.Monitor.OpenTelemetry.Exporter  
    
  2. 在 Program.cs 项目文件中,添加此 using 语句:

    using Azure.Monitor.OpenTelemetry.Exporter; 
    
  3. 配置 OpenTelemetry 的方式取决于项目启动是否使用 IHostBuilder ,或者在 IHostApplicationBuilder.NET 独立辅助角色模型扩展的 v2.x 中引入。

    program.cs中,添加以下代码行:ConfigureFunctionsWebApplication

    builder.Services.AddOpenTelemetry()
        .UseFunctionsWorkerDefaults()
        .UseAzureMonitorExporter();
    

    可以从同一应用导出到两个 OpenTelemetry 终结点。

  1. 将所需的库添加到应用。 添加库的方式取决于是使用 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>
    
  2. 可以选择添加此代码以创建自定义范围:

    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();
    }
    
  1. 在项目中安装以下 npm 包:

    npm install @opentelemetry/api 
    npm install @opentelemetry/auto-instrumentations-node 
    npm install @azure/monitor-opentelemetry-exporter 
    npm install @azure/functions-opentelemetry-instrumentation
    
  1. 在项目中创建代码文件,将此新文件中复制并粘贴以下代码,并将该文件另存为 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()],
});
  1. 更新 package.json 文件中的 main 字段以包含此新 src/index.js 文件,如下所示:

    "main": "src/{index.js,functions/*.js}"
    
  1. 在项目中创建代码文件,将此新文件中复制并粘贴以下代码,并将该文件另存为 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()],
});
  1. 更新 package.json 文件中的 main 字段以包含此新 src/index.ts 文件的输出,如下所示:

    "main": "dist/src/{index.js,functions/*.js}"
    

重要

PowerShell 应用目前不支持从语言辅助角色将 OpenTelemetry 输出输出到 Application Insights。 你可能想要使用 OTLP 导出器终结点。 为 OpenTelemetry 输出配置到 Application Insights 时,PowerShell 工作进程生成的日志仍会得到转发,但目前不支持分布式跟踪。

这些说明仅适用于 OTLP 导出程序:

  1. 添加名为 OTEL_FUNCTIONS_WORKER_ENABLED 的应用程序设置,其值为 True

  2. 在应用的根目录中创建应用级 Modules 文件夹并运行以下命令:

    Save-Module -Name AzureFunctions.PowerShell.OpenTelemetry.SDK
    

    这会直接在应用中安装所需的 AzureFunctions.PowerShell.OpenTelemetry.SDK 模块。 无法使用 requirements.psd1 文件自动安装此依赖项,因为 Flex Consumption 计划预览版目前不支持托管依赖项

  3. 将此代码添加到 profile.ps1 文件:

    Import-Module AzureFunctions.PowerShell.OpenTelemetry.SDK -Force -ErrorAction Stop 
    Initialize-FunctionsOpenTelemetry 
    
  1. 请确保这些库位于 requirements.txt 文件中,无论是取消注释还是自行添加:

    azure-monitor-opentelemetry
    
  2. 将此代码添加到 function_app.py 主入口点文件:

    如果已在应用程序设置中添加 PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY=true ,则可以跳过此步骤。 若要在不自动检测的情况下手动启用 Application Insights 集合,请将以下代码添加到应用:

    from azure.monitor.opentelemetry import configure_azure_monitor 
    configure_azure_monitor() 
    
  3. 查看 Azure Monitor 发行版使用情况 文档,获取有关如何进一步配置 SDK 的选项。

OpenTelemetry 注意事项

使用 OpenTelemetry 导出数据时,请记住当前这些注意事项。

  • 目前,OpenTelemetry 输出仅支持 HTTP、服务总线和事件中心触发器。

  • 当主机配置为使用 OpenTelemetry 时,Azure 门户不支持日志流式处理或最近的函数调用跟踪。

  • 自定义范围会自动包括所有资源属性,并使用应用中配置的导出程序。

  • 应用在 Azure 外部运行(包括在本地开发期间)时,资源检测器默认将 service.name 属性设置为 java-function-app 该属性。

  • 在单元测试期间在本地运行时,使用这些 Java 虚拟机 (JVM) 标志来静音遥测:

    • -Dotel.traces.exporter=none
    • -Dotel.metrics.exporter=none
    • -Dotel.logs.exporter=none
  • 无需手动注册中间件;Java 辅助角色自动发现 OpenTelemetryInvocationMiddleware

若要访问应用中的诊断,请执行以下操作:

  1. Azure 门户中,导航到函数应用资源。

  2. 在左窗格中,选择诊断并解决问题,然后搜索Function App 缺少遥测 Application Insights 或 OpenTelemetry 的工作流

  3. 选择此工作流,选择引入方法,然后选择“ 下一步”。

  4. 请查看故障排除程序提供的指南和任何建议。

监视 Azure Functions弹性消耗计划