use of wavefront.report.SpanLogs in project java by wavefrontHQ.
the class WavefrontPortUnificationHandler method processLine.
/**
* @param ctx ChannelHandler context (to retrieve remote client's IP in case of errors)
* @param message line being processed
*/
@Override
protected void processLine(final ChannelHandlerContext ctx, @Nonnull String message, @Nullable DataFormat format) {
DataFormat dataFormat = format == null ? DataFormat.autodetect(message) : format;
switch(dataFormat) {
case SOURCE_TAG:
ReportableEntityHandler<ReportSourceTag, SourceTag> sourceTagHandler = sourceTagHandlerSupplier.get();
if (sourceTagHandler == null || sourceTagDecoder == null) {
wavefrontHandler.reject(message, "Port is not configured to accept " + "sourceTag-formatted data!");
return;
}
List<ReportSourceTag> output = new ArrayList<>(1);
try {
sourceTagDecoder.decode(message, output, "dummy");
for (ReportSourceTag tag : output) {
sourceTagHandler.report(tag);
}
} catch (Exception e) {
sourceTagHandler.reject(message, formatErrorMessage("WF-300 Cannot parse sourceTag: \"" + message + "\"", e, ctx));
}
return;
case EVENT:
ReportableEntityHandler<ReportEvent, ReportEvent> eventHandler = eventHandlerSupplier.get();
if (eventHandler == null || eventDecoder == null) {
wavefrontHandler.reject(message, "Port is not configured to accept event data!");
return;
}
List<ReportEvent> events = new ArrayList<>(1);
try {
eventDecoder.decode(message, events, "dummy");
for (ReportEvent event : events) {
eventHandler.report(event);
}
} catch (Exception e) {
eventHandler.reject(message, formatErrorMessage("WF-300 Cannot parse event: \"" + message + "\"", e, ctx));
}
return;
case SPAN:
ReportableEntityHandler<Span, String> spanHandler = spanHandlerSupplier.get();
if (spanHandler == null || spanDecoder == null) {
wavefrontHandler.reject(message, "Port is not configured to accept " + "tracing data (spans)!");
return;
}
message = annotator == null ? message : annotator.apply(ctx, message);
receivedSpansTotal.get().inc();
preprocessAndHandleSpan(message, spanDecoder, spanHandler, spanHandler::report, preprocessorSupplier, ctx, span -> sampler.sample(span, discardedSpansBySampler.get()));
return;
case SPAN_LOG:
if (isFeatureDisabled(spanLogsDisabled, SPANLOGS_DISABLED, discardedSpanLogs.get()))
return;
ReportableEntityHandler<SpanLogs, String> spanLogsHandler = spanLogsHandlerSupplier.get();
if (spanLogsHandler == null || spanLogsDecoder == null || spanDecoder == null) {
wavefrontHandler.reject(message, "Port is not configured to accept " + "tracing data (span logs)!");
return;
}
handleSpanLogs(message, spanLogsDecoder, spanDecoder, spanLogsHandler, preprocessorSupplier, ctx, span -> sampler.sample(span, discardedSpanLogsBySampler.get()));
return;
case HISTOGRAM:
if (isFeatureDisabled(histogramDisabled, HISTO_DISABLED, discardedHistograms.get()))
return;
ReportableEntityHandler<ReportPoint, String> histogramHandler = histogramHandlerSupplier.get();
if (histogramHandler == null || histogramDecoder == null) {
wavefrontHandler.reject(message, "Port is not configured to accept " + "histogram-formatted data!");
return;
}
message = annotator == null ? message : annotator.apply(ctx, message);
preprocessAndHandlePoint(message, histogramDecoder, histogramHandler, preprocessorSupplier, ctx, "histogram");
return;
default:
message = annotator == null ? message : annotator.apply(ctx, message);
preprocessAndHandlePoint(message, wavefrontDecoder, wavefrontHandler, preprocessorSupplier, ctx, "metric");
}
}
use of wavefront.report.SpanLogs in project java by wavefrontHQ.
the class RelayPortUnificationHandler method handleHttpMessage.
@Override
protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttpRequest request) {
URI uri = URI.create(request.uri());
StringBuilder output = new StringBuilder();
String path = uri.getPath();
final boolean isDirectIngestion = path.startsWith("/report");
if (path.endsWith("/checkin") && (path.startsWith("/api/daemon") || path.contains("wfproxy"))) {
// simulate checkin response for proxy chaining
ObjectNode jsonResponse = JsonNodeFactory.instance.objectNode();
jsonResponse.put("currentTime", Clock.now());
jsonResponse.put("allowAnyHostKeys", true);
writeHttpResponse(ctx, HttpResponseStatus.OK, jsonResponse, request);
return;
}
String format = URLEncodedUtils.parse(uri, CharsetUtil.UTF_8).stream().filter(x -> x.getName().equals("format") || x.getName().equals("f")).map(NameValuePair::getValue).findFirst().orElse(Constants.PUSH_FORMAT_WAVEFRONT);
// Return HTTP 200 (OK) for payloads received on the proxy endpoint
// Return HTTP 202 (ACCEPTED) for payloads received on the DDI endpoint
// Return HTTP 204 (NO_CONTENT) for payloads received on all other endpoints
HttpResponseStatus okStatus;
if (isDirectIngestion) {
okStatus = HttpResponseStatus.ACCEPTED;
} else if (path.contains("/pushdata/") || path.contains("wfproxy/report")) {
okStatus = HttpResponseStatus.OK;
} else {
okStatus = HttpResponseStatus.NO_CONTENT;
}
HttpResponseStatus status;
switch(format) {
case Constants.PUSH_FORMAT_HISTOGRAM:
if (isFeatureDisabled(histogramDisabled, HISTO_DISABLED, discardedHistograms.get(), output, request)) {
status = HttpResponseStatus.FORBIDDEN;
break;
}
case Constants.PUSH_FORMAT_WAVEFRONT:
case Constants.PUSH_FORMAT_GRAPHITE_V2:
AtomicBoolean hasSuccessfulPoints = new AtomicBoolean(false);
try {
// noinspection unchecked
ReportableEntityDecoder<String, ReportPoint> histogramDecoder = (ReportableEntityDecoder<String, ReportPoint>) decoders.get(ReportableEntityType.HISTOGRAM);
Splitter.on('\n').trimResults().omitEmptyStrings().split(request.content().toString(CharsetUtil.UTF_8)).forEach(message -> {
DataFormat dataFormat = DataFormat.autodetect(message);
switch(dataFormat) {
case EVENT:
wavefrontHandler.reject(message, "Relay port does not support " + "event-formatted data!");
break;
case SOURCE_TAG:
wavefrontHandler.reject(message, "Relay port does not support " + "sourceTag-formatted data!");
break;
case HISTOGRAM:
if (isFeatureDisabled(histogramDisabled, HISTO_DISABLED, discardedHistograms.get(), output)) {
break;
}
preprocessAndHandlePoint(message, histogramDecoder, histogramHandlerSupplier.get(), preprocessorSupplier, ctx, "histogram");
hasSuccessfulPoints.set(true);
break;
default:
// only apply annotator if point received on the DDI endpoint
message = annotator != null && isDirectIngestion ? annotator.apply(ctx, message) : message;
preprocessAndHandlePoint(message, wavefrontDecoder, wavefrontHandler, preprocessorSupplier, ctx, "metric");
hasSuccessfulPoints.set(true);
break;
}
});
status = hasSuccessfulPoints.get() ? okStatus : HttpResponseStatus.BAD_REQUEST;
} catch (Exception e) {
status = HttpResponseStatus.BAD_REQUEST;
output.append(errorMessageWithRootCause(e));
logWarning("WF-300: Failed to handle HTTP POST", e, ctx);
}
break;
case Constants.PUSH_FORMAT_TRACING:
if (isFeatureDisabled(traceDisabled, SPAN_DISABLED, discardedSpans.get(), output, request)) {
receivedSpansTotal.get().inc(discardedSpans.get().count());
status = HttpResponseStatus.FORBIDDEN;
break;
}
List<Span> spans = new ArrayList<>();
// noinspection unchecked
ReportableEntityDecoder<String, Span> spanDecoder = (ReportableEntityDecoder<String, Span>) decoders.get(ReportableEntityType.TRACE);
ReportableEntityHandler<Span, String> spanHandler = spanHandlerSupplier.get();
Splitter.on('\n').trimResults().omitEmptyStrings().split(request.content().toString(CharsetUtil.UTF_8)).forEach(line -> {
try {
receivedSpansTotal.get().inc();
spanDecoder.decode(line, spans, "dummy");
} catch (Exception e) {
spanHandler.reject(line, formatErrorMessage(line, e, ctx));
}
});
spans.forEach(spanHandler::report);
status = okStatus;
break;
case Constants.PUSH_FORMAT_TRACING_SPAN_LOGS:
if (isFeatureDisabled(spanLogsDisabled, SPANLOGS_DISABLED, discardedSpanLogs.get(), output, request)) {
status = HttpResponseStatus.FORBIDDEN;
break;
}
List<SpanLogs> spanLogs = new ArrayList<>();
// noinspection unchecked
ReportableEntityDecoder<JsonNode, SpanLogs> spanLogDecoder = (ReportableEntityDecoder<JsonNode, SpanLogs>) decoders.get(ReportableEntityType.TRACE_SPAN_LOGS);
ReportableEntityHandler<SpanLogs, String> spanLogsHandler = spanLogsHandlerSupplier.get();
Splitter.on('\n').trimResults().omitEmptyStrings().split(request.content().toString(CharsetUtil.UTF_8)).forEach(line -> {
try {
spanLogDecoder.decode(JSON_PARSER.readTree(line), spanLogs, "dummy");
} catch (Exception e) {
spanLogsHandler.reject(line, formatErrorMessage(line, e, ctx));
}
});
spanLogs.forEach(spanLogsHandler::report);
status = okStatus;
break;
default:
status = HttpResponseStatus.BAD_REQUEST;
logger.warning("Unexpected format for incoming HTTP request: " + format);
}
writeHttpResponse(ctx, status, output, request);
}
use of wavefront.report.SpanLogs in project java by wavefrontHQ.
the class ZipkinPortUnificationHandler method processZipkinSpan.
private void processZipkinSpan(zipkin2.Span zipkinSpan) {
if (ZIPKIN_DATA_LOGGER.isLoggable(Level.FINEST)) {
ZIPKIN_DATA_LOGGER.info("Inbound Zipkin span: " + zipkinSpan.toString());
}
// Add application tags, span references, span kind and http uri, responses etc.
List<Annotation> annotations = new ArrayList<>();
// Add original Zipkin trace and span ids as tags to make finding them easier
annotations.add(new Annotation("zipkinSpanId", zipkinSpan.id()));
annotations.add(new Annotation("zipkinTraceId", zipkinSpan.traceId()));
// Set Span's References.
if (zipkinSpan.parentId() != null) {
annotations.add(new Annotation(TraceConstants.PARENT_KEY, Utils.convertToUuidString(zipkinSpan.parentId())));
}
// Set Span Kind.
if (zipkinSpan.kind() != null) {
String kind = zipkinSpan.kind().toString().toLowerCase();
annotations.add(new Annotation("span.kind", kind));
if (zipkinSpan.annotations() != null && !zipkinSpan.annotations().isEmpty()) {
annotations.add(new Annotation("_spanSecondaryId", kind));
}
}
// Set Span's service name.
String serviceName = zipkinSpan.localServiceName() == null ? DEFAULT_SERVICE : zipkinSpan.localServiceName();
annotations.add(new Annotation(SERVICE_TAG_KEY, serviceName));
String applicationName = this.proxyLevelApplicationName;
String cluster = NULL_TAG_VAL;
String shard = NULL_TAG_VAL;
String componentTagValue = NULL_TAG_VAL;
boolean isError = false;
boolean isDebugSpanTag = false;
// Set all other Span Tags.
Set<String> ignoreKeys = new HashSet<>(ImmutableSet.of(SOURCE_KEY));
if (zipkinSpan.tags() != null && zipkinSpan.tags().size() > 0) {
for (Map.Entry<String, String> tag : zipkinSpan.tags().entrySet()) {
if (!ignoreKeys.contains(tag.getKey().toLowerCase()) && !StringUtils.isBlank(tag.getValue())) {
Annotation annotation = new Annotation(tag.getKey(), tag.getValue());
switch(annotation.getKey()) {
case APPLICATION_TAG_KEY:
applicationName = annotation.getValue();
continue;
case CLUSTER_TAG_KEY:
cluster = annotation.getValue();
continue;
case SHARD_TAG_KEY:
shard = annotation.getValue();
continue;
case COMPONENT_TAG_KEY:
componentTagValue = annotation.getValue();
break;
case ERROR_SPAN_TAG_KEY:
isError = true;
// Ignore the original error value
annotation.setValue(ERROR_SPAN_TAG_VAL);
break;
case DEBUG_TAG_KEY:
isDebugSpanTag = annotation.getValue().equals(DEBUG_SPAN_TAG_VAL);
break;
}
annotations.add(annotation);
}
}
}
// Add all wavefront indexed tags. These are set based on below hierarchy.
// Span Level > Proxy Level > Default
annotations.add(new Annotation(APPLICATION_TAG_KEY, applicationName));
annotations.add(new Annotation(CLUSTER_TAG_KEY, cluster));
annotations.add(new Annotation(SHARD_TAG_KEY, shard));
// Add Sampling related annotations.
// Add a debug span tag as needed to enable sampling of this span with intelligent sampling.
boolean isDebug = zipkinSpan.debug() != null ? zipkinSpan.debug() : false;
if (!isDebugSpanTag && isDebug) {
annotations.add(new Annotation(DEBUG_SPAN_TAG_KEY, DEBUG_SPAN_TAG_VAL));
}
// Add additional annotations.
if (zipkinSpan.localEndpoint() != null && zipkinSpan.localEndpoint().ipv4() != null) {
annotations.add(new Annotation("ipv4", zipkinSpan.localEndpoint().ipv4()));
}
if (!spanLogsDisabled.get() && zipkinSpan.annotations() != null && !zipkinSpan.annotations().isEmpty()) {
annotations.add(new Annotation("_spanLogs", "true"));
}
/* Add source of the span following the below:
* 1. If "source" is provided by span tags , use it else
* 2. Default "source" to "zipkin".
*/
String sourceName = DEFAULT_SOURCE;
if (zipkinSpan.tags() != null && zipkinSpan.tags().size() > 0) {
if (zipkinSpan.tags().get(SOURCE_KEY) != null) {
sourceName = zipkinSpan.tags().get(SOURCE_KEY);
}
}
// Set spanName.
String spanName = zipkinSpan.name() == null ? DEFAULT_SPAN_NAME : zipkinSpan.name();
String spanId = Utils.convertToUuidString(zipkinSpan.id());
String traceId = Utils.convertToUuidString(zipkinSpan.traceId());
// Build wavefront span
Span wavefrontSpan = Span.newBuilder().setCustomer("dummy").setName(spanName).setSource(sourceName).setSpanId(spanId).setTraceId(traceId).setStartMillis(zipkinSpan.timestampAsLong() / 1000).setDuration(zipkinSpan.durationAsLong() / 1000).setAnnotations(annotations).build();
if (zipkinSpan.tags().containsKey(SPAN_TAG_ERROR)) {
if (ZIPKIN_DATA_LOGGER.isLoggable(Level.FINER)) {
ZIPKIN_DATA_LOGGER.info("Span id :: " + spanId + " with trace id :: " + traceId + " , includes error tag :: " + zipkinSpan.tags().get(SPAN_TAG_ERROR));
}
}
// Log Zipkin spans as well as Wavefront spans for debugging purposes.
if (ZIPKIN_DATA_LOGGER.isLoggable(Level.FINEST)) {
ZIPKIN_DATA_LOGGER.info("Converted Wavefront span: " + wavefrontSpan.toString());
}
if (preprocessorSupplier != null) {
ReportableEntityPreprocessor preprocessor = preprocessorSupplier.get();
String[] messageHolder = new String[1];
preprocessor.forSpan().transform(wavefrontSpan);
if (!preprocessor.forSpan().filter(wavefrontSpan, messageHolder)) {
if (messageHolder[0] != null) {
spanHandler.reject(wavefrontSpan, messageHolder[0]);
} else {
spanHandler.block(wavefrontSpan);
}
return;
}
}
if (sampler.sample(wavefrontSpan, discardedSpansBySampler)) {
spanHandler.report(wavefrontSpan);
if (zipkinSpan.annotations() != null && !zipkinSpan.annotations().isEmpty() && !isFeatureDisabled(spanLogsDisabled, SPANLOGS_DISABLED, null)) {
SpanLogs spanLogs = SpanLogs.newBuilder().setCustomer("default").setTraceId(wavefrontSpan.getTraceId()).setSpanId(wavefrontSpan.getSpanId()).setSpanSecondaryId(zipkinSpan.kind() != null ? zipkinSpan.kind().toString().toLowerCase() : null).setLogs(zipkinSpan.annotations().stream().map(x -> SpanLog.newBuilder().setTimestamp(x.timestamp()).setFields(ImmutableMap.of("annotation", x.value())).build()).collect(Collectors.toList())).build();
spanLogsHandler.report(spanLogs);
}
}
// report stats irrespective of span sampling.
if (wfInternalReporter != null) {
// Set post preprocessor rule values and report converted metrics/histograms from the span
List<Annotation> processedAnnotations = wavefrontSpan.getAnnotations();
for (Annotation processedAnnotation : processedAnnotations) {
switch(processedAnnotation.getKey()) {
case APPLICATION_TAG_KEY:
applicationName = processedAnnotation.getValue();
continue;
case SERVICE_TAG_KEY:
serviceName = processedAnnotation.getValue();
continue;
case CLUSTER_TAG_KEY:
cluster = processedAnnotation.getValue();
continue;
case SHARD_TAG_KEY:
shard = processedAnnotation.getValue();
continue;
case COMPONENT_TAG_KEY:
componentTagValue = processedAnnotation.getValue();
continue;
case ERROR_TAG_KEY:
isError = true;
continue;
}
}
List<Pair<String, String>> spanTags = processedAnnotations.stream().map(a -> new Pair<>(a.getKey(), a.getValue())).collect(Collectors.toList());
discoveredHeartbeatMetrics.add(reportWavefrontGeneratedData(wfInternalReporter, wavefrontSpan.getName(), applicationName, serviceName, cluster, shard, wavefrontSpan.getSource(), componentTagValue, isError, zipkinSpan.durationAsLong(), traceDerivedCustomTagKeys, spanTags, true));
}
}
use of wavefront.report.SpanLogs in project java by wavefrontHQ.
the class SpanUtils method handleSpanLogs.
/**
* Handle spanLogs.
*
* @param message encoded spanLogs data.
* @param spanLogsDecoder spanLogs decoder.
* @param spanDecoder span decoder.
* @param handler spanLogs handler.
* @param preprocessorSupplier spanLogs preprocessor.
* @param ctx channel handler context.
* @param samplerFunc span sampler.
*/
public static void handleSpanLogs(String message, ReportableEntityDecoder<JsonNode, SpanLogs> spanLogsDecoder, ReportableEntityDecoder<String, Span> spanDecoder, ReportableEntityHandler<SpanLogs, String> handler, @Nullable Supplier<ReportableEntityPreprocessor> preprocessorSupplier, @Nullable ChannelHandlerContext ctx, Function<Span, Boolean> samplerFunc) {
List<SpanLogs> spanLogsOutput = new ArrayList<>(1);
try {
spanLogsDecoder.decode(JSON_PARSER.readTree(message), spanLogsOutput, "dummy");
} catch (Exception e) {
handler.reject(message, formatErrorMessage(message, e, ctx));
return;
}
for (SpanLogs spanLogs : spanLogsOutput) {
String spanMessage = spanLogs.getSpan();
if (spanMessage == null) {
// For backwards compatibility, report the span logs if span line data is not
// included
handler.report(spanLogs);
} else {
ReportableEntityPreprocessor preprocessor = preprocessorSupplier == null ? null : preprocessorSupplier.get();
String[] spanMessageHolder = new String[1];
// transform the line if needed
if (preprocessor != null) {
spanMessage = preprocessor.forPointLine().transform(spanMessage);
if (!preprocessor.forPointLine().filter(message, spanMessageHolder)) {
if (spanMessageHolder[0] != null) {
handler.reject(spanLogs, spanMessageHolder[0]);
} else {
handler.block(spanLogs);
}
return;
}
}
List<Span> spanOutput = new ArrayList<>(1);
try {
spanDecoder.decode(spanMessage, spanOutput, "dummy");
} catch (Exception e) {
handler.reject(spanLogs, formatErrorMessage(message, e, ctx));
return;
}
if (!spanOutput.isEmpty()) {
Span span = spanOutput.get(0);
if (preprocessor != null) {
preprocessor.forSpan().transform(span);
if (!preprocessor.forSpan().filter(span, spanMessageHolder)) {
if (spanMessageHolder[0] != null) {
handler.reject(spanLogs, spanMessageHolder[0]);
} else {
handler.block(spanLogs);
}
return;
}
}
if (samplerFunc.apply(span)) {
// after sampling, span line data is no longer needed
spanLogs.setSpan(null);
handler.report(spanLogs);
}
}
}
}
}
use of wavefront.report.SpanLogs in project java by wavefrontHQ.
the class JaegerProtobufUtils method processSpan.
private static void processSpan(Model.Span span, String serviceName, String sourceName, String applicationName, String cluster, String shard, List<Annotation> processAnnotations, ReportableEntityHandler<Span, String> spanHandler, ReportableEntityHandler<SpanLogs, String> spanLogsHandler, @Nullable WavefrontInternalReporter wfInternalReporter, Supplier<Boolean> spanLogsDisabled, Supplier<ReportableEntityPreprocessor> preprocessorSupplier, SpanSampler sampler, Set<String> traceDerivedCustomTagKeys, Counter discardedSpansBySampler, Set<Pair<Map<String, String>, String>> discoveredHeartbeatMetrics) {
List<Annotation> annotations = new ArrayList<>(processAnnotations);
// serviceName is mandatory in Jaeger
annotations.add(new Annotation(SERVICE_TAG_KEY, serviceName));
String componentTagValue = NULL_TAG_VAL;
boolean isError = false;
if (span.getTagsList() != null) {
for (Model.KeyValue tag : span.getTagsList()) {
if (IGNORE_TAGS.contains(tag.getKey()) || (tag.getVType() == Model.ValueType.STRING && StringUtils.isBlank(tag.getVStr()))) {
continue;
}
Annotation annotation = tagToAnnotation(tag);
if (annotation != null) {
switch(annotation.getKey()) {
case APPLICATION_TAG_KEY:
applicationName = annotation.getValue();
continue;
case CLUSTER_TAG_KEY:
cluster = annotation.getValue();
continue;
case SHARD_TAG_KEY:
shard = annotation.getValue();
continue;
case SOURCE_KEY:
// Do not add source to annotation span tag list.
sourceName = annotation.getValue();
continue;
case SERVICE_TAG_KEY:
// Do not use service tag from annotations, use field instead
continue;
case COMPONENT_TAG_KEY:
componentTagValue = annotation.getValue();
break;
case ERROR_TAG_KEY:
// only error=true is supported
isError = annotation.getValue().equals(ERROR_SPAN_TAG_VAL);
break;
}
annotations.add(annotation);
}
}
}
// Add all wavefront indexed tags. These are set based on below hierarchy.
// Span Level > Process Level > Proxy Level > Default
annotations.add(new Annotation(APPLICATION_TAG_KEY, applicationName));
annotations.add(new Annotation(CLUSTER_TAG_KEY, cluster));
annotations.add(new Annotation(SHARD_TAG_KEY, shard));
if (span.getReferencesList() != null) {
for (Model.SpanRef reference : span.getReferencesList()) {
switch(reference.getRefType()) {
case CHILD_OF:
if (!reference.getSpanId().isEmpty()) {
annotations.add(new Annotation(TraceConstants.PARENT_KEY, toStringId(reference.getSpanId())));
}
break;
case FOLLOWS_FROM:
if (!reference.getSpanId().isEmpty()) {
annotations.add(new Annotation(TraceConstants.FOLLOWS_FROM_KEY, toStringId(reference.getSpanId())));
}
default:
}
}
}
if (!spanLogsDisabled.get() && span.getLogsCount() > 0) {
annotations.add(new Annotation("_spanLogs", "true"));
}
Span wavefrontSpan = Span.newBuilder().setCustomer("dummy").setName(span.getOperationName()).setSource(sourceName).setSpanId(toStringId(span.getSpanId())).setTraceId(toStringId(span.getTraceId())).setStartMillis(toMillis(span.getStartTime())).setDuration(toMillis(span.getDuration())).setAnnotations(annotations).build();
// Log Jaeger spans as well as Wavefront spans for debugging purposes.
if (JAEGER_DATA_LOGGER.isLoggable(Level.FINEST)) {
JAEGER_DATA_LOGGER.info("Inbound Jaeger span: " + span.toString());
JAEGER_DATA_LOGGER.info("Converted Wavefront span: " + wavefrontSpan.toString());
}
if (preprocessorSupplier != null) {
ReportableEntityPreprocessor preprocessor = preprocessorSupplier.get();
String[] messageHolder = new String[1];
preprocessor.forSpan().transform(wavefrontSpan);
if (!preprocessor.forSpan().filter(wavefrontSpan, messageHolder)) {
if (messageHolder[0] != null) {
spanHandler.reject(wavefrontSpan, messageHolder[0]);
} else {
spanHandler.block(wavefrontSpan);
}
return;
}
}
if (sampler.sample(wavefrontSpan, discardedSpansBySampler)) {
spanHandler.report(wavefrontSpan);
if (span.getLogsCount() > 0 && !isFeatureDisabled(spanLogsDisabled, SPANLOGS_DISABLED, null)) {
SpanLogs spanLogs = SpanLogs.newBuilder().setCustomer("default").setTraceId(wavefrontSpan.getTraceId()).setSpanId(wavefrontSpan.getSpanId()).setLogs(span.getLogsList().stream().map(x -> {
Map<String, String> fields = new HashMap<>(x.getFieldsCount());
x.getFieldsList().forEach(t -> {
switch(t.getVType()) {
case STRING:
fields.put(t.getKey(), t.getVStr());
break;
case BOOL:
fields.put(t.getKey(), String.valueOf(t.getVBool()));
break;
case INT64:
fields.put(t.getKey(), String.valueOf(t.getVInt64()));
break;
case FLOAT64:
fields.put(t.getKey(), String.valueOf(t.getVFloat64()));
break;
case BINARY:
// ignore
default:
}
});
return SpanLog.newBuilder().setTimestamp(toMicros(x.getTimestamp())).setFields(fields).build();
}).collect(Collectors.toList())).build();
spanLogsHandler.report(spanLogs);
}
}
// report stats irrespective of span sampling.
if (wfInternalReporter != null) {
// Set post preprocessor rule values and report converted metrics/histograms from the span
List<Annotation> processedAnnotations = wavefrontSpan.getAnnotations();
for (Annotation processedAnnotation : processedAnnotations) {
switch(processedAnnotation.getKey()) {
case APPLICATION_TAG_KEY:
applicationName = processedAnnotation.getValue();
continue;
case SERVICE_TAG_KEY:
serviceName = processedAnnotation.getValue();
continue;
case CLUSTER_TAG_KEY:
cluster = processedAnnotation.getValue();
continue;
case SHARD_TAG_KEY:
shard = processedAnnotation.getValue();
continue;
case COMPONENT_TAG_KEY:
componentTagValue = processedAnnotation.getValue();
continue;
case ERROR_TAG_KEY:
isError = processedAnnotation.getValue().equals(ERROR_SPAN_TAG_VAL);
continue;
}
}
List<Pair<String, String>> spanTags = processedAnnotations.stream().map(a -> new Pair<>(a.getKey(), a.getValue())).collect(Collectors.toList());
discoveredHeartbeatMetrics.add(reportWavefrontGeneratedData(wfInternalReporter, wavefrontSpan.getName(), applicationName, serviceName, cluster, shard, wavefrontSpan.getSource(), componentTagValue, isError, toMicros(span.getDuration()), traceDerivedCustomTagKeys, spanTags, true));
}
}
Aggregations