# 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("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 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 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 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 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 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 { { "CacheKey", "healthcheck" }, { "RedisValue", result }, { "RedisInstance", redis.InstanceName } }); } catch (Exception ex) { return HealthCheckResult.Unhealthy( "Error", HealthCheckSeverity.Critical, Exception: ex, Data: new Dictionary { { "BaseException", ex.GetBaseException() }, { "RedisInstance", redis.InstanceName } }); } } } ```