dotnet healthcheck

配置healthchecks ui ,必须在appsetting.json中指定/health的地址

https://localhost:44398/healthchecks-ui

1
2
3
4
5
6
7
8
"HealthChecks-UI": {
  "HealthChecks": [
    {
      "Name": "Ordering HTTP Check",
      "Uri": "https://localhost:44398/health"
    }
  ]
}

https://localhost:44398/healthchecks-ui#/healthchecks

1
2
3
4
5
6
7
8
9
10
11
12
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
//});

  

1
2
3
4
5
6
app.UseHealthChecks("/health", new HealthCheckOptions()
            {
                Predicate = _ => true,
                ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
            });
            app.UseHealthChecksUI()

可以更改路径

复制代码
app.UseHealthChecks("/hc", new HealthCheckOptions()
        {
            Predicate = _ => true,
            ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
        })
        .UseHealthChecksUI(setup => 
        {
            setup.ApiPath = "/hc";
            setup.UIPath = "/hc-ui";
        });
复制代码

 

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

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    #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; } 
        }

    }
复制代码

 

posted on   白马酒凉  阅读(150)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示