Skip to content

Commit

Permalink
Merge Add health check endpoint #45
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickackermann authored Aug 19, 2022
2 parents 3f50db7 + affa455 commit e8f904f
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/DbUpdateService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ public class DbUpdateService : BackgroundService
private readonly ILogger<DbUpdateService> logger;
private readonly IConfiguration configuration;
private readonly TimeOnly preferredTime;
private readonly DbUpdateServiceHealthCheck healthCheck;

public DbUpdateService(IServiceScopeFactory scopeFactory, ILogger<DbUpdateService> logger, IConfiguration configuration)
public DbUpdateService(IServiceScopeFactory scopeFactory, ILogger<DbUpdateService> logger, IConfiguration configuration, DbUpdateServiceHealthCheck healthCheck)
{
this.scopeFactory = scopeFactory;
this.logger = logger;
this.configuration = configuration;
this.healthCheck = healthCheck;

preferredTime = new TimeOnly(1, 0);
}
Expand Down Expand Up @@ -62,10 +64,13 @@ private async Task UpdateModelRepoDatabase()
logger.LogError("Updating ModelRepoDatabase aborted. Crawler could not parse any repository.");
}
}

healthCheck.LastDbUpdateSuccessful = true;
}
catch (DbUpdateException ex)
{
logger.LogError(ex, "Unable to update ModelRepoDatabase");
healthCheck.LastDbUpdateSuccessful = false;
}
}

Expand Down
30 changes: 30 additions & 0 deletions src/DbUpdateServiceHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace ModelRepoBrowser;

/// <summary>
/// HealthCheck for <see cref="DbUpdateService"/>.
/// Reports a degraded health if the last model repository database update exited with an exception.
/// </summary>
public class DbUpdateServiceHealthCheck : IHealthCheck
{
private volatile bool lastDbUpdateSuccessful;

public bool LastDbUpdateSuccessful
{
get { return lastDbUpdateSuccessful; }
set { lastDbUpdateSuccessful = value; }
}

public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
if (lastDbUpdateSuccessful)
{
return Task.FromResult(HealthCheckResult.Healthy());
}
else
{
return Task.FromResult(HealthCheckResult.Degraded());
}
}
}
8 changes: 8 additions & 0 deletions src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@

builder.Services.AddTransient<IRepositoryCrawler, RepositoryCrawler>().AddHttpClient();
builder.Services.AddHostedService<DbUpdateService>();
builder.Services.AddSingleton<DbUpdateServiceHealthCheck>();

builder.Services.AddHealthChecks()
.AddCheck<RepoBrowserDbHealthCheck>("RepoBrowserDbHealthCheck")
.AddCheck<DbUpdateServiceHealthCheck>("DbUpdateServiceHealthCheck");

var app = builder.Build();

if (!app.Environment.IsDevelopment())
Expand All @@ -29,6 +35,8 @@
app.UseStaticFiles();
app.UseRouting();

app.MapHealthChecks("/health");

app.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
Expand Down
36 changes: 36 additions & 0 deletions src/RepoBrowserDbHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace ModelRepoBrowser;

/// <summary>
/// Health check for model repository database. Checks whether the database is accessible and contains data.
/// </summary>
public class RepoBrowserDbHealthCheck : IHealthCheck
{
private readonly RepoBrowserContext repoBrowserContext;

public RepoBrowserDbHealthCheck(RepoBrowserContext context)
{
repoBrowserContext = context;
}

public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken))
{
var canConnectToDb = await repoBrowserContext.Database.CanConnectAsync(cancellationToken).ConfigureAwait(false);
var dbContainsData = false;

if (canConnectToDb)
{
dbContainsData = repoBrowserContext.Models.Any() && repoBrowserContext.Repositories.Any() && repoBrowserContext.Catalogs.Any();
}

if (canConnectToDb && dbContainsData)
{
return HealthCheckResult.Healthy();
}
else
{
return HealthCheckResult.Unhealthy();
}
}
}

0 comments on commit e8f904f

Please sign in to comment.