use of io.opentelemetry.api.trace.TraceState in project opentelemetry-java by open-telemetry.
the class W3CTraceContextEncoding method decodeTraceState.
/**
* Decodes a trace state header into a {@link TraceState} object.
*
* @throws IllegalArgumentException if {@code traceStateHeader} does not comply with the
* specification
*/
public static TraceState decodeTraceState(String traceStateHeader) {
TraceStateBuilder traceStateBuilder = TraceState.builder();
String[] listMembers = TRACESTATE_ENTRY_DELIMITER_SPLIT_PATTERN.split(traceStateHeader);
checkArgument(listMembers.length <= TRACESTATE_MAX_MEMBERS, "TraceState has too many elements.");
// front of the list.
for (int i = listMembers.length - 1; i >= 0; i--) {
String listMember = listMembers[i];
int index = listMember.indexOf(TRACESTATE_KEY_VALUE_DELIMITER);
checkArgument(index != -1, "Invalid TraceState list-member format.");
traceStateBuilder.put(listMember.substring(0, index), listMember.substring(index + 1));
}
TraceState traceState = traceStateBuilder.build();
if (traceState.size() != listMembers.length) {
// Validation failure, drop the tracestate
return TraceState.getDefault();
}
return traceState;
}
use of io.opentelemetry.api.trace.TraceState in project opentelemetry-java by open-telemetry.
the class W3CTraceContextPropagator method extractImpl.
private static <C> SpanContext extractImpl(@Nullable C carrier, TextMapGetter<C> getter) {
String traceParent = getter.get(carrier, TRACE_PARENT);
if (traceParent == null) {
return SpanContext.getInvalid();
}
SpanContext contextFromParentHeader = extractContextFromTraceParent(traceParent);
if (!contextFromParentHeader.isValid()) {
return contextFromParentHeader;
}
String traceStateHeader = getter.get(carrier, TRACE_STATE);
if (traceStateHeader == null || traceStateHeader.isEmpty()) {
return contextFromParentHeader;
}
try {
TraceState traceState = decodeTraceState(traceStateHeader);
return SpanContext.createFromRemoteParent(contextFromParentHeader.getTraceId(), contextFromParentHeader.getSpanId(), contextFromParentHeader.getTraceFlags(), traceState);
} catch (IllegalArgumentException e) {
logger.fine("Unparseable tracestate header. Returning span context without state.");
return contextFromParentHeader;
}
}
use of io.opentelemetry.api.trace.TraceState in project opentelemetry-java by open-telemetry.
the class SpanMarshaler method create.
// Because SpanMarshaler is always part of a repeated field, it cannot return "null".
static SpanMarshaler create(SpanData spanData) {
KeyValueMarshaler[] attributeMarshalers = KeyValueMarshaler.createRepeated(spanData.getAttributes());
SpanEventMarshaler[] spanEventMarshalers = SpanEventMarshaler.createRepeated(spanData.getEvents());
SpanLinkMarshaler[] spanLinkMarshalers = SpanLinkMarshaler.createRepeated(spanData.getLinks());
String parentSpanId = spanData.getParentSpanContext().isValid() ? spanData.getParentSpanContext().getSpanId() : null;
TraceState traceState = spanData.getSpanContext().getTraceState();
byte[] traceStateUtf8 = traceState.isEmpty() ? EMPTY_BYTES : encodeTraceState(traceState).getBytes(StandardCharsets.UTF_8);
return new SpanMarshaler(spanData.getSpanContext().getTraceId(), spanData.getSpanContext().getSpanId(), traceStateUtf8, parentSpanId, MarshalerUtil.toBytes(spanData.getName()), toProtoSpanKind(spanData.getKind()), spanData.getStartEpochNanos(), spanData.getEndEpochNanos(), attributeMarshalers, spanData.getTotalAttributeCount() - spanData.getAttributes().size(), spanEventMarshalers, spanData.getTotalRecordedEvents() - spanData.getEvents().size(), spanLinkMarshalers, spanData.getTotalRecordedLinks() - spanData.getLinks().size(), SpanStatusMarshaler.create(spanData.getStatus()));
}
use of io.opentelemetry.api.trace.TraceState in project opentelemetry-java by open-telemetry.
the class SdkSpanBuilderTest method sampler_updatedTraceState.
@Test
void sampler_updatedTraceState() {
String samplerAttributeName = "sampler-attribute";
AttributeKey<String> samplerAttributeKey = stringKey(samplerAttributeName);
SdkSpan span = (SdkSpan) SdkTracerProvider.builder().setSampler(new Sampler() {
@Override
public SamplingResult shouldSample(Context parentContext, String traceId, String name, SpanKind spanKind, Attributes attributes, List<LinkData> parentLinks) {
return new SamplingResult() {
@Override
public SamplingDecision getDecision() {
return SamplingDecision.RECORD_AND_SAMPLE;
}
@Override
public Attributes getAttributes() {
return Attributes.empty();
}
@Override
public TraceState getUpdatedTraceState(TraceState parentTraceState) {
return parentTraceState.toBuilder().put("newkey", "newValue").build();
}
};
}
@Override
public String getDescription() {
return "test sampler";
}
}).build().get("test").spanBuilder(SPAN_NAME).setAttribute(samplerAttributeKey, "none").startSpan();
try {
assertThat(span.getSpanContext().isSampled()).isTrue();
assertThat(span.toSpanData().getAttributes().get(samplerAttributeKey)).isNotNull();
assertThat(span.toSpanData().getSpanContext().getTraceState()).isEqualTo(TraceState.builder().put("newkey", "newValue").build());
} finally {
span.end();
}
}
use of io.opentelemetry.api.trace.TraceState 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);
}
Aggregations