新しい ASP.NET Code 2.2 Healthchecks 機能を使用しようとしています。
.netブログのこの link では、例を示しています。
public void ConfigureServices(IServiceCollection services)
{
//...
services
.AddHealthChecks()
.AddCheck(new SqlConnectionHealthCheck("MyDatabase", Configuration["ConnectionStrings:DefaultConnection"]));
//...
}
public void Configure(IApplicationBuilder app)
{
app.UseHealthChecks("/healthz");
}
Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck
インターフェースを実装するカスタムチェックを追加できます。しかし、型ではなくインスタンスをAddCheck
メソッドに提供する必要があり、ConfigureServices
メソッド内で実行する必要があるため、カスタムチェッカーに依存関係を挿入できません。
これを回避する方法はありますか?
.NET Core 3.0以降、登録はより簡単になり、これに要約されます
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks();
services.AddSingleton<SomeDependency>();
services.AddCheck<SomeHealthCheck>("mycheck");
}
singletonとtransientの競合が発生するので、競合が発生しないことに注意してください。エンジンが使用する必要があるもの。
チェックの名前は必須であるため、1つ選択する必要があります。
accepted asnwer は動作しなくなったようです。
ASP.NET Core Health Check内に依存関係を挿入する方法。
サービスを正しい順序で登録すると、SomeDependency
がSomeHealthCheck
コンストラクターへの注入に使用できるようになり、SomeHealthCheck
がヘルスチェック機能の一部として実行されます。
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks();
services.AddSingleton<SomeDependency>();
// register the custom health check
// after AddHealthChecks and after SomeDependency
services.AddSingleton<IHealthCheck, SomeHealthCheck>();
}
A Health Checkサンプルのコメント は次のように述べています。
IHealthCheckサービスはすべて、ヘルスチェックサービスとミドルウェアで利用できます。すべてのヘルスチェックをシングルトンサービスとして登録することをお勧めします。
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
public class SomeDependency
{
public string GetMessage() => "Hello from SomeDependency";
}
public class SomeHealthCheck : IHealthCheck
{
public string Name => nameof(SomeHealthCheck);
private readonly SomeDependency someDependency;
public SomeHealthCheck(SomeDependency someDependency)
{
this.someDependency = someDependency;
}
public Task<HealthCheckResult> CheckHealthAsync(
CancellationToken cancellationToken = default(CancellationToken))
{
var message = this.someDependency.GetMessage();
var result = new HealthCheckResult(HealthCheckStatus.Failed, null, null, null);
return Task.FromResult(result);
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks();
services.AddSingleton<SomeDependency>();
services.AddSingleton<IHealthCheck, SomeHealthCheck>();
}
public void Configure(IApplicationBuilder app)
{
app.UseHealthChecks("/healthz");
app.Run(async (context) => await context.Response.WriteAsync("Hello World!"));
}
}
このサンプルも GitHubで入手可能 です。
Shaunの答えに加えて、 open pull-request があります。これにより、任意のライフタイム(一時的でスコープ付き)のサービスをヘルスチェックに挿入できます。これはおそらく2.2リリースに含まれるでしょう。
ヘルスチェックで一時的なスコープサービスを使用できる場合は、 一時的なライフスタイルを使用してサービスを登録する を行う必要があります。
私はASP.NET Core 3.1 Web APIでこれに苦労していました。
services.AddHealthChecks();
services.AddSingleton<IHealthCheck, MyHealthCheck1>();
services.AddSingleton<IHealthCheck, MyHealthCheck2>();
残念ながら、ASP.NET Core 3.1では、IHealthCheck実装が呼び出されなかったため、実際には機能しないようです。
代わりに、Startup.ConfigureServices()で以下を実行する必要がありました。
services.AddHealthChecks()
.AddCheck<MyHealthCheck1>("My1-check",
HealthStatus.Unhealthy,
new string[] { "tag1" })
.AddCheck<MyHealthCheck2>("My2-check",
HealthStatus.Unhealthy,
new string[] { "tag2" });
次に、Startup.Configure()で、次のようにMapHealthChecks()も呼び出しました。
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHealthChecks("/hc");
});