Xabaril / AspNetCore.Diagnostics.HealthChecks

Enterprise HealthChecks for ASP.NET Core Diagnostics Package
Apache License 2.0
4.11k stars 800 forks source link

UI tree style look #2290

Open BertoSwanepoel opened 2 months ago

BertoSwanepoel commented 2 months ago

What would you like to be added: I am not a seasoned developer but would like to know if there is an option to have tree style look to the web ui. For example, I want to use a single dashboard for all my environments. I currently have 13 micro services in each environment namely development, staging and production. What I am looking for is, to see the 3 environments as parents with the 13 services as children and then the statuses for Redis, Rabbit and SQL.

| - Development | - Example Service | - Redis | - Rabbit | - SQL

Why is this needed: This is so that a single dashboard can be used for multiple environments with multiple service endpoints.

francoax commented 2 months ago

Actually, you already can. Do these

builder.services.AddHealthChecks()
  .AddCheck<DevCheck1>("dev check 1", tags: ["Development"])
  .AddCheck<DevCheck2>("dev check 2", tags: ["Development"])
  .AddCheck<RedisCheck1>("redis check 1", tags: ["Redis"])
  .AddCheck<RedisCheck2>("redis check 2", tags: ["Redis"])
  ...
builder.services.AddHealthChecksUI(options =>
{
    // HealthCheck Sections
    options.AddHealthCheckEndpoint("Development", "health/dev");
    options.AddHealthCheckEndpoint("Redis", "health/redis");
    options.AddHealthCheckEndpoint("Rabbit", "health/rabbit");
    ....
})
.AddInMemoryStorage();
app.MapHealthChecks("/health/dev", new HealthCheckOptions()
{
    Predicate = (check) => check.Tags.Contains("Development"),
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponseNoExceptionDetails
});

app.MapHealthChecks("/health/redis", new HealthCheckOptions()
{
    Predicate = (check) => check.Tags.Contains("Redis"),
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponseNoExceptionDetails,
});

...
BertoSwanepoel commented 2 months ago

Thank you, I tried this quickly, it can maybe just be me but I am not getting what I am looking for. See below, this is how my health dasboard current looks like. What I also should add, the health check is create as a support project, then loaded into each service by calling it like this on the startup.cs of each service.

services.AddHealthCheck(Configuration, "database", "redis", "rabbit");

The AddHealthCheck then looks like this,

namespace WhoYou.Services.Shared.Extensions { public static class HealthCheckExtension {

    public static void AddHealthCheck(this IServiceCollection services, IConfiguration config, params string[] healthChecks)
    {

        var healthCheckBuilder = services.AddHealthChecks();

        // Check if each health check should be added
        if (healthChecks.Contains("database"))
        {
            healthCheckBuilder.AddCheck<DatabaseHealth>("WhoYou Database",
                failureStatus: HealthStatus.Unhealthy,
                tags: [ "database" ]);
            services.AddSingleton(sp => new DatabaseHealth(config.GetConnectionString("WhoYouDatabase")));
        }

        if (healthChecks.Contains("redis"))
        {
            healthCheckBuilder.AddCheck<RedisHealth>("Redis",
                failureStatus: HealthStatus.Unhealthy,
                tags: [ "redis" ]);
            services.AddSingleton(sp => new RedisHealth(config.GetConnectionString("RedisCache")));
        }

        if (healthChecks.Contains("rabbit"))
        {
            healthCheckBuilder.AddCheck<RabbitMQHealth>("RabbitMQ",
                failureStatus: HealthStatus.Unhealthy,
                tags: [ "rabbit" ]);
            services.AddSingleton(sp => new RabbitMQHealth($"amqp://{config["ServiceBus:Username"]}:{config["ServiceBus:Password"]}@{config["ServiceBus:Endpoint"]}"));
        }

        if (healthChecks.Contains("supernode"))
        {
            healthCheckBuilder.AddCheck<SuperNodeHealth>("SuperNode",
                failureStatus: HealthStatus.Unhealthy,
                tags: [ "supernode" ]);
            services.AddSingleton(sp =>
            {
                var connectionString = config.GetConnectionString("WhoYouDatabase");
                var httpClient = sp.GetRequiredService<HttpClient>();
                return new SuperNodeHealth(connectionString, httpClient);
            });
        }

        if (healthChecks.Contains("file-access"))
        {
            var folderPaths = new List<string>
        {
            Path.Combine(Directory.GetCurrentDirectory(), "ReportTemplates"),
            Path.Combine(Directory.GetCurrentDirectory(), "Resources"),
            Path.Combine(Directory.GetCurrentDirectory(), "StaticFiles")
        };

            healthCheckBuilder.AddCheck<FolderAccess>("FileAccess",
                failureStatus: HealthStatus.Unhealthy,
                tags: [ "file-access" ]);
            services.AddSingleton(sp => new FolderAccess(folderPaths));
        }

    }
}

} So based on the service it will only check what it requires. Secondly I took the dashboard code, made a few changes and containerized it for kubernetes, this way I can share with the team a dashboard and in the config file I have all the endpoints. image So each service shows as expected, I would like to place all the services under a group called Development which will not have a URL. Once you expand that you should see all these services, then you can expand each service to view each health endpoint.

Kind Regards Berto Swanepoel