配置healthchecks ui
https://localhost:44398/healthchecks-ui#/healthchecks
context.Services.AddHealthChecks() .AddSqlServer(configuration["ConnectionStrings:Default"]) .AddMongoDb(configuration["ConnectionStrings:TestMongoDb"]) .AddCheck<MemoryHealthCheck>("MemoryHealthCheck") .AddCheck<ApiHealthCheck>("ApiHealthCheck") .AddCheck<WindowsServicesHealthCheck>("RpcSs"); context.Services.AddHealthChecksUI();//.AddInMemoryStorage(); // setupSettings: setup => //{ // setup.SetEvaluationTimeInSeconds(60); //Configures the UI to poll for healthchecks updates every 5 seconds //});
app.UseHealthChecks("/health", new HealthCheckOptions() { Predicate = _ => true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse }); app.UseHealthChecksUI()
ApiHealthCheck
public class ApiHealthCheck : IHealthCheck { private readonly IHttpClientFactory _httpClientFactory; public ApiHealthCheck(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { using (var httpClient = _httpClientFactory.CreateClient()) { var response = await httpClient.GetAsync("https://localhost:44398/api/app/item/items"); if (response.IsSuccessStatusCode) { return HealthCheckResult.Healthy($"API is running."); } return HealthCheckResult.Unhealthy("API is not running"); } } }
MemoryHealthCheck
#region snippet1 public class MemoryHealthCheck : IHealthCheck { private readonly IOptionsMonitor<MemoryCheckOptions> _options; public MemoryHealthCheck(IOptionsMonitor<MemoryCheckOptions> options) { _options = options; } public string Name => "memory_check"; public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { var options = _options.Get(context.Registration.Name); // Include GC information in the reported diagnostics. var allocated = GC.GetTotalMemory(forceFullCollection: false); var data = new Dictionary<string, object>() { { "AllocatedBytes", allocated }, { "Gen0Collections", GC.CollectionCount(0) }, { "Gen1Collections", GC.CollectionCount(1) }, { "Gen2Collections", GC.CollectionCount(2) }, }; var status = (allocated < options.Threshold) ? HealthStatus.Healthy : HealthStatus.Unhealthy; return Task.FromResult(new HealthCheckResult( status, description: "Reports degraded status if allocated bytes " + $">= {options.Threshold} bytes.", exception: null, data: data)); } } #endregion #region snippet2 public static class GCInfoHealthCheckBuilderExtensions { public static IHealthChecksBuilder AddMemoryHealthCheck( this IHealthChecksBuilder builder, string name, HealthStatus? failureStatus = null, IEnumerable<string> tags = null, long? thresholdInBytes = null) { // Register a check of type GCInfo. builder.AddCheck<MemoryHealthCheck>( name, failureStatus ?? HealthStatus.Degraded, tags); // Configure named options to pass the threshold into the check. if (thresholdInBytes.HasValue) { builder.Services.Configure<MemoryCheckOptions>(name, options => { options.Threshold = thresholdInBytes.Value; }); } return builder; } } #endregion #region snippet3 public class MemoryCheckOptions { // Failure threshold (in bytes) public long Threshold { get; set; } = 1024L * 1024L * 1024L; } #endregion
WindowsServicesHealthCheck
public class WindowsServicesHealthCheck : IHealthCheck { private readonly string _serviceName; private readonly IOptionsMonitor<WindowsServicesCheckOptions> _options; public WindowsServicesHealthCheck(IOptionsMonitor<WindowsServicesCheckOptions> options) { _options = options; } public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { var status = GetWindowsServiceStatus(context.Registration.Name); return Task.FromResult(new HealthCheckResult( (status == ServiceControllerStatus.Running)?HealthStatus.Healthy : HealthStatus.Unhealthy, description: "", exception: null, data: null)); } public static ServiceControllerStatus GetWindowsServiceStatus(String SERVICENAME) { ServiceController sc = new ServiceController(SERVICENAME); return sc.Status; //switch (sc.Status) //{ // case ServiceControllerStatus.Running: // return "Running"; // case ServiceControllerStatus.Stopped: // return "Stopped"; // case ServiceControllerStatus.Paused: // return "Paused"; // case ServiceControllerStatus.StopPending: // return "Stopping"; // case ServiceControllerStatus.StartPending: // return "Starting"; // default: // return "Status Changing"; //} } public class WindowsServicesCheckOptions { public string Name { get; set; } } }