private WavefrontTracer(
            IReporter reporter, IList <KeyValuePair <string, string> > tags, IList <ISampler> samplers,
            ApplicationTags applicationTags, ISet <string> redMetricsCustomTagKeys,
            TimeSpan reportFrequency, PropagatorRegistry registry, ILoggerFactory loggerFactory)
        {
            ScopeManager  = new AsyncLocalScopeManager();
            this.reporter = reporter;
            Tags          = tags;
            this.samplers = samplers;
            this.redMetricsCustomTagKeys = redMetricsCustomTagKeys;
            this.applicationTags         = applicationTags;
            this.registry = registry;
            logger        = loggerFactory.CreateLogger <WavefrontTracer>();

            WavefrontSpanReporter spanReporter = GetWavefrontSpanReporter(reporter);

            if (spanReporter != null)
            {
                /*
                 * Tracing spans will be converted to metrics and histograms and will be reported
                 * to Wavefront only if you use the WavefrontSpanReporter.
                 */
                InitMetricsHistogramsReporting(spanReporter, applicationTags, reportFrequency,
                                               loggerFactory, out metricsRoot, out metricsScheduler, out heartbeaterService,
                                               out sdkMetricsRegistry);
            }
        }
        private void InitMetricsHistogramsReporting(
            WavefrontSpanReporter wfSpanReporter, ApplicationTags applicationTags,
            TimeSpan reportFrequency, ILoggerFactory loggerFactory, out IMetricsRoot metricsRoot,
            out AppMetricsTaskScheduler metricsScheduler, out HeartbeaterService heartbeaterService,
            out WavefrontSdkMetricsRegistry sdkMetricsRegistry)
        {
            var tempMetricsRoot = new MetricsBuilder()
                                  .Configuration.Configure(
                options =>
            {
                options.DefaultContextLabel = DerivedMetricPrefix;
            })
                                  .Report.ToWavefront(
                options =>
            {
                options.WavefrontSender = wfSpanReporter.WavefrontSender;
                options.Source          = wfSpanReporter.Source;
                options.ApplicationTags = applicationTags;
                options.WavefrontHistogram.ReportMinuteDistribution = true;
                options.LoggerFactory = loggerFactory;
            })
                                  .Build();

            metricsRoot = tempMetricsRoot;

            metricsScheduler = new AppMetricsTaskScheduler(
                reportFrequency,
                async() =>
            {
                await Task.WhenAll(tempMetricsRoot.ReportRunner.RunAllAsync());
            });
            metricsScheduler.Start();

            heartbeaterService = new HeartbeaterService(
                wfSpanReporter.WavefrontSender, applicationTags, HeartbeaterComponents,
                wfSpanReporter.Source, loggerFactory);
            heartbeaterService.Start();

            sdkMetricsRegistry = new WavefrontSdkMetricsRegistry
                                 .Builder(wfSpanReporter.WavefrontSender)
                                 .Prefix(Constants.SdkMetricPrefix + ".opentracing")
                                 .Source(wfSpanReporter.Source)
                                 .Tags(applicationTags.ToPointTags())
                                 .LoggerFactory(loggerFactory)
                                 .Build();
            wfSpanReporter.SetSdkMetricsRegistry(sdkMetricsRegistry);
        }