public static List <HealthCheckExecutionEntry> ToExecutionEntries(this HealthReport report)
 {
     return(report.Entries
            .Select(item =>
     {
         return new HealthCheckExecutionEntry()
         {
             Name = item.Key,
             Status = item.Value.Status,
             Description = item.Value.Description,
             Duration = item.Value.Duration
         };
     }).ToList());
 }
示例#2
0
        public void Status_MatchesWorstStatusInResults(HealthStatus status)
        {
            var result = new HealthReport(new Dictionary <string, HealthReportEntry>()
            {
                { "Foo", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue, null, null) },
                { "Bar", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue, null, null) },
                { "Baz", new HealthReportEntry(status, exception: null, description: null, duration: TimeSpan.MinValue, data: null) },
                { "Quick", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue, null, null) },
                { "Quack", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue, null, null) },
                { "Quock", new HealthReportEntry(HealthStatus.Healthy, null, TimeSpan.MinValue, null, null) },
            }, totalDuration: TimeSpan.MinValue);

            Assert.Equal(status, result.Status);
        }
示例#3
0
        public static Task WriteHealthCheckResponse(HttpContext httpContext,
                                                    HealthReport result)
        {
            httpContext.Response.ContentType = "application/json";
            var json = new JObject(
                new JProperty("status", result.Status.ToString()),
                new JProperty("results",
                              new JObject(result.Entries.Select(pair =>
                                                                new JProperty(pair.Key,
                                                                              new JObject(
                                                                                  new JProperty("status", pair.Value.Status.ToString()),
                                                                                  new JProperty("description", pair.Value.Description),
                                                                                  new JProperty("data",
                                                                                                new JObject(pair.Value.Data.Select(
                                                                                                                p => new JProperty(p.Key, p.Value))))))))));

            return(httpContext.Response.WriteAsync(
                       json.ToString(Formatting.Indented)));
        }
示例#4
0
        public override async Task <HealthReport> CheckHealthAsync(
            Func <HealthCheckRegistration, bool> predicate,
            CancellationToken cancellationToken = default)
        {
            var registrations = _options.Value.Registrations;

            if (predicate != null)
            {
                registrations = registrations.Where(predicate).ToArray();
            }

            var totalTime = ValueStopwatch.StartNew();

            Log.HealthCheckProcessingBegin(_logger);

            var tasks = new Task <HealthReportEntry> [registrations.Count];
            var index = 0;

            using (var scope = _scopeFactory.CreateScope())
            {
                foreach (var registration in registrations)
                {
                    tasks[index++] = Task.Run(() => RunCheckAsync(scope, registration, cancellationToken), cancellationToken);
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);
            }

            index = 0;
            var entries = new Dictionary <string, HealthReportEntry>(StringComparer.OrdinalIgnoreCase);

            foreach (var registration in registrations)
            {
                entries[registration.Name] = tasks[index++].Result;
            }

            var totalElapsedTime = totalTime.GetElapsedTime();
            var report           = new HealthReport(entries, totalElapsedTime);

            Log.HealthCheckProcessingEnd(_logger, report.Status, totalElapsedTime);
            return(report);
        }
示例#5
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);
            }
        }