예제 #1
0
        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()));
 }
예제 #4
0
        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);
            }
        }