Skip to main content
ClaudeWave
Skill64 estrellas del repoactualizado 22d ago

dotnet-health-checks

Configures health checks for database, external services, and custom application checks. Provides liveness and readiness endpoints for container orchestration.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/ronnythedev/dotnet-clean-architecture-skills /tmp/dotnet-health-checks && cp -r /tmp/dotnet-health-checks/skills/17-dotnet-health-checks ~/.claude/skills/dotnet-health-checks
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# Health Checks Configuration

## Overview

Health checks monitor application dependencies:

- **Liveness** - Is the app running?
- **Readiness** - Is the app ready to serve traffic?
- **Database checks** - PostgreSQL connectivity
- **External service checks** - APIs, caches, queues
- **Custom checks** - Business logic validation

## Quick Reference

| Check Type | Purpose |
|------------|---------|
| `AddNpgSql` | PostgreSQL database |
| `AddUrlGroup` | External HTTP endpoints |
| `AddRedis` | Redis cache |
| `AddRabbitMQ` | RabbitMQ message broker |
| Custom | Application-specific checks |

---

## Template: Health Check Registration

```csharp
// src/{name}.infrastructure/HealthChecks/HealthCheckExtensions.cs
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace {name}.infrastructure.healthchecks;

public static class HealthCheckExtensions
{
    public static IServiceCollection AddHealthChecks(
        this IServiceCollection services,
        IConfiguration configuration)
    {
        services.AddHealthChecks()
            // ═══════════════════════════════════════════════════════════════
            // DATABASE
            // ═══════════════════════════════════════════════════════════════
            .AddNpgSql(
                configuration.GetConnectionString("Database")!,
                name: "postgresql",
                failureStatus: HealthStatus.Unhealthy,
                tags: new[] { "db", "sql", "postgresql", "ready" })

            // ═══════════════════════════════════════════════════════════════
            // EXTERNAL SERVICES
            // ═══════════════════════════════════════════════════════════════
            .AddUrlGroup(
                new Uri(configuration["AuthService:BaseUrl"]!),
                name: "auth-service",
                failureStatus: HealthStatus.Degraded,
                tags: new[] { "external", "auth", "ready" })

            // ═══════════════════════════════════════════════════════════════
            // REDIS (if used)
            // ═══════════════════════════════════════════════════════════════
            // .AddRedis(
            //     configuration.GetConnectionString("Redis")!,
            //     name: "redis",
            //     tags: new[] { "cache", "redis", "ready" })

            // ═══════════════════════════════════════════════════════════════
            // CUSTOM CHECKS
            // ═══════════════════════════════════════════════════════════════
            .AddCheck<DatabaseMigrationHealthCheck>(
                "database-migrations",
                tags: new[] { "db", "migrations", "ready" });

        return services;
    }
}
```

---

## Template: Custom Health Check

```csharp
// src/{name}.infrastructure/HealthChecks/DatabaseMigrationHealthCheck.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace {name}.infrastructure.healthchecks;

internal sealed class DatabaseMigrationHealthCheck : IHealthCheck
{
    private readonly ApplicationDbContext _dbContext;

    public DatabaseMigrationHealthCheck(ApplicationDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        try
        {
            var pendingMigrations = await _dbContext.Database
                .GetPendingMigrationsAsync(cancellationToken);

            var pending = pendingMigrations.ToList();

            if (pending.Any())
            {
                return HealthCheckResult.Degraded(
                    $"Pending migrations: {string.Join(", ", pending)}",
                    data: new Dictionary<string, object>
                    {
                        { "pending_count", pending.Count },
                        { "migrations", pending }
                    });
            }

            return HealthCheckResult.Healthy("All migrations applied");
        }
        catch (Exception ex)
        {
            return HealthCheckResult.Unhealthy(
                "Failed to check migrations",
                exception: ex);
        }
    }
}
```

---

## Template: Program.cs Configuration

```csharp
// src/{name}.api/Program.cs
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;

var app = builder.Build();

// ═══════════════════════════════════════════════════════════════
// LIVENESS: Is the app running?
// ═══════════════════════════════════════════════════════════════
app.MapHealthChecks("/health/live", new HealthCheckOptions
{
    Predicate = _ => false,  // No checks, just confirms app is running
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});

// ═══════════════════════════════════════════════════════════════
// READINESS: Is the app ready to serve traffic?
// ═══════════════════════════════════════════════════════════════
app.MapHealthChecks("/health/ready", new HealthCheckOptions
{
    Predicate = check => check.Tags.Contains("ready"),
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});

// ═══════════════════════════════════════════════════════════════
// FULL: All health checks
// ═══════════════════════════════════════════════════════════════
app.MapHealthChecks("/health", new HealthCheckOptions
{
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
```

---

## Kubernetes Configuration

```yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
        - name: api
          livenessProbe:
            httpGet:
              path: /health/live
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 30
          readinessProbe:
            httpGet:
              path: /health/ready
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
```

---

## Related Skills

- `dotnet-clean-architecture` - Infrastructure lay
dotnet-clean-architectureSkill

Scaffolds a complete .NET solution following Clean Architecture principles with proper layer separation (API, Application, Domain, Infrastructure). Creates project structure, dependency injection setup, and cross-cutting concerns configuration.

dotnet-cqrs-command-generatorSkill

Generates CQRS Commands with Handlers, Validators, and Request DTOs following Clean Architecture patterns. Commands represent actions that modify state and return Result types for proper error handling.

dotnet-cqrs-query-generatorSkill

Generates CQRS Queries with Handlers and Response DTOs for read operations. Uses Dapper for optimized read queries, bypassing the domain model for better performance.

dotnet-domain-entity-generatorSkill

Generates Domain Entities following DDD principles with factory methods, private setters, domain events, and proper encapsulation. Supports aggregate roots, child entities, and value objects.

dotnet-repository-patternSkill

Generates Repository interfaces and implementations following the Repository pattern. Provides data access abstraction for aggregate roots with EF Core implementations.

dotnet-ef-core-configurationSkill

Generates Entity Framework Core configurations using Fluent API. Maps domain entities to database tables with proper relationships, constraints, and conventions.

dotnet-legacy-api-controllersSkill

Generates RESTful API Controllers with proper routing, versioning, authorization, and MediatR integration. Follows REST conventions and Clean Architecture patterns.

dotnet-minimal-api-endpointsSkill

Generates Minimal API endpoints following Microsoft's recommended approach. Creates fast, testable HTTP APIs with minimal code using MapGet/MapPost/MapPut/MapDelete. Preferred over controller-based APIs for new projects.