カスタム ログ メッセージを追加するためのロガーの使用
.NET には、カスタマイズされたテレメトリ データをログに記録するために使用できる API が用意されています。 OpenTelemetry は、そのデータをエクスポートできます。
このユニットでは、構造化ログにイベントを送信する効率的なコードを記述する方法について説明します。
ILogger オブジェクト
テンプレートに基づいてプロジェクトを作成するか、既存のプロジェクトを .NET Aspire オーケストレーションに追加すると、.NET Aspire ツールによって OpenTelemetry API が自動的にセットアップされます。 テレメトリを記録する場合は、独自のログ記録、メトリック、トレース オブジェクトなどを作成する必要はありません。 代わりに、マイクロサービスで依存関係の挿入を使用してそれらを取得できます。
たとえば、次の BasketService
クラスでは、クラス宣言に ILogger
オブジェクトが含まれています。 クラス内の任意の場所でそのロガーを使用して、イベントを書き込むことができます。
public class BasketService(
IBasketRepository repository,
ILogger<BasketService> logger) : Basket.BasketBase
{
[AllowAnonymous]
public override async Task<CustomerBasketResponse> GetBasket(
GetBasketRequest request, ServerCallContext context)
{
var userId = context.GetUserIdentity();
// Use the logger to write events
if (logger.IsEnabled(LogLevel.Debug))
{
logger.LogDebug("Begin GetBasketById call from method {Method} for basket id {userId}", context.Method, userId);
}
var data = await repository.GetBasketAsync(userId);
return new();
}
}
効率的なログ記録
ログは、マイクロサービスを監視可能にするのに役立ちます。 アプリがテストされ、ステージされ、運用環境に配置されると、入念なログ コードによって、障害やボトルネックの迅速な診断が可能になります。 そのため、すべてをログに記録したくなります。 ただし、ログの記録は高速でコストは掛りませんが、効率的にログを記録するように注意する必要があります。
ベンダーは、通常、取り込むデータの量に基づいて Application Performance Management (API) システムに課金します。 メッセージの適切なログ レベルと既定のコレクション レベルを選択すると、毎月の請求に大きな影響を与える可能性があります。 ログ コレクションレベルは、プロバイダーごとに設定できます。これは通常、 ILogger<T>
で使用される種類名です。
ログを記録するたびに、次の方法を使用します。
- 使用するログ レベルが有効になっていることを確認します。 使用可能なレベルには、情報、警告、エラー、クリティカルなどが含まれます。 管理者は、運用環境へのテスト、ステージング、配置時に、さまざまなレベルを有効にできます。 ログ出力は
IConfiguration
、 通常appsettings.json
または環境変数を使用してコントロールされます。 - ログに記録されたメッセージで文字列補間を避けます。 挿入文字列は、
$
シンボルで定義され、選択したログ レベルが有効になっていない場合でも評価されます。 代わりに、LogInformation()
やLogDebug()
などのログメソッドを使用し、引数リストのパラメーターを渡します。 - コンパイル時のソース生成を使用して、ログのパフォーマンスをさらに最適化し、ログ メッセージごとに一意識別子を作成します。これは、APM でログ メッセージのクエリを実行するときに便利です。
コンパイル時のソース生成
ILogger
オブジェクトを使用したコンパイル時のソース生成では、各ログ要求ではなく、文字列解析を 1 回実行することで、ログ記録のコストが削減されます。 また、ログ メッセージの種類ごとに ID も含まれます。 この手法を使用するには、ログ パラメーターを使用して部分的なログ記録方法を定義し、それらに LoggerMessageAttribute
を適用します 。 .NET では、コードのコンパイル時に完全なログメソッドが自動的に生成されます。
.NET Asper では、ILogger を作成する必要はありませんが、代わりに依存関係の挿入から次のものを取得できることに注意してください。
public partial class BasketService(
IBasketRepository repository,
ILogger<BasketService> logger) : Basket.BasketBase
{
[LoggerMessage(
EventId = 0,
Level = LogLevel.Information,
Message = "Obtaining a basket from method {Method} for basket {basketId}")]
public partial void LogGetBasket(string Method, int basketId);
}