Skip to content

Commit

Permalink
Non-template propagator, Implement Global Propagator, no-op propagator (
Browse files Browse the repository at this point in the history
  • Loading branch information
lalitb authored Apr 23, 2021
1 parent a978920 commit f10acac
Show file tree
Hide file tree
Showing 12 changed files with 385 additions and 279 deletions.
50 changes: 18 additions & 32 deletions api/include/opentelemetry/trace/propagation/b3_propagator.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,15 @@ static const int kSpanIdHexStrLength = 16;
// 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. Based on:
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md#b3-extract
template <typename T>
class B3PropagatorExtractor : public TextMapPropagator<T>

class B3PropagatorExtractor : public TextMapPropagator
{
public:
// Rules that manages how context will be extracted from carrier.
using Getter = nostd::string_view (*)(const T &carrier, nostd::string_view trace_type);

// Returns the context that is stored in the HTTP header carrier with the getter as extractor.
context::Context Extract(Getter getter,
const T &carrier,
// Returns the context that is stored in the HTTP header carrier.
context::Context Extract(const TextMapCarrier &carrier,
context::Context &context) noexcept override
{
SpanContext span_context = ExtractImpl(getter, carrier);
SpanContext span_context = ExtractImpl(carrier);
nostd::shared_ptr<Span> sp{new DefaultSpan(span_context)};
return context.SetValue(kSpanKey, sp);
}
Expand Down Expand Up @@ -78,14 +74,14 @@ class B3PropagatorExtractor : public TextMapPropagator<T>
}

private:
static SpanContext ExtractImpl(Getter getter, const T &carrier)
static SpanContext ExtractImpl(const TextMapCarrier &carrier)
{
nostd::string_view trace_id_hex;
nostd::string_view span_id_hex;
nostd::string_view trace_flags_hex;

// first let's try a single-header variant
auto singleB3Header = getter(carrier, kB3CombinedHeader);
auto singleB3Header = carrier.Get(kB3CombinedHeader);
if (!singleB3Header.empty())
{
std::array<nostd::string_view, 3> fields{};
Expand All @@ -101,9 +97,9 @@ class B3PropagatorExtractor : public TextMapPropagator<T>
}
else
{
trace_id_hex = getter(carrier, kB3TraceIdHeader);
span_id_hex = getter(carrier, kB3SpanIdHeader);
trace_flags_hex = getter(carrier, kB3SampledHeader);
trace_id_hex = carrier.Get(kB3TraceIdHeader);
span_id_hex = carrier.Get(kB3SpanIdHeader);
trace_flags_hex = carrier.Get(kB3SampledHeader);
}

if (!detail::IsValidHex(trace_id_hex) || !detail::IsValidHex(span_id_hex))
Expand All @@ -125,16 +121,11 @@ class B3PropagatorExtractor : public TextMapPropagator<T>

// The B3Propagator class provides interface that enables extracting and injecting context into
// single header of HTTP Request.
template <typename T>
class B3Propagator : public B3PropagatorExtractor<T>
class B3Propagator : public B3PropagatorExtractor
{
public:
// Rules that manages how context will be injected to carrier.
using Setter = void (*)(T &carrier,
nostd::string_view trace_type,
nostd::string_view trace_description);
// Sets the context for a HTTP header carrier with self defined rules.
void Inject(Setter setter, T &carrier, const context::Context &context) noexcept override
void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept override
{
SpanContext span_context = detail::GetCurrentSpan(context);
if (!span_context.IsValid())
Expand All @@ -152,19 +143,14 @@ class B3Propagator : public B3PropagatorExtractor<T>
trace_identity[kTraceIdHexStrLength + kSpanIdHexStrLength + 2] =
span_context.trace_flags().IsSampled() ? '1' : '0';

setter(carrier, kB3CombinedHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
carrier.Set(kB3CombinedHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
}
};

template <typename T>
class B3PropagatorMultiHeader : public B3PropagatorExtractor<T>
class B3PropagatorMultiHeader : public B3PropagatorExtractor
{
public:
// Rules that manages how context will be injected to carrier.
using Setter = void (*)(T &carrier,
nostd::string_view trace_type,
nostd::string_view trace_description);
void Inject(Setter setter, T &carrier, const context::Context &context) noexcept override
void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept override
{
SpanContext span_context = detail::GetCurrentSpan(context);
if (!span_context.IsValid())
Expand All @@ -177,9 +163,9 @@ class B3PropagatorMultiHeader : public B3PropagatorExtractor<T>
SpanId(span_context.span_id()).ToLowerBase16(span_id);
char trace_flags[2];
TraceFlags(span_context.trace_flags()).ToLowerBase16(trace_flags);
setter(carrier, kB3TraceIdHeader, nostd::string_view(trace_id, sizeof(trace_id)));
setter(carrier, kB3SpanIdHeader, nostd::string_view(span_id, sizeof(span_id)));
setter(carrier, kB3SampledHeader, nostd::string_view(trace_flags + 1, 1));
carrier.Set(kB3TraceIdHeader, nostd::string_view(trace_id, sizeof(trace_id)));
carrier.Set(kB3SpanIdHeader, nostd::string_view(span_id, sizeof(span_id)));
carrier.Set(kB3SampledHeader, nostd::string_view(trace_flags + 1, 1));
}
};

Expand Down
29 changes: 9 additions & 20 deletions api/include/opentelemetry/trace/propagation/composite_propagator.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,29 @@ namespace trace
namespace propagation
{

template <typename T>
class CompositePropagator : public TextMapPropagator<T>
class CompositePropagator : public TextMapPropagator
{
public:
CompositePropagator(std::vector<std::unique_ptr<TextMapPropagator<T>>> propagators)
CompositePropagator(std::vector<std::unique_ptr<TextMapPropagator>> propagators)
: propagators_(std::move(propagators))
{}
// Rules that manages how context will be extracted from carrier.
using Getter = nostd::string_view (*)(const T &carrier, nostd::string_view trace_type);

// Rules that manages how context will be injected to carrier.
using Setter = void (*)(T &carrier,
nostd::string_view trace_type,
nostd::string_view trace_description);

/**
* Run each of the configured propagators with the given context and carrier.
* Propagators are run in the order they are configured, so if multiple
* propagators write the same carrier key, the propagator later in the list
* will "win".
*
* @param setter Rules that manages how context will be injected to carrier.
* @param carrier Carrier into which context will be injected
* @param context Context to inject
*
*/

void Inject(Setter setter, T &carrier, const context::Context &context) noexcept override
void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept override
{
for (auto &p : propagators_)
{
p->Inject(setter, carrier, context);
p->Inject(carrier, context);
}
}

Expand All @@ -50,12 +41,10 @@ class CompositePropagator : public TextMapPropagator<T>
* propagators write the same context key, the propagator later in the list
* will "win".
*
* @param setter Rules that manages how context will be extracte from carrier.
* @param context Context to add values to
* @param carrier Carrier from which to extract context
* @param context Context to add values to
*/
context::Context Extract(Getter getter,
const T &carrier,
context::Context Extract(const TextMapCarrier &carrier,
context::Context &context) noexcept override
{
auto first = true;
Expand All @@ -64,19 +53,19 @@ class CompositePropagator : public TextMapPropagator<T>
{
if (first)
{
tmp_context = p->Extract(getter, carrier, context);
tmp_context = p->Extract(carrier, context);
first = false;
}
else
{
tmp_context = p->Extract(getter, carrier, tmp_context);
tmp_context = p->Extract(carrier, tmp_context);
}
}
return propagators_.size() ? tmp_context : context;
}

private:
std::vector<std::unique_ptr<TextMapPropagator<T>>> propagators_;
std::vector<std::unique_ptr<TextMapPropagator>> propagators_;
};
} // namespace propagation
} // namespace trace
Expand Down
66 changes: 66 additions & 0 deletions api/include/opentelemetry/trace/propagation/global_propagator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2021, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <mutex>

#include "opentelemetry/trace/propagation/noop_propagator.h"
#include "opentelemetry/trace/propagation/text_map_propagator.h"

#include "opentelemetry/common/spin_lock_mutex.h"
#include "opentelemetry/nostd/shared_ptr.h"

#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace trace
{
namespace propagation
{

/* Stores the singleton TextMapPropagator */

class GlobalTextMapPropagator
{
public:
static nostd::shared_ptr<TextMapPropagator> GetGlobalPropagator() noexcept
{
std::lock_guard<common::SpinLockMutex> guard(GetLock());
return nostd::shared_ptr<TextMapPropagator>(GetPropagator());
}

static void SetGlobalPropagator(nostd::shared_ptr<TextMapPropagator> prop) noexcept
{
std::lock_guard<common::SpinLockMutex> guard(GetLock());
GetPropagator() = prop;
}

private:
static nostd::shared_ptr<TextMapPropagator> &GetPropagator() noexcept
{
static nostd::shared_ptr<TextMapPropagator> propagator(new NoOpPropagator());
return propagator;
}

static common::SpinLockMutex &GetLock() noexcept
{
static common::SpinLockMutex lock;
return lock;
}
};

} // namespace propagation
} // namespace trace
OPENTELEMETRY_END_NAMESPACE
33 changes: 12 additions & 21 deletions api/include/opentelemetry/trace/propagation/http_trace_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,33 +36,24 @@ static const size_t kTraceParentSize = 55;
// Example:
// HttpTraceContext().inject(setter, carrier, context);
// HttpTraceContext().extract(getter, carrier, context);
template <typename T>
class HttpTraceContext : public TextMapPropagator<T>

class HttpTraceContext : public TextMapPropagator
{
public:
// Rules that manages how context will be extracted from carrier.
using Getter = nostd::string_view (*)(const T &carrier, nostd::string_view trace_type);

// Rules that manages how context will be injected to carrier.
using Setter = void (*)(T &carrier,
nostd::string_view trace_type,
nostd::string_view trace_description);

void Inject(Setter setter, T &carrier, const context::Context &context) noexcept override
void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept override
{
SpanContext span_context = detail::GetCurrentSpan(context);
if (!span_context.IsValid())
{
return;
}
InjectImpl(setter, carrier, span_context);
InjectImpl(carrier, span_context);
}

context::Context Extract(Getter getter,
const T &carrier,
context::Context Extract(const TextMapCarrier &carrier,
context::Context &context) noexcept override
{
SpanContext span_context = ExtractImpl(getter, carrier);
SpanContext span_context = ExtractImpl(carrier);
nostd::shared_ptr<Span> sp{new DefaultSpan(span_context)};
return context.SetValue(kSpanKey, sp);
}
Expand Down Expand Up @@ -98,7 +89,7 @@ class HttpTraceContext : public TextMapPropagator<T>
return version != kInvalidVersion;
}

static void InjectImpl(Setter setter, T &carrier, const SpanContext &span_context)
static void InjectImpl(TextMapCarrier &carrier, const SpanContext &span_context)
{
char trace_parent[kTraceParentSize];
trace_parent[0] = '0';
Expand All @@ -110,8 +101,8 @@ class HttpTraceContext : public TextMapPropagator<T>
trace_parent[kTraceIdSize + kSpanIdSize + 4] = '-';
span_context.trace_flags().ToLowerBase16({&trace_parent[kTraceIdSize + kSpanIdSize + 5], 2});

setter(carrier, kTraceParent, nostd::string_view(trace_parent, sizeof(trace_parent)));
setter(carrier, kTraceState, span_context.trace_state()->ToHeader());
carrier.Set(kTraceParent, nostd::string_view(trace_parent, sizeof(trace_parent)));
carrier.Set(kTraceState, span_context.trace_state()->ToHeader());
}

static SpanContext ExtractContextFromTraceHeaders(nostd::string_view trace_parent,
Expand Down Expand Up @@ -162,10 +153,10 @@ class HttpTraceContext : public TextMapPropagator<T>
opentelemetry::trace::TraceState::FromHeader(trace_state));
}

static SpanContext ExtractImpl(Getter getter, const T &carrier)
static SpanContext ExtractImpl(const TextMapCarrier &carrier)
{
nostd::string_view trace_parent = getter(carrier, kTraceParent);
nostd::string_view trace_state = getter(carrier, kTraceState);
nostd::string_view trace_parent = carrier.Get(kTraceParent);
nostd::string_view trace_state = carrier.Get(kTraceState);
if (trace_parent == "")
{
return SpanContext::GetInvalid();
Expand Down
22 changes: 7 additions & 15 deletions api/include/opentelemetry/trace/propagation/jaeger.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,10 @@ namespace propagation

static const nostd::string_view kTraceHeader = "uber-trace-id";

template <typename T>
class JaegerPropagator : public TextMapPropagator<T>
class JaegerPropagator : public TextMapPropagator
{
public:
using Getter = nostd::string_view (*)(const T &carrier, nostd::string_view trace_type);

using Setter = void (*)(T &carrier,
nostd::string_view trace_type,
nostd::string_view trace_description);

void Inject(Setter setter, T &carrier, const context::Context &context) noexcept override
void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept override
{
SpanContext span_context = detail::GetCurrentSpan(context);
if (!span_context.IsValid())
Expand All @@ -60,14 +53,13 @@ class JaegerPropagator : public TextMapPropagator<T>
trace_identity[trace_id_length + span_id_length + 4] = '0';
trace_identity[trace_id_length + span_id_length + 5] = span_context.IsSampled() ? '1' : '0';

setter(carrier, kTraceHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
carrier.Set(kTraceHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
}

context::Context Extract(Getter getter,
const T &carrier,
context::Context Extract(const TextMapCarrier &carrier,
context::Context &context) noexcept override
{
SpanContext span_context = ExtractImpl(getter, carrier);
SpanContext span_context = ExtractImpl(carrier);
nostd::shared_ptr<Span> sp{new DefaultSpan(span_context)};
return context.SetValue(kSpanKey, sp);
}
Expand All @@ -81,9 +73,9 @@ class JaegerPropagator : public TextMapPropagator<T>
return TraceFlags(sampled);
}

static SpanContext ExtractImpl(Getter getter, const T &carrier)
static SpanContext ExtractImpl(const TextMapCarrier &carrier)
{
nostd::string_view trace_identity = getter(carrier, kTraceHeader);
nostd::string_view trace_identity = carrier.Get(kTraceHeader);

const size_t trace_field_count = 4;
nostd::string_view trace_fields[trace_field_count];
Expand Down
Loading

0 comments on commit f10acac

Please sign in to comment.