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);
}
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;
}
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()));
}
}
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());
}
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);
}
Aggregations