次の方法で共有


Azure Functions で OpenTelemetry を使用する

重要

Azure Functions の OpenTelemetry サポートは現在プレビュー段階であり、OpenTelemetry を使用するには、Flex 従量課金プランでアプリをホストする必要があります。

この記事では、OpenTelemetry 形式でログおよびトレース データをエクスポートするように関数アプリを構成する方法について説明します。 Azure Functions は、Functions ホスト プロセスと、関数コードを実行する言語固有のワーカー プロセスの両方から、関数の実行に関するテレメトリ データを生成します。 既定では、このテレメトリ データは Application Insights SDK を使用して Application Insights に送信されます。 ただし、OpenTelemetry セマンティクスを使用してこのデータをエクスポートすることもできます。 OpenTelemetry 形式を使用して Application Insights にデータを送信することはできますが、同じデータを他の OpenTelemetry 準拠のエンドポイントにエクスポートすることもできます。

ヒント

この記事は選択された開発言語を対象としているため、記事の上部で適切な言語を必ず選択してください。

現時点では、Java アプリに対するクライアント最適化 OpenTelemetry のサポートはありません。

OpenTelemetry は現在、C# インプロセス アプリではサポートされていません。

関数アプリで OpenTelemetry を有効にすると、次の利点が得られます。

  • ホストとアプリケーション コードの両方で生成されるトレースとログ間の相関関係。
  • エクスポート可能なテレメトリ データの一貫性のある標準ベースの生成。
  • OpenTeleletry 準拠のデータを使用できる他のプロバイダーとの統合。

OpenTelemetry は、ホスト構成 (host.json) とコード プロジェクトの両方で、関数アプリ レベルで有効になります。 関数は、言語固有のワーカー プロセスで実行されている関数コードから 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 を有効にする

OpenTelemetry を使用するように Functions ホストが構成されている場合は、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. package.json ファイルの main フィールドを更新して、この新しい 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. package.json ファイルの main フィールドを更新して、この新しい src/index.ts ファイルの出力を含めます。これは、次のようになります。

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

重要

言語ワーカーからの Application Insights への OpenTelemetry 出力は、PowerShell アプリでは現在サポートされていません。 代わりに、OTLP エクスポーター エンドポイントを使用することもできます。 ホストが Application Insights への OpenTelemetry 出力用に構成されている場合、PowerShell ワーカー プロセスによって生成されたログは引き続き転送されますが、現在、分散トレースはサポートされていません。

これらの手順は、OTLP エクスポーターにのみ適用されます。

  1. 値が TrueOTEL_FUNCTIONS_WORKER_ENABLED という名前のアプリケーション設定を追加します。

  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 を使用してアプリ プロジェクトをローカルで実行することはできません。 現在、OpenTelemetry 関連の更新プログラムを検証するには、コードを Azure にデプロイする必要があります。

  • 現時点では、OpenTelemetry 出力では HTTP トリガーと Azure SDK ベースのトリガーのみがサポートされています。

Azure Functions の監視Flex 従量課金プラン