-
Notifications
You must be signed in to change notification settings - Fork 16
Add support for B3 headers #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
6de2e14
to
2d2516b
Compare
import sys | ||
import threading | ||
|
||
try: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the example. For the next iterations we will have most likely to update it, as we need to comply with a few proposed changes about how to allow the user to specify this ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, it is basically the same as the previous HTTP example. I can refactor it completely or create one new from scratch too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example can be executed now as it is. Please let me know when we need to update it.
lightstep/lightstep_b3_propagator.py
Outdated
from opentracing.mocktracer.propagator import Propagator | ||
from opentracing.mocktracer.context import SpanContext |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot use these components as they are a mock component, and as such, they are not meant to be used in production code. SpanContext
needs to be used as an interface only, and in our internal code, we extend the basictracer
package, so we internally end up using basictracer.SpanContext
: https://github.com/opentracing/basictracer-python/blob/master/basictracer/context.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!
lightstep/lightstep_b3_propagator.py
Outdated
sampled = baggage.get(self._SAMPLED, None) | ||
if sampled is not None: | ||
if flags == 1: | ||
warn( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather use a log here only, as this is not considered under OT a 'big' error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, changing to logger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!
lightstep/lightstep_b3_propagator.py
Outdated
) | ||
) | ||
else: | ||
if traceid is None or spanid is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't want to raise an Exception
here. And here we can totally use warn
to signal the user about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, will downgrade to warn
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed too
lightstep/lightstep_b3_propagator.py
Outdated
parentspanid = carrier.get(_PARENTSPANID, None) | ||
sampled = carrier.get(_SAMPLED, None) | ||
flags = carrier.get(_FLAGS, None) | ||
if parentspanid is sampled is flags is None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if parentspanid is sampled
doesn't look/read right. Could you confirm this is the expected check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm checking that all three of parentspanid
, sampled
and flags
are None
. I am using is
instead of ==
because None
is a singleton.
lightstep/lightstep_b3_propagator.py
Outdated
) | ||
|
||
|
||
__all__ = ['LightStepB3Propagator'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't use this convention, so we don't need it ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll remove it. How do you specify public interfaces, then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We simply allow users to explicitly load them, i.e.
from lightstep.propagators import B3Propagator
(This is a convention we have also kept from OpenTracing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
lightstep/propagation.py
Outdated
tracer.inject(span.context, LightStepFormat.LIGHTSTEP_BINARY, lightstep_carrier) | ||
tracer.inject( | ||
span.context, LightStepFormat.LIGHTSTEP_BINARY, lightstep_carrier | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This style change is not needed (usually, when we want to make style changes, they can come in a separated PR)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, rolling it back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
lightstep/propagation.py
Outdated
|
||
""" | ||
|
||
# The LIGHTSTEP_BINARY format represents SpanContexts in byte array format. | ||
# https://github.com/lightstep/lightstep-tracer-common/lightstep_carrier.proto | ||
LIGHTSTEP_BINARY = 'lightstep_binary' | ||
# The LIGHTSTEP_B3 format represents SpanContexts in B3 format. | ||
# https://github.com/openzipkin/b3-propagation | ||
LIGHTSTEP_B3 = 'lightstep_b3' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be called B3
(LIGHSTEP_BINARY
has this name because it's a binary specific format that only us use ;) )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed it completely from this class since it is specified to be only for LightStep-specific carrier formats. The module says it is also for this kind of carrier formats. Should the B3 specification identifier declaration (B3 = "b3"
) be on a new file?
Hey, I left some reviews. Let me come back to you on the sampled part (as we don't filter out based on that flag, so I need to confirm our handling in the future). Two things:
|
37a6a33
to
04eaa42
Compare
lightstep/b3_propagator.py
Outdated
if baggage == OTSpanContext.EMPTY_BAGGAGE: | ||
baggage = None | ||
return SpanContext( | ||
# traceid and spanid are encoded in hex, so thet must be encoded |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If no valid traceid
/spanid
were encoded, we need to report it as done here: https://github.com/opentracing/basictracer-python/blob/master/basictracer/text_propagator.py#L51
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, raising SpanContextCorruptedException
.
lightstep/propagation.py
Outdated
@@ -4,6 +4,10 @@ | |||
|
|||
from __future__ import absolute_import | |||
|
|||
# The B3 format represents SpanContexts in B3 format. | |||
# https://github.com/openzipkin/b3-propagation | |||
B3 = "b3" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it can be placed somewhere else if you prefer, of course. I just added it there since that module was holding the register identifier for the other propagator in the package, LightStepBinaryPropagator
.
lightstep/tracer.py
Outdated
@@ -75,6 +76,7 @@ def __init__(self, enable_binary_format, recorder, scope_manager): | |||
super(_LightstepTracer, self).__init__(recorder, scope_manager=scope_manager) | |||
self.register_propagator(Format.TEXT_MAP, TextPropagator()) | |||
self.register_propagator(Format.HTTP_HEADERS, TextPropagator()) | |||
self.register_propagator(B3, B3Propagator()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's leave this as an optional step (so by default only TextMapPropagator
is registered by default).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, removed B3
as a default propagator.
c54f957
to
1641c23
Compare
@carlosalberto I added several more test cases, and fixed all but one of your comments since I need a bit more info still. Thank you! |
@carlosalberto and / or @codeboten - are we good to merge? |
Hey @ocelotl Thanks. Actually we need a last iteration, which I hadn't realize. The way injection/extraction works is to specify one of the formats in # replaces the default propagator with the B3 one
tracer.register_propagator(b3_propagator)
...
# we use the text map format, with the b3 propagator
tracer.inject(span.context, opentracing.Format.TEXT_MAP, carrier) For this you will need to also update the example ;) Once this is done, we will be able to merge. |
@codeboten @carlosalberto I implemented the truncation of the MSb in |
Ok! implementing... |
@carlosalberto Done! |
lightstep/b3_propagator.py
Outdated
carrier.update(baggage) | ||
|
||
if traceid is not None: | ||
# FIXME This adds zeroes on the MS side until traceid is 128b long. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
padding must be on the least significant bits
lightstep/b3_propagator.py
Outdated
if baggage == OTSpanContext.EMPTY_BAGGAGE: | ||
baggage = None | ||
|
||
# FIXME This truncates the MSb of traceid until only 64b are left. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the implementation here should leave the trace ID as is when it's propagated to ensure it matches what was passed in. the truncation should only occur when reporting to lightstep
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I'll change it. What do you refer to with when reporting to lightstep
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A good example of this is in the ruby implementation, where a separate field stores the 128-bit vs the 64-bit trace IDs, to remain compatible with the current propagators: https://github.com/lightstep/lightstep-tracer-ruby/pull/86/files#diff-d87db7512b8e96c0a8d9463d52de94beR13-R14. This ensures existing propagation continues to work as is.
@codeboten Changes added, please confirm 👍 |
lightstep/tracer.py
Outdated
self.register_propagator(Format.TEXT_MAP, TextPropagator()) | ||
self.register_propagator(Format.HTTP_HEADERS, TextPropagator()) | ||
self.register_propagator(Format.TEXT_MAP, B3Propagator()) | ||
self.register_propagator(Format.HTTP_HEADERS, B3Propagator()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think we wanted the default here to continue being the TextPropagator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was requested by @carlosalberto before:
Hey @ocelotl
Thanks. Actually we need a last iteration, which I hadn't realize. The way injection/extraction works is to specify one of the formats in
opentracing.Format
, and not 'create' a new one to use B3 (or laterTraceContext
), but use B3 when eitherTEXT_MAP
orHTTP_HEADERS
are specified:# replaces the default propagator with the B3 one tracer.register_propagator(b3_propagator) ... # we use the text map format, with the b3 propagator tracer.inject(span.context, opentracing.Format.TEXT_MAP, carrier)For this you will need to also update the example ;) Once this is done, we will be able to merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, my understanding is that both TEXT_MAP and HTTP_HEADERS should default to TextPropagator, unless configured otherwise when configuring the Tracer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@carlosalberto can you confirm, please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we want TextPropagator
being the default.
not 'create' a new one to use B3 (or later TraceContext), but use B3 when either TEXT_MAP or HTTP_HEADERS are specified
Correct, we want B3
to completely replace TextPropagator
when registered explicitly (instead of having it as a separate format).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reverted the changes in tracer.py
. I also updated the example to explicitly call register_propagator
twice to register the B3 propagator for TEXT_MAP
and HTTP_HEADERS
respectively.
Just to be sure, @carlosalberto, you mentioned this in your previous comment:
# replaces the default propagator with the B3 one
tracer.register_propagator(b3_propagator)
But is not possible to call register_propagator
with only one argument, the format name and propagator instance are needed.
Please let me know if this is the right implementation.
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But is not possible to call register_propagator with only one argument, the format name and propagator instance are needed.
Yeah, this is fine ;)
LGTM 👍 |
Closes #78
@carlosalberto The example added here is failing because apparently I should use this instead of this. I am using the latter because it (correct me if I'm wrong, please) more closely matches the OpenTracing specification for the Context, as shown here (the latter lacks a
sampled
attribute).If I should use the former context class, should I use its
sampled
attribute to store the value of the very closeX-B3-Sampled
value?