New RelicはOpenTelemetryを使っている向けに、New RelicのAgentをインストールすることなくOpenTelemetryのままNew Relicを利用するために、exporterを提供しています。先日Python向けのNew Relic OpenTelemetry Python Exporterを公開しました。今回はOpenTelemetryを活用できる事例として、このExporterを使ってPythonで書いたAzure Functionの関数を計測してみたいと思います。

今回はサンプルということで、Azure Function Pythonを最初に作るときに作成されるテンプレートのコードを使って、コードの実行にかかる時間を計測します。加えて、HTTP Triggerで実行される場合に呼び出す側が分散トレーシングのTrace Contextを送信した場合にトレースがつながるようにします。ドキュメントとしては、計測のところは主にopnetelemetry-pythonを、New Relicに送信するところはNew Relic OpenTelemetry Python Exporterを参考にします。

サンプルコードはGitHubで公開しています。まず、TraceProviderを設定する部分ではサービス名を設定しますが、context.function_nameを指定すること関数名を設定しています。任意の文字列で指定することも可能です。Trace Contextを設定する部分はtracer.start_as_current_spancontext引数の部分にあります。OpenTelemetryが用意しているpropagators.extractメソッドを利用し、HTTPヘッダーからW3c準拠のTrace Contextを抽出しTraceに設定します。

関数の呼び出しとトレースをひもづけるために、呼び出しごとに一意なcontext.invocation_idスパンに設定してします。そして、最後に重要な点ですが、関数が完了するとTelemetryのデータを送信する機会がなくなってしまうため、完了する前に明示的にnewrelic.shutdownメソッドを呼び出しデータを送信します。

これをAzure Functionで実行し、ブラウザやcurlコマンドでアクセスすると分散トレーシングのデータが送信され、New RelicのDistributed TracingのUIで確認できます。ただ、これだけだとTrace Contextデータの設定が動作しているかわからないので、適当な静的ページからAJAXリクエストで呼び出すようにします。サンプルは同じリポジトリにありますので、Browser Agent有効化のscriptタグを置き換えて試してみてください。すると次のようにBrowserアプリであるAzureFunctionSPAからAzure FunctionのMyHttpPythonFunctionにトレースがつながることが確認できます。

現状、MicrosoftはAzure Function PythonでのOpenTelemetryをネイティブでサポートする予定はないため、計装する場合今回のようにreturnの直前でexporterのshutdownを呼ぶなど自前でコードを書く必要があります。しかし、OpenTelemetryを使うことで、今回はexporterにNew Relicを指定しましたが、exporterを差し替えるだけで好きなオブザーバビリティプラットフォームにデータを送信し計測することが容易になります。