public TelemetryToMetrics(ITelemetryProcessor next)
        {
            // Link processors to each other in a chain.
            _next = next;

            ResetTimer();
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SamplingPercentageEstimatorTelemetryProcessor"/> class.
        /// <param name="settings">Dynamic sampling estimator settings.</param>
        /// <param name="callback">Callback to invoke every time sampling percentage is evaluated.</param>
        /// <param name="next">Next TelemetryProcessor in call chain.</param>
        /// </summary>
        public SamplingPercentageEstimatorTelemetryProcessor(
            SamplingPercentageEstimatorSettings settings,
            AdaptiveSamplingPercentageEvaluatedCallback callback,
            ITelemetryProcessor next)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            if (next == null)
            {
                throw new ArgumentNullException("next");
            }

            this.evaluationCallback = callback;
            this.settings           = settings;
            this.next = next;

            this.currenSamplingRate = settings.EffectiveInitialSamplingRate;

            this.itemCount = new ExponentialMovingAverageCounter(settings.EffectiveMovingAverageRatio);

            this.samplingPercentageLastChangeDateTime = DateTimeOffset.UtcNow;

            // set evaluation interval to default value if it is negative or zero
            this.evaluationInterval = this.settings.EffectiveEvaluationInterval;

            // set up timer to run math to estimate sampling percentage
            this.evaluationTimer = new Timer(
                this.EstimateSamplingPercentage,
                null,
                this.evaluationInterval,
                this.evaluationInterval);
        }
        public ITelemetryProcessor Create(ITelemetryProcessor next)
        {
            var processor = new EventFlowTelemetryProcessor(next);

            processor.Pipeline = pipeline_;
            return(processor);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="QuickPulseTelemetryProcessor"/> class. Internal constructor for unit tests only.
        /// </summary>
        /// <param name="next">The next TelemetryProcessor in the chain.</param>
        /// <param name="timeProvider">Time provider.</param>
        /// <param name="maxTelemetryQuota">Max telemetry quota.</param>
        /// <param name="initialTelemetryQuota">Initial telemetry quota.</param>
        /// <exception cref="ArgumentNullException">Thrown if next is null.</exception>
        internal QuickPulseTelemetryProcessor(
            ITelemetryProcessor next,
            Clock timeProvider,
            int? maxTelemetryQuota = null,
            int? initialTelemetryQuota = null)
        {
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            this.Register();

            this.Next = next;

            this.requestQuotaTracker = new QuickPulseQuotaTracker(
                timeProvider,
                maxTelemetryQuota ?? MaxTelemetryQuota,
                initialTelemetryQuota ?? InitialTelemetryQuota);

            this.dependencyQuotaTracker = new QuickPulseQuotaTracker(
                timeProvider,
                maxTelemetryQuota ?? MaxTelemetryQuota,
                initialTelemetryQuota ?? InitialTelemetryQuota);

            this.exceptionQuotaTracker = new QuickPulseQuotaTracker(
                timeProvider,
                maxTelemetryQuota ?? MaxTelemetryQuota,
                initialTelemetryQuota ?? InitialTelemetryQuota);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="QuickPulseTelemetryProcessor"/> class. Internal constructor for unit tests only.
        /// </summary>
        /// <param name="next">The next TelemetryProcessor in the chain.</param>
        /// <param name="timeProvider">Time provider.</param>
        /// <param name="maxTelemetryQuota">Max telemetry quota.</param>
        /// <param name="initialTelemetryQuota">Initial telemetry quota.</param>
        /// <exception cref="ArgumentNullException">Thrown if next is null.</exception>
        internal QuickPulseTelemetryProcessor(
            ITelemetryProcessor next,
            Clock timeProvider,
            int?maxTelemetryQuota     = null,
            int?initialTelemetryQuota = null)
        {
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            this.Register();

            this.Next = next;

            this.requestQuotaTracker = new QuickPulseQuotaTracker(
                timeProvider,
                maxTelemetryQuota ?? MaxTelemetryQuota,
                initialTelemetryQuota ?? InitialTelemetryQuota);

            this.dependencyQuotaTracker = new QuickPulseQuotaTracker(
                timeProvider,
                maxTelemetryQuota ?? MaxTelemetryQuota,
                initialTelemetryQuota ?? InitialTelemetryQuota);

            this.exceptionQuotaTracker = new QuickPulseQuotaTracker(
                timeProvider,
                maxTelemetryQuota ?? MaxTelemetryQuota,
                initialTelemetryQuota ?? InitialTelemetryQuota);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="SamplingTelemetryProcessor"/> class.
 /// <param name="next">Next TelemetryProcessor in call chain.</param>
 /// </summary>
 public SamplingTelemetryProcessor(ITelemetryProcessor next)
 {
     this.SamplingPercentage          = 100.0;
     this.ProactiveSamplingPercentage = null;
     this.SampledNext   = next ?? throw new ArgumentNullException(nameof(next));
     this.UnsampledNext = next;
 }
        /// <summary>
        /// Registers an instance of type <see cref="QuickPulseTelemetryProcessor"/> with this module.
        /// </summary>
        /// <remarks>This call is only necessary when the module is created in code and not in configuration.</remarks>
        /// <param name="telemetryProcessor">QuickPulseTelemetryProcessor instance to be registered with the module.</param>
        public void RegisterTelemetryProcessor(ITelemetryProcessor telemetryProcessor)
        {
            var quickPulseTelemetryProcessor = telemetryProcessor as IQuickPulseTelemetryProcessor;

            if (quickPulseTelemetryProcessor == null)
            {
                throw new ArgumentNullException(nameof(telemetryProcessor), @"The argument must be of type QuickPulseTelemetryProcessor");
            }

            lock (this.telemetryProcessorsLock)
            {
                const int MaxTelemetryProcessorCount = 100;
                if (!this.TelemetryProcessors.Contains(quickPulseTelemetryProcessor))
                {
                    this.TelemetryProcessors.AddLast(quickPulseTelemetryProcessor);

                    if (this.TelemetryProcessors.Count > MaxTelemetryProcessorCount)
                    {
                        this.TelemetryProcessors.RemoveFirst();
                    }

                    QuickPulseEventSource.Log.ProcessorRegistered(this.TelemetryProcessors.Count.ToString(CultureInfo.InvariantCulture));
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SamplingPercentageEstimatorTelemetryProcessor"/> class.
        /// <param name="settings">Dynamic sampling estimator settings.</param>
        /// <param name="callback">Callback to invoke every time sampling percentage is evaluated.</param>
        /// <param name="next">Next TelemetryProcessor in call chain.</param>
        /// </summary>
        public SamplingPercentageEstimatorTelemetryProcessor(
            Channel.Implementation.SamplingPercentageEstimatorSettings settings,
            Channel.Implementation.AdaptiveSamplingPercentageEvaluatedCallback callback,
            ITelemetryProcessor next)
        {
            this.evaluationCallback = callback;
            this.settings           = settings ?? throw new ArgumentNullException(nameof(settings));
            this.next = next ?? throw new ArgumentNullException(nameof(next));

            this.CurrentSamplingRate          = settings.EffectiveInitialSamplingRate;
            this.CurrentProactiveSamplingRate = settings.EffectiveInitialSamplingRate;

            this.itemCount = new ExponentialMovingAverageCounter(settings.EffectiveMovingAverageRatio);
            this.proactivelySampledInCount = new ExponentialMovingAverageCounter(settings.EffectiveMovingAverageRatio);

            this.samplingPercentageLastChangeDateTime = PreciseTimestamp.GetUtcNow();

            // set evaluation interval to default value if it is negative or zero
            this.evaluationInterval = this.settings.EffectiveEvaluationInterval;

            // set up timer to run math to estimate sampling percentage
            this.evaluationTimer = new Timer(
                this.EstimateSamplingPercentage,
                null,
                this.evaluationInterval,
                this.evaluationInterval);
        }
示例#9
0
        /// <summary>
        /// Builds the chain of linked <see cref="ITelemetryProcessor" /> instances and sets the same in configuration object passed.
        /// A special telemetry processor for handling Transmission is always appended as the last
        /// processor in the chain.
        /// </summary>
        public void Build()
        {
            var telemetryProcessorsList = new List <ITelemetryProcessor>();

            // TransmissionProcessor is always appended by default to the end of the chain.
            ITelemetryProcessor linkedTelemetryProcessor = new TransmissionProcessor(this.configuration);

            telemetryProcessorsList.Add(linkedTelemetryProcessor);

            foreach (var generator in this.factories.AsEnumerable().Reverse())
            {
                ITelemetryProcessor prevTelemetryProcessor = linkedTelemetryProcessor;
                linkedTelemetryProcessor = generator.Invoke(linkedTelemetryProcessor);

                if (linkedTelemetryProcessor == null)
                {
                    // Loading of a telemetry processor failed, so skip it
                    // Error is logged when telemetry processor loading failed
                    linkedTelemetryProcessor = prevTelemetryProcessor;
                    continue;
                }

                telemetryProcessorsList.Add(linkedTelemetryProcessor);
            }

            var telemetryProcessorChain = new TelemetryProcessorChain(telemetryProcessorsList.AsEnumerable().Reverse());

            this.configuration.TelemetryProcessorChain = telemetryProcessorChain;
        }
示例#10
0
        public UrlRequestFilter(ITelemetryProcessor next, string pathToFilter)
        {
            Requires.NotNull(next, nameof(next));
            Requires.NotNullOrWhiteSpace(nameof(pathToFilter), "Path to filter should not be empty");

            next_         = next;
            pathToFilter_ = pathToFilter;
        }
        public UrlDependencyFilter(ITelemetryProcessor next, string urlToFilter)
        {
            Requires.NotNull(next, nameof(next));
            Requires.That(Uri.IsWellFormedUriString(urlToFilter, UriKind.Absolute), nameof(urlToFilter), $"{nameof(urlToFilter)} parameter value should be a valid URL");

            next_        = next;
            urlToFilter_ = urlToFilter;
        }
        public Action(ITelemetryProcessor playingProcessor, ITelemetryProcessor menuProcessor)
        {
            frontEnd = new GameFrontEndState();
            playing  = new GamePlayingState(playingProcessor);
            menu     = new GameMenuState(menuProcessor);

            currentState = frontEnd;
        }
示例#13
0
 public SearchRequestTelemetryProcessor(ITelemetryProcessor nextProcessor)
 {
     _next = new RequestTelemetryProcessor(nextProcessor);
     _next.SuccessfulResponseCodes.Add(400);
     _next.SuccessfulResponseCodes.Add(403);
     _next.SuccessfulResponseCodes.Add(404);
     _next.SuccessfulResponseCodes.Add(405);
 }
示例#14
0
        public DependencyFilteringWithMetricsTelemetryProcessor(ITelemetryProcessor next, TelemetryConfiguration configuration)
        {
            this.next = next;
            var client = new TelemetryClient(configuration);

            this.numberOfDependencies = client.GetMetric("# of dependencies", "type");
            this.dependenciesDuration = client.GetMetric("dependencies duration (ms)", "type");
        }
示例#15
0
        public ITelemetryProcessor Create(ITelemetryProcessor next)
        {
            var options = _serviceProvider.GetService <IOptions <SnapshotCollectorConfiguration> >();

            return(options != null
                ? new SnapshotCollectorTelemetryProcessor(next, options.Value)
                : new SnapshotCollectorTelemetryProcessor(next));
        }
示例#16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UserAgentTelemetryProcessor" /> class.
        /// </summary>
        /// <param name="next">Next TelemetryProcessor in call chain.</param>
        public UserAgentTelemetryProcessor(ITelemetryProcessor next)
        {
            if (next == null)
            {
                throw new ArgumentNullException("next");
            }

            this.Next = next;
        }
        /// <summary>
        /// Invokes the subsequent telemetry processor if it has been initialized.
        /// </summary>
        /// <param name="item">Item to pass.</param>
        private void InvokeNextProcessor(ITelemetry item)
        {
            ITelemetryProcessor next = this.nextProcessorInPipeline;

            if (next != null)
            {
                next.Process(item);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="UserAgentTelemetryProcessor" /> class.
        /// </summary>
        /// <param name="next">Next TelemetryProcessor in call chain.</param>
        public UserAgentTelemetryProcessor(ITelemetryProcessor next)
        {
            if (next == null)
            {
                throw new ArgumentNullException("next");
            }

            this.Next = next;
        }
        internal SamplingTelemetryProcessor(ITelemetryProcessor unsampledNext, ITelemetryProcessor sampledNext) : this(sampledNext)
        {
            if (unsampledNext == null)
            {
                throw new ArgumentNullException("unsampledNext");
            }

            this.UnsampledNext = unsampledNext;
        }
示例#20
0
        public FakeTelemetryProcessor(ITelemetryProcessor next)
        {
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            this.next          = next;
            this.IsInitialized = false;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SamplingTelemetryProcessor"/> class.
        /// <param name="next">Next TelemetryProcessor in call chain.</param>
        /// </summary>
        public SamplingTelemetryProcessor(ITelemetryProcessor next)
        {
            if (next == null)
            {
                throw new ArgumentNullException("next");
            }

            this.SamplingPercentage = 100.0;
            this.Next = next;
        }
示例#22
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SamplingTelemetryProcessor"/> class.
        /// <param name="next">Next TelemetryProcessor in call chain.</param>
        /// </summary>
        public SamplingTelemetryProcessor(ITelemetryProcessor next)
        {
            if (next == null)
            {
                throw new ArgumentNullException("next");
            }

            this.SamplingPercentage = 100.0;
            this.Next = next;
        }
示例#23
0
 public AppInsightAggMetricSink(
     ITelemetryProcessor next,
     IConfiguration config,
     ILogger logger)
     : base(config: config,
            logger: logger,
            name: nameof(AppInsightAggMetricSink))
 {
     _next = next;
 }
示例#24
0
        public AppInsightGraphiteSink(
            ITelemetryProcessor next,
            IConfiguration config,
            ILogger logger)
            : base(config, logger, nameof(AppInsightGraphiteSink))
        {
            _next = next;

            config.GetSection(AppInsightsGraphiteConfig.EventTelemetryPropertiesSection).Bind(graphiteTelemetryProperties.EventTelemetryProperties);
        }
示例#25
0
        /// <summary>
        /// Initializes a new instance of the <see cref="QuickPulseTelemetryProcessor"/> class.
        /// </summary>
        /// <param name="next">The next TelemetryProcessor in the chain.</param>
        /// <exception cref="ArgumentNullException">Thrown if next is null.</exception>
        public QuickPulseTelemetryProcessor(ITelemetryProcessor next)
        {
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            this.Register();

            this.Next = next;
        }
示例#26
0
            public ITelemetryProcessor Create(ITelemetryProcessor next)
            {
                var snapshotConfigurationOptions = _serviceProvider.GetService <
                    IOptions <SnapshotCollectorConfiguration>
                    >();

                return(new SnapshotCollectorTelemetryProcessor(
                           next,
                           configuration: snapshotConfigurationOptions.Value
                           ));
            }
        /// <summary>
        /// Initializes a new instance of the <see cref="QuickPulseTelemetryProcessor"/> class.
        /// </summary>
        /// <param name="next">The next TelemetryProcessor in the chain.</param>
        /// <exception cref="ArgumentNullException">Thrown if next is null.</exception>
        public QuickPulseTelemetryProcessor(ITelemetryProcessor next)
        {
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            this.Register();

            this.Next = next;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AdaptiveSamplingTelemetryProcessor"/> class.
        /// <param name="settings">Sampling percentage estimator settings.</param>
        /// <param name="callback">Callback invoked every time sampling percentage is evaluated.</param>
        /// <param name="next">Next TelemetryProcessor in call chain.</param>
        /// </summary>
        public AdaptiveSamplingTelemetryProcessor(
            SamplingPercentageEstimatorSettings settings,
            AdaptiveSamplingPercentageEvaluatedCallback callback,
            ITelemetryProcessor next)
        {
            this.estimatorSettings = settings;
            this.evaluationCallback = callback;

            // make estimatortelemetry processor  work after sampling was done
            this.estimatorProcessor = new SamplingPercentageEstimatorTelemetryProcessor(settings, this.SamplingPercentageChanged, next);
            this.samplingProcessor = new SamplingTelemetryProcessor(this.estimatorProcessor);
        }
示例#29
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AdaptiveSamplingTelemetryProcessor"/> class.
        /// <param name="settings">Sampling percentage estimator settings.</param>
        /// <param name="callback">Callback invoked every time sampling percentage is evaluated.</param>
        /// <param name="next">Next TelemetryProcessor in call chain.</param>
        /// </summary>
        public AdaptiveSamplingTelemetryProcessor(
            SamplingPercentageEstimatorSettings settings,
            AdaptiveSamplingPercentageEvaluatedCallback callback,
            ITelemetryProcessor next)
        {
            this.estimatorSettings  = settings;
            this.evaluationCallback = callback;

            // make estimatortelemetry processor  work after sampling was done
            this.estimatorProcessor = new SamplingPercentageEstimatorTelemetryProcessor(settings, this.SamplingPercentageChanged, next);
            this.samplingProcessor  = new SamplingTelemetryProcessor(this.estimatorProcessor);
        }
        /// <summary>
        /// Builds the chain of linked <see cref="ITelemetryProcessor" /> instances and sets the same in configuration object passed.
        /// A special telemetry processor for handling Transmission is always appended as the last
        /// processor in the chain.
        /// </summary>
        public void Build()
        {
            var telemetryProcessorsList = new List <ITelemetryProcessor>();
            ITelemetryProcessor linkedTelemetryProcessor;

            if (this.telemetrySink == null)
            {
                // We are building the "common" telemetry processor chain.
                if (this.configuration.TelemetrySinks.Count == 1)
                {
                    // We just need to pass the telemetry directly into the (single) sink.
                    linkedTelemetryProcessor = new PassThroughProcessor(this.configuration.DefaultTelemetrySink);
                }
                else
                {
                    linkedTelemetryProcessor = new BroadcastProcessor(this.configuration.TelemetrySinks);
                }
            }
            else
            {
                linkedTelemetryProcessor = new TransmissionProcessor(this.telemetrySink);
            }

            telemetryProcessorsList.Add(linkedTelemetryProcessor);

            foreach (var generator in this.factories.AsEnumerable().Reverse())
            {
                ITelemetryProcessor prevTelemetryProcessor = linkedTelemetryProcessor;
                linkedTelemetryProcessor = generator.Invoke(linkedTelemetryProcessor);

                if (linkedTelemetryProcessor == null)
                {
                    // Loading of a telemetry processor failed, so skip it
                    // Error is logged when telemetry processor loading failed
                    linkedTelemetryProcessor = prevTelemetryProcessor;
                    continue;
                }

                telemetryProcessorsList.Add(linkedTelemetryProcessor);
            }

            var telemetryProcessorChain = new TelemetryProcessorChain(telemetryProcessorsList.AsEnumerable().Reverse());

            if (this.telemetrySink != null)
            {
                this.telemetrySink.TelemetryProcessorChain = telemetryProcessorChain;
            }
            else
            {
                this.configuration.TelemetryProcessorChain = telemetryProcessorChain;
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="AutocollectedMetricsExtractor" /> class.
        /// </summary>
        /// <param name="nextProcessorInPipeline">Subsequent telemetry processor.</param>
        public AutocollectedMetricsExtractor(ITelemetryProcessor nextProcessorInPipeline)
        {
            this.nextProcessorInPipeline = nextProcessorInPipeline;

            this.extractorForRequestMetrics    = new RequestMetricsExtractor();
            this.extractorForDependencyMetrics = new DependencyMetricsExtractor();

            this.extractors = new ExtractorWithInfo[]
            {
                new ExtractorWithInfo(this.extractorForRequestMetrics, GetExtractorInfo(this.extractorForRequestMetrics)),
                new ExtractorWithInfo(this.extractorForDependencyMetrics, GetExtractorInfo(this.extractorForDependencyMetrics)),
            };
        }
示例#32
0
 public TelemetryReplicationProcessor(ITelemetryProcessor next, AppId appId)
 {
     if (next == null)
     {
         throw new ArgumentNullException(nameof(next));
     }
     if (appId == null)
     {
         throw new ArgumentNullException(nameof(appId));
     }
     this.next  = next;
     this.appId = appId;
 }
示例#33
0
 public AggressivelySampleFastDependencies(ITelemetryProcessor next)
 {
     // Next TelemetryProcessor in the chain
     _next = next;
     this.samplingProcessor = new AdaptiveSamplingTelemetryProcessor(next)
     {
         ExcludedTypes = "Event",                                     // exclude custom events from being sampled
         MaxTelemetryItemsPerSecond        = 1,                       // default: 5 calls/sec
         SamplingPercentageIncreaseTimeout = TimeSpan.FromSeconds(1), // default: 2 min
         SamplingPercentageDecreaseTimeout = TimeSpan.FromSeconds(1), // default: 30 sec
         EvaluationInterval        = TimeSpan.FromSeconds(1),         // default: 15 sec
         InitialSamplingPercentage = 25,                              // default: 100%
     };
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="AdaptiveSamplingTelemetryProcessor"/> class.
        /// <param name="settings">Sampling percentage estimator settings.</param>
        /// <param name="callback">Callback invoked every time sampling percentage is evaluated.</param>
        /// <param name="next">Next TelemetryProcessor in call chain.</param>
        /// </summary>
        public AdaptiveSamplingTelemetryProcessor(
            Channel.Implementation.SamplingPercentageEstimatorSettings settings,
            Channel.Implementation.AdaptiveSamplingPercentageEvaluatedCallback callback,
            ITelemetryProcessor next)
        {
            this.estimatorSettings  = settings;
            this.evaluationCallback = callback;

            // make estimator telemetry processor  work after sampling was done
            this.estimatorProcessor = new SamplingPercentageEstimatorTelemetryProcessor(settings, this.SamplingPercentageChanged, next);
            this.samplingProcessor  = new SamplingTelemetryProcessor(next, this.estimatorProcessor)
            {
                SamplingPercentage = this.estimatorSettings.InitialSamplingPercentage,
            };
        }
示例#35
0
        /// <summary>
        /// Initializes a new instance of the <see cref="QuickPulseTelemetryProcessor"/> class. Internal constructor for unit tests only.
        /// </summary>
        /// <param name="next">The next TelemetryProcessor in the chain.</param>
        /// <param name="timeProvider">Time provider.</param>
        /// <param name="maxGlobalTelemetryQuota">Max overall telemetry quota.</param>
        /// <param name="initialGlobalTelemetryQuota">Initial overall telemetry quota.</param>
        /// <exception cref="ArgumentNullException">Thrown if next is null.</exception>
        internal QuickPulseTelemetryProcessor(
            ITelemetryProcessor next,
            Clock timeProvider,
            float?maxGlobalTelemetryQuota     = null,
            float?initialGlobalTelemetryQuota = null)
        {
            this.Next = next ?? throw new ArgumentNullException(nameof(next));

            this.RegisterSelfWithQuickPulseTelemetryModule();

            this.globalQuotaTracker = new QuickPulseQuotaTracker(
                timeProvider,
                maxGlobalTelemetryQuota ?? MaxGlobalTelemetryQuota,
                initialGlobalTelemetryQuota ?? InitialGlobalTelemetryQuota);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SamplingPercentageEstimatorTelemetryProcessor"/> class.
        /// <param name="settings">Dynamic sampling estimator settings.</param>
        /// <param name="callback">Callback to invoke every time sampling percentage is evaluated.</param>
        /// <param name="next">Next TelemetryProcessor in call chain.</param>
        /// </summary>
        public SamplingPercentageEstimatorTelemetryProcessor(
            SamplingPercentageEstimatorSettings settings, 
            AdaptiveSamplingPercentageEvaluatedCallback callback, 
            ITelemetryProcessor next)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            if (next == null)
            {
                throw new ArgumentNullException("next");
            }

            this.evaluationCallback = callback;
            this.settings = settings;
            this.next = next;

            this.currenSamplingRate = settings.EffectiveInitialSamplingRate;

            this.itemCount = new ExponentialMovingAverageCounter(settings.EffectiveMovingAverageRatio);

            this.samplingPercentageLastChangeDateTime = DateTimeOffset.UtcNow;

            // set evaluation interval to default value if it is negative or zero
            this.evaluationInterval = this.settings.EffectiveEvaluationInterval;

            // set up timer to run math to estimate sampling percentage
            this.evaluationTimer = new Timer(
                this.EstimateSamplingPercentage, 
                null,
                this.evaluationInterval,
                this.evaluationInterval);
        }
        /// <summary>
        /// Registers an instance of type <see cref="QuickPulseTelemetryProcessor"/> with this module.
        /// </summary>
        /// <remarks>This call is only necessary when the module is created in code and not in configuration.</remarks>
        /// <param name="telemetryProcessor">QuickPulseTelemetryProcessor instance to be registered with the module.</param>
        public void RegisterTelemetryProcessor(ITelemetryProcessor telemetryProcessor)
        {
            var quickPulseTelemetryProcessor = telemetryProcessor as IQuickPulseTelemetryProcessor;
            if (quickPulseTelemetryProcessor == null)
            {
                throw new ArgumentNullException(nameof(telemetryProcessor), @"The argument must be of type QuickPulseTelemetryProcessor");
            }

            lock (this.telemetryProcessorsLock)
            {
                const int MaxTelemetryProcessorCount = 100;
                if (!this.telemetryProcessors.Contains(quickPulseTelemetryProcessor))
                {
                    this.telemetryProcessors.AddLast(quickPulseTelemetryProcessor);

                    if (this.telemetryProcessors.Count > MaxTelemetryProcessorCount)
                    {
                        this.telemetryProcessors.RemoveFirst();
                    }

                    QuickPulseEventSource.Log.ProcessorRegistered(this.telemetryProcessors.Count.ToString(CultureInfo.InvariantCulture));
                }
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="StubTelemetryProcessor"/> class.
 /// </summary>
 public StubTelemetryProcessor(ITelemetryProcessor next)
 {
     this.next = next;
 }
 public TelemetryResponseCodeFilter(ITelemetryProcessor next)
 {
     Next = next;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="AdaptiveSamplingTelemetryProcessor"/> class.
 /// <param name="next">Next TelemetryProcessor in call chain.</param>
 /// </summary>
 public AdaptiveSamplingTelemetryProcessor(ITelemetryProcessor next)
     : this(new SamplingPercentageEstimatorSettings(), null, next)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="QuickPulseTelemetryProcessor"/> class.
 /// </summary>
 /// <param name="next">The next TelemetryProcessor in the chain.</param>
 /// <exception cref="ArgumentNullException">Thrown if next is null.</exception>
 public QuickPulseTelemetryProcessor(ITelemetryProcessor next)
     : this(next, new Clock())
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="StubTelemetryProcessor"/> class.
 /// </summary>
 public StubTelemetryProcessor(ITelemetryProcessor next)
 {
     this.OnProcess = telemetry => { };
     this.Next = next;
 }
 // Link processors to each other in a chain.
 public PingMeshExtension(ITelemetryProcessor next)
 {
     m_pingClient = new PingClient();
     this.Next = next;
 }