internal void ReportSpan(WavefrontSpan span) { // Reporter will flush it to Wavefront/proxy. try { reporter.Report(span); } catch (IOException e) { logger.LogWarning(0, e, "Error reporting span"); } }
internal void ReportWavefrontGeneratedData(WavefrontSpan span) { if (metricsRoot == null) { /* * WavefrontSpanReporter not set, so no tracing spans will be reported as * metrics/histograms. */ return; } var pointTagsDict = new Dictionary <string, string> { { Constants.ComponentTagKey, span.GetComponentTagValue() } }; var spanTags = span.GetTagsAsMap(); bool customTagMatch = false; if (redMetricsCustomTagKeys.Count > 0) { foreach (string customTagKey in redMetricsCustomTagKeys) { if (spanTags.ContainsKey(customTagKey)) { customTagMatch = true; // Assuming at least one value exists pointTagsDict[customTagKey] = spanTags[customTagKey].First(); } else if (customTagKey == SpanKind.Key) { customTagMatch = true; // Promote a default value for span.kind even if span doesn't have the tag pointTagsDict[customTagKey] = Constants.NullTagValue; } } } // Promote http.status_code if (spanTags.ContainsKey(HttpStatus.Key) && !pointTagsDict.ContainsKey(HttpStatus.Key)) { customTagMatch = true; string httpStatusValue = spanTags[HttpStatus.Key].First(); pointTagsDict[HttpStatus.Key] = httpStatusValue; } string application = span.GetSingleValuedTagValue(Constants.ApplicationTagKey) ?? applicationTags.Application; string service = span.GetSingleValuedTagValue(Constants.ServiceTagKey) ?? applicationTags.Service; pointTagsDict[Constants.ApplicationTagKey] = application; pointTagsDict[Constants.ServiceTagKey] = service; pointTagsDict[Constants.ClusterTagKey] = span.GetSingleValuedTagValue(Constants.ClusterTagKey) ?? applicationTags.Cluster; pointTagsDict[Constants.ShardTagKey] = span.GetSingleValuedTagValue(Constants.ShardTagKey) ?? applicationTags.Shard; var pointTags = MetricTags.Concat( new MetricTags(OperationNameTag, span.GetOperationName()), pointTagsDict); // Propagate custom tags to ~component.heartbeat if (heartbeaterService != null && customTagMatch) { heartbeaterService.ReportCustomTags(pointTagsDict); } string metricNamePrefix = $"{application}.{service}.{span.GetOperationName()}"; metricsRoot.Measure.Counter.Increment(new DeltaCounterOptions .Builder(metricNamePrefix + InvocationSuffix).Tags(pointTags).Build()); if (span.IsError()) { metricsRoot.Measure.Counter.Increment(new DeltaCounterOptions .Builder(metricNamePrefix + ErrorSuffix).Tags(pointTags).Build()); } long spanDurationMicros = span.GetDurationMicros(); // Convert duration from micros to millis and add to duration counter metricsRoot.Measure.Counter.Increment(new DeltaCounterOptions .Builder(metricNamePrefix + TotalTimeSuffix).Tags(pointTags).Build(), spanDurationMicros / 1000); // Update histogram with duration in micros if (span.IsError()) { metricsRoot.Measure.Histogram.Update( new WavefrontHistogramOptions.Builder(metricNamePrefix + DurationSuffix) .Tags(MetricTags.Concat(pointTags, new MetricTags("error", "true"))) .Build(), spanDurationMicros); } else { metricsRoot.Measure.Histogram.Update( new WavefrontHistogramOptions.Builder(metricNamePrefix + DurationSuffix) .Tags(pointTags) .Build(), spanDurationMicros); } }