銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

OpenTelemetry .NETを理解する (6) コード修正不要な自動計装ライブラリを利用する

前回の投稿から時間が空きましたが、今回は今までとは違う方法での計装を試してみます。

今までの方法は、ソースコードの修正を前提とするものでした。トレース、ログ、メトリクスの1つ1つを詳細に計測するコードは必要なく、例えばASP.NET Coreに対応した計装ライブラリを利用できました。が、それでも、数行程度とはソースコードへの修正が必要でした。 今回試す方法は、ソースコードへの修正を必要としない方法での計装です。これは例えば、従来のNew Relic Agentと同じように、.NETのProfiler APIを利用した方法です。

さて、この方法については数ヶ月前にLTで発表しました。

その時は最初のバージョンでしたが、現在では次の0.2.0-beta1が出ています。今回はこれを試してみました。

github.com

おおまかには同じなのですが、10ページ目で言っていた課題がどうなっているかを確認してみました。

環境変数については相変わらず多いです。Macで動作しないのも同じでした。おそらく、MacOSでの.NET プロセスの権限まわりが問題だと思うのですが、詳しくはわからず... 今回は、Mac上のDockerで動作確認しました。 OTLPでの認証ヘッダーなしでのデータ転送についても変わらずですが、otel/opentelemetry-collectorを経由してデータ転送できます。

動作確認したデモアプリをここに公開しています。docker composeでアプリのコンテナとotel/opentelemetry-collectorを同時に立ち上げています。

github.com

そして、Collectorで適当なOTLPバックエンド(ここではNew Relic)を指定すると実際のデータを確認できます。

また、OpenTelemetry .NET では.NET標準のSystem.Diagnostics.Activityを利用することで手動での計装が可能です。

tech.tanaka733.net

Activityクラスは、今回ためしている自動計装ライブラリでも動作しており、例えば次のようなコードを記述すると

app.MapGet("/ExternalError", async (ILogger<Program> logger) => 
{
    var activity = Activity.Current;
    var client = new HttpClient();
    try
    {
        await client.GetStringAsync("https://httpstat.us/502");
        return "Hello World!";
    }
    catch (System.Exception e)
    {
        activity?.SetStatus(ActivityStatusCode.Error, "外部呼び出しエラー");
        logger.LogError(e, "外部呼び出しエラー");
        return "error";
    }
    
});

このように、HTTPの呼び出しスパンだけではなく、その親スパンもエラー状態と記録することができます。

また、Metricsの収集と送信にも対応しており、次のようなメトリクスを.NET Runtimeメトリクスとして収集しています。

Logsについては未対応なようです。また、更新があればまとめようと思います。