diff --git a/doc/wiki/health-checks.md b/doc/wiki/health-checks.md index e8d9f5fca..db2a68d88 100644 --- a/doc/wiki/health-checks.md +++ b/doc/wiki/health-checks.md @@ -40,7 +40,7 @@ app.MapHealthChecks("/health/live", new() app.MapHealthChecks("/health/ready", new() { - Predicate = check => check.Tags.Contains(HealthCheckExtensions.ReadinessTag), + Predicate = check => check.Tags.Contains(HealthCheckExtensions.ElsaTag) && check.Tags.Contains(HealthCheckExtensions.ReadinessTag), ResultStatusCodes = { [HealthStatus.Degraded] = StatusCodes.Status503ServiceUnavailable, diff --git a/src/apps/Elsa.Server.Web/Program.cs b/src/apps/Elsa.Server.Web/Program.cs index 0623e9103..e61770819 100644 --- a/src/apps/Elsa.Server.Web/Program.cs +++ b/src/apps/Elsa.Server.Web/Program.cs @@ -177,7 +177,7 @@ app.MapHealthChecks("/health/live", new() }); app.MapHealthChecks("/health/ready", new() { - Predicate = check => check.Tags.Contains(HealthCheckExtensions.ReadinessTag), + Predicate = check => check.Tags.Contains(HealthCheckExtensions.ElsaTag) && check.Tags.Contains(HealthCheckExtensions.ReadinessTag), ResultStatusCodes = { [HealthStatus.Degraded] = StatusCodes.Status503ServiceUnavailable, @@ -186,12 +186,7 @@ app.MapHealthChecks("/health/ready", new() }); app.MapHealthChecks("/", new() { - Predicate = _ => false, - ResultStatusCodes = - { - [HealthStatus.Degraded] = StatusCodes.Status503ServiceUnavailable, - [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable - } + Predicate = _ => false }); // Routing used for SignalR. diff --git a/src/modules/Elsa.Workflows.Runtime/Extensions/HealthCheckExtensions.cs b/src/modules/Elsa.Workflows.Runtime/Extensions/HealthCheckExtensions.cs index 8d636d417..8adcafb8f 100644 --- a/src/modules/Elsa.Workflows.Runtime/Extensions/HealthCheckExtensions.cs +++ b/src/modules/Elsa.Workflows.Runtime/Extensions/HealthCheckExtensions.cs @@ -10,12 +10,17 @@ namespace Elsa.Extensions; /// public static class HealthCheckExtensions { + /// + /// Tag applied to Elsa health checks. + /// + public const string ElsaTag = "elsa"; + /// /// Tag applied to Elsa readiness checks. /// public const string ReadinessTag = "readiness"; - private static readonly string[] ReadinessTags = ["elsa", ReadinessTag]; + private static readonly string[] ReadinessTags = [ElsaTag, ReadinessTag]; /// /// Adds conservative Elsa-specific readiness probes for the workflow runtime and its core stores. diff --git a/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaDistributedLockHealthCheck.cs b/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaDistributedLockHealthCheck.cs index 3d1a4b1a2..5d5b32655 100644 --- a/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaDistributedLockHealthCheck.cs +++ b/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaDistributedLockHealthCheck.cs @@ -30,7 +30,7 @@ public class ElsaDistributedLockHealthCheck( }); } - var lockName = $"elsa-health-check-{Environment.MachineName}-{Guid.NewGuid():N}"; + var lockName = $"elsa-health-check-{Guid.NewGuid():N}"; await using var handle = await distributedLockProvider.TryAcquireLockAsync(lockName, options.Value.DistributedLockAcquisitionTimeout, cancellationToken); if (handle == null) { diff --git a/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaWorkflowPersistenceHealthCheck.cs b/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaWorkflowPersistenceHealthCheck.cs index 3c6dca7fb..529f54547 100644 --- a/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaWorkflowPersistenceHealthCheck.cs +++ b/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaWorkflowPersistenceHealthCheck.cs @@ -20,10 +20,22 @@ public class ElsaWorkflowPersistenceHealthCheck(IServiceProvider serviceProvider { var probeResults = new List { - await ProbeAsync("workflow-definitions", serviceProvider.GetService(), async (store, ct) => await store.FindAsync(new WorkflowDefinitionFilter { Id = ProbeId }, ct)), - await ProbeAsync("workflow-instances", serviceProvider.GetService(), async (store, ct) => await store.CountAsync(new WorkflowInstanceFilter { Id = ProbeId }, ct)), - await ProbeAsync("triggers", serviceProvider.GetService(), async (store, ct) => await store.FindAsync(new TriggerFilter { Id = ProbeId }, ct)), - await ProbeAsync("bookmark-queue", serviceProvider.GetService(), async (store, ct) => await store.FindAsync(new BookmarkQueueFilter { Id = ProbeId }, ct)) + await ProbeAsync("workflow-definitions", serviceProvider.GetService(), async (store, ct) => + { + await store.FindAsync(new WorkflowDefinitionFilter { Id = ProbeId }, ct); + }), + await ProbeAsync("workflow-instances", serviceProvider.GetService(), async (store, ct) => + { + await store.CountAsync(new WorkflowInstanceFilter { Id = ProbeId }, ct); + }), + await ProbeAsync("triggers", serviceProvider.GetService(), async (store, ct) => + { + await store.FindAsync(new TriggerFilter { Id = ProbeId }, ct); + }), + await ProbeAsync("bookmark-queue", serviceProvider.GetService(), async (store, ct) => + { + await store.FindAsync(new BookmarkQueueFilter { Id = ProbeId }, ct); + }) }; var attemptedProbes = probeResults.Where(x => !x.Skipped).Select(x => x.StoreName).ToList(); diff --git a/test/unit/Elsa.Workflows.Runtime.UnitTests/HealthChecks/ElsaDistributedLockHealthCheckTests.cs b/test/unit/Elsa.Workflows.Runtime.UnitTests/HealthChecks/ElsaDistributedLockHealthCheckTests.cs index ee7400b6a..d4e8e888a 100644 --- a/test/unit/Elsa.Workflows.Runtime.UnitTests/HealthChecks/ElsaDistributedLockHealthCheckTests.cs +++ b/test/unit/Elsa.Workflows.Runtime.UnitTests/HealthChecks/ElsaDistributedLockHealthCheckTests.cs @@ -50,6 +50,7 @@ public class ElsaDistributedLockHealthCheckTests await sut.CheckHealthAsync(new HealthCheckContext()); Assert.Equal(2, lockNames.Count); + Assert.All(lockNames, x => Assert.DoesNotContain(Environment.MachineName, x, StringComparison.Ordinal)); Assert.NotEqual(lockNames[0], lockNames[1]); }