Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Reporting Service for Microsoft.Extensions.Diagnostics.HealthChecks -> App Metrics
using App.Metrics;
using App.Metrics.Gauge;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace JonasMH.AspNetCore
{
public class HealthMetricsHostedService : IHostedService
{
public static readonly string Context = "Application.Health";
public static GaugeOptions Checks => new GaugeOptions
{
Context = Context,
Name = "Results",
MeasurementUnit = Unit.Items
};
private readonly HealthCheckService _healthCheckService;
private System.Timers.Timer _timer;
private readonly ILogger<HealthMetricsHostedService> _logger;
private readonly IMetrics _metrics;
public HealthMetricsHostedService(
HealthCheckService healthCheckService,
ILogger<HealthMetricsHostedService> logger,
IMetrics metrics)
{
_healthCheckService = healthCheckService;
_logger = logger;
_metrics = metrics;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Health metrics service started");
DoWork(cancellationToken);
_timer = new System.Timers.Timer();
_timer.Elapsed += (sender, e) => DoWork(cancellationToken);
_timer.Interval = TimeSpan.FromSeconds(30).TotalMilliseconds;
_timer.Start();
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Health metrics service stopped");
_timer.Stop();
_timer.Dispose();
return Task.CompletedTask;
}
private Task DoWork(CancellationToken cancellationToken) {
return Task.Run(async () => await SendUpdates(cancellationToken), cancellationToken);
}
private async Task SendUpdates(CancellationToken cancellationToken)
{
_logger.LogInformation("Getting healthchecks");
var result = await _healthCheckService.CheckHealthAsync(cancellationToken);
foreach (var item in result.Entries)
{
var tags = new MetricTags("health_check_name", item.Key);
float healthScore = -1;
switch (item.Value.Status)
{
case HealthStatus.Healthy:
healthScore = 1f;
break;
case HealthStatus.Degraded:
healthScore = 0.5f;
break;
case HealthStatus.Unhealthy:
healthScore = 0f;
break;
default:
_logger.LogWarning($"Healthcheck '${item.Key}' did not have a known service status ${item.Value.Status.ToString()}");
continue;
}
_metrics.Measure.Gauge.SetValue(Checks, tags, healthScore);
}
_timer.Interval = TimeSpan.FromSeconds(30).TotalMilliseconds;
_timer.Start();
}
}
}
[...]
namespace JonasMH.AspNetCore
{
public class Startup
{
[...]
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
[...]
// Add you own health checks or use https://github.com/xabaril/AspNetCore.Diagnostics.HealthChecks as I did here
services
.AddHealthChecks();
//.AddNpgSql(connectionString)
//.AddElasticsearch("http://elasticsearch:9200")
// Register service
services.AddHostedService<HealthMetricsHostedService>();
[...]
}
[...]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment