Search in sources :

Example 1 with SpanLogs

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");
    }
}
Also used : ArrayList(java.util.ArrayList) ReportSourceTag(wavefront.report.ReportSourceTag) SourceTag(com.wavefront.dto.SourceTag) SpanLogs(wavefront.report.SpanLogs) SpanUtils.handleSpanLogs(com.wavefront.agent.listeners.tracing.SpanUtils.handleSpanLogs) SpanUtils.preprocessAndHandleSpan(com.wavefront.agent.listeners.tracing.SpanUtils.preprocessAndHandleSpan) Span(wavefront.report.Span) ReportEvent(wavefront.report.ReportEvent) DataFormat(com.wavefront.agent.formatter.DataFormat) ReportSourceTag(wavefront.report.ReportSourceTag) ReportPoint(wavefront.report.ReportPoint)

Example 2 with SpanLogs

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);
}
Also used : HealthCheckManager(com.wavefront.agent.channel.HealthCheckManager) FeatureCheckUtils.isFeatureDisabled(com.wavefront.agent.listeners.FeatureCheckUtils.isFeatureDisabled) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SPANLOGS_DISABLED(com.wavefront.agent.listeners.FeatureCheckUtils.SPANLOGS_DISABLED) SpanLogs(wavefront.report.SpanLogs) Supplier(java.util.function.Supplier) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) DataFormat(com.wavefront.agent.formatter.DataFormat) ArrayList(java.util.ArrayList) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) TokenAuthenticator(com.wavefront.agent.auth.TokenAuthenticator) ReportableEntityHandler(com.wavefront.agent.handlers.ReportableEntityHandler) ChannelUtils.errorMessageWithRootCause(com.wavefront.agent.channel.ChannelUtils.errorMessageWithRootCause) ChannelUtils.writeHttpResponse(com.wavefront.agent.channel.ChannelUtils.writeHttpResponse) Map(java.util.Map) SharedGraphiteHostAnnotator(com.wavefront.agent.channel.SharedGraphiteHostAnnotator) HandlerKey(com.wavefront.agent.handlers.HandlerKey) Constants(com.wavefront.api.agent.Constants) CharsetUtil(io.netty.util.CharsetUtil) MetricName(com.yammer.metrics.core.MetricName) ReportPoint(wavefront.report.ReportPoint) JsonNode(com.fasterxml.jackson.databind.JsonNode) Clock(com.wavefront.common.Clock) URI(java.net.URI) Splitter(com.google.common.base.Splitter) Nullable(javax.annotation.Nullable) Counter(com.yammer.metrics.core.Counter) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) ReportableEntityPreprocessor(com.wavefront.agent.preprocessor.ReportableEntityPreprocessor) SPAN_DISABLED(com.wavefront.agent.listeners.FeatureCheckUtils.SPAN_DISABLED) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) Span(wavefront.report.Span) Logger(java.util.logging.Logger) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) ReportableEntityType(com.wavefront.data.ReportableEntityType) List(java.util.List) ChannelUtils.formatErrorMessage(com.wavefront.agent.channel.ChannelUtils.formatErrorMessage) ReportableEntityHandlerFactory(com.wavefront.agent.handlers.ReportableEntityHandlerFactory) ReportableEntityDecoder(com.wavefront.ingester.ReportableEntityDecoder) JsonNodeFactory(com.fasterxml.jackson.databind.node.JsonNodeFactory) Utils(com.wavefront.common.Utils) URLEncodedUtils(org.apache.http.client.utils.URLEncodedUtils) ChannelHandler(io.netty.channel.ChannelHandler) Metrics(com.yammer.metrics.Metrics) HISTO_DISABLED(com.wavefront.agent.listeners.FeatureCheckUtils.HISTO_DISABLED) NameValuePair(org.apache.http.NameValuePair) WavefrontPortUnificationHandler.preprocessAndHandlePoint(com.wavefront.agent.listeners.WavefrontPortUnificationHandler.preprocessAndHandlePoint) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) ArrayList(java.util.ArrayList) SpanLogs(wavefront.report.SpanLogs) JsonNode(com.fasterxml.jackson.databind.JsonNode) URI(java.net.URI) Span(wavefront.report.Span) DataFormat(com.wavefront.agent.formatter.DataFormat) NameValuePair(org.apache.http.NameValuePair) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) ReportableEntityDecoder(com.wavefront.ingester.ReportableEntityDecoder) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ReportPoint(wavefront.report.ReportPoint)

Example 3 with SpanLogs

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));
    }
}
Also used : StringUtils(org.apache.commons.lang.StringUtils) URISyntaxException(java.net.URISyntaxException) DEBUG_TAG_KEY(com.wavefront.sdk.common.Constants.DEBUG_TAG_KEY) NULL_TAG_VAL(com.wavefront.sdk.common.Constants.NULL_TAG_VAL) APPLICATION_TAG_KEY(com.wavefront.sdk.common.Constants.APPLICATION_TAG_KEY) ReportableEntityHandler(com.wavefront.agent.handlers.ReportableEntityHandler) ChannelUtils.writeHttpResponse(com.wavefront.agent.channel.ChannelUtils.writeHttpResponse) COMPONENT_TAG_KEY(com.wavefront.sdk.common.Constants.COMPONENT_TAG_KEY) Map(java.util.Map) HandlerKey(com.wavefront.agent.handlers.HandlerKey) TraceConstants(com.wavefront.common.TraceConstants) URI(java.net.URI) WavefrontInternalReporter(com.wavefront.internal.reporter.WavefrontInternalReporter) BytesDecoder(zipkin2.codec.BytesDecoder) ERROR_SPAN_TAG_KEY(com.wavefront.internal.SpanDerivedMetricsUtils.ERROR_SPAN_TAG_KEY) SHARD_TAG_KEY(com.wavefront.sdk.common.Constants.SHARD_TAG_KEY) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) ReportableEntityPreprocessor(com.wavefront.agent.preprocessor.ReportableEntityPreprocessor) Set(java.util.Set) SPAN_DISABLED(com.wavefront.agent.listeners.FeatureCheckUtils.SPAN_DISABLED) HttpResponseStatus(io.netty.handler.codec.http.HttpResponseStatus) Span(wavefront.report.Span) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) Sets(com.google.common.collect.Sets) Executors(java.util.concurrent.Executors) ReportableEntityType(com.wavefront.data.ReportableEntityType) List(java.util.List) SERVICE_TAG_KEY(com.wavefront.sdk.common.Constants.SERVICE_TAG_KEY) Utils(com.wavefront.common.Utils) DEBUG_SPAN_TAG_KEY(com.wavefront.internal.SpanDerivedMetricsUtils.DEBUG_SPAN_TAG_KEY) CLUSTER_TAG_KEY(com.wavefront.sdk.common.Constants.CLUSTER_TAG_KEY) Annotation(wavefront.report.Annotation) ERROR_SPAN_TAG_VAL(com.wavefront.internal.SpanDerivedMetricsUtils.ERROR_SPAN_TAG_VAL) HealthCheckManager(com.wavefront.agent.channel.HealthCheckManager) FeatureCheckUtils.isFeatureDisabled(com.wavefront.agent.listeners.FeatureCheckUtils.isFeatureDisabled) SpanSampler(com.wavefront.agent.sampler.SpanSampler) SPANLOGS_DISABLED(com.wavefront.agent.listeners.FeatureCheckUtils.SPANLOGS_DISABLED) SpanLogs(wavefront.report.SpanLogs) ERROR_TAG_KEY(com.wavefront.sdk.common.Constants.ERROR_TAG_KEY) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) HashSet(java.util.HashSet) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ChannelUtils.errorMessageWithRootCause(com.wavefront.agent.channel.ChannelUtils.errorMessageWithRootCause) SpanDerivedMetricsUtils.reportWavefrontGeneratedData(com.wavefront.internal.SpanDerivedMetricsUtils.reportWavefrontGeneratedData) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) MetricName(com.yammer.metrics.core.MetricName) TokenAuthenticatorBuilder(com.wavefront.agent.auth.TokenAuthenticatorBuilder) AbstractHttpOnlyHandler(com.wavefront.agent.listeners.AbstractHttpOnlyHandler) Nullable(javax.annotation.Nullable) Counter(com.yammer.metrics.core.Counter) WavefrontSender(com.wavefront.sdk.common.WavefrontSender) SpanBytesDecoderDetector(zipkin2.SpanBytesDecoderDetector) Throwables(com.google.common.base.Throwables) IOException(java.io.IOException) SpanLog(wavefront.report.SpanLog) SpanDerivedMetricsUtils.reportHeartbeats(com.wavefront.internal.SpanDerivedMetricsUtils.reportHeartbeats) TimeUnit(java.util.concurrent.TimeUnit) NamedThreadFactory(com.wavefront.common.NamedThreadFactory) ReportableEntityHandlerFactory(com.wavefront.agent.handlers.ReportableEntityHandlerFactory) Pair(com.wavefront.sdk.common.Pair) Closeable(java.io.Closeable) ChannelHandler(io.netty.channel.ChannelHandler) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Metrics(com.yammer.metrics.Metrics) DEBUG_SPAN_TAG_VAL(com.wavefront.internal.SpanDerivedMetricsUtils.DEBUG_SPAN_TAG_VAL) SOURCE_KEY(com.wavefront.sdk.common.Constants.SOURCE_KEY) ReportableEntityPreprocessor(com.wavefront.agent.preprocessor.ReportableEntityPreprocessor) ArrayList(java.util.ArrayList) SpanLogs(wavefront.report.SpanLogs) Span(wavefront.report.Span) Annotation(wavefront.report.Annotation) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashSet(java.util.HashSet) Pair(com.wavefront.sdk.common.Pair)

Example 4 with SpanLogs

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);
                }
            }
        }
    }
}
Also used : ReportableEntityPreprocessor(com.wavefront.agent.preprocessor.ReportableEntityPreprocessor) ArrayList(java.util.ArrayList) SpanLogs(wavefront.report.SpanLogs) Span(wavefront.report.Span)

Example 5 with 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));
    }
}
Also used : Annotation(wavefront.report.Annotation) ERROR_SPAN_TAG_VAL(com.wavefront.internal.SpanDerivedMetricsUtils.ERROR_SPAN_TAG_VAL) StringUtils(org.apache.commons.lang.StringUtils) FeatureCheckUtils.isFeatureDisabled(com.wavefront.agent.listeners.FeatureCheckUtils.isFeatureDisabled) SpanSampler(com.wavefront.agent.sampler.SpanSampler) SPANLOGS_DISABLED(com.wavefront.agent.listeners.FeatureCheckUtils.SPANLOGS_DISABLED) HashMap(java.util.HashMap) NULL_TAG_VAL(com.wavefront.sdk.common.Constants.NULL_TAG_VAL) SpanLogs(wavefront.report.SpanLogs) ERROR_TAG_KEY(com.wavefront.sdk.common.Constants.ERROR_TAG_KEY) Supplier(java.util.function.Supplier) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) APPLICATION_TAG_KEY(com.wavefront.sdk.common.Constants.APPLICATION_TAG_KEY) ReportableEntityHandler(com.wavefront.agent.handlers.ReportableEntityHandler) Durations.toMillis(com.google.protobuf.util.Durations.toMillis) COMPONENT_TAG_KEY(com.wavefront.sdk.common.Constants.COMPONENT_TAG_KEY) Map(java.util.Map) SpanDerivedMetricsUtils.reportWavefrontGeneratedData(com.wavefront.internal.SpanDerivedMetricsUtils.reportWavefrontGeneratedData) TraceConstants(com.wavefront.common.TraceConstants) BigInteger(java.math.BigInteger) Timestamps.toMicros(com.google.protobuf.util.Timestamps.toMicros) WavefrontInternalReporter(com.wavefront.internal.reporter.WavefrontInternalReporter) Nullable(javax.annotation.Nullable) SHARD_TAG_KEY(com.wavefront.sdk.common.Constants.SHARD_TAG_KEY) ImmutableSet(com.google.common.collect.ImmutableSet) Counter(com.yammer.metrics.core.Counter) Durations.toMicros(com.google.protobuf.util.Durations.toMicros) ReportableEntityPreprocessor(com.wavefront.agent.preprocessor.ReportableEntityPreprocessor) Set(java.util.Set) SPAN_DISABLED(com.wavefront.agent.listeners.FeatureCheckUtils.SPAN_DISABLED) UUID(java.util.UUID) Span(wavefront.report.Span) Logger(java.util.logging.Logger) SpanLog(wavefront.report.SpanLog) Collectors(java.util.stream.Collectors) ByteString(com.google.protobuf.ByteString) List(java.util.List) SERVICE_TAG_KEY(com.wavefront.sdk.common.Constants.SERVICE_TAG_KEY) Pair(com.wavefront.sdk.common.Pair) Timestamps.toMillis(com.google.protobuf.util.Timestamps.toMillis) Model(io.opentelemetry.exporters.jaeger.proto.api_v2.Model) VisibleForTesting(com.google.common.annotations.VisibleForTesting) CLUSTER_TAG_KEY(com.wavefront.sdk.common.Constants.CLUSTER_TAG_KEY) SOURCE_KEY(com.wavefront.sdk.common.Constants.SOURCE_KEY) ReportableEntityPreprocessor(com.wavefront.agent.preprocessor.ReportableEntityPreprocessor) ArrayList(java.util.ArrayList) SpanLogs(wavefront.report.SpanLogs) ByteString(com.google.protobuf.ByteString) Span(wavefront.report.Span) Annotation(wavefront.report.Annotation) Model(io.opentelemetry.exporters.jaeger.proto.api_v2.Model) HashMap(java.util.HashMap) Map(java.util.Map) Pair(com.wavefront.sdk.common.Pair)

Aggregations

SpanLogs (wavefront.report.SpanLogs)9 ReportableEntityPreprocessor (com.wavefront.agent.preprocessor.ReportableEntityPreprocessor)7 ArrayList (java.util.ArrayList)6 Span (wavefront.report.Span)6 HashMap (java.util.HashMap)5 ReportableEntityHandler (com.wavefront.agent.handlers.ReportableEntityHandler)4 SPANLOGS_DISABLED (com.wavefront.agent.listeners.FeatureCheckUtils.SPANLOGS_DISABLED)4 SPAN_DISABLED (com.wavefront.agent.listeners.FeatureCheckUtils.SPAN_DISABLED)4 FeatureCheckUtils.isFeatureDisabled (com.wavefront.agent.listeners.FeatureCheckUtils.isFeatureDisabled)4 SpanUtils.handleSpanLogs (com.wavefront.agent.listeners.tracing.SpanUtils.handleSpanLogs)4 Counter (com.yammer.metrics.core.Counter)4 ImmutableSet (com.google.common.collect.ImmutableSet)3 SpanSampler (com.wavefront.agent.sampler.SpanSampler)3 TraceConstants (com.wavefront.common.TraceConstants)3 ERROR_SPAN_TAG_VAL (com.wavefront.internal.SpanDerivedMetricsUtils.ERROR_SPAN_TAG_VAL)3 SpanDerivedMetricsUtils.reportWavefrontGeneratedData (com.wavefront.internal.SpanDerivedMetricsUtils.reportWavefrontGeneratedData)3 WavefrontInternalReporter (com.wavefront.internal.reporter.WavefrontInternalReporter)3 APPLICATION_TAG_KEY (com.wavefront.sdk.common.Constants.APPLICATION_TAG_KEY)3 CLUSTER_TAG_KEY (com.wavefront.sdk.common.Constants.CLUSTER_TAG_KEY)3 COMPONENT_TAG_KEY (com.wavefront.sdk.common.Constants.COMPONENT_TAG_KEY)3