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

Convert HealthChecks logging to use new Logging Source Generator #32414

Merged
merged 3 commits into from
Jul 2, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
110 changes: 49 additions & 61 deletions src/HealthChecks/HealthChecks/src/DefaultHealthCheckService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

namespace Microsoft.Extensions.Diagnostics.HealthChecks
{
internal class DefaultHealthCheckService : HealthCheckService
internal partial class DefaultHealthCheckService : HealthCheckService
pranavkm marked this conversation as resolved.
Show resolved Hide resolved
{
private readonly IServiceScopeFactory _scopeFactory;
private readonly IOptions<HealthCheckServiceOptions> _options;
Expand Down Expand Up @@ -87,7 +87,7 @@ private async Task<HealthReportEntry> RunCheckAsync(HealthCheckRegistration regi
var stopwatch = ValueStopwatch.StartNew();
var context = new HealthCheckContext { Registration = registration };

Log.HealthCheckBegin(_logger, registration);
Log.HealthCheckBegin(_logger, registration.Name);

HealthReportEntry entry;
CancellationTokenSource? timeoutCancellationTokenSource = null;
Expand Down Expand Up @@ -182,92 +182,80 @@ private static void ValidateRegistrations(IEnumerable<HealthCheckRegistration> r

internal static class EventIds
{
public static readonly EventId HealthCheckProcessingBegin = new EventId(100, "HealthCheckProcessingBegin");
public static readonly EventId HealthCheckProcessingEnd = new EventId(101, "HealthCheckProcessingEnd");

public static readonly EventId HealthCheckBegin = new EventId(102, "HealthCheckBegin");
public static readonly EventId HealthCheckEnd = new EventId(103, "HealthCheckEnd");
public static readonly EventId HealthCheckError = new EventId(104, "HealthCheckError");
public static readonly EventId HealthCheckData = new EventId(105, "HealthCheckData");
public const int HealthCheckProcessingBeginId = 100;
public const int HealthCheckProcessingEndId = 101;
public const int HealthCheckBeginId = 102;
public const int HealthCheckEndId = 103;
public const int HealthCheckErrorId = 104;
public const int HealthCheckDataId = 105;

// Hard code the event names to avoid breaking changes. Even if the methods are renamed, these hard-coded names shouldn't change.
public const string HealthCheckProcessingBeginName = "HealthCheckProcessingBegin";
public const string HealthCheckProcessingEndName = "HealthCheckProcessingEnd";
public const string HealthCheckBeginName = "HealthCheckBegin";
public const string HealthCheckEndName = "HealthCheckEnd";
public const string HealthCheckErrorName = "HealthCheckError";
public const string HealthCheckDataName = "HealthCheckData";

public static readonly EventId HealthCheckProcessingBegin = new EventId(HealthCheckProcessingBeginId, HealthCheckProcessingBeginName);
eerhardt marked this conversation as resolved.
Show resolved Hide resolved
public static readonly EventId HealthCheckProcessingEnd = new EventId(HealthCheckProcessingEndId, HealthCheckProcessingEndName);
public static readonly EventId HealthCheckBegin = new EventId(HealthCheckBeginId, HealthCheckBeginName);
public static readonly EventId HealthCheckEnd = new EventId(HealthCheckEndId, HealthCheckEndName);
public static readonly EventId HealthCheckError = new EventId(HealthCheckErrorId, HealthCheckErrorName);
public static readonly EventId HealthCheckData = new EventId(HealthCheckDataId, HealthCheckDataName);
}

private static class Log
private static partial class Log
{
private static readonly Action<ILogger, Exception?> _healthCheckProcessingBegin = LoggerMessage.Define(
LogLevel.Debug,
EventIds.HealthCheckProcessingBegin,
"Running health checks");
[LoggerMessage(EventIds.HealthCheckProcessingBeginId, LogLevel.Debug, "Running health checks", EventName = EventIds.HealthCheckProcessingBeginName)]
public static partial void HealthCheckProcessingBegin(ILogger logger);

public static void HealthCheckProcessingEnd(ILogger logger, HealthStatus status, TimeSpan duration) =>
HealthCheckProcessingEnd(logger, status, duration.TotalMilliseconds);

private static readonly Action<ILogger, double, HealthStatus, Exception?> _healthCheckProcessingEnd = LoggerMessage.Define<double, HealthStatus>(
LogLevel.Debug,
EventIds.HealthCheckProcessingEnd,
"Health check processing with combined status {HealthStatus} completed after {ElapsedMilliseconds}ms");
[LoggerMessage(EventIds.HealthCheckProcessingEndId, LogLevel.Debug, "Health check processing with combined status {HealthStatus} completed after {ElapsedMilliseconds}ms", EventName = EventIds.HealthCheckProcessingEndName)]
private static partial void HealthCheckProcessingEnd(ILogger logger, HealthStatus HealthStatus, double ElapsedMilliseconds);

private static readonly Action<ILogger, string, Exception?> _healthCheckBegin = LoggerMessage.Define<string>(
LogLevel.Debug,
EventIds.HealthCheckBegin,
"Running health check {HealthCheckName}");
[LoggerMessage(EventIds.HealthCheckBeginId, LogLevel.Debug, "Running health check {HealthCheckName}", EventName = EventIds.HealthCheckBeginName)]
public static partial void HealthCheckBegin(ILogger logger, string HealthCheckName);

// These are separate so they can have different log levels
private const string HealthCheckEndText = "Health check {HealthCheckName} with status {HealthStatus} completed after {ElapsedMilliseconds}ms with message '{HealthCheckDescription}'";

private static readonly Action<ILogger, string, double, HealthStatus, string?, Exception?> _healthCheckEndHealthy = LoggerMessage.Define<string, double, HealthStatus, string?>(
LogLevel.Debug,
EventIds.HealthCheckEnd,
HealthCheckEndText);

private static readonly Action<ILogger, string, double, HealthStatus, string?, Exception?> _healthCheckEndDegraded = LoggerMessage.Define<string, double, HealthStatus, string?>(
LogLevel.Warning,
EventIds.HealthCheckEnd,
HealthCheckEndText);

private static readonly Action<ILogger, string, double, HealthStatus, string?, Exception?> _healthCheckEndUnhealthy = LoggerMessage.Define<string, double, HealthStatus, string?>(
LogLevel.Error,
EventIds.HealthCheckEnd,
HealthCheckEndText);
#pragma warning disable SYSLIB1006
[LoggerMessage(EventIds.HealthCheckEndId, LogLevel.Debug, HealthCheckEndText, EventName = EventIds.HealthCheckEndName)]
private static partial void HealthCheckEndHealthy(ILogger logger, string HealthCheckName, HealthStatus HealthStatus, double ElapsedMilliseconds, string? HealthCheckDescription);

private static readonly Action<ILogger, string, double, Exception?> _healthCheckError = LoggerMessage.Define<string, double>(
LogLevel.Error,
EventIds.HealthCheckError,
"Health check {HealthCheckName} threw an unhandled exception after {ElapsedMilliseconds}ms");
[LoggerMessage(EventIds.HealthCheckEndId, LogLevel.Warning, HealthCheckEndText, EventName = EventIds.HealthCheckEndName)]
private static partial void HealthCheckEndDegraded(ILogger logger, string HealthCheckName, HealthStatus HealthStatus, double ElapsedMilliseconds, string? HealthCheckDescription);

public static void HealthCheckProcessingBegin(ILogger logger)
{
_healthCheckProcessingBegin(logger, null);
}

public static void HealthCheckProcessingEnd(ILogger logger, HealthStatus status, TimeSpan duration)
{
_healthCheckProcessingEnd(logger, duration.TotalMilliseconds, status, null);
}

public static void HealthCheckBegin(ILogger logger, HealthCheckRegistration registration)
{
_healthCheckBegin(logger, registration.Name, null);
}
[LoggerMessage(EventIds.HealthCheckEndId, LogLevel.Error, HealthCheckEndText, EventName = EventIds.HealthCheckEndName)]
private static partial void HealthCheckEndUnhealthy(ILogger logger, string HealthCheckName, HealthStatus HealthStatus, double ElapsedMilliseconds, string? HealthCheckDescription, Exception? exception);
#pragma warning restore SYSLIB1006

public static void HealthCheckEnd(ILogger logger, HealthCheckRegistration registration, HealthReportEntry entry, TimeSpan duration)
{
switch (entry.Status)
{
case HealthStatus.Healthy:
_healthCheckEndHealthy(logger, registration.Name, duration.TotalMilliseconds, entry.Status, entry.Description, null);
HealthCheckEndHealthy(logger, registration.Name, entry.Status, duration.TotalMilliseconds, entry.Description);
break;

case HealthStatus.Degraded:
_healthCheckEndDegraded(logger, registration.Name, duration.TotalMilliseconds, entry.Status, entry.Description, null);
HealthCheckEndDegraded(logger, registration.Name, entry.Status, duration.TotalMilliseconds, entry.Description);
break;

case HealthStatus.Unhealthy:
_healthCheckEndUnhealthy(logger, registration.Name, duration.TotalMilliseconds, entry.Status, entry.Description, entry.Exception);
HealthCheckEndUnhealthy(logger, registration.Name, entry.Status, duration.TotalMilliseconds, entry.Description, entry.Exception);
break;
}
}

public static void HealthCheckError(ILogger logger, HealthCheckRegistration registration, Exception exception, TimeSpan duration)
{
_healthCheckError(logger, registration.Name, duration.TotalMilliseconds, exception);
}
[LoggerMessage(EventIds.HealthCheckErrorId, LogLevel.Error, "Health check {HealthCheckName} threw an unhandled exception after {ElapsedMilliseconds}ms", EventName = EventIds.HealthCheckErrorName)]
private static partial void HealthCheckError(ILogger logger, string HealthCheckName, double ElapsedMilliseconds, Exception exception);

public static void HealthCheckError(ILogger logger, HealthCheckRegistration registration, Exception exception, TimeSpan duration) =>
HealthCheckError(logger, registration.Name, duration.TotalMilliseconds, exception);

public static void HealthCheckData(ILogger logger, HealthCheckRegistration registration, HealthReportEntry entry)
{
Expand Down
Loading