DEV Community

Cover image for QuickStart Health Check Setup in ASP.NET Core 5 Web API
Caio Cesar
Caio Cesar

Posted on

QuickStart Health Check Setup in ASP.NET Core 5 Web API

In this post we will integrate ASP.NET Core Health-Checks in .NET 5 Core API Project. This is a straightforward, quick start guide to get things started with health checks with a graphical user interface and no database dependency.

In this example a memory check based on the Garbage collector will be setup. We will use the AspNetCore.Diagnostics.HealthChecks library to display the results in a more friendly User interface.

Setup

The first step is to create a new ASP.NET Core WebApi project in your environment. In this example I will use openApi set as true and .NET 5.

Alt Text

Packages

Install the following nuget packages:

  • AspNetCore.HealthChecks.UI
  • AspNetCore.HealthChecks.UI.InMemory.Storage
  • AspNetCore.HealthChecks.UI.Client

ConfigureServices

  public void ConfigureServices(IServiceCollection services)
        {
            services.AddHealthChecks().AddCheck<MemoryHealthCheck>("Memory");
            services.AddHealthChecksUI(opt =>
            {
                opt.SetEvaluationTimeInSeconds(15); //time in seconds between check
            }).AddInMemoryStorage();

            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApi.HealthCheck", Version = "v1" });
            });
        }
Enter fullscreen mode Exit fullscreen mode

Configure

  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApi.HealthCheck v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            app.UseRouting()
             .UseEndpoints(config =>
             {
                 config.MapHealthChecks("/hc", new HealthCheckOptions
                 {
                     Predicate = _ => true,
                     ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
                 });

                 config.MapHealthChecksUI(setup =>
                 {
                     setup.UIPath = "/hc-ui";
                     setup.ApiPath = "/hc-json";  
                 });

                 config.MapDefaultControllerRoute();
             });
        }
Enter fullscreen mode Exit fullscreen mode

MemoryCheck.cs

 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 : context.Registration.FailureStatus;

            return Task.FromResult(new HealthCheckResult(
                status,
                description: "Reports degraded status if allocated bytes " +
                    $">= {options.Threshold} bytes.",
                exception: null,
                data: data));
        }
    }

    public class MemoryCheckOptions
    {
        // Failure threshold (in bytes)
        public long Threshold { get; set; } = 1024L * 1024L * 1024L;
    }
Enter fullscreen mode Exit fullscreen mode

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "HealthChecksUI": {
    "HealthChecks": [
      {
        "Name": "Web App",
        "Uri": "/hc"
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Result

Alt Text

References

Top comments (0)