共用方式為


搭配 Azure Functions 使用 OpenTelemetry

重要

Azure Functions 的 OpenTelemetry 支援目前為預覽狀態,您的應用程式必須裝載在 Flex 取用方案中 ,才能使用 OpenTelemetry。

本文說明如何設定函式應用程式,以 OpenTelemetry 格式匯出記錄和追蹤數據。 Azure Functions 會從 Functions 主機進程和函式程式碼執行所在的語言特定背景工作進程產生函式執行的遙測數據。 根據預設,此遙測數據會使用Application Insights SDK 傳送至Application Insights。 不過,您可以選擇使用 OpenTelemetry 語意匯出此數據。 雖然您仍然可以使用 OpenTelemetry 格式將數據傳送至 Application Insights,但您現在可以將相同的數據導出至任何其他符合 OpenTelemetry 規範的端點。

提示

因為本文是以您選擇的開發語言為目標,請記得選擇文章頂端的正確語言。

目前,Java 應用程式沒有客戶端優化的 OpenTelemetry 支援。

C# 行程內應用程式目前不支援 OpenTelemetry。

您可以在函式應用程式中啟用 OpenTelemetry 來取得這些優點:

  • 在主機和應用程式程式代碼中產生之追蹤和記錄之間的相互關聯。
  • 一致且以標準為基礎的可導出遙測數據產生。
  • 與其他可取用 OpenTeleletry 相容數據的提供者整合。

OpenTelemetry 會在函式應用程式層級啟用,同時在主機組態 (host.json) 和程式代碼項目中啟用。 Functions 也提供用戶端優化體驗,從以語言特定背景工作進程執行的函式程式碼匯出 OpenTelemetry 數據。

1.在 Functions 主機中啟用 OpenTelemetry

當您在函式應用程式的 host.json 檔案中啟用 OpenTelemetry 輸出時,您的主機會匯出 OpenTelemetry 輸出,而不論應用程式所使用的語言堆棧為何。

若要從 Functions 主機啟用 OpenTelemetry 輸出,請更新 程式代碼專案中的 host.json 檔案 ,以將專案新增 "telemetryMode": "openTelemetry" 至根集合。 啟用 OpenTelemetry 之後,您的host.json檔案看起來可能如下所示:

{
    "version": "2.0",
    "logging": {
        "applicationInsights": {
            "samplingSettings": {
                "isEnabled": true,
                "excludedTypes": "Request"
            },
            "enableLiveMetricsFilters": true
        }
    },
    "telemetryMode": "openTelemetry"
}

2.設定應用程式設定

在 host.json 檔案中啟用 OpenTelemetry 時,系統會根據應用程式環境變數中支援 OpenTelemetry 的應用程式設定來決定傳送數據的端點。

根據 OpenTelemetry 輸出目的地,在您的函式應用程式中建立特定的應用程式設定。 當 Application Insights 和 OpenTelemetry 通訊協定 (OTLP) 導出工具提供連線設定時,OpenTelemetry 數據會傳送至這兩個端點。

APPLICATIONINSIGHTS_CONNECTION_STRING:Application Insights 工作區的 連接字串。 當此設定存在時,OpenTelemetry 數據會傳送至該工作區。 此設定與未啟用 OpenTelemetry 的情況下連線到 Application Insights 所使用的設定相同。 如果您的應用程式還沒有此設定,您可能需要 啟用 Application Insights 整合

3.在您的應用程式中啟用OpenTelemetry

當 Functions 主機設定為使用 OpenTelemetry 時,您也應該更新應用程式程式代碼以輸出 OpenTelemetry 數據。 在主機和應用程式程式代碼中啟用OpenTelemetry,可讓Functions主機進程和語言背景工作進程發出之追蹤與記錄之間的更相互關聯。

檢測應用程式以使用 OpenTelemetry 的方式取決於您的目標 OpenTelemetry 端點:

  1. 執行下列命令,以在應用程式中安裝必要的元件:

    dotnet add package Microsoft.Azure.Functions.Worker.OpenTelemetry --version 1.0.0-preview1 
    dotnet add package OpenTelemetry.Extensions.Hosting 
    dotnet add package Azure.Monitor.OpenTelemetry.AspNetCore  
    
  2. 在您的Program.cs項目檔中,新增下列 using 語句:

    using Azure.Monitor.OpenTelemetry.AspNetCore; 
    
  3. 在委派中 ConfigureServices ,新增此服務組態:

    services.AddOpenTelemetry()
    .UseFunctionsWorkerDefaults()
    .UseAzureMonitor();
    

    若要匯出至兩個 OpenTelemetry 端點,請呼叫 UseAzureMonitorUseOtlpExporter

Java 背景工作角色優化尚未可供 OpenTelemetry 使用,因此您的 Java 程式代碼中沒有任何可設定的專案。

  1. 在您的項目中安裝下列 npm 套件:

    npm install @opentelemetry/api 
    npm install @opentelemetry/auto-instrumentations-node 
    npm install @azure/monitor-opentelemetry-exporter 
    
  1. 在您的專案中建立程式碼檔案、複製並貼上這個新檔案中的下列程式代碼,並將檔案儲存為 src/index.js

    const { app } = require('@azure/functions');
    const { AzureMonitorLogExporter, AzureMonitorTraceExporter } = require('@azure/monitor-opentelemetry-exporter');
    const { context: otelContext, propagation } = require('@opentelemetry/api');
    const { SeverityNumber } = require('@opentelemetry/api-logs');
    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()] });
    
    // NOTE: The below code will soon be a part of a new package `@opentelemetry/instrumentation-azure-functions`
    // See here for more info: https://github.com/Azure/azure-functions-nodejs-library/issues/245
    app.setup({ capabilities: { WorkerOpenTelemetryEnabled: true } });
    
    const logger = loggerProvider.getLogger('default');
    app.hook.log((context) => {
        logger.emit({
            body: context.message,
            severityNumber: toOtelSeverityNumber(context.level),
            severityText: context.level,
        });
    });
    
    app.hook.preInvocation((context) => {
        context.functionHandler = otelContext.bind(
            propagation.extract(otelContext.active(), {
                traceparent: context.invocationContext.traceContext.traceParent,
                tracestate: context.invocationContext.traceContext.traceState,
            }),
            context.functionHandler
        );
    });
    
    function toOtelSeverityNumber(level) {
        switch (level) {
            case 'information':
                return SeverityNumber.INFO;
            case 'debug':
                return SeverityNumber.DEBUG;
            case 'error':
                return SeverityNumber.ERROR;
            case 'trace':
                return SeverityNumber.TRACE;
            case 'warning':
                return SeverityNumber.WARN;
            case 'critical':
                return SeverityNumber.FATAL;
            default:
                return SeverityNumber.UNSPECIFIED;
        }
    }
    
  2. main更新package.json檔案中的欄位,以包含這個新src/index.js檔案,如下所示:

    "main": "src/{index.js,functions/*.js}"
    
  1. 在您的專案中建立程式碼檔案、複製並貼上這個新檔案中的下列程式代碼,並將檔案儲存為 src/index.ts

    import { app, LogLevel } from '@azure/functions';
    import { AzureMonitorLogExporter, AzureMonitorTraceExporter } from '@azure/monitor-opentelemetry-exporter';
    import { context as otelContext, propagation } from '@opentelemetry/api';
    import { SeverityNumber } from '@opentelemetry/api-logs';
    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()] });
    
    // NOTE: The below code will soon be a part of a new package `@opentelemetry/instrumentation-azure-functions`
    // See here for more info: https://github.com/Azure/azure-functions-nodejs-library/issues/245
    app.setup({ capabilities: { WorkerOpenTelemetryEnabled: true } });
    
    const logger = loggerProvider.getLogger('default');
    app.hook.log((context) => {
        logger.emit({
            body: context.message,
            severityNumber: toOtelSeverityNumber(context.level),
            severityText: context.level,
        });
    });
    
    app.hook.preInvocation((context) => {
        context.functionHandler = otelContext.bind(
            propagation.extract(otelContext.active(), {
                traceparent: context.invocationContext.traceContext.traceParent,
                tracestate: context.invocationContext.traceContext.traceState,
            }),
            context.functionHandler
        );
    });
    
    function toOtelSeverityNumber(level: LogLevel): SeverityNumber {
        switch (level) {
            case 'information':
                return SeverityNumber.INFO;
            case 'debug':
                return SeverityNumber.DEBUG;
            case 'error':
                return SeverityNumber.ERROR;
            case 'trace':
                return SeverityNumber.TRACE;
            case 'warning':
                return SeverityNumber.WARN;
            case 'critical':
                return SeverityNumber.FATAL;
            default:
                return SeverityNumber.UNSPECIFIED;
        }
    }
    
  2. main更新package.json檔案中的欄位,以包含這個新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 取用方案預覽目前不支援受控相依性。

  3. 將此程式代碼新增至您的 profile.ps1 檔案:

    Import-Module AzureFunctions.PowerShell.OpenTelemetry.SDK -Force -ErrorAction Stop 
    Initialize-FunctionsOpenTelemetry 
    
  1. 在您的檔案中 requirements.txt 新增此專案:

    azure.monitor.opentelemetry
    
  2. 將此程式代碼新增至主要 function_app.py 進入點檔案:

    from azure.monitor.opentelemetry import configure_azure_monitor 
    configure_azure_monitor() 
    

OpenTelemetry 的考慮

當您使用 OpenTelemetry 導出資料時,請記住這些目前的考慮。

  • 當主機設定為使用 OpenTelemetry 時,只會匯出記錄和追蹤。 主機計量目前未匯出。

  • 當您在主機中啟用OpenTelemetry時,目前無法使用Core Tools在本機執行應用程式專案。 您目前必須將程式代碼部署至 Azure,以驗證您的 OpenTelemetry 相關更新。

  • 目前,OpenTelemetry 輸出僅支援 HTTP 觸發程式和 Azure SDK 型觸發程式。

監視 Azure FunctionsFlex 取用方案