Exemplo n.º 1
0
        /// <summary>
        ///     Transmits the current contents of the span buffer to the SplunkTracing Collector.
        ///     Note that this creates a copy of the current spans and clears the span buffer!
        /// </summary>
        public async void Flush()
        {
            if (_options.Run)
            {
                if (_options.EnableMetaEventLogging && _firstReportHasRun == false)
                {
                    BuildSpan(SplunkTracingConstants.MetaEvent.TracerCreateOperation)
                    .IgnoreActiveSpan()
                    .WithTag(SplunkTracingConstants.MetaEvent.MetaEventKey, true)
                    .WithTag(SplunkTracingConstants.MetaEvent.TracerGuidKey, _options.TracerGuid)
                    .Start()
                    .Finish();
                    _firstReportHasRun = true;
                }
                // save current spans and clear the buffer
                ISpanRecorder currentBuffer;
                lock (_lock)
                {
                    currentBuffer = _spanRecorder.GetSpanBuffer();
                    _spanRecorder = new SplunkTracingSpanRecorder();
                    _logger.Trace($"{currentBuffer.GetSpans().Count()} spans in buffer.");
                }

                /**
                 * there are two ways spans can be dropped:
                 * 1. the buffer drops a span because it's too large, malformed, etc.
                 * 2. the report failed to be sent to the collector.
                 * since flush is async and there can potentially be any number of buffers in flight to the collector,
                 * we need to set the current drop count on the tracer to be the amount of dropped spans from the buffer
                 * plus the existing dropped spans, then mutate the current buffer to this new total value.
                 */
                currentDroppedSpanCount       += currentBuffer.DroppedSpanCount;
                currentBuffer.DroppedSpanCount = currentDroppedSpanCount;

                if (currentBuffer.GetSpans().Count() > 0)
                {
                    try
                    {
                        // since translate can throw exceptions, place it in the try and drop spans as appropriate
                        var data = _httpClient.Translate(currentBuffer);
                        var resp = await _httpClient.SendReport(data);

                        if (resp.code > 0)
                        {
                            _logger.Warn($"Errors in report: {resp.text}");
                        }
                        // if the collector is in developer mode, set the tracer to development mode as well
                        // don't re-enable if it's already enabled though
                        // TODO: iterate through all commands to find devmode flag
                        if (_options.EnableMetaEventLogging == false)
                        {
                            _logger.Info("Enabling meta event logging");
                            _options.EnableMetaEventLogging = true;
                        }

                        lock (_lock)
                        {
                            _logger.Trace($"Resetting tracer dropped span count as the last report was successful.");
                            currentDroppedSpanCount = 0;
                        }
                    }
                    catch (Exception ex) when(ex is HttpRequestException || ex is TaskCanceledException || ex is OperationCanceledException || ex is Exception)
                    {
                        lock (_lock)
                        {
                            _logger.Warn($"Adding {currentBuffer.GetSpans().Count()} spans to dropped span count (current total: {currentDroppedSpanCount})");
                            _logger.Warn($"Exception: {ex}");
                            currentDroppedSpanCount += currentBuffer.GetSpans().Count();
                            if (this._options.ExceptionHandlerRegistered)
                            {
                                this._options.ExceptionHandler.Invoke(ex);
                            }
                        }
                    }
                }
            }
        }