Round #715
10 May 2026, 15:12· csharp· Meta-Llama-3.3-70B-Instruct· r13-clean-hints
- Complexity
- band 1
- ZP / UO / OBS
- 9 / 5 / 3
- Journey weight
- 1187
- Lightshift ΔL
- +0.00
Prompt
Add health checks using IHealthCheckPublisher with a custom HealthCheckResult that exposes degraded state metrics.
Zero-point index (what the engine surfaced)
ZPI-ZPI-0014 | 2026-05-10T15:12:09Z
Add health checks using IHealthCheckPublisher with a custom HealthCheckResult that exposes degraded state metrics.
ZERO POINT — 9 entries (structural invariants)
● hsl(190.26, 100%, 27%) IHealthCheck [contract]
● hsl(302.56, 100%, 27%) HealthCheckResult [contract]
● hsl(190.42, 100%, 27%) IHealthCheckPublisher [contract]
● hsl(337.38, 100%, 32%) IPublishEndpoint [contract]
● hsl(116.66, 100%, 32%) IConsumer<T> [contract]
● hsl(352.98, 100%, 30%) IBus [contract]
● hsl(257.53, 100%, 32%) ActivitySource [contract]
● hsl(329.94, 100%, 32%) Meter [contract]
● hsl(22.09, 100%, 32%) TracerProvider [contract]
UNOBSERVED — 5 entries (implied truths)
○ hsl(27.69, 100%, 50%) async [feature]
○ hsl(173.54, 100%, 10%) Liveness check [function]
○ hsl(175.38, 100%, 10%) Readiness check [function]
○ hsl(179.08, 100%, 10%) Custom health check [function]
○ hsl(184.62, 100%, 10%) Health check response writer [function]
OBSERVED — 3 entries (explicit in request)
◉ hsl(85.13, 100%, 50%) using [feature]
◉ hsl(98.46, 100%, 50%) with [feature]
◉ hsl(234.87, 100%, 50%) using [feature]
COMPLEXITY │ 17 entries │ spread: 207° │ band: MEDIUM
Baseline response (no ZPI)
**Implementing Health Checks with IHealthCheckPublisher and Custom HealthCheckResult**
To add health checks using `IHealthCheckPublisher` with a custom `HealthCheckResult` that exposes degraded state metrics, you can follow these steps:
### Step 1: Create a Custom HealthCheckResult Class
First, create a custom `HealthCheckResult` class that exposes degraded state metrics. This class will inherit from the `HealthCheckResult` class provided by the `Microsoft.Extensions.Diagnostics.HealthChecks` namespace.
```csharp
using Microsoft.Extensions.Diagnostics.HealthChecks;
public class CustomHealthCheckResult : HealthCheckResult
{
public CustomHealthCheckResult(HealthStatus status, TimeSpan duration, string description = null, Dictionary<string, object> data = null)
: base(status, description, data)
{
Duration = duration;
}
public TimeSpan Duration { get; }
}
```
### Step 2: Create a Custom Health Check
Next, create a custom health check that uses the `IHealthCheckPublisher` interface to publish health check results. This health check will also use the custom `HealthCheckResult` class to expose degraded state metrics.
```csharp
using Microsoft.Extensions.Diagnostics.HealthChecks;
using System.Threading;
using System.Threading.Tasks;
public class CustomHealthCheck : IHealthCheck
{
private readonly IHealthCheckPublisher _publisher;
public CustomHealthCheck(IHealthCheckPublisher publisher)
{
_publisher = publisher;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
// Simulate a health check that takes 1 second to complete
await Task.Delay(1000, cancellationToken);
// Determine the health status based on some condition
var status = HealthStatus.Healthy; // or HealthStatus.Degraded or HealthStatus.Unhealthy
// Create a custom health check result with degraded state metrics
var result = new CustomHealthCheckResult(status, TimeSpan.FromSeconds(1), "Custom health check result");
// Publish the health check result
_publisher.PublishAsync(new HealthReport
{
Status = status,
Duration = TimeSpan.FromSeconds(1),
Description = "Custom health check result",
Entries = new Dictionary<string, HealthCheckEntry>
{
{ "CustomHealthCheck", new HealthCheckEntry(result, TimeSpan.FromSeconds(1)) }
}
}, cancellationToken);
return result;
}
}
```
### Step 3: Register the Custom Health Check
Finally, register the custom health check in the `Startup.cs` file or wherever you configure your services.
```csharp
using Microsoft.Extensions.DependencyInjection;
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks()
.AddCheck<CustomHealthCheck>("CustomHealthCheck");
services.AddSingleton<IHealthCheckPublisher, HealthCheckPublisher>();
}
```
### Example Use Case
To use the custom health check, you can create a controller that exposes a health check endpoint.
```csharp
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Diagnostics.HealthChecks;
[ApiController]
[Route("api/[controller]")]
public class HealthController : ControllerBase
{
private readonly IHealthCheckService _healthCheckService;
public HealthController(IHealthCheckService healthCheckService)
{
_healthCheckService = healthCheckService;
}
[HttpGet]
public async Task<IActionResult> GetHealthAsync()
{
var report = await _healthCheckService.CheckHealthAsync();
return Ok(report);
}
}
```
You can then use a tool like Postman or curl to send a GET request to the `/api/health` endpoint to retrieve the health check report.
**Full Code Example**
Here is the full code example that demonstrates how to add health checks using `IHealthCheckPublisher` with a custom `HealthCheckResult` that exposes degraded state metrics.
```csharp
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks()
.AddCheck<CustomHealthCheck>("CustomHealthCheck");
services.AddSingleton<IHealthCheckPublisher, HealthCheckPublisher>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/api/health");
});
}
}
public class CustomHealthCheck : IHealthCheck
{
private readonly IHealthCheckPublisher _publisher;
public CustomHealthCheck(IHealthCheckPublisher publisher)
{
_publisher = publisher;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
// Simulate a health check that takes 1 second to complete
await Task.Delay(1000, cancellationToken);
// Determine the health status based on some condition
var status = HealthStatus.Healthy; // or HealthStatus.Degraded or HealthStatus.Unhealthy
// Create a custom health check result with degraded state metrics
var result = new CustomHealthCheckResult(status, TimeSpan.FromSeconds(1), "Custom health check result");
// Publish the health check result
_publisher.PublishAsync(new HealthReport
{
Status = status,
Duration = TimeSpan.FromSeconds(1),
Description = "Custom health check result",
Entries = new Dictionary<string, HealthCheckEntry>
{
{ "CustomHealthCheck", new HealthCheckEntry(result, TimeSpan.FromSeconds(1)) }
}
}, cancellationToken);
return result;
}
}
public class CustomHealthCheckResult : HealthCheckResult
{
public CustomHealthCheckResult(HealthStatus status, TimeSpan duration, string description = null, Dictionary<string, object> data = null)
: base(status, description, data)
{
Duration = duration;
}
public TimeSpan Duration { get; }
}
```
This code example demonstrates how to add health checks using `IHealthCheckPublisher` with a custom `HealthCheckResult` that exposes degraded state metrics. The custom health check uses the `IHealthCheckPublisher` interface to publish health check results, and the custom `HealthCheckResult` class exposes degraded state metrics. The example also includes a full code example that demonstrates how to use the custom health check in a real-world application.
Enhanced response (with ZPI)
Here's an example implementation of a custom health check using `IHealthCheckPublisher` and a custom `HealthCheckResult` that exposes degraded state metrics:
```csharp
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
using System.Threading.Tasks;
// Custom HealthCheckResult that exposes degraded state metrics
public class CustomHealthCheckResult : HealthCheckResult
{
public CustomHealthCheckResult(HealthStatus status, TimeSpan duration, string description = null, Exception exception = null, IReadOnlyDictionary<string, object> data = null)
: base(status, description, exception, data)
{
Duration = duration;
}
public TimeSpan Duration { get; }
}
// Custom health check that exposes degraded state metrics
public class CustomHealthCheck : IHealthCheck
{
private readonly IHostApplicationLifetime _lifetime;
public CustomHealthCheck(IHostApplicationLifetime lifetime)
{
_lifetime = lifetime;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
// Simulate a health check that may take some time
await Task.Delay(1000, cancellationToken);
// Check if the application is shutting down
if (_lifetime.ApplicationStopping.IsCancellationRequested)
{
// Return a degraded state if the application is shutting down
return new CustomHealthCheckResult(HealthStatus.Degraded, TimeSpan.FromSeconds(1), "Application is shutting down");
}
// Return a healthy state if the application is running normally
return new CustomHealthCheckResult(HealthStatus.Healthy, TimeSpan.FromSeconds(1));
}
catch (Exception ex)
{
// Return an unhealthy state if an exception occurs
return new CustomHealthCheckResult(HealthStatus.Unhealthy, TimeSpan.FromSeconds(1), "An error occurred", ex);
}
}
}
// Register the custom health check with the IHealthCheckPublisher
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks()
.AddCheck<CustomHealthCheck>("custom_health_check");
services.AddSingleton<IHealthCheckPublisher, HealthCheckPublisher>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
});
}
}
// HealthCheckPublisher that publishes health check results
public class HealthCheckPublisher : IHealthCheckPublisher
{
private readonly ILogger<HealthCheckPublisher> _logger;
public HealthCheckPublisher(ILogger<HealthCheckPublisher> logger)
{
_logger = logger;
}
public void PublishAsync(HealthReport report)
{
foreach (var entry in report.Entries)
{
var result = entry.Value;
if (result.Status == HealthStatus.Degraded)
{
_logger.LogWarning($"Health check {entry.Key} is in a degraded state: {result.Description}");
}
else if (result.Status == HealthStatus.Unhealthy)
{
_logger.LogError($"Health check {entry.Key} is in an unhealthy state: {result.Description}");
}
else
{
_logger.LogInformation($"Health check {entry.Key} is healthy");
}
}
}
}
```
This implementation includes a custom `CustomHealthCheckResult` class that exposes degraded state metrics, a custom `CustomHealthCheck` class that performs a health check and returns a `CustomHealthCheckResult`, and a `HealthCheckPublisher` class that publishes health check results.
The `CustomHealthCheck` class simulates a health check that may take some time and checks if the application is shutting down. If the application is shutting down, it returns a degraded state. If an exception occurs, it returns an unhealthy state.
The `HealthCheckPublisher` class publishes health check results by logging warnings for degraded states, errors for unhealthy states, and information for healthy states.
The custom health check is registered with the `IHealthCheckPublisher` in the `Startup` class, and the `HealthCheckPublisher` is registered as a singleton instance.
You can test the health check by visiting the `/health` endpoint, which will return a JSON response indicating the health status of the application.
Grader chain
Each grader reads the same baseline + enhanced pair and casts an independent verdict. Disagreement is the framework's own signal — not noise to be averaged away.
V1samba/Meta-Llama-3.3-70B-Instruct
BetterV4qwen2.5-coder-3b-instruct
BetterV5openrouter/qwen/qwen3-235b-a22b-2507
BetterV7qwen2.5-coder-7b-instruct
BetterV8openai/gpt-4.1
BetterV9anthropic/claude-opus-4-7
BetterV12openai/gpt-4o
BetterComments
Our grader said what it said. What do you say? Comment as a guest below.
No comments yet. Be the first to say what you make of this round.