Skip to content

Commit 07f4a96

Browse files
authored
Simplify propagators (#608)
1 parent fdd6303 commit 07f4a96

File tree

6 files changed

+170
-357
lines changed

6 files changed

+170
-357
lines changed

api/include/opentelemetry/trace/propagation/b3_propagator.h

Lines changed: 50 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
11
#pragma once
22

3-
#include <array>
4-
#include <iostream>
5-
#include <map>
6-
#include <string>
73
#include "detail/context.h"
8-
#include "opentelemetry/common/key_value_iterable.h"
9-
#include "opentelemetry/context/context.h"
10-
#include "opentelemetry/nostd/shared_ptr.h"
11-
#include "opentelemetry/nostd/span.h"
12-
#include "opentelemetry/nostd/string_view.h"
13-
#include "opentelemetry/nostd/variant.h"
4+
#include "detail/hex.h"
5+
#include "detail/string.h"
146
#include "opentelemetry/trace/default_span.h"
157
#include "opentelemetry/trace/propagation/text_map_propagator.h"
16-
#include "opentelemetry/trace/span.h"
17-
#include "opentelemetry/trace/span_context.h"
8+
9+
#include <array>
1810

1911
OPENTELEMETRY_BEGIN_NAMESPACE
2012
namespace trace
@@ -38,9 +30,8 @@ static const nostd::string_view kB3SampledHeader = "X-B3-Sampled";
3830
X-B3-TraceId X-B3-SpanId X-B3-ParentSpanId (ignored)
3931
*/
4032

41-
static const int kTraceIdHexStrLength = 32;
42-
static const int kSpanIdHexStrLength = 16;
43-
static const int kTraceFlagHexStrLength = 1;
33+
static const int kTraceIdHexStrLength = 32;
34+
static const int kSpanIdHexStrLength = 16;
4435

4536
// The B3PropagatorExtractor class provides an interface that enables extracting context from
4637
// headers of HTTP requests. HTTP frameworks and clients can integrate with B3Propagator by
@@ -63,21 +54,21 @@ class B3PropagatorExtractor : public TextMapPropagator<T>
6354
return context.SetValue(kSpanKey, sp);
6455
}
6556

66-
static TraceId GenerateTraceIdFromString(nostd::string_view trace_id)
57+
static TraceId TraceIdFromHex(nostd::string_view trace_id)
6758
{
6859
uint8_t buf[kTraceIdHexStrLength / 2];
69-
GenerateBuffFromHexStrPad0(trace_id, sizeof(buf), buf);
60+
detail::HexToBinary(trace_id, buf, sizeof(buf));
7061
return TraceId(buf);
7162
}
7263

73-
static SpanId GenerateSpanIdFromString(nostd::string_view span_id)
64+
static SpanId SpanIdFromHex(nostd::string_view span_id)
7465
{
7566
uint8_t buf[kSpanIdHexStrLength / 2];
76-
GenerateBuffFromHexStrPad0(span_id, sizeof(buf), buf);
67+
detail::HexToBinary(span_id, buf, sizeof(buf));
7768
return SpanId(buf);
7869
}
7970

80-
static TraceFlags GenerateTraceFlagsFromString(nostd::string_view trace_flags)
71+
static TraceFlags TraceFlagsFromHex(nostd::string_view trace_flags)
8172
{
8273
if (trace_flags.length() != 1 || (trace_flags[0] != '1' && trace_flags[0] != 'd'))
8374
{ // check for invalid length of flags and treat 'd' as sampled
@@ -87,106 +78,48 @@ class B3PropagatorExtractor : public TextMapPropagator<T>
8778
}
8879

8980
private:
90-
// Converts hex numbers (string_view) into bytes stored in a buffer and pads buffer with 0.
91-
static void GenerateBuffFromHexStrPad0(nostd::string_view hexStr, int bufSize, uint8_t *buf)
92-
{ // we are doing this starting from "right" side for left-padding
93-
nostd::string_view::size_type posInp = hexStr.length();
94-
int posOut = bufSize;
95-
while (posOut--)
96-
{
97-
int val = 0;
98-
if (posInp)
99-
{
100-
int hexDigit2 = HexToInt(hexStr[--posInp]); // low nibble
101-
int hexDigit1 = 0;
102-
if (posInp)
103-
{
104-
hexDigit1 = HexToInt(hexStr[--posInp]);
105-
}
106-
if (hexDigit1 < 0 || hexDigit2 < 0)
107-
{ // malformed hex sequence. Fill entire buffer with zeroes.
108-
for (int j = 0; j < bufSize; j++)
109-
{
110-
buf[j] = 0;
111-
}
112-
return;
113-
}
114-
val = hexDigit1 * 16 + hexDigit2;
115-
}
116-
buf[posOut] = val;
117-
}
118-
}
119-
120-
// Converts a single character to a corresponding integer (e.g. '1' to 1), return -1
121-
// if the character is not a valid number in hex.
122-
static int8_t HexToInt(char c)
123-
{
124-
if (c >= '0' && c <= '9')
125-
{
126-
return (int8_t)(c - '0');
127-
}
128-
else if (c >= 'a' && c <= 'f')
129-
{
130-
return (int8_t)(c - 'a' + 10);
131-
}
132-
else if (c >= 'A' && c <= 'F')
133-
{
134-
return (int8_t)(c - 'A' + 10);
135-
}
136-
else
137-
{
138-
return -1;
139-
}
140-
}
141-
14281
static SpanContext ExtractImpl(Getter getter, const T &carrier)
14382
{
144-
// all these are hex values
145-
nostd::string_view trace_id;
146-
nostd::string_view span_id;
147-
nostd::string_view trace_flags;
83+
nostd::string_view trace_id_hex;
84+
nostd::string_view span_id_hex;
85+
nostd::string_view trace_flags_hex;
14886

14987
// first let's try a single-header variant
15088
auto singleB3Header = getter(carrier, kB3CombinedHeader);
15189
if (!singleB3Header.empty())
15290
{
153-
// From: https://github.com/openzipkin/b3-propagation/blob/master/RATIONALE.md
154-
// trace_id can be 16 or 32 chars
155-
auto firstSep = singleB3Header.find('-');
156-
trace_id = singleB3Header.substr(0, firstSep);
157-
if (firstSep != nostd::string_view::npos)
158-
{ // at least two fields are required
159-
auto secondSep = singleB3Header.find('-', firstSep + 1);
160-
if (secondSep != nostd::string_view::npos)
161-
{ // more than two fields - check also trace_flags
162-
span_id = singleB3Header.substr(firstSep + 1, secondSep - firstSep - 1);
163-
if (secondSep + 1 < singleB3Header.size())
164-
{
165-
trace_flags = singleB3Header.substr(secondSep + 1, kTraceFlagHexStrLength);
166-
}
167-
}
168-
else
169-
{
170-
span_id = singleB3Header.substr(firstSep + 1);
171-
}
91+
std::array<nostd::string_view, 3> fields{};
92+
// https://github.com/openzipkin/b3-propagation/blob/master/RATIONALE.md
93+
if (detail::SplitString(singleB3Header, '-', fields.data(), 3) < 2)
94+
{
95+
return SpanContext::GetInvalid();
17296
}
97+
98+
trace_id_hex = fields[0];
99+
span_id_hex = fields[1];
100+
trace_flags_hex = fields[2];
173101
}
174102
else
175103
{
176-
trace_id = getter(carrier, kB3TraceIdHeader);
177-
span_id = getter(carrier, kB3SpanIdHeader);
178-
trace_flags = getter(carrier, kB3SampledHeader);
104+
trace_id_hex = getter(carrier, kB3TraceIdHeader);
105+
span_id_hex = getter(carrier, kB3SpanIdHeader);
106+
trace_flags_hex = getter(carrier, kB3SampledHeader);
179107
}
180108

181-
// now convert hex to objects
182-
TraceId trace_id_obj = GenerateTraceIdFromString(trace_id);
183-
SpanId span_id_obj = GenerateSpanIdFromString(span_id);
184-
if (!trace_id_obj.IsValid() || !span_id_obj.IsValid())
109+
if (!detail::IsValidHex(trace_id_hex) || !detail::IsValidHex(span_id_hex))
185110
{
186-
return SpanContext(false, false);
111+
return SpanContext::GetInvalid();
187112
}
188-
TraceFlags trace_flags_obj = GenerateTraceFlagsFromString(trace_flags);
189-
return SpanContext(trace_id_obj, span_id_obj, trace_flags_obj, true);
113+
114+
TraceId trace_id = TraceIdFromHex(trace_id_hex);
115+
SpanId span_id = SpanIdFromHex(span_id_hex);
116+
117+
if (!trace_id.IsValid() || !span_id.IsValid())
118+
{
119+
return SpanContext::GetInvalid();
120+
}
121+
122+
return SpanContext(trace_id, span_id, TraceFlagsFromHex(trace_flags_hex), true);
190123
}
191124
};
192125

@@ -208,26 +141,18 @@ class B3Propagator : public B3PropagatorExtractor<T>
208141
{
209142
return;
210143
}
211-
char trace_id[kTraceIdHexStrLength];
212-
TraceId(span_context.trace_id()).ToLowerBase16(trace_id);
213-
char span_id[kSpanIdHexStrLength];
214-
SpanId(span_context.span_id()).ToLowerBase16(span_id);
215-
char trace_flags[2];
216-
TraceFlags(span_context.trace_flags()).ToLowerBase16(trace_flags);
217-
// Note: This is only temporary replacement for appendable string
218-
std::string hex_string = "";
219-
for (int i = 0; i < 32; i++)
220-
{
221-
hex_string.push_back(trace_id[i]);
222-
}
223-
hex_string.push_back('-');
224-
for (int i = 0; i < 16; i++)
225-
{
226-
hex_string.push_back(span_id[i]);
227-
}
228-
hex_string.push_back('-');
229-
hex_string.push_back(trace_flags[1]);
230-
setter(carrier, kB3CombinedHeader, hex_string);
144+
145+
char trace_identity[kTraceIdHexStrLength + kSpanIdHexStrLength + 3];
146+
static_assert(sizeof(trace_identity) == 51, "b3 trace identity buffer size mismatch");
147+
span_context.trace_id().ToLowerBase16({&trace_identity[0], kTraceIdHexStrLength});
148+
trace_identity[kTraceIdHexStrLength] = '-';
149+
span_context.span_id().ToLowerBase16(
150+
{&trace_identity[kTraceIdHexStrLength + 1], kSpanIdHexStrLength});
151+
trace_identity[kTraceIdHexStrLength + kSpanIdHexStrLength + 1] = '-';
152+
trace_identity[kTraceIdHexStrLength + kSpanIdHexStrLength + 2] =
153+
span_context.trace_flags().IsSampled() ? '1' : '0';
154+
155+
setter(carrier, kB3CombinedHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
231156
}
232157
};
233158

api/include/opentelemetry/trace/propagation/detail/hex.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ bool IsValidHex(nostd::string_view s)
4343
*/
4444
bool HexToBinary(nostd::string_view hex, uint8_t *buffer, size_t buffer_size)
4545
{
46+
std::memset(buffer, 0, buffer_size);
47+
4648
if (hex.size() > buffer_size * 2)
4749
{
4850
return false;
4951
}
5052

51-
std::memset(buffer, 0, buffer_size);
52-
5353
int64_t hex_size = int64_t(hex.size());
5454
int64_t buffer_pos = int64_t(buffer_size) - (hex_size + 1) / 2;
5555
int64_t last_hex_pos = hex_size - 1;

0 commit comments

Comments
 (0)