From 7c8282226f5dd604ae4c3723a1dff5daa0919969 Mon Sep 17 00:00:00 2001 From: Piotr Kowalski Date: Mon, 6 Sep 2021 20:12:29 +0200 Subject: [PATCH 1/3] Add basic database health check --- .../DatabaseHealthCheck.cs | 33 +++++++++++++++++++ ...nkudesu.Services.Links.HealthChecks.csproj | 17 ++++++++++ .../Rinkudesu.Services.Links.sln | 6 ++++ .../Rinkudesu.Services.Links.csproj | 1 + .../Rinkudesu.Services.Links/Startup.cs | 8 ++++- 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/DatabaseHealthCheck.cs create mode 100644 Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/Rinkudesu.Services.Links.HealthChecks.csproj diff --git a/Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/DatabaseHealthCheck.cs b/Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/DatabaseHealthCheck.cs new file mode 100644 index 0000000..e84cad4 --- /dev/null +++ b/Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/DatabaseHealthCheck.cs @@ -0,0 +1,33 @@ +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Rinkudesu.Services.Links.Data; + +namespace Rinkudesu.Services.Links.HealthChecks +{ + public class DatabaseHealthCheck : IHealthCheck + { + private readonly LinkDbContext _context; + + public DatabaseHealthCheck(LinkDbContext context) + { + this._context = context; + } + + public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = new CancellationToken()) + { + if (!await _context.Database.CanConnectAsync(cancellationToken)) + { + return HealthCheckResult.Unhealthy("Unable to connect to the database"); + } + var migrations = await _context.Database.GetPendingMigrationsAsync(cancellationToken); + if (migrations?.Any() ?? false) + { + return HealthCheckResult.Degraded("Database migrations are pending, functionality may be limited"); + } + return HealthCheckResult.Healthy(); + } + } +} \ No newline at end of file diff --git a/Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/Rinkudesu.Services.Links.HealthChecks.csproj b/Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/Rinkudesu.Services.Links.HealthChecks.csproj new file mode 100644 index 0000000..7de0e99 --- /dev/null +++ b/Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/Rinkudesu.Services.Links.HealthChecks.csproj @@ -0,0 +1,17 @@ + + + + netcoreapp3.1 + enable + + + + + + + + + + + + diff --git a/Rinkudesu.Services.Links/Rinkudesu.Services.Links.sln b/Rinkudesu.Services.Links/Rinkudesu.Services.Links.sln index b614ba8..fad321c 100644 --- a/Rinkudesu.Services.Links/Rinkudesu.Services.Links.sln +++ b/Rinkudesu.Services.Links/Rinkudesu.Services.Links.sln @@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rinkudesu.Services.Links.Mo EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rinkudesu.Services.Links.Data", "Rinkudesu.Services.Links.Data\Rinkudesu.Services.Links.Data.csproj", "{26A791B3-4BAA-4F25-8AE7-AAF90BEC4594}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rinkudesu.Services.Links.HealthChecks", "Rinkudesu.Services.Links.HealthChecks\Rinkudesu.Services.Links.HealthChecks.csproj", "{E43C4BCB-2BB1-4602-A5BC-AB7216F679E2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -42,5 +44,9 @@ Global {26A791B3-4BAA-4F25-8AE7-AAF90BEC4594}.Debug|Any CPU.Build.0 = Debug|Any CPU {26A791B3-4BAA-4F25-8AE7-AAF90BEC4594}.Release|Any CPU.ActiveCfg = Release|Any CPU {26A791B3-4BAA-4F25-8AE7-AAF90BEC4594}.Release|Any CPU.Build.0 = Release|Any CPU + {E43C4BCB-2BB1-4602-A5BC-AB7216F679E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E43C4BCB-2BB1-4602-A5BC-AB7216F679E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E43C4BCB-2BB1-4602-A5BC-AB7216F679E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E43C4BCB-2BB1-4602-A5BC-AB7216F679E2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Rinkudesu.Services.Links.csproj b/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Rinkudesu.Services.Links.csproj index b1e7d8d..a7ec41f 100644 --- a/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Rinkudesu.Services.Links.csproj +++ b/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Rinkudesu.Services.Links.csproj @@ -43,6 +43,7 @@ + diff --git a/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Startup.cs b/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Startup.cs index 812ba21..56cdae0 100644 --- a/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Startup.cs +++ b/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Startup.cs @@ -14,6 +14,7 @@ using Microsoft.OpenApi.Models; using Rinkudesu.Services.Links.Data; using Rinkudesu.Services.Links.DataTransferObjects; +using Rinkudesu.Services.Links.HealthChecks; using Rinkudesu.Services.Links.Repositories; using Rinkudesu.Services.Links.Utilities; using Serilog; @@ -68,6 +69,8 @@ public void ConfigureServices(IServiceCollection services) var xmlPath = AppContext.BaseDirectory; c.IncludeXmlComments(Path.Combine(xmlPath, xmlName)); }); + + services.AddHealthChecks().AddCheck("Database health check"); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -91,7 +94,10 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseAuthorization(); - app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); + app.UseEndpoints(endpoints => { + endpoints.MapControllers(); + endpoints.MapHealthChecks("/health"); + }); if (InputArguments.Current.ApplyMigrations) { From b7f7224eb4bb521722068add61a3cfedd0cdfc90 Mon Sep 17 00:00:00 2001 From: Piotr Kowalski Date: Mon, 6 Sep 2021 20:13:44 +0200 Subject: [PATCH 2/3] Exclude `DatabaseHealthCheck` from code coverage tests --- .../DatabaseHealthCheck.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/DatabaseHealthCheck.cs b/Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/DatabaseHealthCheck.cs index e84cad4..96e8c42 100644 --- a/Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/DatabaseHealthCheck.cs +++ b/Rinkudesu.Services.Links/Rinkudesu.Services.Links.HealthChecks/DatabaseHealthCheck.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; @@ -7,6 +8,7 @@ namespace Rinkudesu.Services.Links.HealthChecks { + [ExcludeFromCodeCoverage] public class DatabaseHealthCheck : IHealthCheck { private readonly LinkDbContext _context; From 2629f6b6dbfe348f91788d5f4621de1330200331 Mon Sep 17 00:00:00 2001 From: Piotr Kowalski Date: Mon, 6 Sep 2021 20:28:04 +0200 Subject: [PATCH 3/3] Add healthchecks to Dockerfile --- Rinkudesu.Services.Links/Rinkudesu.Services.Links/Dockerfile | 1 + .../Rinkudesu.Services.Links/Rinkudesu.Services.Links.csproj | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Dockerfile b/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Dockerfile index e796f44..dbcf0c5 100644 --- a/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Dockerfile +++ b/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Dockerfile @@ -12,4 +12,5 @@ FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS final EXPOSE 80 WORKDIR /app COPY --from=publish /app/publish . +HEALTHCHECK --interval=20s --start-period=5s --retries=3 CMD curl --fail http://localhost/health || exit 1 ENTRYPOINT ["dotnet", "Rinkudesu.Services.Links.dll"] diff --git a/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Rinkudesu.Services.Links.csproj b/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Rinkudesu.Services.Links.csproj index a7ec41f..0a11d5c 100644 --- a/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Rinkudesu.Services.Links.csproj +++ b/Rinkudesu.Services.Links/Rinkudesu.Services.Links/Rinkudesu.Services.Links.csproj @@ -5,8 +5,8 @@ Linux enable true - 0.0.0 - 0.0.0 + 0.2.0 + 0.2.0 Rinkudesu Rinkudesu