public async Task <bool> GenerateAsync(
            IMetricReporter reporter,
            IMetrics metrics,
            IFilterMetrics reporterMetricsFilter,
            CancellationToken token)
        {
            var startTimestamp = _logger.IsEnabled(LogLevel.Trace) ? Stopwatch.GetTimestamp() : 0;

            _logger.ReportedStarted(reporter);

            if (reporterMetricsFilter == default(IFilterMetrics))
            {
                reporterMetricsFilter = metrics.GlobalFilter;
            }

            reporter.StartReportRun(metrics);

            var data = metrics.Snapshot.Get(reporterMetricsFilter);

            if (data.Environment.Entries.Any() && reporterMetricsFilter.ReportEnvironment)
            {
                reporter.ReportEnvironment(data.Environment);
            }

            if (reporterMetricsFilter.ReportHealthChecks)
            {
                await ReportHealth(reporter, metrics, token);
            }

            ReportMetricTypes(reporter, token, data);

            var result = await reporter.EndAndFlushReportRunAsync(metrics);

            _logger.ReportRan(reporter, startTimestamp);

            return(result);
        }
        public async Task <bool> GenerateAsync(IMetricReporter reporter,
                                               IMetrics metrics,
                                               IMetricsFilter reporterMetricsFilter,
                                               CancellationToken token)
        {
            var startTimestamp = _logger.IsEnabled(LogLevel.Information) ? Stopwatch.GetTimestamp() : 0;

            _logger.ReportedStarted(reporter);

            if (reporterMetricsFilter == default(IMetricsFilter))
            {
                reporterMetricsFilter = metrics.Advanced.GlobalFilter;
            }

            reporter.StartReportRun(metrics);

            var data = metrics.Advanced.Data.ReadData(reporterMetricsFilter);

            if (data.Environment.Entries.Any() && reporterMetricsFilter.ReportEnvironment)
            {
                reporter.ReportEnvironment(data.Environment);
            }

            if (reporterMetricsFilter.ReportHealthChecks)
            {
                var healthStatus = await metrics.Advanced.Health.ReadStatusAsync(token);

                var passed   = healthStatus.Results.Where(r => r.Check.Status.IsHealthy()).ToArray();
                var failed   = healthStatus.Results.Where(r => r.Check.Status.IsUnhealthy()).ToArray();
                var degraded = healthStatus.Results.Where(r => r.Check.Status.IsDegraded()).ToArray();

                reporter.ReportHealth(metrics.Advanced.GlobalTags, passed, degraded, failed);

                foreach (var check in passed)
                {
                    metrics.Increment(ApplicationHealthMetricRegistry.HealthyCheckCounter, check.Name);
                }

                foreach (var check in degraded)
                {
                    metrics.Increment(ApplicationHealthMetricRegistry.DegradedCheckCounter, check.Name);
                }

                foreach (var check in failed)
                {
                    metrics.Increment(ApplicationHealthMetricRegistry.UnhealthyCheckCounter, check.Name);
                }
            }

            foreach (var contextValueSource in data.Contexts)
            {
                ReportMetricType(contextValueSource.Counters,
                                 c => { reporter.ReportMetric($"{contextValueSource.Context}", c); }, token);

                ReportMetricType(contextValueSource.Gauges,
                                 g => { reporter.ReportMetric($"{contextValueSource.Context}", g); }, token);

                ReportMetricType(contextValueSource.Histograms,
                                 h => { reporter.ReportMetric($"{contextValueSource.Context}", h); }, token);

                ReportMetricType(contextValueSource.Meters,
                                 m => { reporter.ReportMetric($"{contextValueSource.Context}", m); }, token);

                ReportMetricType(contextValueSource.Timers,
                                 t => { reporter.ReportMetric($"{contextValueSource.Context}", t); }, token);

                ReportMetricType(contextValueSource.ApdexScores,
                                 t => { reporter.ReportMetric($"{contextValueSource.Context}", t); }, token);
            }

            var result = await reporter.EndAndFlushReportRunAsync(metrics);

            _logger.ReportRan(reporter, startTimestamp);

            return(result);
        }