Skip to content

Commit

Permalink
feat: allow adding links after span creation (#4536)
Browse files Browse the repository at this point in the history
* feat: allow adding links after span creation

* update changelog

* improve docs

* test: increase coverage

* Update api/CHANGELOG.md

Co-authored-by: Marc Pichler <[email protected]>

* update changelog

---------

Co-authored-by: Marc Pichler <[email protected]>
  • Loading branch information
seemk and pichlermarc authored May 6, 2024
1 parent 1c5de7a commit c503ff1
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/
* feat(instrumentation): Make `init()` method public [#4418](https://github.com/open-telemetry/opentelemetry-js/pull/4418)
* feat(context-zone-peer-dep, context-zone): support zone.js 0.13.x, 0.14.x [#4469](https://github.com/open-telemetry/opentelemetry-js/pull/4469) @pichlermarc
* chore: Semantic Conventions export individual strings [4185](https://github.com/open-telemetry/opentelemetry-js/issues/4185)
* feat(sdk-trace-base): allow adding span links after span creation [#4536](https://github.com/open-telemetry/opentelemetry-js/pull/4536) @seemk

### :bug: (Bug Fix)

Expand Down
2 changes: 2 additions & 0 deletions api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file.

### :rocket: (Enhancement)

* feat(api): allow adding span links after span creation [#4536](https://github.com/open-telemetry/opentelemetry-js/pull/4536) @seemk
* This change is non-breaking for end-users, but breaking for Trace SDK implmentations in accordance with the [specification](https://github.com/open-telemetry/opentelemetry-specification/blob/a03382ada8afa9415266a84dafac0510ec8c160f/specification/upgrading.md?plain=1#L97-L122) as new features need to be implemented.
* feat: support node 22 [#4666](https://github.com/open-telemetry/opentelemetry-js/pull/4666) @dyladan

### :bug: (Bug Fix)
Expand Down
9 changes: 9 additions & 0 deletions api/src/trace/NonRecordingSpan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { INVALID_SPAN_CONTEXT } from './invalid-span-constants';
import { Span } from './span';
import { SpanContext } from './span_context';
import { SpanStatus } from './status';
import { Link } from './link';

/**
* The NonRecordingSpan is the default {@link Span} that is used when no Span
Expand Down Expand Up @@ -52,6 +53,14 @@ export class NonRecordingSpan implements Span {
return this;
}

addLink(_link: Link): this {
return this;
}

addLinks(_links: Link[]): this {
return this;
}

// By default does nothing
setStatus(_status: SpanStatus): this {
return this;
Expand Down
21 changes: 21 additions & 0 deletions api/src/trace/span.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { TimeInput } from '../common/Time';
import { SpanAttributes, SpanAttributeValue } from './attributes';
import { SpanContext } from './span_context';
import { SpanStatus } from './status';
import { Link } from './link';

/**
* An interface that represents a span. A span represents a single operation
Expand Down Expand Up @@ -76,6 +77,26 @@ export interface Span {
startTime?: TimeInput
): this;

/**
* Adds a single link to the span.
*
* Links added after the creation will not affect the sampling decision.
* It is preferred span links be added at span creation.
*
* @param link the link to add.
*/
addLink(link: Link): this;

/**
* Adds multiple links to the span.
*
* Links added after the creation will not affect the sampling decision.
* It is preferred span links be added at span creation.
*
* @param links the links to add.
*/
addLinks(links: Link[]): this;

/**
* Sets a status to the span. If used, this will override the default Span
* status. Default is {@link SpanStatusCode.UNSET}. SetStatus overrides the value
Expand Down
8 changes: 8 additions & 0 deletions api/test/common/noop-implementations/noop-span.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ describe('NonRecordingSpan', () => {
my_number_attribute: 123,
});

const linkContext = {
traceId: 'e4cda95b652f4a1592b449d5929fda1b',
spanId: '7e0c63257de34c92',
traceFlags: TraceFlags.SAMPLED,
};
span.addLink({ context: linkContext });
span.addLinks([{ context: linkContext }]);

span.addEvent('sent');
span.addEvent('sent', { id: '42', key: 'value' });

Expand Down
10 changes: 10 additions & 0 deletions packages/opentelemetry-sdk-trace-base/src/Span.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,16 @@ export class Span implements APISpan, ReadableSpan {
return this;
}

addLink(link: Link): this {
this.links.push(link);
return this;
}

addLinks(links: Link[]): this {
this.links.push(...links);
return this;
}

setStatus(status: SpanStatus): this {
if (this._isSpanEnded()) return this;
this.status = status;
Expand Down
76 changes: 52 additions & 24 deletions packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -771,30 +771,6 @@ describe('Span', () => {
});
});

it('should set a link', () => {
const spanContext: SpanContext = {
traceId: 'a3cda95b652f4a1592b449d5929fda1b',
spanId: '5e0c63257de34c92',
traceFlags: TraceFlags.SAMPLED,
};
const linkContext: SpanContext = {
traceId: 'b3cda95b652f4a1592b449d5929fda1b',
spanId: '6e0c63257de34c92',
traceFlags: TraceFlags.SAMPLED,
};
const attributes = { attr1: 'value', attr2: 123, attr3: true };
const span = new Span(
tracer,
ROOT_CONTEXT,
name,
spanContext,
SpanKind.CLIENT,
'12345',
[{ context: linkContext }, { context: linkContext, attributes }]
);
span.end();
});

it('should drop extra events', () => {
const span = new Span(
tracer,
Expand Down Expand Up @@ -959,6 +935,58 @@ describe('Span', () => {
span.end();
});

it('should be possible to add a link after span creation', () => {
const span = new Span(
tracer,
ROOT_CONTEXT,
'my-span',
spanContext,
SpanKind.CONSUMER
);

span.addLink({ context: linkContext });

span.end();

assert.strictEqual(span.links.length, 1);
assert.deepStrictEqual(span.links, [
{
context: linkContext,
},
]);
});

it('should be possible to add multiple links after span creation', () => {
const span = new Span(
tracer,
ROOT_CONTEXT,
'my-span',
spanContext,
SpanKind.CONSUMER
);

span.addLinks([
{ context: linkContext },
{
context: linkContext,
attributes: { attr1: 'value', attr2: 123, attr3: true },
},
]);

span.end();

assert.strictEqual(span.links.length, 2);
assert.deepStrictEqual(span.links, [
{
context: linkContext,
},
{
attributes: { attr1: 'value', attr2: 123, attr3: true },
context: linkContext,
},
]);
});

it('should return ReadableSpan with events', () => {
const span = new Span(
tracer,
Expand Down

0 comments on commit c503ff1

Please sign in to comment.