From 1052e88ff7b75f7119aa633e901ad8e8f8504f47 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Mon, 23 Mar 2020 10:39:46 -0400 Subject: [PATCH 1/3] feat: start a root span with spanOptions.parent = null --- .../opentelemetry-api/src/trace/SpanOptions.ts | 3 +++ packages/opentelemetry-tracing/src/Tracer.ts | 17 ++++++++++++++--- .../test/BasicTracerProvider.test.ts | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/opentelemetry-api/src/trace/SpanOptions.ts b/packages/opentelemetry-api/src/trace/SpanOptions.ts index 131d6d4f70..c6dcf0fc18 100644 --- a/packages/opentelemetry-api/src/trace/SpanOptions.ts +++ b/packages/opentelemetry-api/src/trace/SpanOptions.ts @@ -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; diff --git a/packages/opentelemetry-tracing/src/Tracer.ts b/packages/opentelemetry-tracing/src/Tracer.ts index f7fd4d6248..7ab34100e8 100644 --- a/packages/opentelemetry-tracing/src/Tracer.ts +++ b/packages/opentelemetry-tracing/src/Tracer.ts @@ -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(); @@ -149,6 +147,19 @@ 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) { + 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; } diff --git a/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts b/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts index 85422703fc..bfe14c7650 100644 --- a/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts +++ b/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts @@ -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( From bd16a994380ca20a89dd582130534527de203b13 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Mon, 23 Mar 2020 10:49:29 -0400 Subject: [PATCH 2/3] chore: lint --- packages/opentelemetry-tracing/src/Tracer.ts | 2 +- packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/opentelemetry-tracing/src/Tracer.ts b/packages/opentelemetry-tracing/src/Tracer.ts index 7ab34100e8..624a18dc91 100644 --- a/packages/opentelemetry-tracing/src/Tracer.ts +++ b/packages/opentelemetry-tracing/src/Tracer.ts @@ -150,7 +150,7 @@ 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 */ diff --git a/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts b/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts index bfe14c7650..832128e9c4 100644 --- a/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts +++ b/packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts @@ -252,7 +252,7 @@ describe('BasicTracerProvider', () => { 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'); From 9e4449bd634c9a89244b57018068ffc152c1f8d7 Mon Sep 17 00:00:00 2001 From: Daniel Dyla Date: Mon, 23 Mar 2020 13:28:54 -0400 Subject: [PATCH 3/3] chore: add return type for readability --- packages/opentelemetry-api/src/trace/SpanOptions.ts | 2 +- packages/opentelemetry-tracing/src/Tracer.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/opentelemetry-api/src/trace/SpanOptions.ts b/packages/opentelemetry-api/src/trace/SpanOptions.ts index c6dcf0fc18..bfda7e001c 100644 --- a/packages/opentelemetry-api/src/trace/SpanOptions.ts +++ b/packages/opentelemetry-api/src/trace/SpanOptions.ts @@ -44,7 +44,7 @@ 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. */ diff --git a/packages/opentelemetry-tracing/src/Tracer.ts b/packages/opentelemetry-tracing/src/Tracer.ts index 624a18dc91..9ca8e6a80e 100644 --- a/packages/opentelemetry-tracing/src/Tracer.ts +++ b/packages/opentelemetry-tracing/src/Tracer.ts @@ -154,7 +154,10 @@ export class Tracer implements api.Tracer { * @param options span options * @param context context to check for parent */ -function getParent(options: api.SpanOptions, context: api.Context) { +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);