Skip to content

Commit

Permalink
[API] Create root span with active span (#2427)
Browse files Browse the repository at this point in the history
  • Loading branch information
lalitb authored Dec 5, 2023
1 parent d91e5ba commit 48e633e
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 3 deletions.
10 changes: 10 additions & 0 deletions api/include/opentelemetry/trace/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ inline nostd::shared_ptr<Span> GetSpan(const context::Context &context) noexcept
return nostd::shared_ptr<Span>(new DefaultSpan(SpanContext::GetInvalid()));
}

inline bool IsRootSpan(const context::Context &context) noexcept
{
context::ContextValue is_root_span = context.GetValue(kIsRootSpanKey);
if (nostd::holds_alternative<bool>(is_root_span))
{
return nostd::get<bool>(is_root_span);
}
return false;
}

// Set Span into explicit context
inline context::Context SetSpan(context::Context &context, nostd::shared_ptr<Span> span) noexcept
{
Expand Down
3 changes: 2 additions & 1 deletion api/include/opentelemetry/trace/span_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ enum class SpanKind
};

// The key identifies the active span in the current context.
constexpr char kSpanKey[] = "active_span";
constexpr char kSpanKey[] = "active_span";
constexpr char kIsRootSpanKey[] = "is_root_span";

// StatusCode - Represents the canonical set of status codes of a finished Span.
enum class StatusCode
Expand Down
27 changes: 25 additions & 2 deletions api/include/opentelemetry/trace/span_startoptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,31 @@ struct StartSpanOptions

// Explicitly set the parent of a Span.
//
// This defaults to an invalid span context. In this case, the Span is
// automatically parented to the currently active span.
// The `parent` field is designed to establish parent-child relationships
// in tracing spans. It can be set to either a `SpanContext` or a
// `context::Context` object.
//
// - When set to valid `SpanContext`, it directly assigns a specific Span as the parent
// of the newly created Span.
//
// - Alternatively, setting the `parent` field to a `context::Context` allows for
// more nuanced parent identification:
// 1. If the `Context` contains a Span object, this Span is treated as the parent.
// 2. If the `Context` contains the boolean flag `is_root_span` set to `true`,
// it indicates that the new Span should be treated as a root Span, i.e., it
// does not have a parent Span.
// Example Usage:
// ```cpp
// trace_api::StartSpanOptions options;
// opentelemetry::context::Context root;
// root = root.SetValue(kIsRootSpanKey, true);
// options.parent = root;
// auto root_span = tracer->StartSpan("span root", options);
// ```
//
// - If the `parent` field is not set, the newly created Span will inherit the
// parent of the currently active Span (if any) in the current context.
//
nostd::variant<SpanContext, context::Context> parent = SpanContext::GetInvalid();

// TODO:
Expand Down
7 changes: 7 additions & 0 deletions sdk/src/trace/tracer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ nostd::shared_ptr<opentelemetry::trace::Span> Tracer::StartSpan(
{
parent_context = span_context;
}
else
{
if (opentelemetry::trace::IsRootSpan(context))
{
parent_context = opentelemetry::trace::SpanContext{false, false};
}
}
}

opentelemetry::trace::TraceId trace_id;
Expand Down
20 changes: 20 additions & 0 deletions sdk/test/trace/tracer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,26 @@ TEST(Tracer, WithActiveSpan)
spans = span_data->GetSpans();
ASSERT_EQ(1, spans.size());
EXPECT_EQ("span 2", spans.at(0)->GetName());
EXPECT_EQ(spans.at(0).get()->GetParentSpanId(), span_first->GetContext().span_id());
EXPECT_EQ(spans.at(0).get()->GetTraceId(), span_first->GetContext().trace_id());

{
trace_api::StartSpanOptions options;
opentelemetry::context::Context c1;
c1 = c1.SetValue(opentelemetry::trace::kIsRootSpanKey, true);
options.parent = c1;
auto root_span = tracer->StartSpan("span root", options);

spans = span_data->GetSpans();
ASSERT_EQ(0, spans.size());

root_span->End();
}
spans = span_data->GetSpans();
ASSERT_EQ(1, spans.size());
EXPECT_EQ("span root", spans.at(0)->GetName());
EXPECT_EQ(spans.at(0).get()->GetParentSpanId(), opentelemetry::trace::SpanId());
EXPECT_NE(spans.at(0).get()->GetTraceId(), span_first->GetContext().trace_id());

span_first->End();
}
Expand Down

1 comment on commit 48e633e

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'OpenTelemetry-cpp sdk Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: 48e633e Previous: d91e5ba Ratio
BM_AttributseProcessorFilter 612.9794055658843 ns/iter 267.2542035396508 ns/iter 2.29
BM_BaselineBuffer/1 12188823.223114014 ns/iter 2296566.2479400635 ns/iter 5.31

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.