-
Notifications
You must be signed in to change notification settings - Fork 423
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
Adding B3 propagator #523
Adding B3 propagator #523
Conversation
Codecov Report
@@ Coverage Diff @@
## main #523 +/- ##
==========================================
+ Coverage 94.17% 94.30% +0.12%
==========================================
Files 195 197 +2
Lines 8572 8802 +230
==========================================
+ Hits 8073 8301 +228
- Misses 499 501 +2
|
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 working on this. Looks good to me in general. Would wait for other's feedback for proper place for it:
repo_root/api/include/opentelemetry/trace/propagation/
or
repo_root/propagators
As per Opentelemetry specs (https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/context/api-propagators.md#propagators-distribution ) - only W3C Tracecontext
and W3C Baggage
MAY be distributed as part of API package, and rest as extension packages.
} | ||
}; | ||
|
||
// The B3Propagator class provides an interface that enables extracting and injecting |
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.
Would header description as below more readable ?
// B3Propogator
class provides interface that enables extracting and injecting context into single header of HTTP Request.
// B3PropogatorMultiHeader
class provides interface that enables extracting and injecting context into multiple headers of HTTP Request.
{ | ||
uint8_t buf[kTraceIdHexStrLength / 2]; | ||
uint8_t *b_ptr = buf; | ||
GenerateHexFromString(trace_id, kTraceIdHexStrLength, b_ptr); |
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.
As B3 trace_id could also be 16 hex chars, while we are always trying to read 32 chars/bytes here. This may result in reading past the hex string ?
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! Thanks for pointing this out. I'll create fix and test for such case.
Thank you for review. Any more opinions on this one? In go there's propagation directory same in dotnet whereas Java has extensions directory on top level. |
- added support for TraceId 16 and 32 length - added tests for scenario above and inject multi-header nostd::string_view - added find for single character
|
||
// Converts a single character to a corresponding integer (e.g. '1' to 1), return -1 | ||
// if the character is not a valid number in hex. | ||
static uint8_t HexToInt(char c) |
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.
Perhaps we should move hex to int conversion to a shared part? Currently the method (+ comment) is duplicated by b3 and http propagators.
// From: https://github.com/openzipkin/b3-propagation/blob/master/RATIONALE.md | ||
// trace_id can be 16 or 32 chars | ||
auto firstSep = singleB3Header.find('-'); | ||
trace_id = singleB3Header.substr(0, firstSep); |
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 will allow an invalid length trace id and span id to pass through, e.g. a-b
will produce 000000000000000a
as the trace ID.
{ | ||
hexDigit1 = HexToInt(hexStr[--posInp]); | ||
} | ||
if (hexDigit1 < 0 || hexDigit2 < 0) |
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 branch is never taken as HexToInt
returns uint8_t
(uint8_t(-1) = int(255)
), thus a malformed hex sequence is generated.
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.
Yep :( copied from here...
opentelemetry-cpp/api/include/opentelemetry/trace/propagation/http_trace_context.h
Lines 120 to 123 in ce89aa1
int tmp1 = HexToInt(trace_flags[0]); | |
int tmp2 = HexToInt(trace_flags[1]); | |
if (tmp1 < 0 || tmp2 < 0) | |
return TraceFlags(0); // check for invalid char |
} | ||
} | ||
|
||
static SpanContext ExtractImpl(Getter getter, const T &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.
Might be a nitpick, but I think we should validate the parsed trace_id, span_id lengths for validity. Say if a malformed header with too large of a trace_id gets sent, currently this logic will produce a valid SpanContext
, but with some of the trace_id cut off - my opinion is we should just fail early in these cases.
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.
Would like to get more opinion on this topic Robustness vs it's potential harmful consequences from others as I have not found clear guidance on this one.
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.
In case of any error in parsing trace_id
and span_id
, the right approach should be to set them invalid ( i.e. all zeros ) and return the SpanContext. This will ensure that SpanContext is also invalid.
@@ -120,6 +120,20 @@ class string_view | |||
return substr(pos1, count1).compare(string_view(s, count2)); | |||
}; | |||
|
|||
size_type find(char ch, size_type pos = 0) const noexcept |
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.
Looks good. Minor concern is - since we're adding it here, it would'be been ideal to add all overloads:
constexpr size_type find(basic_string_view v, size_type pos = 0) const noexcept;
constexpr size_type find(CharT ch, size_type pos = 0) const noexcept;
constexpr size_type find(const CharT* s, size_type pos, size_type count) const;
constexpr size_type find(const CharT* s, size_type pos = 0) const;
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 like to avoid Scope creep and complaints related to complexity for those operations.
Sorry, I'm a bit late with my comment.
Would it be better to put this under |
|
||
// The B3PropagatorExtractor class provides an interface that enables extracting context from | ||
// headers of HTTP requests. HTTP frameworks and clients can integrate with B3Propagator by | ||
// providing the object containing the headers, and a getter function for the extraction. |
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.
nit: extra space after object.
static TraceId GenerateTraceIdFromString(nostd::string_view trace_id) | ||
{ | ||
uint8_t buf[kTraceIdHexStrLength / 2]; | ||
uint8_t *b_ptr = buf; |
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.
b_ptr
is unused now?
static SpanId GenerateSpanIdFromString(nostd::string_view span_id) | ||
{ | ||
uint8_t buf[kSpanIdHexStrLength / 2]; | ||
uint8_t *b_ptr = buf; |
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.
Ditto.
{ | ||
if (c >= '0' && c <= '9') | ||
{ | ||
return (int)(c - '0'); |
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.
Convert return value to int8_t
to be consistent with the declared return type?
{ | ||
return; | ||
} | ||
char trace_id[32]; |
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.
Declare the length with the constants defined in the begining of this file?
@lalitb @ThomsonTan Can this be merged now? |
Thanks @TomRoSystems . @pyohannes suggested on moving B3 propagator to |
I'd like to do it as part of #539 |
Basing on https://github.com/open-telemetry/opentelemetry-cpp/blob/880e392e10b6d8e964ade2e22d7231950d6d2443/api/include/opentelemetry/trace/propagation/http_trace_context.h