Search in sources :

Example 1 with SpanContextParseException

use of io.opencensus.trace.propagation.SpanContextParseException in project instrumentation-java by census-instrumentation.

the class BinaryFormatImpl method fromByteArray.

@Override
public SpanContext fromByteArray(byte[] bytes) throws SpanContextParseException {
    checkNotNull(bytes, "bytes");
    if (bytes.length == 0 || bytes[0] != VERSION_ID) {
        throw new SpanContextParseException("Unsupported version.");
    }
    if (bytes.length < REQUIRED_FORMAT_LENGTH) {
        throw new SpanContextParseException("Invalid input: truncated");
    }
    // TODO: the following logic assumes that fields are written in ID order. The spec does not say
    // that. If it decides not to, this logic would need to be more like a loop
    TraceId traceId;
    SpanId spanId;
    TraceOptions traceOptions = TraceOptions.DEFAULT;
    int pos = 1;
    if (bytes[pos] == TRACE_ID_FIELD_ID) {
        traceId = TraceId.fromBytes(bytes, pos + ID_SIZE);
        pos += ID_SIZE + TraceId.SIZE;
    } else {
        // TODO: update the spec to suggest that the trace ID is not actually optional
        throw new SpanContextParseException("Invalid input: expected trace ID at offset " + pos);
    }
    if (bytes[pos] == SPAN_ID_FIELD_ID) {
        spanId = SpanId.fromBytes(bytes, pos + ID_SIZE);
        pos += ID_SIZE + SpanId.SIZE;
    } else {
        // TODO: update the spec to suggest that the span ID is not actually optional.
        throw new SpanContextParseException("Invalid input: expected span ID at offset " + pos);
    }
    // failing.
    if (bytes.length > pos && bytes[pos] == TRACE_OPTION_FIELD_ID) {
        if (bytes.length < ALL_FORMAT_LENGTH) {
            throw new SpanContextParseException("Invalid input: truncated");
        }
        traceOptions = TraceOptions.fromByte(bytes[pos + ID_SIZE]);
    }
    return SpanContext.create(traceId, spanId, traceOptions, TRACESTATE_DEFAULT);
}
Also used : SpanContextParseException(io.opencensus.trace.propagation.SpanContextParseException) TraceId(io.opencensus.trace.TraceId) TraceOptions(io.opencensus.trace.TraceOptions) SpanId(io.opencensus.trace.SpanId)

Example 2 with SpanContextParseException

use of io.opencensus.trace.propagation.SpanContextParseException in project instrumentation-java by census-instrumentation.

the class TraceContextFormat method extract.

@Override
public <C> /*>>> extends @NonNull Object*/
SpanContext extract(C carrier, Getter<C> getter) throws SpanContextParseException {
    checkNotNull(carrier, "carrier");
    checkNotNull(getter, "getter");
    TraceId traceId;
    SpanId spanId;
    TraceOptions traceOptions;
    String traceparent = getter.get(carrier, TRACEPARENT);
    if (traceparent == null) {
        throw new SpanContextParseException("Traceparent not present");
    }
    try {
        // TODO(bdrutu): Do we need to verify that version is hex and that for the version
        // the length is the expected one?
        checkArgument(traceparent.charAt(TRACE_OPTION_OFFSET - 1) == TRACEPARENT_DELIMITER && (traceparent.length() == TRACEPARENT_HEADER_SIZE || (traceparent.length() > TRACEPARENT_HEADER_SIZE && traceparent.charAt(TRACEPARENT_HEADER_SIZE) == TRACEPARENT_DELIMITER)) && traceparent.charAt(SPAN_ID_OFFSET - 1) == TRACEPARENT_DELIMITER && traceparent.charAt(TRACE_OPTION_OFFSET - 1) == TRACEPARENT_DELIMITER, "Missing or malformed TRACEPARENT.");
        traceId = TraceId.fromLowerBase16(traceparent, TRACE_ID_OFFSET);
        spanId = SpanId.fromLowerBase16(traceparent, SPAN_ID_OFFSET);
        traceOptions = TraceOptions.fromLowerBase16(traceparent, TRACE_OPTION_OFFSET);
    } catch (IllegalArgumentException e) {
        throw new SpanContextParseException("Invalid traceparent: " + traceparent, e);
    }
    String tracestate = getter.get(carrier, TRACESTATE);
    try {
        if (tracestate == null || tracestate.isEmpty()) {
            return SpanContext.create(traceId, spanId, traceOptions, TRACESTATE_DEFAULT);
        }
        Tracestate.Builder tracestateBuilder = Tracestate.builder();
        List<String> listMembers = TRACESTATE_ENTRY_DELIMITER_SPLITTER.splitToList(tracestate);
        checkArgument(listMembers.size() <= TRACESTATE_MAX_MEMBERS, "Tracestate has too many elements.");
        // front of the list.
        for (int i = listMembers.size() - 1; i >= 0; i--) {
            String listMember = listMembers.get(i);
            int index = listMember.indexOf(TRACESTATE_KEY_VALUE_DELIMITER);
            checkArgument(index != -1, "Invalid tracestate list-member format.");
            tracestateBuilder.set(listMember.substring(0, index), listMember.substring(index + 1, listMember.length()));
        }
        return SpanContext.create(traceId, spanId, traceOptions, tracestateBuilder.build());
    } catch (IllegalArgumentException e) {
        throw new SpanContextParseException("Invalid tracestate: " + tracestate, e);
    }
}
Also used : SpanContextParseException(io.opencensus.trace.propagation.SpanContextParseException) TraceId(io.opencensus.trace.TraceId) TraceOptions(io.opencensus.trace.TraceOptions) Tracestate(io.opencensus.trace.Tracestate) SpanId(io.opencensus.trace.SpanId)

Example 3 with SpanContextParseException

use of io.opencensus.trace.propagation.SpanContextParseException in project grpc-java by grpc.

the class CensusModulesTest method traceHeaderMalformed.

@Test
public void traceHeaderMalformed() throws Exception {
    // As comparison, normal header parsing
    Metadata headers = new Metadata();
    headers.put(censusTracing.tracingHeader, fakeAttemptSpanContext);
    // mockTracingPropagationHandler was stubbed to always return fakeServerParentSpanContext
    assertSame(spyAttemptSpan.getContext(), headers.get(censusTracing.tracingHeader));
    // Make BinaryPropagationHandler always throw when parsing the header
    when(mockTracingPropagationHandler.fromByteArray(any(byte[].class))).thenThrow(new SpanContextParseException("Malformed header"));
    headers = new Metadata();
    assertNull(headers.get(censusTracing.tracingHeader));
    headers.put(censusTracing.tracingHeader, fakeAttemptSpanContext);
    assertSame(SpanContext.INVALID, headers.get(censusTracing.tracingHeader));
    assertNotSame(spyClientSpan.getContext(), SpanContext.INVALID);
    // A null Span is used as the parent in this case
    censusTracing.getServerTracerFactory().newServerStreamTracer(method.getFullMethodName(), headers);
    verify(tracer).spanBuilderWithRemoteParent(eq("Recv.package1.service2.method3"), ArgumentMatchers.<SpanContext>isNull());
    verify(spyServerSpanBuilder).setRecordEvents(eq(true));
}
Also used : SpanContextParseException(io.opencensus.trace.propagation.SpanContextParseException) Metadata(io.grpc.Metadata) Test(org.junit.Test)

Example 4 with SpanContextParseException

use of io.opencensus.trace.propagation.SpanContextParseException in project instrumentation-java by census-instrumentation.

the class HttpServerHandler method handleStart.

/**
 * Instrument an incoming request before it is handled.
 *
 * <p>This method will create a span under the deserialized propagated parent context. If the
 * parent context is not present, the span will be created under the current context.
 *
 * <p>The generated span will NOT be set as current context. User can control when to enter the
 * scope of this span. Use {@link AbstractHttpHandler#getSpanFromContext} to retrieve the span.
 *
 * @param carrier the entity that holds the HTTP information.
 * @param request the request entity.
 * @return the {@link HttpRequestContext} that contains stats and trace data associated with the
 *     request.
 * @since 0.19
 */
public HttpRequestContext handleStart(C carrier, Q request) {
    checkNotNull(carrier, "carrier");
    checkNotNull(request, "request");
    SpanBuilder spanBuilder = null;
    String spanName = getSpanName(request, extractor);
    // de-serialize the context
    SpanContext spanContext = null;
    try {
        spanContext = textFormat.extract(carrier, getter);
    } catch (SpanContextParseException e) {
    // TODO: Currently we cannot distinguish between context parse error and missing context.
    // Logging would be annoying so we just ignore this error and do not even log a message.
    }
    if (spanContext == null || publicEndpoint) {
        spanBuilder = tracer.spanBuilder(spanName);
    } else {
        spanBuilder = tracer.spanBuilderWithRemoteParent(spanName, spanContext);
    }
    Span span = spanBuilder.setSpanKind(Kind.SERVER).startSpan();
    if (publicEndpoint && spanContext != null) {
        span.addLink(Link.fromSpanContext(spanContext, Type.PARENT_LINKED_SPAN));
    }
    if (span.getOptions().contains(Options.RECORD_EVENTS)) {
        addSpanRequestAttributes(span, request, extractor);
    }
    return getNewContext(span, tagger.getCurrentTagContext());
}
Also used : SpanBuilder(io.opencensus.trace.SpanBuilder) SpanContext(io.opencensus.trace.SpanContext) SpanContextParseException(io.opencensus.trace.propagation.SpanContextParseException) Span(io.opencensus.trace.Span)

Example 5 with SpanContextParseException

use of io.opencensus.trace.propagation.SpanContextParseException in project instrumentation-java by census-instrumentation.

the class CloudTraceFormat method extract.

@Override
public <C> /*>>> extends @NonNull Object*/
SpanContext extract(C carrier, Getter<C> getter) throws SpanContextParseException {
    checkNotNull(carrier, "carrier");
    checkNotNull(getter, "getter");
    try {
        String headerStr = getter.get(carrier, HEADER_NAME);
        if (headerStr == null || headerStr.length() < MIN_HEADER_SIZE) {
            throw new SpanContextParseException("Missing or too short header: " + HEADER_NAME);
        }
        checkArgument(headerStr.charAt(TRACE_ID_SIZE) == SPAN_ID_DELIMITER, "Invalid TRACE_ID size");
        TraceId traceId = TraceId.fromLowerBase16(headerStr.subSequence(0, TRACE_ID_SIZE));
        int traceOptionsPos = headerStr.indexOf(TRACE_OPTION_DELIMITER, TRACE_ID_SIZE);
        CharSequence spanIdStr = headerStr.subSequence(SPAN_ID_START_POS, traceOptionsPos < 0 ? headerStr.length() : traceOptionsPos);
        SpanId spanId = longToSpanId(UnsignedLongs.parseUnsignedLong(spanIdStr.toString(), 10));
        TraceOptions traceOptions = OPTIONS_NOT_SAMPLED;
        if (traceOptionsPos > 0) {
            String traceOptionsStr = headerStr.substring(traceOptionsPos + TRACE_OPTION_DELIMITER_SIZE);
            if ((UnsignedInts.parseUnsignedInt(traceOptionsStr, 10) & CLOUD_TRACE_IS_SAMPLED) != 0) {
                traceOptions = OPTIONS_SAMPLED;
            }
        }
        return SpanContext.create(traceId, spanId, traceOptions, TRACESTATE_DEFAULT);
    } catch (IllegalArgumentException e) {
        throw new SpanContextParseException("Invalid input", e);
    }
}
Also used : SpanContextParseException(io.opencensus.trace.propagation.SpanContextParseException) TraceId(io.opencensus.trace.TraceId) TraceOptions(io.opencensus.trace.TraceOptions) SpanId(io.opencensus.trace.SpanId)

Aggregations

SpanContextParseException (io.opencensus.trace.propagation.SpanContextParseException)7 SpanId (io.opencensus.trace.SpanId)4 TraceId (io.opencensus.trace.TraceId)4 TraceOptions (io.opencensus.trace.TraceOptions)4 Span (io.opencensus.trace.Span)2 Test (org.junit.Test)2 Metadata (io.grpc.Metadata)1 FakeSpan (io.opencensus.contrib.http.util.testing.FakeSpan)1 SpanBuilder (io.opencensus.trace.SpanBuilder)1 SpanContext (io.opencensus.trace.SpanContext)1 Tracestate (io.opencensus.trace.Tracestate)1