Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for HAS_IS_REMOTE and IS_REMOTE spans and span links #4637

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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): add bit masks for `HAS_IS_REMOTE` and `IS_REMOTE` flags to be used in span and span link flags.

### :bug: (Bug Fix)

### :books: (Refine Doc)
Expand Down
4 changes: 4 additions & 0 deletions api/src/trace/trace_flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ export enum TraceFlags {
NONE = 0x0,
/** Bit to represent whether trace is sampled in trace flags. */
SAMPLED = 0x1 << 0,
/** Bit to represent whether this SDK understands the "is remote" flag */
HAS_IS_REMOTE = 0x100 << 0,
/** Bit to represent the parent span is remote */
IS_REMOTE = 0x200 << 0,
}
8 changes: 6 additions & 2 deletions packages/opentelemetry-sdk-trace-base/src/Tracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,13 @@ export class Tracer implements api.Tracer {
traceState = samplingResult.traceState ?? traceState;

const traceFlags =
samplingResult.decision === api.SamplingDecision.RECORD_AND_SAMPLED
(samplingResult.decision === api.SamplingDecision.RECORD_AND_SAMPLED
? api.TraceFlags.SAMPLED
: api.TraceFlags.NONE;
: api.TraceFlags.NONE) |
(parentSpanContext?.isRemote
? api.TraceFlags.HAS_IS_REMOTE | api.TraceFlags.IS_REMOTE
: api.TraceFlags.HAS_IS_REMOTE);

const spanContext = { traceId, spanId, traceFlags, traceState };
if (samplingResult.decision === api.SamplingDecision.NOT_RECORD) {
api.diag.debug(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export class ConsoleSpanExporter implements SpanExporter {
traceId: span.spanContext().traceId,
parentId: span.parentSpanId,
traceState: span.spanContext().traceState?.serialize(),
flags: span.spanContext().traceFlags,
name: span.name,
id: span.spanContext().spanId,
kind: span.kind,
Expand All @@ -76,7 +77,13 @@ export class ConsoleSpanExporter implements SpanExporter {
attributes: span.attributes,
status: span.status,
events: span.events,
links: span.links,
links: span.links.map(({ context, attributes }) => ({
traceId: context.traceId,
spanId: context.spanId,
traceState: context.traceState,
flags: context.traceFlags,
attributes: attributes,
})),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,13 +207,14 @@ describe('Tracer', () => {
});
});

it('should use traceId, spanId and traceState from parent', () => {
it('should use traceId, spanId and traceState and is_remote from parent', () => {
const traceState = createTraceState();
const parent: SpanContext = {
traceId: '00112233445566778899001122334455',
spanId: '0011223344556677',
traceFlags: TraceFlags.SAMPLED,
traceState,
isRemote: true,
};
const tracer = new Tracer(
{ name: 'default', version: '0.0.1' },
Expand All @@ -228,6 +229,38 @@ describe('Tracer', () => {
assert.strictEqual((span as Span).parentSpanId, parent.spanId);
assert.strictEqual(span.spanContext().traceId, parent.traceId);
assert.strictEqual(span.spanContext().traceState, traceState);
assert.strictEqual(
span.spanContext().traceFlags,
TraceFlags.SAMPLED & TraceFlags.HAS_IS_REMOTE & TraceFlags.IS_REMOTE
);
});

it('should not set is_remote for local parents', () => {
const traceState = createTraceState();
const parent: SpanContext = {
traceId: '00112233445566778899001122334455',
spanId: '0011223344556677',
traceFlags: TraceFlags.SAMPLED,
traceState,
isRemote: false,
};
const tracer = new Tracer(
{ name: 'default', version: '0.0.1' },
{},
tracerProvider
);
const span = tracer.startSpan(
'aSpan',
undefined,
trace.setSpanContext(ROOT_CONTEXT, parent)
);
assert.strictEqual((span as Span).parentSpanId, parent.spanId);
assert.strictEqual(span.spanContext().traceId, parent.traceId);
assert.strictEqual(span.spanContext().traceState, traceState);
assert.strictEqual(
span.spanContext().traceFlags,
TraceFlags.SAMPLED & TraceFlags.HAS_IS_REMOTE
);
});

it('should not use spanId from invalid parent', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ describe('ConsoleSpanExporter', () => {
'attributes',
'duration',
'events',
'flags',
'id',
'kind',
'links',
Expand Down