Você usa HealthChecks?

Os HealthChecks são mecanismos utilizados para monitorar e verificar o estado de saúde de um sistema ou serviço em tempo real. Essas verificações podem avaliar a disponibilidade de recursos externos, como bancos de dados, APIs ou serviços, e também podem verificar o estado interno da aplicação. Ao implementar HealthChecks em seu aplicativo C#, você pode identificar e solucionar problemas antes que eles afetem negativamente a experiência do usuário ou causem indisponibilidade do sistema.

Exemplos

Vamos criar um exemplo prático de healthcheck em .NET usando as bibliotecas padrão da Microsoft para SQL Server e uma API. Vamos partir do projeto padrão de ASP.NET Core Web Api com .Net 6. Nossa solution se chama Weather e nosso projeto Weather.WebApi.

Configurando a estrutura

Vamos começar configurando a estrutura do projeto para separar as responsabilidades, deixando o projeto organizado. Ao invés de criar a estrutura diretamente do program.cs, vamos extender as injeções de dependências para o healthcheck, utilizando uma Class Library chamada Weather.HealthCheck. O Projeto ficará com a seguinte estrutura:

Adicionamos os seguintes pacotes NuGet dentro desta biblioteca Weather.HealthCheck.

Plaintext
dotnet add package Microsoft.Extensions.Configuration.Abstractions
dotnet add package Microsoft.Extensions.DependencyInjection.Abstractions

Renomeamos a classe que é criada automaticamente Class1.cs para ServiceRegistration.cs e adicionamos o seguinte código:

C#
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Weather.HealthCheck
{
    public static class ServiceRegistration
    {
        private const string UriHealthCheck = "/health";

        public static void AddHealthCheckService(this IServiceCollection services, IConfiguration _config)
        {
            services
                .AddHealthChecks();
        }

        public static void AddHealthCheckApp(this WebApplication app)
        {
            app.MapHealthChecks(UriHealthCheck, new()
            {
                ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
            });
        }
    }
}

Adicionamos a referência do projeto Weather.HealthCheck no projeto Wheather.WebApi.

No program.cs da Wheather.WebApi adicione os serviços:

Program.cs
using Weather.HealthCheck;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddHealthCheck(builder.Configuration);

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.AddHealthCheck();

app.Run();

Pronto! Agora seu projeto já responde com healthcheck. Acesse https://localhost:7273/health (verifique a porta que seu projeto foi criado) e agora seu projeto já faz uma verificação de integridade:

JSON
// 20230704153210
// https://localhost:7273/health

{
  "status": "Healthy",
  "totalDuration": "00:00:00.0000728",
  "entries": {
    
  }
}

Verificação do Banco de Dados SQL Server

Instale o pacote NuGet que verifica o funcionamento do SQL Server dentro de Weather.HealthCheck, executando o comando abaixo:

Plaintext
dotnet add package AspNetCore.HealthChecks.SqlServer

Depois de instalado, dentro do arquivo ServiceRegistration.cs, vamos configurar apontando para a conexão do banco de dados e definindo o nome e tags que devem aparecer, conforme o código abaixo:

C#
public static void AddHealthCheckService(this IServiceCollection services, IConfiguration _config)
{
    services
      .AddHealthChecks()
          .AddSqlServer(_config.GetConnectionString("defaultConnection"),
                        name: "Banco de Dados Principal",
                        tags: new[] { "SQL Server", "Local" });
}

Pronto! Agora já temos a verificação do banco de dados. Podemos visualizar o resultado acessando novamente o /health da API.

Plaintext
// 20230704154313
// https://localhost:7273/health

{
  "status": "Healthy",
  "totalDuration": "00:00:00.0117515",
  "entries": {
    "Banco de Dados Principal": {
      "data": {
        
      },
      "duration": "00:00:00.0115469",
      "status": "Healthy",
      "tags": [
        "SQL Server",
        "Local"
      ]
    }
  }
}

Verificação de uma API Externa

Assim como foi feito no passo anterior, primeiro temos que instalar o pacote que faz a verificação:

Plaintext
dotnet add package AspNetCore.HealthChecks.Uris

E adicionar a verificação da API dentro do arquivo ServiceRegistration.cs.

C#
public static void AddHealthCheckService(this IServiceCollection services, IConfiguration _config)
{
    services
        .AddHealthChecks()
            .AddSqlServer(_config.GetConnectionString("defaultConnection"),
                          name: "Banco de Dados Principal",
                          tags: new[] { "SQL Server", "Local" })
            .AddUrlGroup(new Uri("http://api1"), 
                         name: "API 1", 
                         tags:new[] {"API"});
}

Mais uma verificação adicionada! Podemos visualizar novamente o resultado acessando novamente o /health da API.

JSON
// 20230704154820
// https://localhost:7273/health

{
  "status": "Healthy",
  "totalDuration": "00:00:00.2361306",
  "entries": {
    "Banco de Dados Principal": {
      "data": {
        
      },
      "duration": "00:00:00.0060158",
      "status": "Healthy",
      "tags": [
        "SQL Server",
        "Local"
      ]
    },
    "API 1": {
      "data": {
        
      },
      "duration": "00:00:00.2358059",
      "status": "Healthy",
      "tags": [
        "API"
      ]
    }
  }
}

Opções atuais para Implementar Healthchecks

Além das bibliotecas mencionadas acima, existem várias outras opções disponíveis para implementar healthchecks em aplicativos C#:

  • ApplicationStatus
  • ArangoDB
  • Amazon S3
  • Amazon Secrets Manager
  • Amazon SNS
  • Amazon SQS
  • Amazon Systems Manager
  • Azure IoT Hub
  • Azure DigitalTwin
  • Azure Key Vault
  • Azure Search
  • Azure Service Bus
  • Azure Storage
  • Consul
  • CosmosDb
  • Azure DocumentDb
  • Amazon DynamoDb
  • Elasticsearch
  • EventStore
  • EventStore gRPC
  • Google Cloud Firestore
  • Gremlin
  • Hangfire
  • IbmMQ
  • InfluxDB
  • Kafka
  • Kubernetes
  • MongoDB
  • MySql
  • Nats
  • Network
  • Postgres
  • Identity Server
  • Oracle
  • RabbitMQ
  • RavenDB
  • Redis
  • SendGrid
  • SignalR
  • Solr
  • Sqlite
  • Sql Server
  • System
  • Uri

Adicionando a Interface com HealthCheckUI

Para adicionar uma interface utilizando o HealthcheckUI, você pode seguir as seguintes etapas:

Instale o pacote NuGet abaixo na biblioteca Weather.HealthCheck:

Plaintext
dotnet add package AspNetCore.HealthChecks.UI
dotnet add package AspNetCore.HealthChecks.UI.Client
dotnet add package AspNetCore.HealthChecks.UI.InMemory.Storage

Registre o serviço do HealthcheckUI no método AddHealthCheck do arquivo ServiceRegistration.cs:

C#
public static void AddHealthCheckService(this IServiceCollection services, IConfiguration _config)
{
    services
        .AddHealthChecks()
            .AddSqlServer(_config.GetConnectionString("defaultConnection"),
                          name: "Banco de Dados Principal",
                          tags: new[] { "SQL Server", "Local" })
            .AddUrlGroup(new Uri("http://api1"),
                         name: "API 1",
                         tags:new[] {"API"});

    services
        .AddHealthChecksUI(options =>
        {
            options.AddHealthCheckEndpoint("Healthcheck API", UriHealthCheck);
        })
        .AddInMemoryStorage();
}

Adicione as configurações no método AddHealthCheckApp do arquivo ServiceRegistration.cs:

C#
public static void AddHealthCheckApp(this WebApplication app)
{
    app.MapHealthChecks(UriHealthCheck, new()
    {
        ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
    });

    app.MapHealthChecksUI(options =>
    {
        options.UIPath = "/dashboard";
        options.PageTitle = "HealthCheck Dashboard";
    });
}

Agora você também possui uma interface para visualização dos status. Acesse /dashboard:

BÔNUS: Customize as cores e ícone da interface

É possível ajustar algumas opções da interface para manter uma integridade com o padrão visual do sistema e apresentando uma visão mais personalizada. para este ajuste basta adicionar um arquivo css com as configurações aceitas pela biblioteca.

Dentro da biblioteca Weather.HealthCheck adicione uma arquivo chamado style.css, no meu exemplo adicionei as seguintes configurações:

CSS
:root {
    --primaryColor: #8204ff;
    --secondaryColor: #f4f4f4;
    --bgMenuActive: #c10fff;
    --bgButton: #68217a;
    --logoImageUrl: url('https://bianchini.tech/wp-content/uploads/2023/07/Icone-Branco.png');
    --bgAside: var(--primaryColor);
}

Adicione a referência para o arquivo no método AddHealthCheckApp dentro de Weather.HealthCheck.

C#
public static void AddHealthCheckApp(this WebApplication app)
{
    app.MapHealthChecks(UriHealthCheck, new()
    {
        ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
    });

    app.MapHealthChecksUI(options =>
    {
        options.UIPath = "/dashboard";
        options.PageTitle = "HealthCheck Dashboard";
        options.AddCustomStylesheet("../Weather.HealthCheck/style.css");
    });
}

Alterei algumas opções e veja como uma simples modificação alterar totalmente a percepção visual. Veja como ficou:

A implementação de healthchecks em seu aplicativo C# é uma prática fundamental para manter a saúde e a disponibilidade do sistema. Ao adotar essas práticas, você estará melhor preparado para identificar e resolver problemas antes que eles afetem seus usuários e sua aplicação.

Link do Código Fonte:

Link da documentação:

Compartilhe:

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Rolar para cima