Skip to content
This repository was archived by the owner on Mar 2, 2022. It is now read-only.

Commit 812a99d

Browse files
authored
fix: Update span, Update trace header (getsentry#2128)
* fix: Update span, Update trace header * meta: Changelog
1 parent 872a194 commit 812a99d

File tree

8 files changed

+90
-40
lines changed

8 files changed

+90
-40
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
- [core] feat: Expose `Span` class
6+
37
## 5.4.2
48

59
- [core] fix: Allow Integration<T> constructor to have arguments

packages/browser/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export {
3030
setTag,
3131
setTags,
3232
setUser,
33+
Span,
3334
withScope,
3435
} from '@sentry/core';
3536

packages/core/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export {
1212
setUser,
1313
withScope,
1414
} from '@sentry/minimal';
15-
export { addGlobalEventProcessor, getCurrentHub, Hub, getHubFromCarrier, Scope } from '@sentry/hub';
15+
export { addGlobalEventProcessor, getCurrentHub, getHubFromCarrier, Hub, Scope, Span } from '@sentry/hub';
1616
export { API } from './api';
1717
export { BaseClient } from './baseclient';
1818
export { BackendClass, BaseBackend } from './basebackend';

packages/hub/src/scope.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,9 @@ export class Scope implements ScopeInterface {
203203
/**
204204
* @inheritDoc
205205
*/
206-
public startSpan(): Span {
206+
public startSpan(parentSpan?: Span): Span {
207207
const span = new Span();
208+
span.setParent(parentSpan);
208209
this.setSpan(span);
209210
return span;
210211
}

packages/hub/src/span.ts

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Span as SpanInterface } from '@sentry/types';
22
import { uuid4 } from '@sentry/utils';
33

4-
export const TRACEPARENT_REGEXP = /([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})/;
4+
export const TRACEPARENT_REGEXP = /^[ \t]*([0-9a-f]{32})?-?([0-9a-f]{16})?-?([01])?[ \t]*$/;
55

66
/**
77
* Span containg all data about a span
@@ -10,19 +10,41 @@ export class Span implements SpanInterface {
1010
public constructor(
1111
private readonly _traceId: string = uuid4(),
1212
private readonly _spanId: string = uuid4().substring(16),
13-
private readonly _recorded: boolean = false,
14-
private readonly _parent?: Span,
13+
private _sampled?: boolean,
14+
private _parent?: Span,
1515
) {}
1616

17+
/**
18+
* Setter for parent
19+
*/
20+
public setParent(parent: Span | undefined): this {
21+
this._parent = parent;
22+
return this;
23+
}
24+
25+
/**
26+
* Setter for sampled
27+
*/
28+
public setSampled(sampled: boolean | undefined): this {
29+
this._sampled = sampled;
30+
return this;
31+
}
32+
1733
/**
1834
* Continues a trace
1935
* @param traceparent Traceparent string
2036
*/
2137
public static fromTraceparent(traceparent: string): Span | undefined {
2238
const matches = traceparent.match(TRACEPARENT_REGEXP);
2339
if (matches) {
24-
const parent = new Span(matches[2], matches[3], matches[4] === '01' ? true : false);
25-
return new Span(matches[2], undefined, undefined, parent);
40+
let sampled;
41+
if (matches[3] === '1') {
42+
sampled = true;
43+
} else if (matches[3] === '0') {
44+
sampled = false;
45+
}
46+
const parent = new Span(matches[1], matches[2], sampled);
47+
return new Span(matches[1], undefined, sampled, parent);
2648
}
2749
return undefined;
2850
}
@@ -31,7 +53,14 @@ export class Span implements SpanInterface {
3153
* @inheritDoc
3254
*/
3355
public toTraceparent(): string {
34-
return `00-${this._traceId}-${this._spanId}-${this._recorded ? '01' : '00'}`;
56+
let sampled = '';
57+
if (this._sampled === true) {
58+
sampled = '-1';
59+
} else if (this._sampled === false) {
60+
sampled = '-0';
61+
}
62+
63+
return `${this._traceId}-${this._spanId}${sampled}`;
3564
}
3665

3766
/**
@@ -40,6 +69,7 @@ export class Span implements SpanInterface {
4069
public toJSON(): object {
4170
return {
4271
parent: (this._parent && this._parent.toJSON()) || undefined,
72+
sampled: this._sampled,
4373
span_id: this._spanId,
4474
trace_id: this._traceId,
4575
};

packages/hub/test/span.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { Span, TRACEPARENT_REGEXP } from '../src';
2+
3+
describe('Span', () => {
4+
test('toTraceparent', () => {
5+
expect(new Span().toTraceparent()).toMatch(TRACEPARENT_REGEXP);
6+
});
7+
8+
describe('fromTraceparent', () => {
9+
test('no sample', () => {
10+
const from = Span.fromTraceparent('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb') as any;
11+
expect(from._parent._traceId).toEqual('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
12+
expect(from._parent._spanId).toEqual('bbbbbbbbbbbbbbbb');
13+
expect(from._traceId).toEqual('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
14+
expect(from._spanId).not.toEqual('bbbbbbbbbbbbbbbb');
15+
expect(from._sampled).toBeUndefined();
16+
});
17+
test('sample true', () => {
18+
const from = Span.fromTraceparent('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-1') as any;
19+
expect(from._sampled).toBeTruthy();
20+
});
21+
22+
test('sample false', () => {
23+
const from = Span.fromTraceparent('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-0') as any;
24+
expect(from._sampled).toBeFalsy();
25+
});
26+
});
27+
28+
test('fromTraceparent - invalid', () => {
29+
expect(Span.fromTraceparent('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-x')).toBeUndefined();
30+
});
31+
32+
test('toJSON', () => {
33+
expect(JSON.stringify(new Span('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'bbbbbbbbbbbbbbbb'))).toEqual(
34+
`{"span_id":"bbbbbbbbbbbbbbbb","trace_id":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}`,
35+
);
36+
});
37+
38+
test('toJSON with parent', () => {
39+
const spanA = new Span('a', 'b');
40+
const spanB = new Span('c', 'd', false, spanA);
41+
expect(JSON.stringify(spanB)).toEqual(
42+
`{"parent":{"span_id":"b","trace_id":"a"},"sampled":false,"span_id":"d","trace_id":"c"}`,
43+
);
44+
});
45+
});

packages/hub/test/spancontext.test.ts

Lines changed: 0 additions & 32 deletions
This file was deleted.

packages/node/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export {
3030
setTag,
3131
setTags,
3232
setUser,
33+
Span,
3334
withScope,
3435
} from '@sentry/core';
3536

0 commit comments

Comments
 (0)