Skip to content

Commit

Permalink
Add IHeathCheck implementation to Asp.Net Core hosting
Browse files Browse the repository at this point in the history
The healthcheck just checks if dotvvm pages can be compiled.
  • Loading branch information
exyi committed Dec 10, 2021
1 parent 892aaf2 commit cb021f2
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 1 deletion.
Expand Up @@ -49,5 +49,7 @@
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="2.2.0" />
</ItemGroup>
</Project>
58 changes: 58 additions & 0 deletions src/Framework/Hosting.AspNetCore/Hosting/DotvvmHealthCheck.cs
@@ -0,0 +1,58 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using DotVVM.Framework.Compilation;
using DotVVM.Framework.Utils;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace DotVVM.Framework.Hosting
{
public class DotvvmHealthCheck : IHealthCheck
{
private readonly IDotvvmViewCompilationService compilationService;

public DotvvmHealthCheck(IDotvvmViewCompilationService compilationService)
{
this.compilationService = compilationService;
}

public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
var c = compilationService.GetRoutes().AddRange(compilationService.GetControls().AddRange(compilationService.GetMasterPages()));

if (!c.Any(p => p.Status == CompilationState.CompilationFailed))
{
return Task.FromResult(new HealthCheckResult(HealthStatus.Healthy));
}

// if nothing compiles, we say unhealthy. If at least something works, we say only degraded
var state =
c.Any(p => p.Status is CompilationState.CompletedSuccessfully or CompilationState.CompilationWarning)
? HealthStatus.Degraded
: HealthStatus.Unhealthy;

var views = c.Where(p => p.Status == CompilationState.CompilationFailed)
.Select(c => c.VirtualPath);
return Task.FromResult(new HealthCheckResult(state, $"Dothtml pages can not be compiled: {views.Take(10).StringJoin(", ")}. See /_dotvvm/diagnostics/compilation for more information."));
}

public static void RegisterHealthCheck(IServiceCollection services)
{
services.ConfigureWithServices<HealthCheckServiceOptions>((options, s) => {
if (options.Registrations.Any(c => c.Name == "DotVVM"))
return;
options.Registrations.Add(
new HealthCheckRegistration(
"DotVVM",
ActivatorUtilities.CreateInstance<DotvvmHealthCheck>(s),
null,
new [] { "dotvvm" }
)
);
});
}
}
}
Expand Up @@ -88,6 +88,8 @@ private static void AddDotVVMServices(IServiceCollection services)
services.AddTransient<IDotvvmWarningSink, AspNetCoreLoggerWarningSink>();

services.TryAddSingleton<IStartupTracer>(startupTracer);

DotvvmHealthCheck.RegisterHealthCheck(services);
}
}
}
7 changes: 6 additions & 1 deletion src/Samples/AspNetCoreLatest/Startup.cs
Expand Up @@ -50,6 +50,8 @@ public void ConfigureServices(IServiceCollection services)
services.AddAuthentication("Scheme3")
.AddCookie("Scheme3");

services.AddHealthChecks();

services.AddLocalization(o => o.ResourcesPath = "Resources");

services.AddDotVVM<DotvvmServiceConfigurator>();
Expand Down Expand Up @@ -78,11 +80,14 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF
}
});


#if AssertConfiguration
// this compilation symbol is set by CI server
config.AssertConfigurationIsValid();
#endif
app.UseRouting();
app.UseEndpoints(endpoints => {
endpoints.MapHealthChecks("/health");
});
app.UseStaticFiles();

app.UseEndpoints(endpoints => {
Expand Down

0 comments on commit cb021f2

Please sign in to comment.