@@ -64,9 +64,10 @@ class Span;
64
64
template <class SpanType , class TracerType >
65
65
SpanType *new_span (TracerType *objPtr,
66
66
nostd::string_view name,
67
- const opentelemetry::trace::StartSpanOptions &options)
67
+ const opentelemetry::trace::StartSpanOptions &options,
68
+ std::unique_ptr<opentelemetry::trace::SpanContext> spanContext)
68
69
{
69
- return new (std::nothrow) SpanType{*objPtr, name, options};
70
+ return new (std::nothrow) SpanType{*objPtr, name, options, std::move (spanContext) };
70
71
}
71
72
72
73
/* *
@@ -374,30 +375,6 @@ class Tracer : public opentelemetry::trace::Tracer,
374
375
const opentelemetry::trace::SpanContextKeyValueIterable &links,
375
376
const opentelemetry::trace::StartSpanOptions &options = {}) noexcept override
376
377
{
377
- const auto &cfg = GetConfiguration (tracerProvider_);
378
-
379
- // Parent Context:
380
- // - either use current span
381
- // - or attach to parent SpanContext specified in options
382
- opentelemetry::trace::SpanContext parentContext = GetCurrentSpan ()->GetContext ();
383
- if (nostd::holds_alternative<opentelemetry::trace::SpanContext>(options.parent ))
384
- {
385
- auto span_context = nostd::get<opentelemetry::trace::SpanContext>(options.parent );
386
- if (span_context.IsValid ())
387
- {
388
- parentContext = span_context;
389
- }
390
- }
391
- auto sampling_result =
392
- GetSampler (tracerProvider_)
393
- .ShouldSample (parentContext, traceId_, name, options.kind , attributes, links);
394
- if (sampling_result.decision == sdk::trace::Decision::DROP)
395
- {
396
- static nostd::shared_ptr<trace::Span> noop_span (
397
- new trace::NoopSpan{this ->shared_from_this ()});
398
- return noop_span;
399
- }
400
-
401
378
#ifdef OPENTELEMETRY_RTTI_ENABLED
402
379
common::KeyValueIterable &attribs = const_cast <common::KeyValueIterable &>(attributes);
403
380
Properties *evt = dynamic_cast <Properties *>(&attribs);
@@ -433,12 +410,42 @@ class Tracer : public opentelemetry::trace::Tracer,
433
410
opentelemetry::trace::SpanContext parentContext = GetCurrentSpan ()->GetContext ();
434
411
if (nostd::holds_alternative<opentelemetry::trace::SpanContext>(options.parent ))
435
412
{
436
- auto span_context = nostd::get<opentelemetry::trace::SpanContext>(options.parent );
437
- if (span_context .IsValid ())
413
+ auto spanContext = nostd::get<opentelemetry::trace::SpanContext>(options.parent );
414
+ if (spanContext .IsValid ())
438
415
{
439
- parentContext = span_context ;
416
+ parentContext = spanContext ;
440
417
}
441
418
}
419
+ auto traceId = parentContext.IsValid () ? parentContext.trace_id () : traceId_;
420
+
421
+ // Sampling based on attributes is not supported for now, so passing empty below.
422
+ std::map<std::string, int > emptyAttributes = {{}};
423
+ opentelemetry::sdk::trace::SamplingResult sampling_result =
424
+ GetSampler (tracerProvider_)
425
+ .ShouldSample (parentContext, traceId, name, options.kind ,
426
+ opentelemetry::common::KeyValueIterableView<std::map<std::string, int >>(
427
+ emptyAttributes),
428
+ links);
429
+
430
+ opentelemetry::trace::TraceFlags traceFlags =
431
+ sampling_result.decision == opentelemetry::sdk::trace::Decision::DROP
432
+ ? opentelemetry::trace::TraceFlags{}
433
+ : opentelemetry::trace::TraceFlags{opentelemetry::trace::TraceFlags::kIsSampled };
434
+
435
+ auto spanContext =
436
+ std::unique_ptr<opentelemetry::trace::SpanContext>(new opentelemetry::trace::SpanContext (
437
+ traceId, GetIdGenerator (tracerProvider_).GenerateSpanId (), traceFlags, false ,
438
+ sampling_result.trace_state
439
+ ? sampling_result.trace_state
440
+ : parentContext.IsValid () ? parentContext.trace_state ()
441
+ : opentelemetry::trace::TraceState::GetDefault ()));
442
+
443
+ if (sampling_result.decision == sdk::trace::Decision::DROP)
444
+ {
445
+ auto noopSpan = nostd::shared_ptr<trace::Span>{
446
+ new (std::nothrow) trace::NoopSpan (this ->shared_from_this (), std::move (spanContext))};
447
+ return noopSpan;
448
+ }
442
449
443
450
// Populate Etw.RelatedActivityId at envelope level if enabled
444
451
GUID RelatedActivityId;
@@ -456,11 +463,9 @@ class Tracer : public opentelemetry::trace::Tracer,
456
463
457
464
// This template pattern allows us to forward-declare the etw::Span,
458
465
// create an instance of it, then assign it to tracer::Span result.
459
- auto currentSpan = new_span<Span, Tracer>(this , name, options);
466
+ auto currentSpan = new_span<Span, Tracer>(this , name, options, std::move (spanContext) );
460
467
nostd::shared_ptr<opentelemetry::trace::Span> result = to_span_ptr<Span>(currentSpan);
461
468
462
- auto spanContext = result->GetContext ();
463
-
464
469
// Decorate with additional standard fields
465
470
std::string eventName = name.data ();
466
471
@@ -475,13 +480,13 @@ class Tracer : public opentelemetry::trace::Tracer,
475
480
{
476
481
evt[ETW_FIELD_SPAN_PARENTID] = ToLowerBase16 (parentContext.span_id ());
477
482
}
478
- evt[ETW_FIELD_SPAN_ID] = ToLowerBase16 (spanContext .span_id ());
483
+ evt[ETW_FIELD_SPAN_ID] = ToLowerBase16 (result. get ()-> GetContext () .span_id ());
479
484
}
480
485
481
486
// Populate Etw.Payload["TraceId"] attribute
482
487
if (cfg.enableTraceId )
483
488
{
484
- evt[ETW_FIELD_TRACE_ID] = ToLowerBase16 (spanContext .trace_id ());
489
+ evt[ETW_FIELD_TRACE_ID] = ToLowerBase16 (result. get ()-> GetContext () .trace_id ());
485
490
}
486
491
487
492
// Populate Etw.ActivityId at envelope level if enabled
@@ -705,7 +710,7 @@ class Span : public opentelemetry::trace::Span
705
710
*/
706
711
Span *GetParent () const { return parent_; }
707
712
708
- opentelemetry::trace::SpanContext context_;
713
+ std::unique_ptr< opentelemetry::trace::SpanContext> context_;
709
714
710
715
public:
711
716
/* *
@@ -759,13 +764,13 @@ class Span : public opentelemetry::trace::Span
759
764
Span (Tracer &owner,
760
765
nostd::string_view name,
761
766
const opentelemetry::trace::StartSpanOptions &options,
767
+ std::unique_ptr<opentelemetry::trace::SpanContext> spanContext,
762
768
Span *parent = nullptr ) noexcept
763
769
: opentelemetry::trace::Span(),
764
770
start_time_ (std::chrono::system_clock::now()),
765
771
owner_(owner),
766
- parent_(parent),
767
- context_{owner.traceId_ , GetIdGenerator (owner.tracerProvider_ ).GenerateSpanId (),
768
- opentelemetry::trace::TraceFlags{0 }, false }
772
+ context_(std::move(spanContext)),
773
+ parent_(parent)
769
774
{
770
775
name_ = name;
771
776
UNREFERENCED_PARAMETER (options);
@@ -883,7 +888,7 @@ class Span : public opentelemetry::trace::Span
883
888
* @brief Obtain SpanContext
884
889
* @return
885
890
*/
886
- opentelemetry::trace::SpanContext GetContext () const noexcept override { return context_; }
891
+ opentelemetry::trace::SpanContext GetContext () const noexcept override { return * context_. get () ; }
887
892
888
893
/* *
889
894
* @brief Check if Span is recording data.
0 commit comments