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
.
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:
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:
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:
// 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:
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:
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.
// 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:
dotnet add package AspNetCore.HealthChecks.Uris
E adicionar a verificação da API dentro do arquivo ServiceRegistration.cs
.
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.
// 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
:
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
:
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
:
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:
: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
.
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.