-
Notifications
You must be signed in to change notification settings - Fork 0
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 #1
Conversation
#include <array> | ||
#include <iostream> | ||
#include <map> | ||
#include <string> | ||
#include "opentelemetry/common/key_value_iterable.h" | ||
#include "opentelemetry/context/context.h" | ||
#include "opentelemetry/nostd/shared_ptr.h" | ||
#include "opentelemetry/nostd/span.h" | ||
#include "opentelemetry/nostd/string_view.h" | ||
#include "opentelemetry/nostd/variant.h" | ||
#include "opentelemetry/trace/default_span.h" | ||
#include "opentelemetry/trace/propagation/http_text_format.h" | ||
#include "opentelemetry/trace/span.h" | ||
#include "opentelemetry/trace/span_context.h" |
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.
Order of includes, use clang to 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.
This PR is running same set of checks as opentelemtry-cpp and clang formatting is OK:
https://github.com/TomRoSystems/opentelemetry-cpp/pull/1/checks?check_run_id=1724608707
static const nostd::string_view B3CombinedHeader = "b3"; | ||
|
||
static const nostd::string_view B3TraceIdHeader = "X-B3-TraceId"; | ||
static const nostd::string_view B3SpanIdHeader = "X-B3-SpanId"; | ||
static const nostd::string_view B3SampledHeader = "X-B3-Sampled"; |
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 you need this to be public and exported?
static const int kTraceIdHexStrLength = 32; | ||
static const int kSpanIdHexStrLength = 16; | ||
static const int kTraceFlagHexStrLength = 1; |
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.
Same question for these values, if not we can move them to the cc file.
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 file was highly inspired by https://github.com/open-telemetry/opentelemetry-cpp/blob/880e392e10b6d8e964ade2e22d7231950d6d2443/api/include/opentelemetry/trace/propagation/http_trace_context.h and all API in C++ is header-only so there's no cc file.
static TraceId GenerateTraceIdFromString(nostd::string_view trace_id) | ||
{ | ||
uint8_t buf[kTraceIdHexStrLength / 2]; | ||
uint8_t *b_ptr = buf; | ||
GenerateHexFromString(trace_id, kTraceIdHexStrLength, b_ptr); | ||
return TraceId(buf); | ||
} | ||
|
||
static SpanId GenerateSpanIdFromString(nostd::string_view span_id) | ||
{ | ||
uint8_t buf[kSpanIdHexStrLength / 2]; | ||
uint8_t *b_ptr = buf; | ||
GenerateHexFromString(span_id, kSpanIdHexStrLength, b_ptr); | ||
return SpanId(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.
No need to be public correct?
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.
Same as with https://github.com/open-telemetry/opentelemetry-cpp/blob/880e392e10b6d8e964ade2e22d7231950d6d2443/api/include/opentelemetry/trace/propagation/http_trace_context.h - I think it's public for testing purposes.
static TraceFlags GenerateTraceFlagsFromString(nostd::string_view trace_flags) | ||
{ | ||
if (trace_flags.length() != 1 || (trace_flags[0] != '1' && trace_flags[0] != 'd')) | ||
{ | ||
return TraceFlags(0); // check for invalid length of flags | ||
} | ||
return TraceFlags(TraceFlags::kIsSampled); // treat 'd' as kIsSampled | ||
} |
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.
Same.
// Converts the hex numbers stored as strings into bytes stored in a buffer. | ||
static void GenerateHexFromString(nostd::string_view string, int bytes, uint8_t *buf) | ||
{ | ||
const char *str_id = string.data(); | ||
for (int i = 0; i < bytes; i++) | ||
{ | ||
int tmp = HexToInt(str_id[i]); | ||
if (tmp < 0) | ||
{ | ||
for (int j = 0; j < bytes / 2; j++) | ||
{ | ||
buf[j] = 0; | ||
} | ||
return; | ||
} | ||
if (i % 2 == 0) | ||
{ | ||
buf[i / 2] = tmp * 16; | ||
} | ||
else | ||
{ | ||
buf[i / 2] += tmp; | ||
} | ||
} | ||
} | ||
|
||
// 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) | ||
{ | ||
if (c >= '0' && c <= '9') | ||
{ | ||
return (int)(c - '0'); | ||
} | ||
else if (c >= 'a' && c <= 'f') | ||
{ | ||
return (int)(c - 'a' + 10); | ||
} | ||
else if (c >= 'A' && c <= 'F') | ||
{ | ||
return (int)(c - 'A' + 10); | ||
} | ||
else | ||
{ | ||
return -1; | ||
} | ||
} | ||
|
||
static bool IsValidHex(nostd::string_view string_view) | ||
{ | ||
for (int i = 0; i < string_view.length(); i++) | ||
{ | ||
if (!(string_view[i] >= '0' && string_view[i] <= '9') && | ||
!(string_view[i] >= 'a' && string_view[i] <= 'f')) | ||
return false; | ||
} | ||
return true; | ||
} |
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 it make sense to move these elsewhere? It's repeated here and at http_trace_context
auto singleB3Header = getter(carrier, B3CombinedHeader); | ||
if (singleB3Header != "") | ||
{ | ||
trace_id = singleB3Header.substr(0, kTraceIdHexStrLength); |
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.
B3 trace ID can be either 64 or 128 bits (that is 16 or 32 hex chars): https://github.com/openzipkin/b3-propagation#traceid-1
{ | ||
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.
This would be a buffer overrun in case of 64 bit trace ids (which are unhandled currently, but a word of caution)
trace_id = singleB3Header.substr(0, kTraceIdHexStrLength); | ||
if (singleB3Header.size() > 33) | ||
{ | ||
span_id = singleB3Header.substr(33, kSpanIdHexStrLength); |
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.
What would happen if the input header size is 40?
char trace_flags[2]; | ||
TraceFlags(span_context.trace_flags()).ToLowerBase16(trace_flags); | ||
// Note: This is only temporary replacement for appendable string | ||
std::string 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.
This is on the hot path and will most likely allocate twice here when appending. Could use a stack buffer here with the appropriate size, since a string_view is passed to the setter anyway.
EXPECT_EQ(headers["X-B3-TraceId"], "0102030405060708090a0b0c0d0e0f10"); | ||
EXPECT_EQ(headers["X-B3-SpanId"], "0102030405060708"); | ||
EXPECT_EQ(headers["X-B3-Sampled"], "1"); | ||
} |
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 be nice to have a test of left-padding an incoming 64 bit trace id with zeroes
- 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
Codecov Report
@@ Coverage Diff @@
## master #1 +/- ##
=========================================
Coverage ? 94.57%
=========================================
Files ? 196
Lines ? 8739
Branches ? 0
=========================================
Hits ? 8265
Misses ? 474
Partials ? 0 |
Already merged open-telemetry#523 |
No description provided.