Skip to content
This repository has been archived by the owner on Jul 1, 2022. It is now read-only.

Add W3C TraceContext codec/propagation #694

Merged
merged 15 commits into from
Mar 11, 2020

Conversation

pavolloffay
Copy link
Member

Supersedes #649
Related to jaegertracing/jaeger#855

I have made slight changes to #649 (the spanId was incorrect set, improved inject perfomance) and aligned the implementation with https://github.com/open-telemetry/opentelemetry-java/blob/master/api/src/main/java/io/opentelemetry/trace/propagation/HttpTraceContext.java#L40

@codecov
Copy link

codecov bot commented Mar 5, 2020

Codecov Report

Merging #694 into master will decrease coverage by 0.1%.
The diff coverage is 85.71%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #694      +/-   ##
============================================
- Coverage     90.08%   89.98%   -0.11%     
- Complexity      571      590      +19     
============================================
  Files            69       70       +1     
  Lines          2088     2157      +69     
  Branches        266      281      +15     
============================================
+ Hits           1881     1941      +60     
- Misses          126      130       +4     
- Partials         81       86       +5
Impacted Files Coverage Δ Complexity Δ
...a/io/jaegertracing/internal/JaegerSpanContext.java 98.11% <100%> (+0.19%) 32 <2> (+2) ⬆️
.../src/main/java/io/jaegertracing/Configuration.java 93.23% <100%> (+0.1%) 44 <0> (ø) ⬇️
...racing/internal/propagation/TraceContextCodec.java 83.33% <83.33%> (ø) 16 <16> (?)
...ing/internal/samplers/RemoteControlledSampler.java 92.5% <0%> (+1.25%) 17% <0%> (+1%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f726853...525480b. Read the comment docs.

@pavolloffay pavolloffay changed the title Add W3C TraceContext Add W3C TraceContext, only traceparent Mar 5, 2020
@pavolloffay
Copy link
Member Author

The question also is whether we want to support baggage - tracestate


package io.jaegertracing.internal.propagation;

import static io.jaegertracing.internal.propagation.B3TextMapCodec.SAMPLED_FLAG;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you sure you want this here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This certainly no ;)

assertNotNull(traceContextHeader);
assertTrue(traceContextHeader.contains("0000000000000001"));
//For 64 bit traces, we need to pad the left side with a random number to conform with the specification.
//It should not contain all zeros.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't seem to match the assertion below?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the code commet seems wrong. I haven't found this in the spec. @yurishkuro do you know something about this?

/**
* The W3C TraceContext propagation format.
*/
TRACE_CONTEXT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in the doc PR, just wondering whether this should be W3C rather than trace_context which is very generic. But not sure if there is a convention being used across jaeger (or wider).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have any preference. I don't think there will be any other variant of trace context that will collide with this name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which case, I would prefer W3C as it clearly identifies the standards body - in the same way as B3 above identifies the defacto-standard.

@yurishkuro Any preference?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

W3C sgtm, or W3C_TRACE_CONTEXT (but if we also support it in the Config class as a string, then I would just go with "w3x" string)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which case, I would prefer W3C as it clearly identifies the standards body - in the same way as B3 above identifies the defacto-standard.

I don't have much preference but. B3 identifies the protocol, the same as trace_context. Whereas W3C is the standard body like or organization which for B3 is Zipkin. So if we follow the same naming conventions the B3 should be rather named zipkin.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree the analogy was wrong. However the problem I have with trace_context is that it is a generic term so could cause confusion.


boolean sampled = false;
long traceContextFlags = HexCodec.hexToUnsignedLong(traceparent, TRACE_OPTION_OFFSET, TRACE_OPTION_OFFSET + 2);
if ((traceContextFlags & SAMPLED_FLAG) == SAMPLED_FLAG) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@yurishkuro yurishkuro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • is there any way we can use OTel implementation instead of creating our own?
  • only doing traceparent is not compliant with W3C spec, is it?

/**
* The W3C TraceContext propagation format.
*/
TRACE_CONTEXT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

W3C sgtm, or W3C_TRACE_CONTEXT (but if we also support it in the Config class as a string, then I would just go with "w3x" string)

@@ -0,0 +1,142 @@
/*
* Copyright 2019, OpenTelemetry Authors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2020

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should consider removing dates altogether

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what the license plugin gave me

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will have a look at this in a separate PR.

backjo and others added 10 commits March 6, 2020 10:15
Signed-off-by: Jonah Back <jonah@jonahback.com>
Signed-off-by: Jonah Back <jonah@jonahback.com>
Signed-off-by: Jonah Back <jonah@jonahback.com>
Signed-off-by: Jonah Back <jonah@jonahback.com>
Signed-off-by: Jonah Back <jonah@jonahback.com>
…had 64 bits of data

Signed-off-by: Jonah Back <jonah@jonahback.com>
Signed-off-by: Pavol Loffay <ploffay@redhat.com>
Signed-off-by: Pavol Loffay <ploffay@redhat.com>
Signed-off-by: Pavol Loffay <ploffay@redhat.com>
Signed-off-by: Pavol Loffay <ploffay@redhat.com>
Signed-off-by: Pavol Loffay <ploffay@redhat.com>
@pavolloffay
Copy link
Member Author

is there any way we can use OTel implementation instead of creating our own?

It does not seem right to put on the classpath OTEL API only just for this class.

only doing traceparent is not compliant with W3C spec, is it?

Based on the OTEL impl it seems to be compliant. The header is not added if there is no baggage and not parsed if it is missing.

@pavolloffay
Copy link
Member Author

pavolloffay commented Mar 6, 2020

@yurishkuro I have added support for tracestate.

There are two limitations associated with it: https://github.com/w3c/trace-context/blob/master/spec/20-http_header_format.md

The tracestate field value is a list of list-members separated by commas (,). A list-member is a key/value pair separated by an equals sign (=). Spaces and horizontal tabs surrounding list-members are ignored. There can be a maximum of 32 list-members in a list.

The OTEL and this impl does not extract baggage if there are more than 32 items.

Vendors SHOULD propagate at least 512 characters of a combined header. This length includes commas required to separate list items and optional white space (OWS) characters.

There are systems where propagating of 512 characters of tracestate may be expensive. In this case, the maximum size of the propagated tracestate header SHOULD be documented and explained. The cost of propagating tracestate SHOULD be weighted against the value of monitoring scenarios enabled for the end users.

In a situation where tracestate needs to be truncated due to size limitations, the vendor MUST truncate whole entries. Entries larger than 128 characters long SHOULD be removed first. Then entries SHOULD be removed starting from the end of tracestate. Note that other truncation strategies like safe list entries, blocked list entries, or size-based truncation MAY be used, but are highly discouraged. Those strategies decrease the interoperability of various tracing vendors.

The OTEL and this impl allows inject/extract of tracestate longer than 512 chars

@yurishkuro
Copy link
Member

@pavolloffay I don't believe tracestate is meant for baggage. Since Jaeger only needs traceparent, my understanding was that tracestate simply needs to be propagated intact (we don't even need to parse it).

Signed-off-by: Pavol Loffay <ploffay@redhat.com>
@pavolloffay
Copy link
Member Author

My bad I mixed it with correlation context. I have removed the baggage and just add propagation of the tracestate

Signed-off-by: Pavol Loffay <ploffay@redhat.com>
return new JaegerSpanContext(traceIdHigh, traceIdLow, spanId, parentId, flags, traceState, baggage, debugId, this);
}

public JaegerSpanContext createSpanContext(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the factory interface minimal.

Can we instead have a setTracestate() method on the context and not change the factory? I realize that we can't make the field final in that case, but it's better for backwards compatibility than breaking this interface.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JaegerObjectFactory is not an interface hence this is not a breaking change.

@@ -0,0 +1,136 @@
/*
* Copyright (c) 2016, Uber Technologies, Inc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2020

Signed-off-by: Pavol Loffay <ploffay@redhat.com>
Signed-off-by: Pavol Loffay <ploffay@redhat.com>
@pavolloffay
Copy link
Member Author

@yurishkuro PR updated

Copy link
Member

@yurishkuro yurishkuro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for restoring SpanContextFactory. It should've been an interface, and can't really work with overloaded methods because they would silently bypass the subclasses.

@pavolloffay pavolloffay merged commit 568ab68 into jaegertracing:master Mar 11, 2020
@pavolloffay pavolloffay changed the title Add W3C TraceContext, only traceparent Add W3C TraceContext codec/propagation Mar 11, 2020
@fischerman
Copy link

@pavolloffay Can this be used together with the Uber format, i.e. extract the context from either format and inject both?

@pavolloffay
Copy link
Member Author

I am not sure, there is a composite Codec but I we are probably not testing this.

You can try to play with tracer builder/configuration and see whether it is possible. Please open an issue with your findings.

HexCodec.writeHexLong(chars, SPAN_ID_OFFSET, spanContext.getSpanId());
chars[TRACE_OPTION_OFFSET - 1] = TRACEPARENT_DELIMITER;
chars[TRACE_OPTION_OFFSET] = '0';
chars[TRACE_OPTION_OFFSET + 1] = spanContext.isSampled() ? '1' : '0';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should be carrying all Jaeger flags, not just sampled bit: #702

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants