private async Task <HealthReportEntry> RunCheckAsync(IServiceScope scope, HealthCheckRegistration registration, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var healthCheck = registration.Factory(scope.ServiceProvider); // If the health check does things like make Database queries using EF or backend HTTP calls, // it may be valuable to know that logs it generates are part of a health check. So we start a scope. using (_logger.BeginScope(new HealthCheckLogScope(registration.Name))) { var stopwatch = ValueStopwatch.StartNew(); var context = new HealthCheckContext { Registration = registration }; Log.HealthCheckBegin(_logger, registration); HealthReportEntry entry; CancellationTokenSource timeoutCancellationTokenSource = null; try { HealthCheckResult result; var checkCancellationToken = cancellationToken; if (registration.Timeout > TimeSpan.Zero) { timeoutCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); timeoutCancellationTokenSource.CancelAfter(registration.Timeout); checkCancellationToken = timeoutCancellationTokenSource.Token; } result = await healthCheck.CheckHealthAsync(context, checkCancellationToken).ConfigureAwait(false); var duration = stopwatch.GetElapsedTime(); entry = new HealthReportEntry( status: result.Status, description: result.Description, duration: duration, exception: result.Exception, data: result.Data); Log.HealthCheckEnd(_logger, registration, entry, duration); Log.HealthCheckData(_logger, registration, entry); } catch (OperationCanceledException ex) when(!cancellationToken.IsCancellationRequested) { var duration = stopwatch.GetElapsedTime(); entry = new HealthReportEntry( status: HealthStatus.Unhealthy, description: "A timeout occured while running check.", duration: duration, exception: ex, data: null); Log.HealthCheckError(_logger, registration, ex, duration); } // Allow cancellation to propagate if it's not a timeout. catch (Exception ex) when(ex as OperationCanceledException == null) { var duration = stopwatch.GetElapsedTime(); entry = new HealthReportEntry( status: HealthStatus.Unhealthy, description: ex.Message, duration: duration, exception: ex, data: null); Log.HealthCheckError(_logger, registration, ex, duration); } finally { timeoutCancellationTokenSource?.Dispose(); } return(entry); } }
/// <summary> /// Runs the health check, returning the status of the component being checked. /// </summary> /// <param name="context">A context object associated with the current execution.</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the health check.</param> /// <returns>A <see cref="Task{HealthCheckResult}"/> that completes when the health check has finished, yielding the status of the component being checked.</returns> public Task <HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) => _check(cancellationToken);
public Task <HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { return(Task.FromResult(HealthCheckResult.Healthy())); }
public override async Task <HealthReport> CheckHealthAsync( Func <HealthCheckRegistration, bool> predicate, CancellationToken cancellationToken = default) { var registrations = _options.Value.Registrations; using (var scope = _scopeFactory.CreateScope()) { var context = new HealthCheckContext(); var entries = new Dictionary <string, HealthReportEntry>(StringComparer.OrdinalIgnoreCase); var totalTime = ValueStopwatch.StartNew(); Log.HealthCheckProcessingBegin(_logger); foreach (var registration in registrations) { if (predicate != null && !predicate(registration)) { continue; } cancellationToken.ThrowIfCancellationRequested(); var healthCheck = registration.Factory(scope.ServiceProvider); // If the health check does things like make Database queries using EF or backend HTTP calls, // it may be valuable to know that logs it generates are part of a health check. So we start a scope. using (_logger.BeginScope(new HealthCheckLogScope(registration.Name))) { var stopwatch = ValueStopwatch.StartNew(); context.Registration = registration; Log.HealthCheckBegin(_logger, registration); HealthReportEntry entry; try { var result = await healthCheck.CheckHealthAsync(context, cancellationToken); entry = new HealthReportEntry( result.Result ? HealthStatus.Healthy : registration.FailureStatus, result.Description, result.Exception, result.Data); Log.HealthCheckEnd(_logger, registration, entry, stopwatch.GetElapsedTime()); Log.HealthCheckData(_logger, registration, entry); } // Allow cancellation to propagate. catch (Exception ex) when(ex as OperationCanceledException == null) { entry = new HealthReportEntry(HealthStatus.Failed, ex.Message, ex, data: null); Log.HealthCheckError(_logger, registration, ex, stopwatch.GetElapsedTime()); } entries[registration.Name] = entry; } } var report = new HealthReport(entries); Log.HealthCheckProcessingEnd(_logger, report.Status, totalTime.GetElapsedTime()); return(report); } }