Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work on probes and health checks. #4042

Merged
merged 1 commit into from
Jun 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks;
internal sealed class ApplicationLifecycleHealthCheck : IHealthCheck
{
private static readonly Task<HealthCheckResult> _healthy = Task.FromResult(HealthCheckResult.Healthy());
private static readonly Task<HealthCheckResult> _unhealthy = Task.FromResult(HealthCheckResult.Unhealthy());
private static readonly Task<HealthCheckResult> _unhealthyNotStarted = Task.FromResult(HealthCheckResult.Unhealthy("Not Started"));
private static readonly Task<HealthCheckResult> _unhealthyStopping = Task.FromResult(HealthCheckResult.Unhealthy("Stopping"));
private static readonly Task<HealthCheckResult> _unhealthyStopped = Task.FromResult(HealthCheckResult.Unhealthy("Stopped"));
private readonly IHostApplicationLifetime _appLifetime;

/// <summary>
Expand Down Expand Up @@ -42,9 +44,23 @@ public ApplicationLifecycleHealthCheck(IHostApplicationLifetime appLifetime)
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
bool isStarted = _appLifetime.ApplicationStarted.IsCancellationRequested;
if (!isStarted)
{
return _unhealthyNotStarted;
}

bool isStopping = _appLifetime.ApplicationStopping.IsCancellationRequested;
if (isStopping)
{
return _unhealthyStopping;
}

bool isStopped = _appLifetime.ApplicationStopped.IsCancellationRequested;
bool isHealthy = isStarted && !isStopping && !isStopped;
return isHealthy ? _healthy : _unhealthy;
if (isStopped)
{
return _unhealthyStopped;
}

return _healthy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Shared.Diagnostics;

Expand All @@ -12,28 +11,17 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks;
/// <summary>
/// Controls various health check features.
/// </summary>
public static partial class CoreHealthChecksExtensions
public static partial class CommonHealthChecksExtensions
{
/// <summary>
/// Registers a health check provider that's tied to the application's lifecycle.
/// </summary>
/// <param name="builder">The builder to add the provider to.</param>
/// <returns>The value of <paramref name="builder"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="builder" /> is <see langword="null" />.</exception>
public static IHealthChecksBuilder AddApplicationLifecycleHealthCheck(this IHealthChecksBuilder builder)
=> Throw.IfNull(builder)
.AddCheck<ApplicationLifecycleHealthCheck>("ApplicationLifecycleHealthCheck");

/// <summary>
/// Registers a health check provider that's tied to the application's lifecycle.
/// </summary>
/// <param name="builder">The builder to add the provider to.</param>
/// <param name="tags">A list of tags that can be used to filter health checks.</param>
/// <returns>The value of <paramref name="builder"/>.</returns>
[Experimental]
public static IHealthChecksBuilder AddApplicationLifecycleHealthCheck(this IHealthChecksBuilder builder, params string[] tags)
=> Throw.IfNull(builder)
.AddCheck<ApplicationLifecycleHealthCheck>("ApplicationLifecycleHealthCheck", tags: Throw.IfNull(tags));
.AddCheck<ApplicationLifecycleHealthCheck>("ApplicationLifecycle", tags: Throw.IfNull(tags));

/// <summary>
/// Registers a health check provider that's tied to the application's lifecycle.
Expand All @@ -44,5 +32,5 @@ public static IHealthChecksBuilder AddApplicationLifecycleHealthCheck(this IHeal
/// <exception cref="ArgumentNullException">If <paramref name="builder" /> or <paramref name="tags"/> are <see langword="null" />.</exception>
public static IHealthChecksBuilder AddApplicationLifecycleHealthCheck(this IHealthChecksBuilder builder, IEnumerable<string> tags)
=> Throw.IfNull(builder)
.AddCheck<ApplicationLifecycleHealthCheck>("ApplicationLifecycleHealthCheck", tags: Throw.IfNull(tags));
.AddCheck<ApplicationLifecycleHealthCheck>("ApplicationLifecycle", tags: Throw.IfNull(tags));
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,8 @@

namespace Microsoft.Extensions.Diagnostics.HealthChecks;

public static partial class CoreHealthChecksExtensions
public static partial class CommonHealthChecksExtensions
{
/// <summary>
/// Registers a health check provider that enables manual control of the application's health.
/// </summary>
/// <param name="builder">The builder to add the provider to.</param>
/// <returns>The value of <paramref name="builder"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="builder" /> is <see langword="null" />.</exception>
public static IHealthChecksBuilder AddManualHealthCheck(this IHealthChecksBuilder builder)
=> Throw.IfNull(builder)
.AddManualHealthCheckDependencies()
.AddCheck<ManualHealthCheckService>("ManualHealthCheck");

/// <summary>
/// Registers a health check provider that enables manual control of the application's health.
/// </summary>
Expand All @@ -31,7 +20,7 @@ public static IHealthChecksBuilder AddManualHealthCheck(this IHealthChecksBuilde
public static IHealthChecksBuilder AddManualHealthCheck(this IHealthChecksBuilder builder, params string[] tags)
=> Throw.IfNull(builder)
.AddManualHealthCheckDependencies()
.AddCheck<ManualHealthCheckService>("ManualHealthCheck", tags: Throw.IfNull(tags));
.AddCheck<ManualHealthCheckService>("Manual", tags: Throw.IfNull(tags));

/// <summary>
/// Registers a health check provider that enables manual control of the application's health.
Expand All @@ -43,7 +32,7 @@ public static IHealthChecksBuilder AddManualHealthCheck(this IHealthChecksBuilde
public static IHealthChecksBuilder AddManualHealthCheck(this IHealthChecksBuilder builder, IEnumerable<string> tags)
=> Throw.IfNull(builder)
.AddManualHealthCheckDependencies()
.AddCheck<ManualHealthCheckService>("ManualHealthCheck", tags: Throw.IfNull(tags));
.AddCheck<ManualHealthCheckService>("Manual", tags: Throw.IfNull(tags));

/// <summary>
/// Sets the manual health check to the healthy state.
Expand All @@ -63,8 +52,8 @@ public static void ReportUnhealthy(this IManualHealthCheck manualHealthCheck, st
=> Throw.IfNull(manualHealthCheck).Result = HealthCheckResult.Unhealthy(Throw.IfNullOrWhitespace(reason));

private static IHealthChecksBuilder AddManualHealthCheckDependencies(this IHealthChecksBuilder builder)
=> builder
.Services.AddSingleton<IManualHealthCheckTracker, ManualHealthCheckTracker>()
=> builder.Services
.AddSingleton<ManualHealthCheckTracker>()
.AddTransient(typeof(IManualHealthCheck<>), typeof(ManualHealthCheck<>))
.AddHealthChecks();
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace Microsoft.Extensions.Diagnostics.HealthChecks;

public static partial class CoreHealthChecksExtensions
public static partial class CommonHealthChecksExtensions
{
/// <summary>
/// Registers a health check publisher which emits telemetry representing the application's health.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ public HealthCheckResult Result
}
}

private readonly IManualHealthCheckTracker _tracker;
private readonly ManualHealthCheckTracker _tracker;

[SuppressMessage("Major Code Smell", "S3366:\"this\" should not be exposed from constructors", Justification = "It's OK, just registering into a list")]
public ManualHealthCheck(IManualHealthCheckTracker tracker)
public ManualHealthCheck(ManualHealthCheckTracker tracker)
{
Result = HealthCheckResult.Unhealthy("Initial state");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks;
/// </remarks>
internal sealed class ManualHealthCheckService : IHealthCheck
{
private readonly IManualHealthCheckTracker _tracker;
private readonly ManualHealthCheckTracker _tracker;

public ManualHealthCheckService(IManualHealthCheckTracker tracker)
public ManualHealthCheckService(ManualHealthCheckTracker tracker)
{
_tracker = tracker;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@

namespace Microsoft.Extensions.Diagnostics.HealthChecks;

internal sealed class ManualHealthCheckTracker : IManualHealthCheckTracker
internal sealed class ManualHealthCheckTracker
{
private static readonly HealthCheckResult _healthy = HealthCheckResult.Healthy();

private readonly ConcurrentDictionary<IManualHealthCheck, bool> _checks = new();

/// <inheritdoc />
public void Register(IManualHealthCheck check)
{
_ = _checks.AddOrUpdate(check, true, (_, _) => true);
Expand All @@ -25,7 +24,6 @@ public void Unregister(IManualHealthCheck checkToRemove)
_ = _checks.TryRemove(checkToRemove, out _);
}

/// <inheritdoc />
public HealthCheckResult GetHealthCheckResult()
{
// Construct string showing all reasons for unhealthy manual health checks
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
"Name": "Microsoft.Extensions.Diagnostics.HealthChecks.Common, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
"Types": [
{
"Type": "static class Microsoft.Extensions.Diagnostics.HealthChecks.CommonHealthChecksExtensions",
"Stage": "Stable",
"Methods": [
{
"Member": "static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder Microsoft.Extensions.Diagnostics.HealthChecks.CommonHealthChecksExtensions.AddApplicationLifecycleHealthCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, params string[] tags);",
"Stage": "Stable"
},
{
"Member": "static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder Microsoft.Extensions.Diagnostics.HealthChecks.CommonHealthChecksExtensions.AddApplicationLifecycleHealthCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Collections.Generic.IEnumerable<string> tags);",
"Stage": "Stable"
},
{
"Member": "static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder Microsoft.Extensions.Diagnostics.HealthChecks.CommonHealthChecksExtensions.AddManualHealthCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, params string[] tags);",
"Stage": "Stable"
},
{
"Member": "static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder Microsoft.Extensions.Diagnostics.HealthChecks.CommonHealthChecksExtensions.AddManualHealthCheck(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Collections.Generic.IEnumerable<string> tags);",
"Stage": "Stable"
},
{
"Member": "static Microsoft.Extensions.DependencyInjection.IServiceCollection Microsoft.Extensions.Diagnostics.HealthChecks.CommonHealthChecksExtensions.AddTelemetryHealthCheckPublisher(this Microsoft.Extensions.DependencyInjection.IServiceCollection services);",
"Stage": "Stable"
},
{
"Member": "static Microsoft.Extensions.DependencyInjection.IServiceCollection Microsoft.Extensions.Diagnostics.HealthChecks.CommonHealthChecksExtensions.AddTelemetryHealthCheckPublisher(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Microsoft.Extensions.Configuration.IConfigurationSection section);",
"Stage": "Experimental"
},
{
"Member": "static Microsoft.Extensions.DependencyInjection.IServiceCollection Microsoft.Extensions.Diagnostics.HealthChecks.CommonHealthChecksExtensions.AddTelemetryHealthCheckPublisher(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action<Microsoft.Extensions.Diagnostics.HealthChecks.TelemetryHealthCheckPublisherOptions> configure);",
"Stage": "Experimental"
},
{
"Member": "static void Microsoft.Extensions.Diagnostics.HealthChecks.CommonHealthChecksExtensions.ReportHealthy(this Microsoft.Extensions.Diagnostics.HealthChecks.IManualHealthCheck manualHealthCheck);",
"Stage": "Stable"
},
{
"Member": "static void Microsoft.Extensions.Diagnostics.HealthChecks.CommonHealthChecksExtensions.ReportUnhealthy(this Microsoft.Extensions.Diagnostics.HealthChecks.IManualHealthCheck manualHealthCheck, string reason);",
"Stage": "Stable"
}
]
},
{
"Type": "interface Microsoft.Extensions.Diagnostics.HealthChecks.IManualHealthCheck : System.IDisposable",
"Stage": "Stable",
"Properties": [
{
"Member": "Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult Microsoft.Extensions.Diagnostics.HealthChecks.IManualHealthCheck.Result { get; set; }",
"Stage": "Stable"
}
]
},
{
"Type": "interface Microsoft.Extensions.Diagnostics.HealthChecks.IManualHealthCheck<T> : Microsoft.Extensions.Diagnostics.HealthChecks.IManualHealthCheck, System.IDisposable",
"Stage": "Stable"
},
{
"Type": "class Microsoft.Extensions.Diagnostics.HealthChecks.TelemetryHealthCheckPublisherOptions",
"Stage": "Experimental",
"Methods": [
{
"Member": "Microsoft.Extensions.Diagnostics.HealthChecks.TelemetryHealthCheckPublisherOptions.TelemetryHealthCheckPublisherOptions();",
"Stage": "Experimental"
}
],
"Properties": [
{
"Member": "bool Microsoft.Extensions.Diagnostics.HealthChecks.TelemetryHealthCheckPublisherOptions.LogOnlyUnhealthy { get; set; }",
"Stage": "Experimental"
}
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,5 @@ public class TelemetryHealthCheckPublisherOptions
/// <remarks>
/// Default set to false.
/// </remarks>
[Experimental]
public bool LogOnlyUnhealthy { get; set; }
}

This file was deleted.

This file was deleted.

Loading