年の瀬も迫ってまいりました。
本記事は C# Advent Calendar 2024 の16日目の記事です。
本記事は未完成で鋭意執筆中ではありますが、Advent Calendar に穴を空けたままにしておくのも申し訳ないので、一旦プレビュー版として公開します。
年内には完成させたいと思っています。しばらくお待ちください。
GitHub に dotnet/extensions というリポジトリがあります。
ここはかつて、Microsoft.Extensions.DependencyInjection 等に代表される Microsoft.Extensions 系ライブラリのソースコード リポジトリだったのですが、.NET 5.0 の頃に、それらは dotnet/runtime や dotnet/aspnetcore といったリポジトリに統合されていきました。
その後しばらく廃墟になっていたのですが、2023年にリポジトリを再利用して新しいプロジェクトがスタートしました。
それが Enriched Capabilities です。
README によれば
This repository contains a suite of libraries that provide facilities commonly needed when creating production-ready applications. Initially developed to support high-scale and high-availability services within Microsoft, such as Microsoft Teams, these libraries deliver functionality that can help make applications more efficient, more robust, and more manageable.
https://github.com/dotnet/extensions/blob/v9.0.0/README.md
とのことです。なんか便利そうですね。
去る11月12日に .NET 9 がリリースされました。時を同じくして、このリポジトリからも一連のライブラリが、バージョン 9.0.0 としてリリースされました*1。
そこで、正式リリースとなったこれらのライブラリを一挙紹介していきます。
なお、一部のライブラリに関しては、本稿執筆時点で、まだプレビュー リリースに留まっています。それらに関しては、文末に簡単にリストアップするに留めます。
- Microsoft.Extensions.AmbientMetadata.Application
- Microsoft.Extensions.AsyncState
- Microsoft.Extensions.Compliance.Abstractions
- Microsoft.Extensions.Compliance.Redaction
- Microsoft.Extensions.Compliance.Testing
- Microsoft.Extensions.DependencyInjection.AutoActivation
- Microsoft.Extensions.Diagnostics.ExceptionSummarization
- Microsoft.Extensions.Diagnostics.HealthChecks.Common
- Microsoft.Extensions.Diagnostics.HealthChecks.ResourceUtilization
- Microsoft.Extensions.Diagnostics.ResourceMonitoring
- Microsoft.Extensions.Http.Diagnostics
- Microsoft.Extensions.Http.Resilience
- Microsoft.Extensions.ObjectPool.DependencyInjection
- Microsoft.Extensions.Resilience
- Microsoft.Extensions.Telemetry.Abstractions
- Microsoft.Extensions.Telemetry
- Microsoft.Extensions.TimeProvider.Testing
- Microsoft.AspNetCore.AsyncState
- Microsoft.AspNetCore.Diagnostics.Middleware
- Microsoft.AspNetCore.HeaderParsing
- Microsoft.AspNetCore.Testing
- Microsoft.Extensions.StaticAnalysis
- Microsoft.Extensions.AuditReports
- まだプレビュー版のパッケージ
- おわりに
Microsoft.Extensions.AmbientMetadata.Application
ApplicationMetadata オブジェクトを DI できます。
ApplicationName
、BuildVersion
、Environemnt
、DeploymentRing
といったプロパティがあり、まぁ、地味に需要がありそうです。
var services = new ServiceCollection(); // IServiceCollection に注入(手動で構成) services.AddApplicationMetadata(metadata => { metadata.ApplicationName = "..."; }); // IConfiguration(appsettings.json や環境変数)から注入 services.AddApplicationMetadata(/* IConfigurationSection */ configurationSection); // ASP.NET Core で使うなら var appBuilder = WebApplication.CreateBuilder(args); appBuilder.Host.UseApplicationMetadata();
appsettings.json
に書いておく場合は、このようなスキーマを使います(セクション名はカスタマイズできます)。
{ "AmbientMetadata": { "Application": { "BuildVersion": "1.0-alpha1.2346", "DeploymentRing": "InnerRing" } } }
Microsoft.Extensions.AsyncState
非同期フローに追従して状態オブジェクトを受け渡せるようにしたもので、要するに AsyncLocal のようなものですが、それより便利です。
- AsyncLocal は上流から下流への一方向の伝達しかできないが、AsyncState は双方向の伝達が可能
- インターフェイスになっているので DI で使いやすい
- 任意のタイミングで明示的にリセットすることができる。
DI で使う場合は AddAsyncState メソッドでセットアップします。
また、最初に一度だけ、IAsyncState.Initialize メソッドで初期化します。
var services = new ServiceCollection(); services.AddAsyncState(); using var serviceProvider = services.BuildServiceProvider(); serviceProvider.GetRequiredService<IAsyncState>().Initialize(); var context = serviceProvider.GetRequiredService<IAsyncContext<MyState>>(); context.Set(new MyState()); var state = context.Get();
こんなふうに同一箇所で Set
と Get
をするだけでは何も面白みがありませんが、AsyncLocal
のように、非同期メソッドの上流と下流で、一方で Set
したものを他方で Get
することが、引数等で引き回さなくてもできるということです。
Microsoft.Extensions.Compliance.Abstractions
アプリケーション中で取り扱う情報を分類する機能と、次節で紹介する情報の変形の実装のためのインターフェイスを提供します。
たとえば以下のようにして、特定のプロパティの値が機密情報であることを指定できます。
static class MyDataClassification { // DataClassification コンストラクタの値は何を指定すればいいのかよくわかってない public static readonly DataClassification CustomerName = new DataClassification("type", "customer-name"); } class CustomerNameAttribute : DataClassificationAttribute { public CustomerNameAttribute() : base(MyDataClassification.CustomerName) { } } class Customer { [CustomerName] public string Name { get; set; } }
Microsoft.Extensions.Compliance.Redaction
「機密データをうっかりログに記録していた」みたいなことがないように、あらかじめ属性を付けておいたデータをログに記録する際に、伏字にしたり削ったりハッシュ化したりできます。
こんな感じにすると、LogCustomer
メソッドが出力する name
の部分がハッシュ化されます。
サンプルコードは前節も併せて参照してください。
var services = new ServiceCollection(); services.AddLogging(static loggingBuilder => loggingBuilder.EnableRedaction()); services.AddRedaction(static redactionBuilder => redactionBuilder.SetRedactor<HmacRedactor>( DataClassificationSet.FromDataClassification(MyDataClassification.CustomerName)); services.AddSingleton<MyBusinessLogic>(); using var serviceProvider = services.BuildServiceProvider(); var myService = serviceProvider.GetRequiredService<MyService>(); myService.Run(); partial class MyService { private readonly ILogger _logger; public MyBusinessLogic(ILogger<MyBusinessLogic> logger) { _logger = logger; } public void Run() { var customer = new Customer { Name = "Jane Doe" }; LogCustomer(customer.Name); } [LoggerMessage(1, LogLevel.Information, "Name = {name}")] private partial void LogCustomer( [CustomerName] string name); }
LogCustomer
メソッドの引数name
にはCustomerNameAttribute
がついているCustomerNameAttribute
はMyDataClassification.CustomerName
というデータ分類を持っているAddRedaction
メソッドによって、MyDataClassification.CustomerName
は出力前にHmacRedactor
によって処理される
みたいな感じでログに機密データが出力されるのが阻止されます。
で、これだと Customer.Name
プロパティについている CustomerNameAttribute
は意味をなしていません。
まぁこのへんは、ログ出力以外でも、例えばアプリケーションの顧客管理画面で、閲覧権限が限定的な人に対しては伏字にするとか、そういった応用も効くんじゃないかなと思います。
Microsoft.Extensions.Compliance.Testing
データ分類と Redactor のテストのためのライブラリです。
Microsoft.Extensions.DependencyInjection.AutoActivation
Microsoft.Extensions.DependencyInjection
の DI 機能では、登録された型のインスタンスは、それが必要になった時に作成されます。
しかし、それだと初回の作成時に複雑な依存関係の解決処理が必要になるので、結構な時間がかかってしまうことがあります。
そこで、Singleton で登録される型について、アプリケーション起動時に実行される IHostedService によってあらかじめ実体化しておいて、インスタンス解決を高速化しようというものです。
使い方は簡単で、既存の AddSingleton メソッドを AddActivatedSingleton メソッドに変えるだけです。
また、他のメソッド中で AddSingleton
メソッドが使われていて変えられないときは、追加で ActivateSingleton メソッドを呼ぶことによって、事前インスタンス化させることができます。
なお、IHostedService
を使う都合上、汎用ホストで動かす必要があります。汎用ホストを使わない場合、ただの AddSingleton
と同じです。
また、その性質上、事前インスタンス化ができるのは、ライフタイムが Singleton の型のみです。
var appBuilder = Host.CreateApplicationBuilder(args); appBuilder.Services.AddActivatedSingleton<IFooService, FooService>(); appBuilder.Build().Run();
Microsoft.Extensions.Diagnostics.ExceptionSummarization
例外の情報をログ等に出力したいときに、いい感じに要約するライブラリです。
var services = new ServiceCollection(); services.AddExceptionSummarizer(static summarizationBuilder => summarizationBuilder.AddHttpProvider()); using var serviceProvider = services.BuildServiceProvider(); try { // 何らかのネットワーク処理 } catch (Exception exception) { var summarizer = serviceProvider.GetRequiredService<IExceptionSummarizer>(); var exceptionSummary = summarizer.Summarize(exception); LogException(exceptionSummary); }
標準で AddHttpProvider というメソッドだけが実装されています。が、こいつが処理してくれるのは、以下の例外だけです。
なんで HttpRequestException とかは処理してくれないんですかね。
IExceptionSummaryProvider インターフェイスの実装を用意すれば、その他の例外に対する要約処理を提供することも可能です。
Microsoft.Extensions.Diagnostics.HealthChecks.Common
アプリケーションのヘルスチェックに対する拡張機能です。そのため、まずは標準的なヘルスチェックの実装が必要です。
その上で、このライブラリが提供する機能は以下の3つです。
- IHostApplicationLifetime を監視して、アプリケーションが正しく起動しているか、予期せず停止していないか等を確認する。
- IManualHealthCheck インターフェイスによって、アプリケーションコードの任意の場所から健康状態を報告する。
- ヘルスチェックの状態をメトリクスに報告する
var appBuilder = Host.CreateApplicationBuilder(args); appBuilder.Services .AddHealthCheck() .AddApplicationLifecycleHealthCheck() // IHostApplicationLifetime の監視を追加 .AddManualHealthCheck(); // 任意の報告を追加 appBuilder.Services .AddTelemetryHealthCheckPublisher(); // テレメトリ報告を追加 appBuilder.Build().Run(); class MyService { private readonly IManualHealthCheck _healthCheck; public MyService(IManualHealthCheck<MyService> healthCheck) { _healthCheck = healthCheck; } public void SomeOperation() { if (何かエラーが起きた) { _healthCheck.ReportUnhealthy("やばい"); } else { _healthCheck.ReportHealthy("健康"); } } }
アプリケーション ライフタイムの正常性チェックのドキュメントも参照してください。
また、メトリクスについては .NET 拡張メトリクスのドキュメントも参照してください。
Microsoft.Extensions.Diagnostics.HealthChecks.ResourceUtilization
CPU とメモリの使用率に基づくヘルスチェック機能を追加します。
前述のパッケージ同様、まずは標準的なヘルスチェックの実装が必要です。
var appBuilder = Host.CreateApplicationBuilder(args); appBuilder.Services .AddHealthChecks() .AddResourceUtilizationHealthCheck(static options => { // 使用率 80% で機能低下状態、90% で不健康状態 options.CpuThresholds = new() { DegradedUtilizationPercentage = 80, UnhealthyUtilizationPercentage = 90 }; options.MemoryThresholds = new() { DegradedUtilizationPercentage = 80, UnhealthyUtilizationPercentage = 90 }; }); appBuilder.Build.Run();
リソース使用率の正常性チェックのドキュメントも参照してください。
Microsoft.Extensions.Diagnostics.ResourceMonitoring
アプリケーション内で、自身の CPU 使用率とメモリ使用率を取得するためのパッケージです。
前節のライブラリで使われています。自分で利用することで、より細かいモニタリングを実装することもできます。
このライブラリは BackgroundService を使ってリソース使用状況を収集するため、ホスト上で動かす必要があります。
var appBuilder = Host.CreateApplicationBuilder(args); appBuilder.Services.AddResourceMonitoring(static monitorBuilder => { // データの収集間隔を構成したりする }); appBuilder.Build.Run();
リソース モニタリングのドキュメントも参照してください。
また、これを入れておくと MeterListener 等のメトリクス機構でもリソース使用状況を取得できます。
OpenTelemetry による監視が構成されていれば、何もしなくてもモニタリング ツールに連携されるでしょう。
詳細は .NET 拡張メトリクスのドキュメントを参照してください。
using var listener = new MeterListener(); listener.InstrumentPublished = static (instrument, listener) => { if (instrument.Meter.Name == "Microsoft.Extensions.Diagnostics.ResourceMonitoring") { listener.EnableMeasurementEvents(instrument); // タイマーなどで定期的に listener.RecordObservableInstruments() を呼んであげる必要がある } }; listener.SetMeasurementEventCallback<double>(static (instrument, measurement, tags, state) => { if (instrument.Meter.Name == "Microsoft.Extensions.Diagnostics.ResourceMonitoring") { if (instrument.Name == "process.cpu.utilization") { // CPU 使用率を記録 } else if (instrument.Name == "dotnet.process.memory.virtual.utilization") { // メモリ使用量を記録 } } }); listener.Start();
Microsoft.Extensions.Http.Diagnostics
IHttpClientFactory によって作成される HttpClient に対して、拡張されたロギングとテレメトリの機能を追加します。
ロギングはこう。Microsoft.Extensions.Compliance.Redaction が必要です。
後半の AddLogging からのコードは必須ではありませんし、Indented プロパティを true
に設定してしまうのはログとしては不適ですが、どういうものが出力されるのかわかりやすくするために書いています。
実際に使用される場合にはご注意ください。
var services = new ServiceCollection(); services .AddHttpClient() .AddRedaction() .AddExtendedHttpClientLogging(); services.AddLogging(static loggingBuilder => { loggingBuilder.AddJsonConsole(static options => { options.JsonWriterOptions = new() { Indented = true }; }); });
既定の構成ではこのようなログが出力されます。
{ "EventId": 1, "LogLevel": "Information", "Category": "Microsoft.Extensions.Http.Logging.HttpClientLogger", "Message": "GET dot.net/REDACTED", "State": { "Message": "http.request.method=GET,server.address=dot.net,url.path=REDACTED,Duration=1740,http.response.status_code=200", "http.request.method": "GET", "server.address": "dot.net", "url.path": "REDACTED", "Duration": 1740, "http.response.status_code": 200 } }
IHttpClientLogEnricher インターフェイスを実装して AddHttpClientLogEnricher メソッドで登録することで、ログに記録される情報を追加することができます。
この機能を使わずに、AddDefaultLogger メソッドによって構成したログはこうなりました。
{ "EventId": 100, "LogLevel": "Information", "Category": "System.Net.Http.HttpClient.Default.LogicalHandler", "Message": "Start processing HTTP request GET https://dot.net/", "State": { "Message": "Start processing HTTP request GET https://dot.net/", "HttpMethod": "GET", "Uri": "https://dot.net/", "{OriginalFormat}": "Start processing HTTP request {HttpMethod} {Uri}" } } { "EventId": 100, "LogLevel": "Information", "Category": "System.Net.Http.HttpClient.Default.ClientHandler", "Message": "Sending HTTP request GET https://dot.net/", "State": { "Message": "Sending HTTP request GET https://dot.net/", "HttpMethod": "GET", "Uri": "https://dot.net/", "{OriginalFormat}": "Sending HTTP request {HttpMethod} {Uri}" } } { "EventId": 101, "LogLevel": "Information", "Category": "System.Net.Http.HttpClient.Default.ClientHandler", "Message": "Received HTTP response headers after 1774.878ms - 200", "State": { "Message": "Received HTTP response headers after 1774.878ms - 200", "ElapsedMilliseconds": 1774.878, "StatusCode": 200, "{OriginalFormat}": "Received HTTP response headers after {ElapsedMilliseconds}ms - {StatusCode}" } } { "EventId": 101, "LogLevel": "Information", "Category": "System.Net.Http.HttpClient.Default.LogicalHandler", "Message": "End processing HTTP request after 1819.5803ms - 200", "State": { "Message": "End processing HTTP request after 1819.5803ms - 200", "ElapsedMilliseconds": 1819.5803, "StatusCode": 200, "{OriginalFormat}": "End processing HTTP request after {ElapsedMilliseconds}ms - {StatusCode}" } }
個々のハンドラがログを出力しているので、細かいですが煩雑ですね。
AddExtendedHttpClientLogging
によるロギングは、1回のリクエストが1個のエントリになっていて読みやすいと思います。
ハンドラごとの追加情報が必要であれば、ハンドラで記憶しておいた情報をログに追加する IHttpClientLogEnricher
を実装するようなこともできるかと思います。
なお、この機能を使う場合、既存の AddLogger メソッドによるロガーはすべて削除されます。
テレメトリ機能を利用する場合は、加えてこのような設定が必要です。
var services = new ServiceCollection(); services .AddLatencyContext() .AddHttpClientLatencyTelemetry();
こちらはちょっと、正しい使い方を調べ切れていません。わかり次第追記します。
Microsoft.Extensions.ObjectPool.DependencyInjection
ObjectPool<T> を Dependency Injection に注入できます。
var services = new ServiceCollection(); services.AddPooled<MyService>(); using var serviceProvider = services.BuildServiceProvider(); var pool = serviceProvider.GetRequiredService<ObjectPool<MyService>>(); var service = pool.Get(); pool.Return(service);
プールされていないオブジェクトを Get メソッドで取得しようとすると、新しいインスタンスが作られます。
このインスタンスの作り方を決めているのは IPooledObjectPolicy<T> であり、既定の実装である DefaultPooledObjectPolicy<T> では、単に new T()
するだけです。
このライブラリを使うと、new T()
の代わりに ActivatorUtilities.CreateInstance が使われて、DI によって依存関係を注入されたオブジェクトを取得することができます。
ObjectPool<T>
自体は Singleton で登録されること、また、DI コンテナに Singleton で登録した型は DI コンテナ自体に1つしか存在できないことを考えると、プールできる型は DI コンテナに Transient で登録した型のみになるでしょうね。
Microsoft.Extensions.Telemetry.Abstractions
以下の機能を持ちます
ログの拡張機能
Microsoft.Extensions.Logging.Abstractions パッケージを(間接的にでも)インストールすると LoggerMessageAttribute による Logger Source Generator が使えるようになります。これは Microsoft.Extensions.Logging.Generators
というアナライザーが受け持っています。
一方、この Microsoft.Extensions.Telemetry.Abstractions
パッケージを(間接的にでも)インストールすると、そのアナライザーは無効になり、代わって Microsoft.Gen.Logging
というアナライザーが有効になります。このパッケージは多くの Enriched Capabilities ライブラリから参照されているので、こちらのアナライザーが有効になる機会は多いです。
Microsoft.Gen.Logging
アナライザーも LoggerMessageAttribute
を解釈してロガーを生成しますが、その機能は Microsoft.Extensions.Logging.Generators
よりも強化されています。
具体的には、ロギングメソッドに渡されたコレクションを展開したり、LogPropertiesAttribute をつけたオブジェクトのプロパティを展開してくれたりします。
こんな感じのコードを書くと、
var services = new ServiceCollection(); services .AddLogging(static loggingBuilder => { loggingBuilder.AddJsonConsole(static options => { options.JsonWriterOptions = new() { Indented = true }; }); }); services.AddSingleton<X>(); using var serviceProvider = services.BuildServiceProvider(); var x = serviceProvider.GetRequiredService<X>(); x.LogX("hello.", [1, 2 ,3], new(23, 99)); partial class X { private readonly ILogger<X> _logger; public X(ILogger<X> logger) { _logger = logger; } [LoggerMessage(1, LogLevel.Information, "Message = {message}")] public partial void LogX(string message, List<int> d, [LogProperties] Q q); } record Q(int a, int b);
こんなログが出ます。
{ "EventId": 1, "LogLevel": "Information", "Category": "X", "Message": "Message = hello.", "State": { "Message": "{OriginalFormat}=Message = {message},q.b=99,q.a=23,d=[\u00221\u0022,\u00222\u0022,\u00223\u0022],message=hello.", "{OriginalFormat}": "Message = {message}", "q.b": 99, "q.a": 23, "d": "[\u00221\u0022,\u00222\u0022,\u00223\u0022]", "message": "hello." } }
構造化ログを簡単に確認するために AddJsonConsole を使っていますが、JSON である都合からか、コレクションの展開は何だか残念な感じになってしまっていますね。
メトリクスの拡張機能
メトリクスの拡張機能は、System.Diagnostics.Metrics に対する拡張機能です。
たとえば、何らかのイベントが発生した回数を数えるには Counter<T> を使います。
class MyApi { private static readonly Meter _meter; private static readonly Counter<int> _requestCounter; static MyApi() { _meter = new Meter("MyApi"); _requestCounter = _meter.CreateCounter<int>("request_count"); } public void Request() { _requestCounter.Add(1); } }
発行されたメトリクスは MeterListener で取得できるほか、OpenTelemetry とも連携します。
こうした標準機能に対して、このライブラリは CounterAttribute<T> 等の属性とソース ジェネレーターを提供します。
それを使うとこのように書けます。
class MyApi { private static readonly Meter _meter; private static readonly RequestCounter _requestCounter; static MyApi() { _meter = new Meter("MyApi"); _requestCounter = _meter.CreateRequestCounter(); } public void Request() { _requestCounter.Add(1); } } public partial class MyApiMetrics { [Counter<int>] public static partial RequestCounter CreateRequestCounter(this Meter meter); }
このとき RequestCounter
はソース ジェネレーターによって生成される型になるので、既存の型名を入れてはいけません。
Microsoft.Extensions.TimeProvider.Testing
.NET 8.0 で追加された TimeProvider を使ったコードをテストするための FakeTimeProvider が含まれます。
これの便利なところは、CreateTimer メソッドで作ったタイマーを止めておけるところです。
Task.Delay など、内部でタイマーを作るメソッドも、多くに TimeProvider
を受け付けるオーバーロードが追加されています。
var timeProvider = new FakeTimeProvider(); // 10秒待つ。 var task = Task.Delay(TimeSpan.FromSeconds(10), timeProvider); // 10秒進めたことにする。 timeProvider.Advance(TimeSpan.FromSeconds(10)); // 終わっている Assert.IsTrue(task.IsCompleted);
Advance メソッドを呼ぶことで一瞬で時間を進められますし、Advance
メソッドを呼ばなければ時が止まったままなので、テストの制御がしやすくなります。
Microsoft.AspNetCore.AsyncState
先の Microsoft.Extensions.AsyncState を ASP.NET Core 用に使いやすくしたものです。
DI で使う場合は AddAsyncStateHttpContext メソッドでセットアップします。前述の AddAsyncState
メソッドは自動的に呼ばれるため必要ありません。
セットしたオブジェクトが HttpContext に連動します。
Microsoft.Extensions.StaticAnalysis
あらかじめ構成されたアナライザーの診断ルール集です。
NuGet パッケージへの参照を追加した後、csproj ファイルに以下のように書くことで、一般的な診断が有効になります。
<PropertyGroup> <StaticAnalysisCodeType>General</StaticAnalysisCodeType> </PropertyGroup>
他にも以下のような値が定義されています。
値 | 意味 |
---|---|
Benchmark | ベンチマーク プロジェクト |
General | 一般的なプロジェクト |
NonProdExe | プロダクション利用を想定していない exe |
NonProdLib | プロダクション利用を想定していないライブラリ |
ProdExe | プロダクション利用を想定した exe |
ProdLib | プロダクション利用を想定したライブラリ |
Test | テスト |
また、それぞれの値の後ろに -Tier1
または -Tier2
というオプションを付けることができます(Generic-Tier1
のように)。
- Tier1 は、特に重要な診断のみが有効になります。
- Tier2 は、Tier1 の内容に加え、重要性の低い診断も有効になります。
- Tier を指定しない場合は、Tier1 および 2 のすべての診断と、その他の利用可能な診断が有効になります。
Microsoft.Extensions.AuditReports
アプリケーション中に存在する機密情報およびメトリクスの一覧を生成するアナライザーです。
機密情報レポートを生成するには、csproj ファイルに以下のように書き加えます。
<PropertyGroup> <GenerateComplianceReport>true</GenerateComplianceReport> <ComplianceReportOutputPath>C:\ComplianceReports</ComplianceReportOutputPath> </PropertyGroup>
機密情報をマークする方法は Microsoft.Extensions.Compliance.Abstractions の節を参照してください。
メトリクス レポートを生成するには、csproj ファイルに以下のように書き加えます。
<PropertyGroup> <GenerateMetricsReport>true</GenerateMetricsReport> <MetricsReportOutputPath>C:\MetricsReports</MetricsReportOutputPath> </PropertyGroup>
レポートには、Microsoft.Extensions.Telemetry.Abstractions の節で説明したメトリクス属性のついているメソッドが出力されます。
アプリケーションから収集できるメトリクスの一覧が得られるので、監視に役立ちますね。
まだプレビュー版のパッケージ
ざっくりと概要だけ紹介します。
Microsoft.Extensions.Caching.Hybrid
メモリ キャッシュと分散キャッシュのいいとこ取りをする HybridCache を提供します。
HybridCache の概要および使い方のドキュメントを参照してください。
Microsoft.Extensions.Diagnostics.Probes
Kubernetes Probe のサポートを提供します。
おわりに
これ、一人 Advent Calendar してもよかったんじゃねぇかな。
ともあれ皆様、本年中は大変お世話になりました。
体調にお気をつけて、よいお年をお迎えください。
*1:8.0.0 もリリースされていたことに気づいていませんでした