skip to Main Content

I am trying to implement health checks in my blazor application. To do so, I have used the Microsoft.AspNetCore.Diagnostics.HealthChecks package among others. Below you can see sql and url health checks.

startup.cs

//using AjuaBlazorServerApp.Data;
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AjuaBlazorServerApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddHostedService<PeriodicExecutor>();
            services.AddHealthChecks().AddUrlGroup(new Uri("https://api.example.com/post"),
                name: "Example Endpoint",
                failureStatus: HealthStatus.Degraded)
            .AddSqlServer(Configuration["sqlString"],
                healthQuery: "select 1",
                failureStatus: HealthStatus.Degraded,
                name: "SQL Server");
            services.AddHealthChecksUI(opt =>
            {
                opt.SetEvaluationTimeInSeconds(5); //time in seconds between check    
                opt.MaximumHistoryEntriesPerEndpoint(60); //maximum history of checks    
                opt.SetApiMaxActiveRequests(1); //api requests concurrency    
                opt.AddHealthCheckEndpoint("Ajua API", "/api/health"); //map health check api    
            }).AddInMemoryStorage();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            app.UseStaticFiles();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
                endpoints.MapHealthChecks("/api/health", new HealthCheckOptions()
                {
                    Predicate = _ => true,
                    ResponseWriter = UIResponseWriter.
                    WriteHealthCheckUIResponse
                });
                endpoints.MapHealthChecksUI();
            });
        }
    }
}

The sql one works perfectly. However the url health check returns the following error:

Discover endpoint #0 is not responding with code in 200...299 range, the current status is MethodNotAllowed.

What i would like to know is if there is a way to maybe set the method type and if need be send some test details to the endpoint so that we can actually get a valid response.

2

Answers


  1. Chosen as BEST ANSWER

    I accepted the answer above because it technically answered my question. However, this is the implementation I ended up using. Basically you will have to create your own custom healthcheck.

    1. Add a new folder under you projects main directory and name it accordingly enter image description here

    2. Create a new class in that folder and add code similar to what I have below

    EndpointHealth.cs

    using Microsoft.Extensions.Diagnostics.HealthChecks;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.Json;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Net;
    using System.IO;
    using Microsoft.Extensions.Configuration;
    
    namespace BlazorServerApp.HealthChecks
    {
        public class EndpointHealth : IHealthCheck
        {
            public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken =
             default)
            {
                
                    //create a json string of parameters and send it to the endpoint
                    var data = new
                    {
                        test = "Example",
                    };
                    string jsonString = JsonSerializer.Serialize(data);
                    var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://api.example.com/post");
                    httpWebRequest.ContentType = Configuration["application/json"];
                    httpWebRequest.Method = Configuration["POST"];
                    using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                    {
                        streamWriter.Write(jsonString);
                    }
                    //Get the endpoint result and use it to return the appropriate health check result
                    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                    if (((int)httpResponse.StatusCode) >= 200 && ((int)httpResponse.StatusCode) < 300)
                    return Task.FromResult(HealthCheckResult.Healthy());
                    else
                    return Task.FromResult(HealthCheckResult.Unhealthy());
            }
        }
    }
    
    

    Then add the following code to the top of your startup.cs file using BlazorServerApp.HealthChecks;

    and finally the below code:

            public void ConfigureServices(IServiceCollection services)
            {
                services.AddRazorPages();
                services.AddServerSideBlazor();
                services.AddHealthChecks()
                .AddCheck<EndpointHealth>("Endpoint",null);
    
            }
    

  2. AddUrlGroup has an overload that allows you to specify the method through the httpMethod parameter. Try using :

    .AddUrlGroup(new Uri("https://api.example.com/post"),
                httpMethod: HttpMethod.Post,
                name: "Example Endpoint",
                failureStatus: HealthStatus.Degraded)
    

    Another overload allows configuring the HttpClient and HttpMessageHandler explicitly, to add specific default headers for example, enable compression or redirection.

    .AddUrlGroup(new Uri("https://api.example.com/post"),
                httpMethod: HttpMethod.Post,
                name: "Example Endpoint",
                configureClient: client => {
                    client.DefaultRequest.Headers.IfModifiedSince=
                                    DateTimeOffset.Now.AddMinutes(-10);
                },
                failureStatus: HealthStatus.Degraded)
    

    Yet another overload allows explicitly configuring the UriHealthCheckOptions class generated by other AddUrlGroup overloads:

    .AddUrlGroup(uriOptions=>{
        uriOptions
            .UsePost()
            .AddUri(someUrl,setup=>{
                setup.AddCustomHeader("...","...");
        });
    });
    

    There’s no way to specify content headers because the health check code doesn’t send a body.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search