diff --git a/.env.example b/.env.example index 9921e78..48288c0 100644 --- a/.env.example +++ b/.env.example @@ -8,6 +8,7 @@ Umbraco__CMS__Global__Smtp__Host= Umbraco__CMS__Global__Smtp__Port= Umbraco__CMS__Global__Smtp__Username= Umbraco__CMS__Global__Smtp__Password= +Umbraco__CMS__Global__Smtp__SecureSocketOptions=StartTls Sentry__Dsn= CADDY_ENVIRONMENT=Development HTTP_PORT=80 diff --git a/SgfDevs/HealthChecks/ReadinessHealthCheck.cs b/SgfDevs/HealthChecks/ReadinessHealthCheck.cs new file mode 100644 index 0000000..f0ab1d6 --- /dev/null +++ b/SgfDevs/HealthChecks/ReadinessHealthCheck.cs @@ -0,0 +1,30 @@ +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Infrastructure.Persistence; + +namespace SgfDevs.HealthChecks; + +internal sealed class ReadinessHealthCheck( + IRuntimeState runtimeState, + IUmbracoDatabaseFactory databaseFactory) : IHealthCheck +{ + public Task CheckHealthAsync( + HealthCheckContext context, + CancellationToken cancellationToken = default) + { + if (runtimeState.Level != RuntimeLevel.Run) + { + return Task.FromResult(HealthCheckResult.Unhealthy()); + } + + using var database = databaseFactory.CreateDatabase(); + var result = database.ExecuteScalar("SELECT 1"); + + return Task.FromResult(result == 1 + ? HealthCheckResult.Healthy() + : HealthCheckResult.Unhealthy()); + } +} diff --git a/SgfDevs/Program.cs b/SgfDevs/Program.cs index 9b5a8bd..ab93106 100644 --- a/SgfDevs/Program.cs +++ b/SgfDevs/Program.cs @@ -1,6 +1,8 @@ using System; using System.Data.Common; +using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.Data.Sqlite; using Microsoft.Extensions.DependencyInjection; @@ -10,6 +12,7 @@ using SgfDevs.Dev.EventSync; using SgfDevs.Dev.EventSync.Meetup; using SgfDevs.Dev.EventSync.Sessionize; +using SgfDevs.HealthChecks; using SGFDevs.Dev; using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Persistence.Sqlite; @@ -44,6 +47,8 @@ umbracoBuilder.Build(); +builder.Services.AddHealthChecks() + .AddCheck("ready", tags: ["ready"]); builder.Services.AddHttpClient(); builder.Services.Configure(builder.Configuration.GetSection("SGFDevs")); builder.Services.AddScoped(); @@ -71,6 +76,20 @@ await app.BootUmbracoAsync(); +var healthCheckOptions = new HealthCheckOptions +{ + ResponseWriter = static (_, _) => Task.CompletedTask +}; +app.MapHealthChecks("/health/live", new HealthCheckOptions +{ + Predicate = static _ => false, + ResponseWriter = healthCheckOptions.ResponseWriter +}).AllowAnonymous(); +app.MapHealthChecks("/health/ready", new HealthCheckOptions +{ + Predicate = static check => check.Tags.Contains("ready"), + ResponseWriter = healthCheckOptions.ResponseWriter +}).AllowAnonymous(); app.UseUmbraco() .WithMiddleware(u =>