この記事はOpenTelemetry Advent Calendarの6日目の記事です。
先日リリースされた .NET 7ではObservabilityへの投資がリリースブログに項目にあります。
.NETにおけるOpenTelemetry対応は、.NET本体ではなくOpenTelemetry .NETというプロジェクトが進め、ライブラリとして提供しています。
それでは.NET本体が行った改善とはどのようなものでしょうか。まずは3点からなる改善内容を確認します。
Activity.Current Change Eventの導入
.NET におけるOpenTelemetry対応が他の言語と異なっている点の1つに、OpenTelemetryのSpanに対応するものとして.NETに従来からあったActivityクラスというものに対応させています。
そのため、Spanに対する操作をActivityクラスから行うことができます。一方、Spanの追跡には内部的にはAsyncLocal
Span Contextの変化を追跡する場合、AsyncLocal
Activity.CurrentChanged += CurrentChanged; void CurrentChanged(object? sender, ActivityChangedEventArgs e) { Console.WriteLine($"Activity.Current value changed from Activity: {e.Previous?.OperationName} to Activity: {e.Current?.OperationName}"); }
パフォーマンスに優れたActivityのプロパティ列挙メソッドの導入
ActivityのTags、Links、Eventsに対してよりパフォーマンスの高いプロパティ列挙メソッドが提供されました。C# 7.2で導入された読み取り専用参照機能を利用しており、余分なアロケーションも発生しません。
void setTag() { var a = Activity.Current; a.SetTag("key1", "value1"); a.SetTag("key2", "value2"); foreach (ref readonly KeyValuePair<string, object?> tag in a.EnumerateTagObjects()) { Console.WriteLine($"{tag.Key}, {tag.Value}"); } } setTag();
パフォーマンスに優れたActivityLinkとActivityEvent のプロパティ列挙メソッドの導入
ActivityLinkとActivityEventに関しても同様にプロパティを列挙するメソッドが用意されています。
ActivityLink link = new ActivityLink(default, new ActivityTagsCollection(tags)); foreach (ref readonly KeyValuePair<string, object?> tag in link.EnumerateTagObjects()) { // } ActivityEvent e = new ActivityEvent("SomeEvent", tags: new ActivityTagsCollection(tags)); foreach (ref readonly KeyValuePair<string, object?> tag in e.EnumerateTagObjects()) { // }
まとめ
実際、今回追加された機能をOpenTelemetry .NETを使う際に利用することはあまりないのではと思います。OpenTelemetry .NET 内部で利用するケースを想定しているのではないでしょうか。.NET 7を含めた最近の.NETはパフォーマンスの改善に大きく投資をしています。OpenTelemetry利用時にもその恩恵を受けられるような機能追加と考えられます。