본문 바로가기

c#/ASP.NET CORE

ASP.NET CORE HTTP health Check

asp.net core에서 health Check는 해당 어플리케이션이 정상적으로 작동하는지 확인하는 기능입니다.

위 기능으로는 크게 아래와 같이 활용 가능합니다.

  1. 애플리케이션의 가용성 모니터링: Health Check는 애플리케이션이 정상적으로 작동하는지 확인하는데 사용됩니다. 이를 통해 시스템이 언제든지 사용할 수 있는지 여부를 판단할 수 있습니다.
  2. 종속 서비스 상태 확인: 데이터베이스, 캐시, 외부 API 등 애플리케이션이 의존하고 있는 서비스들의 상태를 확인할 수 있습니다. 만약 종속 서비스 중 하나가 비정상 상태라면, 이를 즉시 감지하고 조치를 취할 수 있습니다.
  3. 컨테이너 오케스트레이션 도구 통합: Kubernetes와 같은 컨테이너 오케스트레이션 도구에서는 애플리케이션의 상태를 확인하기 위해 Health Check를 사용합니다. 이러한 도구들은 Health Check의 결과를 바탕으로 컨테이너를 재시작하거나 다른 노드로 이동시킬 수 있습니다.
  4. 로드 밸런서와의 통합: 로드 밸런서는 Health Check를 통해 애플리케이션 인스턴스의 상태를 확인하고, 비정상 상태의 인스턴스에 트래픽을 보내지 않도록 할 수 있습니다
  5. 애플리케이션 성능 및 신뢰성 향상: Health Check를 통해 애플리케이션의 다양한 구성 요소들의 상태를 주기적으로 모니터링함으로써, 사전에 문제를 발견하고 대응할 수 있습니다.

우선 health check를 사용하려면 NuGet패키지를 설치해야합니다.

dotnet add package Microsoft.Extensions.Diagnostics.HealthChecks

 위 명령어로 패키지를 다운로드하고

program.cs

builder.Services.AddHealthChecks();

var app = builder.Build();

app.MapHealthChecks("/testCheck");

위와 같이 미들웨어를 구성하고

주소창에 testCheck입력

 

healty출력

프로그램 실행후 주소창에 미들웨어에서 입력한 /testCheck를 입력하면 이상이 없을때 healty라는 화면이 보이게 됩니다.

또한 health check를 커스텀하여 사용할 수 있는데 CustomHealthCehck클래스를 생성하여 그안에 로직이나 사용자 지정문구와 같은 내용을 작성할 수 있습니다.

class CustomHealthCheck : IHealthCheck
{
    public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        var isHealthy = true;
 
        if (isHealthy)
        {
            return Task.FromResult(HealthCheckResult.Healthy("All systems are looking good"));
        }
 
        return Task.FromResult(new HealthCheckResult(context.Registration.FailureStatus, "System Unhealty"));
 
 
 
    }
 
}
builder.Services.AddHealthChecks()
    .AddCheck<CustomHealthCheck>("Custom Health Check", failureStatus: HealthStatus.Degraded, tags: new[] { "custom" })

failureStatus: Health Check가 실패했을때 반환 상태를 지정하는것 입니다.

  1. Healthy: 시스템이 정상적으로 작동하고 있음을 나타냅니다. Health Check가 성공했을 때 반환됩니다.
  2. Degraded: 시스템이 작동 중이지만 일부 문제가 있음을 나타냅니다. 이는 성능 저하나 부분적인 장애를 의미할 수 있습니다. Health Check가 일부 문제를 발견했을 때 반환될 수 있습니다.
  3. Unhealthy: 시스템에 심각한 문제가 있음을 나타냅니다. 이는 시스템이 정상적으로 작동하지 않거나 주요 기능이 중단되었음을 의미합니다. Health Check가 실패했을 때 반환됩니다.

tags :  태그를 지정하여 그룹화나 필터링을 하여 선택적으로 모니터링이 가능하게 됩니다.

app.MapHealthChecks("/healthcheck", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
{
	Predicate = healthcheck => healthcheck.Tags.Contains("custom"),
    ResultStatusCodes =
    {
        [HealthStatus.Healthy] = StatusCodes.Status200OK,
        [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable,
        [HealthStatus.Degraded] = StatusCodes.Status200OK,
    },
    ResponseWriter = WriteResponse
});
static Task WriteResponse(HttpContext context, HealthReport healthReport)
{
    context.Response.ContentType = "application/json; charset=utf-8";

    var options = new JsonWriterOptions { Indented = true };

    using var memoryStream = new MemoryStream();

    using (var jsonWriter = new Utf8JsonWriter(memoryStream, options))
    {
        jsonWriter.WriteStartObject();
        jsonWriter.WriteString("status", healthReport.Status.ToString());
        jsonWriter.WriteStartObject("result");

        foreach (var healthReportEntry in healthReport.Entries)
        {
            jsonWriter.WriteStartObject(healthReportEntry.Key);
            jsonWriter.WriteString("status", healthReportEntry.Value.Status.ToString());
            jsonWriter.WriteString("description",
                healthReportEntry.Value.Description);
            jsonWriter.WriteStartObject("data");

            foreach (var item in healthReportEntry.Value.Data)
            {
                jsonWriter.WritePropertyName(item.Key);

                JsonSerializer.Serialize(jsonWriter, item.Value, item.Value?.GetType() ?? typeof(object));
            }

            jsonWriter.WriteEndObject();
            jsonWriter.WriteEndObject();
        }

        jsonWriter.WriteEndObject();
        jsonWriter.WriteEndObject();
    }

    return context.Response.WriteAsJsonAsync(Encoding.UTF8.GetString(memoryStream.ToArray()));
}

 

  • app.MapHealthChecks("매핑엔드포인트", ...): 해당 부분에 엔드포인트에 대해 헬스 체크를 매핑합니다.
  • new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions: 헬스 체크 옵션을 정의합니다.
  • ResultStatusCodes = { ... }: 헬스 체크 상태에 따른 HTTP 응답 상태 코드를 설정합니다.
  • HealthStatus.Healthy] = StatusCodes.Status200OK: 시스템이 건강할 때 200 OK 응답을 반환합니다.
  • [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable: 시스템이 불건강할 때 503 서비스 사용 불가 응답을 반환합니다.
  • [HealthStatus.Degraded] = StatusCodes.Status200OK: 시스템 상태가 저하되었을 때도 200 OK 응답을 반환합니다.

그리고 json으로 health Check의 관한 내용을 return하게 됩니다.

ef-core를 사용한다 가정하면 efcore healthcheck를 통해서 해당 db가 정상적으로 작동하는지도 확인이 가능합니다. 

 

builder.Services.AddHealthChecks()
    .AddCheck<CustomHealthCheck>("Custom Health Check", failureStatus: HealthStatus.Degraded, tags: new[] { "custom" })
    .AddSqlServer(connectionString, tags: new[] { "database" })//db연결가능 체크
    .AddDbContextCheck<testDbContext>(tags: new[] { "database" });

이때 알맞은 db에 맞게 메서드를 지정하고 AddDbContextCheck메서드에 체크할 dbcontext객체를 넣어 타입을 지정합니다.

그리고 tag를 database로 필터링하여 MapHealthChecks를 지정해주면 db 상태에 관한 healthcheck도 가능해집니다.

app.MapHealthChecks("/databasehealthcheck", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
{
    Predicate = healthcheck => healthcheck.Tags.Contains("database"),
    ResultStatusCodes =
    {
        [HealthStatus.Healthy] = StatusCodes.Status200OK,
        [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable,
        [HealthStatus.Degraded] = StatusCodes.Status200OK,
    },
    ResponseWriter = WriteResponse
});

그리고 실행하면 데이터베이스의 상태에 대한 결과가 아래와 같이 출력되게 됩니다.

1.databasehealthcheck

2.healthcheck

 

'c# > ASP.NET CORE' 카테고리의 다른 글

ASP.NET CORE 전역 에러 처리 Global Error Exception  (0) 2024.03.09
ASP.NET CORE AutoMapper 사용법  (0) 2024.03.05