183 lines
6.0 KiB
Markdown
183 lines
6.0 KiB
Markdown
# MCVIngenieros.Healthchecks
|
|
|
|
LICENCIA: [GNU General Public License v3.0](LICENSE.md)
|
|
|
|
Librería para la gestión y exposición de healthchecks personalizables en aplicaciones .NET. Permite definir múltiples chequeos de salud, exponerlos vía API y configurarlos fácilmente.
|
|
|
|
## ¿Cómo funciona?
|
|
|
|
1. Define tus healthchecks implementando la interfaz `IHealthCheck`.
|
|
2. Regístralos en el contenedor de servicios usando los métodos de extensión.
|
|
3. Opcionalmente, configura las opciones en `appsettings.json`.
|
|
4. Accede a los resultados mediante los endpoints expuestos por el controlador.
|
|
|
|
---
|
|
|
|
## Ejemplo de configuración en appsettings.json
|
|
|
|
```json appsettings.json
|
|
{
|
|
"HealthChecksConfigs": {
|
|
"CacheDuration": "00:30:00",
|
|
"Timeout": "00:00:05",
|
|
"AssembliesToScan": [
|
|
"MyAssembly"
|
|
],
|
|
"MyCheck": {
|
|
"RetryAttempts": 2,
|
|
"Timeout": "00:05:00",
|
|
"RetryDelay": "00:00:10",
|
|
"Severity": "Info"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Ejemplo de configuración en CSharp
|
|
|
|
```csharp
|
|
builder.Services.AddHealthChecksSupport(); // <--- Usará la configuración de appsettings.json
|
|
|
|
builder.Services.AddHealthChecksSupport(options => {
|
|
options.AssembliesToScan.Add(typeof(Program).Assembly);
|
|
options.CacheDuration = TimeSpan.FromMinutes(10);
|
|
options.Timeout = TimeSpan.FromSeconds(5);
|
|
options.Threshold = 0.7;
|
|
});
|
|
```
|
|
|
|
## Ejemplo de uso en CSharp
|
|
|
|
```csharp
|
|
// Registro manual de healthchecks
|
|
builder.Services.AddHealthChecksSupport()
|
|
.AddCheck<CustomHealthCheck>("Custom");
|
|
|
|
// Registro automático de healthchecks
|
|
builder.Services.AddHealthChecksSupport()
|
|
.DiscoverHealthChecks();
|
|
```
|
|
|
|
### Ejemplo de implementación de un healthcheck personalizado
|
|
|
|
```csharp
|
|
public class CustomHealthCheck () : HealthCheck
|
|
{
|
|
public string Description => "Custom health check";
|
|
|
|
public Task<HealthCheckResult> CheckAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
// Lógica de chequeo
|
|
return Task.FromResult(HealthCheckResult.Healthy("Todo OK"));
|
|
}
|
|
}
|
|
```
|
|
|
|
```csharp
|
|
public partial class HealthChecksConfigs : MCVIngenieros.Healthchecks.Options.HealthChecksConfigs
|
|
{
|
|
public const string CustomHealthCheckWithOptions = nameof(CustomHealthCheckWithOptions);
|
|
}
|
|
|
|
---
|
|
|
|
public class CustomHealthCheckWithOptions (IOptionsMonitor<HealthChecksConfigs> healthchecksConfig) : HealthCheck
|
|
{
|
|
private readonly HealthChecksConfigs hcConfig = healthchecksConfig.Get(HealthChecksConfigs.CustomHealthCheckWithOptions);
|
|
public string Description => hcConfig.Description;
|
|
public int? RetryAttempts => hcConfig.RetryAttempts ?? 2;
|
|
public TimeSpan? Timeout => hcConfig.Timeout ?? TimeSpan.FromSeconds(5);
|
|
public TimeSpan? RetryDelay => hcConfig.RetryDelay ?? TimeSpan.FromSeconds(1);
|
|
public HealthCheckSeverity? Severity => hcConfig.Severity ?? HealthCheckSeverity.Critical;
|
|
|
|
public Task<HealthCheckResult> CheckAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
// Lógica de chequeo
|
|
return Task.FromResult(HealthCheckResult.Healthy("Todo OK"));
|
|
}
|
|
}
|
|
```
|
|
|
|
## Endpoints disponibles
|
|
|
|
La librería expone un controlador con endpoints como:
|
|
|
|
- `GET /health` — Estado general de la aplicación con detalle de todos los healthchecks.
|
|
- `GET /health/{nombre}` — Estado de un healthcheck específico.
|
|
|
|
Ejemplo de llamada con curl:
|
|
|
|
```bash
|
|
curl http://localhost:5000/health
|
|
curl http://localhost:5000/health/Database
|
|
```
|
|
|
|
_Si se envia Acept `*/*` o `text/html`, o se usa un User-Agent compatible, se devolverá un HTML con el estado de los healthchecks y una interfaz interactiva para la consulta y visualización de resultados. También permite ejecutar uno o varios checks al momento_
|
|
|
|
### Ejemplos avanzados
|
|
|
|
```json appsettings.json
|
|
{
|
|
"HealthChecksConfigs": {
|
|
"CacheDuration": "00:30:00",
|
|
"Timeout": "00:02:00",
|
|
"AssembliesToScan": [
|
|
"MCVIngenieros.Backend"
|
|
],
|
|
"MyCheck": {
|
|
"RetryAttempts": 5,
|
|
"Timeout": "00:00:30",
|
|
"RetryDelay": "00:00:10",
|
|
"Severity": "Critical"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
```csharp
|
|
public partial class HealthChecksConfigs : MCVIngenieros.Healthchecks.Options.HealthChecksConfigs
|
|
{
|
|
public const string CustomHealthCheckWithOptions = nameof(CustomHealthCheckWithOptions);
|
|
}
|
|
|
|
---
|
|
|
|
public class CustomHealthCheckWithOptions (IDistributedCache redis, IOptionsMonitor<HealthChecksConfigs> healthchecksConfig) : HealthCheck
|
|
{
|
|
private readonly HealthChecksConfigs hcConfig = healthchecksConfig.Get(HealthChecksConfigs.CustomHealthCheckWithOptions);
|
|
public string Description => hcConfig.Description;
|
|
public int? RetryAttempts => hcConfig.RetryAttempts ?? 2;
|
|
public TimeSpan? Timeout => hcConfig.Timeout ?? TimeSpan.FromSeconds(5);
|
|
public TimeSpan? RetryDelay => hcConfig.RetryDelay ?? TimeSpan.FromSeconds(1);
|
|
public HealthCheckSeverity? Severity => hcConfig.Severity ?? HealthCheckSeverity.Critical;
|
|
|
|
public async Task<HealthCheckResult> CheckAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var result = await redis.GetStringAsync("healthcheck");
|
|
return result != null
|
|
? HealthCheckResult.Healthy("Todo OK", HealthCheckSeverity.Info)
|
|
: HealthCheckResult.Unhealthy(
|
|
"No se encontró el estado",
|
|
HealthCheckSeverity.Critical,
|
|
Data: new Dictionary<string, object?> {
|
|
{ "CacheKey", "healthcheck" },
|
|
{ "RedisValue", result },
|
|
{ "RedisInstance", redis.InstanceName }
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return HealthCheckResult.Unhealthy(
|
|
"Error",
|
|
HealthCheckSeverity.Critical,
|
|
Exception: ex,
|
|
Data: new Dictionary<string, object?> {
|
|
{ "BaseException", ex.GetBaseException() },
|
|
{ "RedisInstance", redis.InstanceName }
|
|
});
|
|
}
|
|
}
|
|
}
|
|
``` |