Skip to content
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

Merged
merged 10 commits into from
Jan 28, 2021
Merged

Adding B3 propagator #523

merged 10 commits into from
Jan 28, 2021

Conversation

@TomRoSystems TomRoSystems requested a review from a team as a code owner January 19, 2021 23:37
@codecov
Copy link

codecov bot commented Jan 19, 2021

Codecov Report

Merging #523 (f52ce7b) into main (d94a368) will increase coverage by 0.12%.
The diff coverage is 99.13%.

Impacted file tree graph

@@            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     
Impacted Files Coverage Δ
...de/opentelemetry/trace/propagation/b3_propagator.h 97.95% <97.95%> (ø)
api/include/opentelemetry/nostd/string_view.h 97.87% <100.00%> (+0.37%) ⬆️
api/test/nostd/string_view_test.cc 100.00% <100.00%> (ø)
api/test/trace/propagation/b3_propagation_test.cc 100.00% <100.00%> (ø)
sdk/test/metrics/counter_aggregator_test.cc 98.21% <0.00%> (-1.79%) ⬇️
sdk/test/common/circular_buffer_test.cc 100.00% <0.00%> (+1.02%) ⬆️

Copy link
Member

@lalitb lalitb 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 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
Copy link
Member

@lalitb lalitb Jan 20, 2021

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);
Copy link
Member

@lalitb lalitb Jan 20, 2021

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 ?

Copy link
Member Author

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.

@TomRoSystems
Copy link
Member Author

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.

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)
Copy link
Contributor

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);
Copy link
Contributor

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)
Copy link
Contributor

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep :( copied from here...

int tmp1 = HexToInt(trace_flags[0]);
int tmp2 = HexToInt(trace_flags[1]);
if (tmp1 < 0 || tmp2 < 0)
return TraceFlags(0); // check for invalid char

@lalitb lalitb requested a review from pyohannes January 25, 2021 19:35
Base automatically changed from master to main January 26, 2021 00:46
}
}

static SpanContext ExtractImpl(Getter getter, const T &carrier)
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Member

@lalitb lalitb Jan 26, 2021

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
Copy link
Contributor

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 = 0const noexcept;
constexpr size_type find(CharT ch, size_type pos = 0const 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 = 0const;

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'd like to avoid Scope creep and complaints related to complexity for those operations.

@pyohannes
Copy link
Contributor

Sorry, I'm a bit late with my comment.

As per Opentelemetry specs - only W3C Tracecontext and W3C Baggage MAY be distributed as part of API package, and rest as extension packages.

Would it be better to put this under ext, instead of api? This would be more true to the spec, and help to keep the API part small. Java has those in an extension directory.


// 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.
Copy link
Contributor

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;
Copy link
Contributor

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;
Copy link
Contributor

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');
Copy link
Contributor

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];
Copy link
Contributor

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?

@TomRoSystems
Copy link
Member Author

@lalitb @ThomsonTan
Guys I've created #539 and will move rest of work over there.

Can this be merged now?

@lalitb
Copy link
Member

lalitb commented Jan 28, 2021

@lalitb @ThomsonTan
Guys I've created #539 and will move rest of work over there.

Can this be merged now?

Thanks @TomRoSystems . @pyohannes suggested on moving B3 propagator to ext directory. If you agree on that, we can either do it as part of #539, or have a separate issue to let someone pick it up.

@TomRoSystems
Copy link
Member Author

@lalitb @ThomsonTan
Guys I've created #539 and will move rest of work over there.
Can this be merged now?

Thanks @TomRoSystems . @pyohannes suggested on moving B3 propagator to ext directory. If you agree on that, we can either do it as part of #539, or have a separate issue to let someone pick it up.

I'd like to do it as part of #539

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

Successfully merging this pull request may close these issues.

None yet

7 participants