Example #1
0
        protected internal ProxyConnectionHandler(string host, int port,
                                                  WavefrontSdkMetricsRegistry sdkMetricsRegistry, string entityPrefix,
                                                  ILoggerFactory loggerFactory)
        {
            this.host          = host;
            this.port          = port;
            this.loggerFactory = loggerFactory;
            reconnectingSocket = null;

            this.sdkMetricsRegistry = sdkMetricsRegistry;
            this.entityPrefix       = string.IsNullOrWhiteSpace(entityPrefix) ? "" : entityPrefix + ".";
            errors        = this.sdkMetricsRegistry.DeltaCounter(this.entityPrefix + "errors");
            connectErrors = this.sdkMetricsRegistry.DeltaCounter(this.entityPrefix + "connect.errors");
        }
        internal void SetSdkMetricsRegistry(WavefrontSdkMetricsRegistry sdkMetricsRegistry)
        {
            this.sdkMetricsRegistry = sdkMetricsRegistry;

            // init internal metrics
            double sdkVersion = Utils.GetSemVer(Assembly.GetExecutingAssembly());

            this.sdkMetricsRegistry.Gauge("version", () => sdkVersion);
            this.sdkMetricsRegistry.Gauge("reporter.queue.size", () => spanBuffer.Count);
            this.sdkMetricsRegistry.Gauge("reporter.queue.remaining_capacity",
                                          () => spanBuffer.BoundedCapacity - spanBuffer.Count);
            spansReceived = this.sdkMetricsRegistry.DeltaCounter("reporter.spans.received");
            spansDropped  = this.sdkMetricsRegistry.DeltaCounter("reporter.spans.dropped");
            reportErrors  = this.sdkMetricsRegistry.DeltaCounter("reporter.errors");
        }
        internal WavefrontSpan(
            WavefrontTracer tracer, string operationName, WavefrontSpanContext spanContext,
            DateTime startTimestampUtc, IList <Reference> parents, IList <Reference> follows,
            IList <KeyValuePair <string, string> > tags)
        {
            this.tracer            = tracer;
            this.operationName     = operationName;
            this.spanContext       = spanContext;
            this.startTimestampUtc = startTimestampUtc;
            this.parents           = parents;
            this.follows           = follows;
            this.spanLogs          = new List <SpanLog>();

            IList <KeyValuePair <string, string> > globalTags = tracer.Tags;

            if ((globalTags == null || globalTags.Count == 0) && (tags == null || tags.Count == 0))
            {
                this.tags = null;
            }
            else
            {
                this.tags = new List <KeyValuePair <string, string> >();
            }
            this.singleValuedTags = null;
            if (globalTags != null)
            {
                foreach (var tag in globalTags)
                {
                    SetTagObject(tag.Key, tag.Value);
                }
            }
            if (tags != null)
            {
                foreach (var tag in tags)
                {
                    SetTagObject(tag.Key, tag.Value);
                }
            }

            spansDiscarded = tracer.SdkMetricsRegistry?.DeltaCounter("spans.discarded");
        }
        public MetricSnapshotWavefrontWriter(
            IWavefrontSender wavefrontSender,
            string source,
            IDictionary <string, string> globalTags,
            ISet <HistogramGranularity> histogramGranularities,
            WavefrontSdkMetricsRegistry sdkMetricsRegistry,
            MetricFields fields)
        {
            this.wavefrontSender        = wavefrontSender;
            this.source                 = source;
            this.globalTags             = globalTags;
            this.histogramGranularities = histogramGranularities;
            this.fields                 = fields;

            gaugesReported        = sdkMetricsRegistry.DeltaCounter("gauges.reported");
            deltaCountersReported = sdkMetricsRegistry.DeltaCounter("delta_counters.reported");
            countersReported      = sdkMetricsRegistry.DeltaCounter("counters.reported");
            wfHistogramsReported  = sdkMetricsRegistry.DeltaCounter("wavefront_histograms.reported");
            histogramsReported    = sdkMetricsRegistry.DeltaCounter("histograms.reported");
            metersReported        = sdkMetricsRegistry.DeltaCounter("meters.reported");
            timersReported        = sdkMetricsRegistry.DeltaCounter("timers.reported");
            apdexesReported       = sdkMetricsRegistry.DeltaCounter("apdexes.reported");
            writerErrors          = sdkMetricsRegistry.DeltaCounter("writer.errors");
        }
Example #5
0
        /// <summary>
        /// Initializes a new instance of the
        /// <see cref="T:Wavefront.SDK.CSharp.Common.ReconnectingSocket"/> class.
        /// </summary>
        /// <param name="host">The hostname of the Wavefront proxy.</param>
        /// <param name="port">The port number of the Wavefront proxy to connect to.</param>
        /// <param name="loggerFactory">The logger factory used to create a logger.</param>
        public ReconnectingSocket(string host, int port,
                                  WavefrontSdkMetricsRegistry sdkMetricsRegistry, string entityPrefix,
                                  ILoggerFactory loggerFactory)
        {
            this.host = host;
            this.port = port;
            logger    = loggerFactory.CreateLogger <ReconnectingSocket>() ??
                        throw new ArgumentNullException(nameof(loggerFactory));

            entityPrefix   = string.IsNullOrWhiteSpace(entityPrefix) ? "" : entityPrefix + ".";
            writeSuccesses = sdkMetricsRegistry.DeltaCounter(entityPrefix + "write.success");
            writeErrors    = sdkMetricsRegistry.DeltaCounter(entityPrefix + "write.errors");
            flushSuccesses = sdkMetricsRegistry.DeltaCounter(entityPrefix + "flush.success");
            flushErrors    = sdkMetricsRegistry.DeltaCounter(entityPrefix + "flush.errors");
            resetSuccesses = sdkMetricsRegistry.DeltaCounter(entityPrefix + "reset.success");
            resetErrors    = sdkMetricsRegistry.DeltaCounter(entityPrefix + "reset.errors");

            client = new TcpClient
            {
                ReceiveTimeout = serverReadTimeoutMillis
            };
            // Block while attempting to establish a connection
            ConnectAsync(false).GetAwaiter().GetResult();
        }
Example #6
0
        public WavefrontReporter(MetricsReportingWavefrontOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (options.WavefrontSender == null)
            {
                throw new ArgumentNullException(
                          nameof(MetricsReportingWavefrontOptions.WavefrontSender));
            }

            wavefrontSender = options.WavefrontSender;

            source = options.Source;

            if (options.ApplicationTags != null)
            {
                globalTags = new Dictionary <string, string>(options.ApplicationTags.ToPointTags());
            }
            else
            {
                globalTags = new Dictionary <string, string>();
            }

            histogramGranularities = new HashSet <HistogramGranularity>();
            if (options.WavefrontHistogram.ReportMinuteDistribution)
            {
                histogramGranularities.Add(HistogramGranularity.Minute);
            }
            if (options.WavefrontHistogram.ReportHourDistribution)
            {
                histogramGranularities.Add(HistogramGranularity.Hour);
            }
            if (options.WavefrontHistogram.ReportDayDistribution)
            {
                histogramGranularities.Add(HistogramGranularity.Day);
            }

            if (options.FlushInterval < TimeSpan.Zero)
            {
                throw new InvalidOperationException(
                          $"{nameof(MetricsReportingWavefrontOptions.FlushInterval)} " +
                          "must not be less than zero");
            }

            Filter = options.Filter;

            FlushInterval = options.FlushInterval > TimeSpan.Zero
                ? options.FlushInterval
                : AppMetricsConstants.Reporting.DefaultFlushInterval;

            // Formatting will be handled by the Wavefront sender.
            Formatter = null;

            metricFields = options.MetricFields ?? new MetricFields();

            var registryBuilder = new WavefrontSdkMetricsRegistry.Builder(wavefrontSender)
                                  .Prefix(Constants.SdkMetricPrefix + ".app_metrics")
                                  .Source(source)
                                  .Tags(globalTags);

            if (options.LoggerFactory != null)
            {
                registryBuilder.LoggerFactory(options.LoggerFactory);
            }
            sdkMetricsRegistry = registryBuilder.Build();

            reporterErrors = sdkMetricsRegistry.DeltaCounter("reporter.errors");

            double sdkVersion = Utils.GetSemVer(Assembly.GetExecutingAssembly());

            sdkMetricsRegistry.Gauge("version", () => sdkVersion);

            Logger.Info($"Using Wavefront Reporter {this}. FlushInterval: {FlushInterval}");
        }
        private void InternalFlush(BlockingCollection <string> buffer, string format,
                                   string entityPrefix, WavefrontSdkDeltaCounter dropped, WavefrontSdkDeltaCounter reportErrors)
        {
            var batch = GetBatch(buffer);

            if (batch.Count == 0)
            {
                return;
            }

            try
            {
                using (var stream = BatchToStream(batch))
                {
                    int statusCode = directService.Report(format, stream);
                    sdkMetricsRegistry.DeltaCounter(entityPrefix + ".report." + statusCode).Inc();
                    if ((statusCode >= 400 && statusCode < 600) || statusCode == Constants.HttpNoResponse)
                    {
                        switch (statusCode)
                        {
                        case 401:
                            logger.LogWarning("Error sending " + entityPrefix + " to Wavefront (HTTP " + statusCode + "). " +
                                              "Please verify that your API Token is correct! All " + entityPrefix + " are " +
                                              "discarded.");
                            dropped.Inc(batch.Count);
                            break;

                        case 403:
                            if (format.Equals(Constants.WavefrontMetricFormat))
                            {
                                logger.LogWarning("Error sending " + entityPrefix + " to Wavefront (HTTP " + statusCode + "). " +
                                                  "Please verify that Direct Data Ingestion is enabled for your account! " +
                                                  "All " + entityPrefix + " are discarded.");
                            }
                            else
                            {
                                logger.LogWarning("Error sending " + entityPrefix + " to Wavefront (HTTP " + statusCode + "). " +
                                                  "Please verify that Direct Data Ingestion and " + entityPrefix + " are " +
                                                  "enabled for your account! All " + entityPrefix + " are discarded.");
                            }
                            dropped.Inc(batch.Count);
                            break;

                        default:
                            logger.LogWarning("Error sending " + entityPrefix + " to Wavefront (HTTP " + statusCode + "). Data " +
                                              "will be requeued and resent.");
                            int numAddedBackToBuffer = 0;
                            foreach (var item in batch)
                            {
                                if (buffer.TryAdd(item))
                                {
                                    numAddedBackToBuffer++;
                                }
                                else
                                {
                                    int numDropped = batch.Count - numAddedBackToBuffer;
                                    dropped.Inc(numDropped);
                                    logger.LogWarning("Buffer full, dropping " + numDropped + " " + entityPrefix + ". Consider increasing " +
                                                      "the batch size of your sender to increase throughput.");
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }
            }
            catch (IOException e) {
                dropped.Inc(batch.Count);
                reportErrors.Inc();
                throw e;
            }
        }