미화 건강 검사
이전 기사에서는 건강검진에 대한 지식, 건강검진을 만드는 방법, Microsoft Orleans의 관점에서 건강검진을 보는 방법에 대해 알아봤습니다.최종 결과는'건강','퇴화'또는'건강하지 않다'는 단어의 대답이다.자극적이지 않은 물건.
이 글은 당신이 어떻게'총체적 상태'를 보고할 뿐만 아니라 이 총체적 상태를 구성하는 개인 건강 검사에 대한 상세한 정보를 제공할 것인지를 빠르게 되돌아보고 싶습니다.
(주의: 나는 확실히 issue이 있는데 그 위에 Hacket Toberfest 라벨이 있다. 나는 확실히 PR이 있다. 그러나 나는 결국 조금 다른 노선을 걷고 싶다. 비록 한동안 그것을 마스터에 통합시켰지만.)
Health check documentation은 건강검진의 미화를 어떻게 완성하는지 상세하게 소개했지만 저는'수동'으로 JSON을 쓰는 것을 별로 좋아하지 않습니다.반대로 나는 익명 대상을 선택했다.
부동산 잠재력을 미화하다.
health check GET endpoint에 대한 응답에서 다음과 같은 새로운 사항을 보고하고 싶습니다.
다행히도 이 모든 정보는 건강검진의 일부로 생성된
HealthReport
을 통해 제공된다.건강검진
우리는 건강 검사 단점에 사용자 정의 응답을 작성하는 새로운 방법을 도입할 것이다.시작부터 ResponseWriter
에 사용자 지정 MapHealthChecks
을 제공하고자 합니다.
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks(
"/health",
new HealthCheckOptions
{
AllowCachingResponses = false,
ResponseWriter = HealthCheckResponseWriter.WriteResponse
})
.WithMetadata(new AllowAnonymousAttribute());
endpoints.MapControllers();
});
이 중 인용된 HealthCheckResponseWriter
은 새로운 정태류로 다음에 소개할 것이다.ResponseWriter
에는 다음과 같은 서명 방법이 필요합니다.
위의 방법은 HttpContext
및 HealthReport을 수신하는 것입니다.이 HealthReport
은 저희에게 몇 가지 데이터를 제공할 것입니다. 저희는 모든 사람의 건강 검사를 구체적으로 보고할 수 있습니다.
우리의 실제 응답 컴파일러는 다음과 같이 L-Dogg의 PR에서 Master의 원본 버전으로 통합되었습니다.
private static Task WriteResponse(HttpContext context, HealthReport result)
{
context.Response.ContentType = "application/json; charset=utf-8";
var options = new JsonWriterOptions
{
Indented = true
};
using var stream = new MemoryStream();
using (var writer = new Utf8JsonWriter(stream, options))
{
writer.WriteStartObject();
writer.WriteString("status", result.Status.ToString());
writer.WriteStartObject("results");
foreach (var entry in result.Entries)
{
writer.WriteStartObject(entry.Key);
writer.WriteString("status", entry.Value.Status.ToString());
writer.WriteString("description", entry.Value.Description);
writer.WriteStartObject("data");
foreach (var item in entry.Value.Data)
{
writer.WritePropertyName(item.Key);
JsonSerializer.Serialize(
writer, item.Value, item.Value?.GetType() ??
typeof(object));
}
writer.WriteEndObject();
writer.WriteEndObject();
}
writer.WriteEndObject();
writer.WriteEndObject();
}
var json = Encoding.UTF8.GetString(stream.ToArray());
return context.Response.WriteAsync(json);
}
상술한 방법은 확실히 효과가 있지만, 나는 수동으로 json을 작성하는 것을 잘하지 못한다.어쨌든 나는 이 방면에 박문을 한 편 더 쓰고 싶다. 왜냐하면 나는 이미 지점(실제로는 PR:O를 기대하지 않는다)이 있기 때문에 나의 해결 방안은 다음과 같다.
internal static class HealthCheckResponseWriter
{
public static Task WriteResponse(HttpContext context, HealthReport healthReport)
{
context.Response.ContentType = "application/json; charset=utf-8";
var result = JsonConvert.SerializeObject(new
{
status = healthReport.Status.ToString(),
details = healthReport.Entries.Select(e => new
{
key = e.Key,
description = e.Value.Description,
status = e.Value.Status.ToString(),
data = e.Value.Data
})
}, Formatting.Indented);
return context.Response.WriteAsync(result);
}
}
나는 익명의 대상을 사용하는 것이 좀 더 간결하다는 것을 발견했다.
상태 점검 업데이트
현재 HealthCheckResponseWriter
에서 이용할 수 있는 건강검진에서 '데이터' 정보를 생성하지 못했기 때문에 우리가 그곳에서 무엇을 할 수 있는지 살펴보자.
익명 객체의 데이터 속성에 대한 나의 의도는 특정 상태 점검이 성능 저하 또는 비건강으로 되돌아갈 수 있는 이유를 설명하는 것입니다. 이 두 상태를 제외한 모든 상태는 건강으로 가정할 수 있습니다.
성능 저하 및 불건전 상태를 나타내기 위해 건강 검진에 임계값을 설정한 것을 기억하신다면 건강 보고서에서 사용할 수 있는 임계값만 제공해 주십시오.HealthCheckResult
클래스 보기:
이 방법은 선택할 수 있는 IReadOnlyDictionary<string, object> data = null
을 포함하고 있습니다. 이것은 바로 본고의 앞부분에서 WriteResponse
방법에서 되돌아오는 '데이터' 구성원을 확보하는 것입니다.
우리는 이 IReadonlyDictionary
을 이용하여 각 곡물의 한도값 정보를 제공할 것이다.이 임계값 정보를 CPU와 메모리 입자에 넣을 것입니다. 그러나 예를 들면 다음과 같습니다.
[StatelessWorker(1)]
public class CpuHealthCheckGrain : Grain, ICpuHealthCheckGrain
{
private const float UnhealthyThreshold = 90;
private const float DegradedThreshold = 70;
private readonly ReadOnlyDictionary<string, object> HealthCheckData = new ReadOnlyDictionary<string, object>(
new Dictionary<string, object>()
{
{ "Unhealthy Threshold", UnhealthyThreshold},
{ "Degraded Threshold", DegradedThreshold}
});
private readonly IHostEnvironmentStatistics _hostEnvironmentStatistics;
public CpuHealthCheckGrain(IHostEnvironmentStatistics hostEnvironmentStatistics)
{
_hostEnvironmentStatistics = hostEnvironmentStatistics;
}
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new CancellationToken())
{
if (_hostEnvironmentStatistics.CpuUsage == null)
{
return Task.FromResult(HealthCheckResult.Unhealthy("Could not determine CPU usage.", data: HealthCheckData));
}
if (_hostEnvironmentStatistics.CpuUsage > UnhealthyThreshold)
{
return Task.FromResult(HealthCheckResult.Unhealthy(
$"CPU utilization is unhealthy at {_hostEnvironmentStatistics.CpuUsage:0.00}%.", data: HealthCheckData));
}
if (_hostEnvironmentStatistics.CpuUsage > DegradedThreshold)
{
return Task.FromResult(HealthCheckResult.Degraded(
$"CPU utilization is degraded at {_hostEnvironmentStatistics.CpuUsage:0.00}%.", data: HealthCheckData));
}
return Task.FromResult(HealthCheckResult.Healthy(
$"CPU utilization is healthy at {_hostEnvironmentStatistics.CpuUsage:0.00}%.", data: HealthCheckData));
}
}
위에서 ReadOnlyDictionary
을 도입하였는데, 강등과 건강하지 않은 한도값을 포함하고, 이 ReadOnlyDictionary
을 data
의 정적 방법의 HealthCheckResult
매개 변수에 전달하는 것을 주의해야 합니다.
테스트
유일하게 해야 할 건 테스트야!스포일러가 포함된 표지 그림을 보았을 수도 있지만, 요컨대, 우리가 변경한 후에 "/건강"단추를 눌렀을 때 다음과 같이 보입니다.
도구책
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks(
"/health",
new HealthCheckOptions
{
AllowCachingResponses = false,
ResponseWriter = HealthCheckResponseWriter.WriteResponse
})
.WithMetadata(new AllowAnonymousAttribute());
endpoints.MapControllers();
});
private static Task WriteResponse(HttpContext context, HealthReport result)
{
context.Response.ContentType = "application/json; charset=utf-8";
var options = new JsonWriterOptions
{
Indented = true
};
using var stream = new MemoryStream();
using (var writer = new Utf8JsonWriter(stream, options))
{
writer.WriteStartObject();
writer.WriteString("status", result.Status.ToString());
writer.WriteStartObject("results");
foreach (var entry in result.Entries)
{
writer.WriteStartObject(entry.Key);
writer.WriteString("status", entry.Value.Status.ToString());
writer.WriteString("description", entry.Value.Description);
writer.WriteStartObject("data");
foreach (var item in entry.Value.Data)
{
writer.WritePropertyName(item.Key);
JsonSerializer.Serialize(
writer, item.Value, item.Value?.GetType() ??
typeof(object));
}
writer.WriteEndObject();
writer.WriteEndObject();
}
writer.WriteEndObject();
writer.WriteEndObject();
}
var json = Encoding.UTF8.GetString(stream.ToArray());
return context.Response.WriteAsync(json);
}
internal static class HealthCheckResponseWriter
{
public static Task WriteResponse(HttpContext context, HealthReport healthReport)
{
context.Response.ContentType = "application/json; charset=utf-8";
var result = JsonConvert.SerializeObject(new
{
status = healthReport.Status.ToString(),
details = healthReport.Entries.Select(e => new
{
key = e.Key,
description = e.Value.Description,
status = e.Value.Status.ToString(),
data = e.Value.Data
})
}, Formatting.Indented);
return context.Response.WriteAsync(result);
}
}
현재
HealthCheckResponseWriter
에서 이용할 수 있는 건강검진에서 '데이터' 정보를 생성하지 못했기 때문에 우리가 그곳에서 무엇을 할 수 있는지 살펴보자.익명 객체의 데이터 속성에 대한 나의 의도는 특정 상태 점검이 성능 저하 또는 비건강으로 되돌아갈 수 있는 이유를 설명하는 것입니다. 이 두 상태를 제외한 모든 상태는 건강으로 가정할 수 있습니다.
성능 저하 및 불건전 상태를 나타내기 위해 건강 검진에 임계값을 설정한 것을 기억하신다면 건강 보고서에서 사용할 수 있는 임계값만 제공해 주십시오.
HealthCheckResult
클래스 보기:이 방법은 선택할 수 있는
IReadOnlyDictionary<string, object> data = null
을 포함하고 있습니다. 이것은 바로 본고의 앞부분에서 WriteResponse
방법에서 되돌아오는 '데이터' 구성원을 확보하는 것입니다.우리는 이
IReadonlyDictionary
을 이용하여 각 곡물의 한도값 정보를 제공할 것이다.이 임계값 정보를 CPU와 메모리 입자에 넣을 것입니다. 그러나 예를 들면 다음과 같습니다.[StatelessWorker(1)]
public class CpuHealthCheckGrain : Grain, ICpuHealthCheckGrain
{
private const float UnhealthyThreshold = 90;
private const float DegradedThreshold = 70;
private readonly ReadOnlyDictionary<string, object> HealthCheckData = new ReadOnlyDictionary<string, object>(
new Dictionary<string, object>()
{
{ "Unhealthy Threshold", UnhealthyThreshold},
{ "Degraded Threshold", DegradedThreshold}
});
private readonly IHostEnvironmentStatistics _hostEnvironmentStatistics;
public CpuHealthCheckGrain(IHostEnvironmentStatistics hostEnvironmentStatistics)
{
_hostEnvironmentStatistics = hostEnvironmentStatistics;
}
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new CancellationToken())
{
if (_hostEnvironmentStatistics.CpuUsage == null)
{
return Task.FromResult(HealthCheckResult.Unhealthy("Could not determine CPU usage.", data: HealthCheckData));
}
if (_hostEnvironmentStatistics.CpuUsage > UnhealthyThreshold)
{
return Task.FromResult(HealthCheckResult.Unhealthy(
$"CPU utilization is unhealthy at {_hostEnvironmentStatistics.CpuUsage:0.00}%.", data: HealthCheckData));
}
if (_hostEnvironmentStatistics.CpuUsage > DegradedThreshold)
{
return Task.FromResult(HealthCheckResult.Degraded(
$"CPU utilization is degraded at {_hostEnvironmentStatistics.CpuUsage:0.00}%.", data: HealthCheckData));
}
return Task.FromResult(HealthCheckResult.Healthy(
$"CPU utilization is healthy at {_hostEnvironmentStatistics.CpuUsage:0.00}%.", data: HealthCheckData));
}
}
위에서 ReadOnlyDictionary
을 도입하였는데, 강등과 건강하지 않은 한도값을 포함하고, 이 ReadOnlyDictionary
을 data
의 정적 방법의 HealthCheckResult
매개 변수에 전달하는 것을 주의해야 합니다.테스트
유일하게 해야 할 건 테스트야!스포일러가 포함된 표지 그림을 보았을 수도 있지만, 요컨대, 우리가 변경한 후에 "/건강"단추를 눌렀을 때 다음과 같이 보입니다.
도구책
Reference
이 문제에 관하여(미화 건강 검사), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/kritner/prettifying-healthchecks-169g텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)