diff --git a/examples/App.cpp b/examples/App.cpp index f7df8a2a..71c035f3 100644 --- a/examples/App.cpp +++ b/examples/App.cpp @@ -24,6 +24,11 @@ void tracedSubroutine(const std::unique_ptr& parentSpan) void tracedFunction() { + // jaegertracing::SpanContext spanContextWithUserIDs { {111, 222}, 333, 0, 0, {} }; // TraceId and SpanID must be != 0 + // auto span = opentracing::Tracer::Global()->StartSpan( + // "tracedFunction1", {jaegertracing::JaegerSpecific_UseTheseIDs(&spanContextWithUserIDs)}); + // // spanID of span is 222, not 333, because it's a root span + auto span = opentracing::Tracer::Global()->StartSpan("tracedFunction"); tracedSubroutine(span); } diff --git a/src/jaegertracing/Reference.h b/src/jaegertracing/Reference.h index 52277aea..e11629b1 100644 --- a/src/jaegertracing/Reference.h +++ b/src/jaegertracing/Reference.h @@ -30,6 +30,10 @@ namespace thrift { class SpanRef; } +// An extension of enum opentracing::SpanReferenceType, for a new Span. Only to copy traceID and (for non-root spans) spanID +// spanID for root spans == traceID.low() +const static int SpanReferenceType_JaegerSpecific_UseTheseIDs = 99; + class Reference { public: using Type = opentracing::SpanReferenceType; diff --git a/src/jaegertracing/Tracer.cpp b/src/jaegertracing/Tracer.cpp index 1fb6087a..64ec8e4d 100644 --- a/src/jaegertracing/Tracer.cpp +++ b/src/jaegertracing/Tracer.cpp @@ -67,6 +67,7 @@ Tracer::StartSpanWithOptions(string_view operationName, try { const auto result = analyzeReferences(options.references); const auto* parent = result._parent; + const auto* self = result._self; const auto& references = result._references; std::vector samplerTags; @@ -75,10 +76,19 @@ Tracer::StartSpanWithOptions(string_view operationName, if (!parent || !parent->isValid()) { newTrace = true; auto highID = static_cast(0); - if (_options & kGen128BitOption) { - highID = randomID(); + auto lowID = static_cast(0); + if (self) { + highID = self->traceID().high(); + lowID = self->traceID().low(); } - const TraceID traceID(highID, randomID()); + else { + if (_options & kGen128BitOption) { + highID = randomID(); + } + lowID = randomID(); + } + const TraceID traceID(highID, lowID); + // self.spanID is ignored for the root span const auto spanID = traceID.low(); const auto parentID = 0; auto flags = static_cast(0); @@ -101,7 +111,7 @@ Tracer::StartSpanWithOptions(string_view operationName, } else { const auto traceID = parent->traceID(); - const auto spanID = randomID(); + const auto spanID = self ? self->spanID() : randomID(); const auto parentID = parent->spanID(); const auto flags = parent->flags(); ctx = SpanContext(traceID, spanID, parentID, flags, StrMap()); @@ -194,6 +204,12 @@ Tracer::analyzeReferences(const std::vector& references) const continue; } + if (static_cast(ref.first) == SpanReferenceType_JaegerSpecific_UseTheseIDs) + { + result._self = ctx; + continue; // not a reference + } + result._references.emplace_back(Reference(*ctx, ref.first)); if (!hasParent) { diff --git a/src/jaegertracing/Tracer.h b/src/jaegertracing/Tracer.h index b0619696..e52abf4b 100644 --- a/src/jaegertracing/Tracer.h +++ b/src/jaegertracing/Tracer.h @@ -273,11 +273,13 @@ class Tracer : public opentracing::Tracer, struct AnalyzedReferences { AnalyzedReferences() : _parent(nullptr) + , _self(nullptr) , _references() { } const SpanContext* _parent; + const SpanContext* _self; std::vector _references; }; @@ -301,6 +303,14 @@ class Tracer : public opentracing::Tracer, int _options; }; + +// JaegerSpecific_Self returns a StartSpanOption pointing to the Span that should be used as the started span context +// +// See opentracing::SpanReference +inline opentracing::SpanReference JaegerSpecific_UseTheseIDs(const opentracing::SpanContext* span_context) noexcept { + return {static_cast(SpanReferenceType_JaegerSpecific_UseTheseIDs), span_context}; +} + } // namespace jaegertracing #endif // JAEGERTRACING_TRACER_H