每次系統剛上線時,總是會有某些功能出現錯誤,或與正式環境設定不一致的地方,無法執行。一開始筆者都會自己建立測試頁面,讓管理員可以查看各功能是否正常,但其實 ASP.NET Core 本身就有內建系統健康檢查,能夠快速確認定義好的健康檢查事項是否都正常。
只要開啟 /healthz 頁面,就會看到顯示當前健康度狀態的訊息
如果將上面的 isHealthy 設定為 false,回應內容就會變成 Unhealthy ,然後會在 log 中出現下方的警告訊息:
範例回應:
參考資料:
Microsoft.Learn - Health checks in ASP.NET Core
Microsoft.Learn - Health monitoring
健康檢查範例
這裡建立兩個健康檢查範例,都需要實作 IHealthCheck 介面。簡單健康檢查範例
這是微軟官網中的範例,透過修改 isHealthy 為 false 方便觀察不健康時的訊息。
public class SampleHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default
)
{
var isHealthy = true;
if (isHealthy)
{
return Task.FromResult(
HealthCheckResult.Healthy("健康"));
}
return Task.FromResult(
new HealthCheckResult(
context.Registration.FailureStatus, "不健康"));
}
}
連線到 Google
這個範例是用來檢查是否能夠連線到 google ,用以當作能否連線到網際網路的依據。
public class GoogleHealthCheck : IHealthCheck
{
public async Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default
)
{
Console.WriteLine("GoogleHealthCheck");
using var client = new HttpClient();
try
{
var response = await client.GetAsync("http://www.google.com", cancellationToken);
if (response.IsSuccessStatusCode)
{
return HealthCheckResult.Healthy("可以正常連線到 Google");
}
}
catch (Exception e)
{
Console.WriteLine("GoogleHealthCheck Exception");
}
return HealthCheckResult.Unhealthy("無法連線到 Google");
}
}
註冊服務
將系統健康檢查服務註冊連結為 /healthz
builder.Services.AddHealthChecks()
.AddCheck<GoogleHealthCheck>("Google 連接檢查")
.AddCheck<SampleHealthCheck>("範例健康檢查");
var app = builder.Build();
app.MapHealthChecks("/healthz");
只要開啟 /healthz 頁面,就會看到顯示當前健康度狀態的訊息
Healthy
如果將上面的 isHealthy 設定為 false,回應內容就會變成 Unhealthy ,然後會在 log 中出現下方的警告訊息:
fail: Microsoft.Extensions.Diagnostics.HealthChecks.DefaultHealthCheckService[103]
Health check 範例健康檢查 with status Unhealthy completed after 0.9322ms with message '不健康'
回傳錯誤訊息
上面提到 /healthz API 只有當前狀態名稱,不會有詳細的訊息,那想要顯示各個的狀態該怎麼做?其實我們可以自訂回傳的訊息:
// app.MapHealthChecks("/healthz");
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
ResponseWriter = (context, report) =>
{
context.Response.ContentType = "application/json";
var response = new
{
Status = report.Status.ToString(),
TotalDuration = report.TotalDuration,
Entries = report.Entries.Select(e => new
{
Service = e.Key,
Status = e.Value.Status.ToString(),
Description = e.Value.Description
})
};
var json = JsonSerializer.Serialize(response, new JsonSerializerOptions
{
WriteIndented = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
});
return context.Response.WriteAsync(json);
}
}
);
範例回應:
{
"Status": "Unhealthy",
"TotalDuration": "00:00:00.0656890",
"Entries": [
{
"Service": "Google 連接檢查",
"Status": "Healthy",
"Description": "可以正常連線到 Google"
},
{
"Service": "範例健康檢查",
"Status": "Unhealthy",
"Description": "不健康"
}
]
}
參考資料:
Microsoft.Learn - Health checks in ASP.NET Core
Microsoft.Learn - Health monitoring
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com