Search in sources :

Example 36 with SpanContext

use of io.opentelemetry.api.trace.SpanContext in project opentelemetry-java by open-telemetry.

the class SdkSpanBuilder method startSpan.

@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public Span startSpan() {
    Context parentContext = parent == null ? Context.current() : parent;
    Span parentSpan = Span.fromContext(parentContext);
    SpanContext parentSpanContext = parentSpan.getSpanContext();
    String traceId;
    IdGenerator idGenerator = tracerSharedState.getIdGenerator();
    String spanId = idGenerator.generateSpanId();
    if (!parentSpanContext.isValid()) {
        // New root span.
        traceId = idGenerator.generateTraceId();
    } else {
        // New child span.
        traceId = parentSpanContext.getTraceId();
    }
    List<LinkData> immutableLinks = links == null ? Collections.emptyList() : Collections.unmodifiableList(links);
    // Avoid any possibility to modify the links list by adding links to the Builder after the
    // startSpan is called. If that happens all the links will be added in a new list.
    links = null;
    Attributes immutableAttributes = attributes == null ? Attributes.empty() : attributes;
    SamplingResult samplingResult = tracerSharedState.getSampler().shouldSample(parentContext, traceId, spanName, spanKind, immutableAttributes, immutableLinks);
    SamplingDecision samplingDecision = samplingResult.getDecision();
    TraceState samplingResultTraceState = samplingResult.getUpdatedTraceState(parentSpanContext.getTraceState());
    SpanContext spanContext = ImmutableSpanContext.create(traceId, spanId, isSampled(samplingDecision) ? TraceFlags.getSampled() : TraceFlags.getDefault(), samplingResultTraceState, /* remote= */
    false, tracerSharedState.isIdGeneratorSafeToSkipIdValidation());
    if (!isRecording(samplingDecision)) {
        return Span.wrap(spanContext);
    }
    Attributes samplingAttributes = samplingResult.getAttributes();
    if (!samplingAttributes.isEmpty()) {
        samplingAttributes.forEach((key, value) -> attributes().put((AttributeKey) key, value));
    }
    // Avoid any possibility to modify the attributes by adding attributes to the Builder after the
    // startSpan is called. If that happens all the attributes will be added in a new map.
    AttributesMap recordedAttributes = attributes;
    attributes = null;
    return SdkSpan.startSpan(spanContext, spanName, instrumentationLibraryInfo, spanKind, parentSpan, parentContext, spanLimits, tracerSharedState.getActiveSpanProcessor(), tracerSharedState.getClock(), tracerSharedState.getResource(), recordedAttributes, immutableLinks, totalNumberOfLinksAdded, startEpochNanos);
}
Also used : Context(io.opentelemetry.context.Context) SpanContext(io.opentelemetry.api.trace.SpanContext) ImmutableSpanContext(io.opentelemetry.api.internal.ImmutableSpanContext) TraceState(io.opentelemetry.api.trace.TraceState) SpanContext(io.opentelemetry.api.trace.SpanContext) ImmutableSpanContext(io.opentelemetry.api.internal.ImmutableSpanContext) LinkData(io.opentelemetry.sdk.trace.data.LinkData) SamplingResult(io.opentelemetry.sdk.trace.samplers.SamplingResult) Attributes(io.opentelemetry.api.common.Attributes) Span(io.opentelemetry.api.trace.Span) AttributeKey(io.opentelemetry.api.common.AttributeKey) SamplingDecision(io.opentelemetry.sdk.trace.samplers.SamplingDecision)

Example 37 with SpanContext

use of io.opentelemetry.api.trace.SpanContext in project opentelemetry-java by open-telemetry.

the class AwsXrayPropagator method getContextFromHeader.

private static <C> Context getContextFromHeader(Context context, @Nullable C carrier, TextMapGetter<C> getter) {
    String traceHeader = getter.get(carrier, TRACE_HEADER_KEY);
    if (traceHeader == null || traceHeader.isEmpty()) {
        return context;
    }
    String traceId = TraceId.getInvalid();
    String spanId = SpanId.getInvalid();
    Boolean isSampled = false;
    BaggageBuilder baggage = null;
    int baggageReadBytes = 0;
    int pos = 0;
    while (pos < traceHeader.length()) {
        int delimiterIndex = traceHeader.indexOf(TRACE_HEADER_DELIMITER, pos);
        String part;
        if (delimiterIndex >= 0) {
            part = traceHeader.substring(pos, delimiterIndex);
            pos = delimiterIndex + 1;
        } else {
            // Last part.
            part = traceHeader.substring(pos);
            pos = traceHeader.length();
        }
        String trimmedPart = part.trim();
        int equalsIndex = trimmedPart.indexOf(KV_DELIMITER);
        if (equalsIndex < 0) {
            logger.fine("Error parsing X-Ray trace header. Invalid key value pair: " + part);
            return context;
        }
        String value = trimmedPart.substring(equalsIndex + 1);
        if (trimmedPart.startsWith(TRACE_ID_KEY)) {
            traceId = parseTraceId(value);
        } else if (trimmedPart.startsWith(PARENT_ID_KEY)) {
            spanId = parseSpanId(value);
        } else if (trimmedPart.startsWith(SAMPLED_FLAG_KEY)) {
            isSampled = parseTraceFlag(value);
        } else if (baggageReadBytes + trimmedPart.length() <= 256) {
            if (baggage == null) {
                baggage = Baggage.builder();
            }
            baggage.put(trimmedPart.substring(0, equalsIndex), value);
            baggageReadBytes += trimmedPart.length();
        }
    }
    if (isSampled == null) {
        logger.fine("Invalid Sampling flag in X-Ray trace header: '" + TRACE_HEADER_KEY + "' with value " + traceHeader + "'.");
        return context;
    }
    SpanContext spanContext = SpanContext.createFromRemoteParent(StringUtils.padLeft(traceId, TraceId.getLength()), spanId, isSampled ? TraceFlags.getSampled() : TraceFlags.getDefault(), TraceState.getDefault());
    if (spanContext.isValid()) {
        context = context.with(Span.wrap(spanContext));
    }
    if (baggage != null) {
        context = context.with(baggage.build());
    }
    return context;
}
Also used : SpanContext(io.opentelemetry.api.trace.SpanContext) BaggageBuilder(io.opentelemetry.api.baggage.BaggageBuilder)

Example 38 with SpanContext

use of io.opentelemetry.api.trace.SpanContext in project opentelemetry-java by open-telemetry.

the class OtTracePropagator method inject.

@Override
public <C> void inject(Context context, @Nullable C carrier, TextMapSetter<C> setter) {
    if (context == null || setter == null) {
        return;
    }
    SpanContext spanContext = Span.fromContext(context).getSpanContext();
    if (!spanContext.isValid()) {
        return;
    }
    // Lightstep trace id MUST be 64-bits therefore OpenTelemetry trace id is truncated to 64-bits
    // by retaining least significant (right-most) bits.
    setter.set(carrier, TRACE_ID_HEADER, spanContext.getTraceId().substring(TraceId.getLength() / 2));
    setter.set(carrier, SPAN_ID_HEADER, spanContext.getSpanId());
    setter.set(carrier, SAMPLED_HEADER, String.valueOf(spanContext.isSampled()));
    // Baggage is only injected if there is a valid SpanContext
    Baggage baggage = Baggage.fromContext(context);
    if (!baggage.isEmpty()) {
        // Metadata is not supported by OpenTracing
        baggage.forEach((key, baggageEntry) -> setter.set(carrier, PREFIX_BAGGAGE_HEADER + key, baggageEntry.getValue()));
    }
}
Also used : SpanContext(io.opentelemetry.api.trace.SpanContext) Baggage(io.opentelemetry.api.baggage.Baggage)

Example 39 with SpanContext

use of io.opentelemetry.api.trace.SpanContext in project opentelemetry-java by open-telemetry.

the class AwsXrayPropagator method inject.

@Override
public <C> void inject(Context context, @Nullable C carrier, TextMapSetter<C> setter) {
    if (context == null) {
        return;
    }
    if (setter == null) {
        return;
    }
    Span span = Span.fromContext(context);
    if (!span.getSpanContext().isValid()) {
        return;
    }
    SpanContext spanContext = span.getSpanContext();
    String otTraceId = spanContext.getTraceId();
    String xrayTraceId = TRACE_ID_VERSION + TRACE_ID_DELIMITER + otTraceId.substring(0, TRACE_ID_FIRST_PART_LENGTH) + TRACE_ID_DELIMITER + otTraceId.substring(TRACE_ID_FIRST_PART_LENGTH);
    String parentId = spanContext.getSpanId();
    char samplingFlag = spanContext.isSampled() ? IS_SAMPLED : NOT_SAMPLED;
    // TODO: Add OT trace state to the X-Ray trace header
    StringBuilder traceHeader = new StringBuilder();
    traceHeader.append(TRACE_ID_KEY).append(KV_DELIMITER).append(xrayTraceId).append(TRACE_HEADER_DELIMITER).append(PARENT_ID_KEY).append(KV_DELIMITER).append(parentId).append(TRACE_HEADER_DELIMITER).append(SAMPLED_FLAG_KEY).append(KV_DELIMITER).append(samplingFlag);
    Baggage baggage = Baggage.fromContext(context);
    // Truncate baggage to 256 chars per X-Ray spec.
    baggage.forEach(new BiConsumer<String, BaggageEntry>() {

        private int baggageWrittenBytes;

        @Override
        public void accept(String key, BaggageEntry entry) {
            if (key.equals(TRACE_ID_KEY) || key.equals(PARENT_ID_KEY) || key.equals(SAMPLED_FLAG_KEY)) {
                return;
            }
            // Size is key/value pair, excludes delimiter.
            int size = key.length() + entry.getValue().length() + 1;
            if (baggageWrittenBytes + size > 256) {
                return;
            }
            traceHeader.append(TRACE_HEADER_DELIMITER).append(key).append(KV_DELIMITER).append(entry.getValue());
            baggageWrittenBytes += size;
        }
    });
    setter.set(carrier, TRACE_HEADER_KEY, traceHeader.toString());
}
Also used : SpanContext(io.opentelemetry.api.trace.SpanContext) BaggageEntry(io.opentelemetry.api.baggage.BaggageEntry) Span(io.opentelemetry.api.trace.Span) Baggage(io.opentelemetry.api.baggage.Baggage)

Example 40 with SpanContext

use of io.opentelemetry.api.trace.SpanContext in project opentelemetry-java by open-telemetry.

the class B3PropagatorInjectorMultipleHeaders method inject.

@Override
public <C> void inject(Context context, @Nullable C carrier, TextMapSetter<C> setter) {
    if (context == null) {
        return;
    }
    if (setter == null) {
        return;
    }
    SpanContext spanContext = Span.fromContext(context).getSpanContext();
    if (!spanContext.isValid()) {
        return;
    }
    String sampled = spanContext.isSampled() ? Common.TRUE_INT : Common.FALSE_INT;
    if (Boolean.TRUE.equals(context.get(B3Propagator.DEBUG_CONTEXT_KEY))) {
        setter.set(carrier, B3Propagator.DEBUG_HEADER, Common.TRUE_INT);
        sampled = Common.TRUE_INT;
    }
    setter.set(carrier, TRACE_ID_HEADER, spanContext.getTraceId());
    setter.set(carrier, SPAN_ID_HEADER, spanContext.getSpanId());
    setter.set(carrier, SAMPLED_HEADER, sampled);
}
Also used : SpanContext(io.opentelemetry.api.trace.SpanContext)

Aggregations

SpanContext (io.opentelemetry.api.trace.SpanContext)62 Test (org.junit.jupiter.api.Test)33 Span (io.opentelemetry.api.trace.Span)31 Context (io.opentelemetry.context.Context)31 SpanKind (io.opentelemetry.api.trace.SpanKind)13 TraceState (io.opentelemetry.api.trace.TraceState)12 W3CTraceContextPropagator (io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator)12 Collectors (java.util.stream.Collectors)12 Attributes (io.opentelemetry.api.common.Attributes)11 TraceFlags (io.opentelemetry.api.trace.TraceFlags)10 SemanticAttributes (io.opentelemetry.semconv.trace.attributes.SemanticAttributes)10 Instant (java.time.Instant)10 SpanId (io.opentelemetry.api.trace.SpanId)9 TraceId (io.opentelemetry.api.trace.TraceId)9 LinkData (io.opentelemetry.sdk.trace.data.LinkData)9 Mockito.when (org.mockito.Mockito.when)9 AttributesBuilder (io.opentelemetry.api.common.AttributesBuilder)8 ContextKey (io.opentelemetry.context.ContextKey)7 TextMapGetter (io.opentelemetry.context.propagation.TextMapGetter)7 InstrumentationVersion (io.opentelemetry.instrumentation.api.InstrumentationVersion)7