Skip to content

Commit

Permalink
feat: start a root span with spanOptions.parent = null (#889)
Browse files Browse the repository at this point in the history
* feat: start a root span with spanOptions.parent = null

* chore: lint

* chore: add return type for readability
  • Loading branch information
dyladan authored Mar 26, 2020
1 parent e9bc887 commit 9e114d1
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
3 changes: 3 additions & 0 deletions packages/opentelemetry-api/src/trace/SpanOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export interface SpanOptions {
* A parent `SpanContext` (or `Span`, for convenience) that the newly-started
* span will be the child of. This overrides the parent span extracted from
* the currently active context.
*
* A null value here should prevent the SDK from extracting a parent from
* the current context, forcing the new span to be a root span.
*/
parent?: Span | SpanContext | null;

Expand Down
20 changes: 17 additions & 3 deletions packages/opentelemetry-tracing/src/Tracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ export class Tracer implements api.Tracer {
options: api.SpanOptions = {},
context = api.context.active()
): api.Span {
const parentContext = options.parent
? getContext(options.parent)
: getParentSpanContext(context);
const parentContext = getParent(options, context);
// make sampling decision
const samplingDecision = this._sampler.shouldSample(parentContext);
const spanId = randomSpanId();
Expand Down Expand Up @@ -149,6 +147,22 @@ export class Tracer implements api.Tracer {
}
}

/**
* Get the parent to assign to a started span. If options.parent is null,
* do not assign a parent.
*
* @param options span options
* @param context context to check for parent
*/
function getParent(
options: api.SpanOptions,
context: api.Context
): api.SpanContext | undefined {
if (options.parent === null) return undefined;
if (options.parent) return getContext(options.parent);
return getParentSpanContext(context);
}

function getContext(span: api.Span | api.SpanContext) {
return isSpan(span) ? span.context() : span;
}
Expand Down
15 changes: 15 additions & 0 deletions packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,21 @@ describe('BasicTracerProvider', () => {
childSpan.end();
});

it('should create a root span when parent is null', () => {
const tracer = new BasicTracerProvider().getTracer('default');
const span = tracer.startSpan('my-span');
const overrideParent = tracer.startSpan('my-parent-override-span');
const rootSpan = tracer.startSpan(
'root-span',
{ parent: null },
setActiveSpan(Context.ROOT_CONTEXT, span)
);
const context = rootSpan.context();
assert.notStrictEqual(context.traceId, overrideParent.context().traceId);
span.end();
rootSpan.end();
});

it('should start a span with name and with invalid parent span', () => {
const tracer = new BasicTracerProvider().getTracer('default');
const span = tracer.startSpan(
Expand Down

0 comments on commit 9e114d1

Please sign in to comment.