Skip to content

Commit 41c974c

Browse files
HazATkamilogorek
authored andcommitted
feat: Add simple API, timestampWithMs helper
1 parent cff9c0e commit 41c974c

File tree

7 files changed

+119
-29
lines changed

7 files changed

+119
-29
lines changed

packages/hub/src/hub.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,15 @@ import {
1111
SpanContext,
1212
User,
1313
} from '@sentry/types';
14-
import { consoleSandbox, dynamicRequire, getGlobalObject, isNodeEnv, logger, uuid4 } from '@sentry/utils';
14+
import {
15+
consoleSandbox,
16+
dynamicRequire,
17+
getGlobalObject,
18+
isNodeEnv,
19+
logger,
20+
timestampWithMs,
21+
uuid4,
22+
} from '@sentry/utils';
1523

1624
import { Carrier, Layer } from './interfaces';
1725
import { Scope } from './scope';
@@ -253,7 +261,7 @@ export class Hub implements HubInterface {
253261
return;
254262
}
255263

256-
const timestamp = new Date().getTime() / 1000;
264+
const timestamp = timestampWithMs();
257265
const mergedBreadcrumb = { timestamp, ...breadcrumb };
258266
const finalBreadcrumb = beforeBreadcrumb
259267
? (consoleSandbox(() => beforeBreadcrumb(mergedBreadcrumb, hint)) as Breadcrumb | null)
@@ -389,17 +397,22 @@ export class Hub implements HubInterface {
389397
/**
390398
* @inheritDoc
391399
*/
392-
public startSpan(spanContext?: SpanContext): Span {
393-
const scope = this.getScope();
400+
public startSpan(spanContext?: SpanContext, bindOnScope: boolean = false): Span {
401+
const top = this.getStackTop();
394402

395-
if (scope) {
396-
const span = scope.getSpan();
403+
const simpleNewSpan = new Span(spanContext);
404+
if (top.scope && top.client) {
405+
if (bindOnScope) {
406+
top.scope.setSpan(simpleNewSpan);
407+
return simpleNewSpan;
408+
}
409+
const span = top.scope.getSpan();
397410
if (span) {
398411
return span.newSpan(spanContext);
399412
}
400413
}
401414

402-
return new Span(spanContext);
415+
return simpleNewSpan;
403416
}
404417

405418
/**

packages/hub/src/scope.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Breadcrumb, Event, EventHint, EventProcessor, Scope as ScopeInterface, Severity, User } from '@sentry/types';
2-
import { getGlobalObject, isThenable, normalize, SyncPromise } from '@sentry/utils';
2+
import { getGlobalObject, isThenable, normalize, SyncPromise, timestampWithMs } from '@sentry/utils';
33

44
import { Span } from './span';
55

@@ -250,7 +250,7 @@ export class Scope implements ScopeInterface {
250250
* @inheritDoc
251251
*/
252252
public addBreadcrumb(breadcrumb: Breadcrumb, maxBreadcrumbs?: number): this {
253-
const timestamp = new Date().getTime() / 1000;
253+
const timestamp = timestampWithMs();
254254
const mergedBreadcrumb = { timestamp, ...breadcrumb };
255255

256256
this._breadcrumbs =

packages/hub/src/span.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Span as SpanInterface, SpanContext } from '@sentry/types';
2-
import { uuid4 } from '@sentry/utils';
2+
import { timestampWithMs, uuid4 } from '@sentry/utils';
33

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

@@ -8,57 +8,57 @@ export const TRACEPARENT_REGEXP = /^[ \t]*([0-9a-f]{32})?-?([0-9a-f]{16})?-?([01
88
*/
99
export class Span implements SpanInterface, SpanContext {
1010
/**
11-
* Trace ID
11+
* @inheritDoc
1212
*/
1313
private readonly _traceId: string = uuid4();
1414

1515
/**
16-
* Span ID
16+
* @inheritDoc
1717
*/
1818
private readonly _spanId: string = uuid4().substring(16);
1919

2020
/**
21-
* Parent Span ID
21+
* @inheritDoc
2222
*/
2323
private readonly _parentSpanId?: string;
2424

2525
/**
26-
* Has the sampling decision been made?
26+
* @inheritDoc
2727
*/
2828
public readonly sampled?: boolean;
2929

3030
/**
3131
* Timestamp when the span was created.
3232
*/
33-
public readonly startTimestamp: number = new Date().getTime() / 1000;
33+
public readonly startTimestamp: number = timestampWithMs();
3434

3535
/**
3636
* Finish timestamp of the span.
3737
*/
3838
public timestamp?: number;
3939

4040
/**
41-
* Transaction of the Span.
41+
* @inheritDoc
4242
*/
4343
public transaction?: string;
4444

4545
/**
46-
* Operation of the Span.
46+
* @inheritDoc
4747
*/
4848
public op?: string;
4949

5050
/**
51-
* Description of the Span.
51+
* @inheritDoc
5252
*/
5353
public description?: string;
5454

5555
/**
56-
* Tags of the Span.
56+
* @inheritDoc
5757
*/
5858
public tags?: { [key: string]: string };
5959

6060
/**
61-
* Data of the Span.
61+
* @inheritDoc
6262
*/
6363
public data?: { [key: string]: any };
6464

@@ -101,7 +101,10 @@ export class Span implements SpanInterface, SpanContext {
101101
}
102102
}
103103

104-
/** JSDoc */
104+
/**
105+
* Creates a new `Span` while setting the current `Span.id` as `parentSpanId`.
106+
* Also the `sampled` decision will be inherited.
107+
*/
105108
public newSpan(spanContext?: Pick<SpanContext, Exclude<keyof SpanContext, 'spanId'>>): Span {
106109
const span = new Span({
107110
...spanContext,
@@ -116,7 +119,7 @@ export class Span implements SpanInterface, SpanContext {
116119
}
117120

118121
/**
119-
* Continues a trace
122+
* Continues a trace from a string (usually the header).
120123
* @param traceparent Traceparent string
121124
*/
122125
public static fromTraceparent(
@@ -131,7 +134,6 @@ export class Span implements SpanInterface, SpanContext {
131134
} else if (matches[3] === '0') {
132135
sampled = false;
133136
}
134-
135137
return new Span({
136138
...spanContext,
137139
parentSpanId: matches[2],
@@ -146,7 +148,7 @@ export class Span implements SpanInterface, SpanContext {
146148
* Sets the finish timestamp on the current span
147149
*/
148150
public finish(): void {
149-
this.timestamp = new Date().getTime() / 1000;
151+
this.timestamp = timestampWithMs();
150152
this.finishedSpans.push(this);
151153
}
152154

packages/minimal/src/index.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getCurrentHub, Hub, Scope } from '@sentry/hub';
2-
import { Breadcrumb, Event, Severity, User } from '@sentry/types';
2+
import { Breadcrumb, Event, Severity, Span, SpanContext, User } from '@sentry/types';
33

44
/**
55
* This calls a function on the current hub.
@@ -166,3 +166,28 @@ export function withScope(callback: (scope: Scope) => void): void {
166166
export function _callOnClient(method: string, ...args: any[]): void {
167167
callOnHub<void>('_invokeClient', method, ...args);
168168
}
169+
170+
/**
171+
* This functions starts a span. If just a `SpanContext` is passed and there is already a Span
172+
* on the Scope, the created Span will have a reference to the one on the Scope.
173+
* If a Span is on the current Scope it is considered a `transaction`.
174+
* When using the second parameter it will set the created Span on the Scope (replacing whats there).
175+
* This can be used as a shortcut to not set it manually on the Scope.
176+
*
177+
* @param spanContext Properties with which the span should be created
178+
* @param bindOnScope Determines if the started span will be set on the Scope
179+
*/
180+
export function startSpan(spanContext?: SpanContext, bindOnScope?: boolean): Span {
181+
return callOnHub<Span>('startSpan', spanContext, bindOnScope);
182+
}
183+
184+
/**
185+
* This finishes the passed `Span`. If the `Span` has the property `transaction` set and it's bound on the
186+
* current Scope, an `transaction` Event will be sent to Sentry containing all finished Spans inbetween.
187+
* Returns either an `event.id` or `undefined` in case event wasn't sent.
188+
*
189+
* @param span `Span` instance that was created by {@link startSpan}
190+
*/
191+
export function finishSpan(span: Span): string | undefined {
192+
return callOnHub<string | undefined>('startSpan', span);
193+
}

packages/types/src/hub.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,24 @@ export interface Hub {
172172
/** Returns all trace headers that are currently on the top scope. */
173173
traceHeaders(): { [key: string]: string };
174174

175-
/** JSDoc */
176-
startSpan(spanContext?: SpanContext): Span;
175+
/**
176+
* This functions starts a span. If just a `SpanContext` is passed and there is already a Span
177+
* on the Scope, the created Span will have a reference to the one on the Scope.
178+
* If a Span is on the current Scope it is considered a `transaction`.
179+
* When using the second parameter it will set the created Span on the Scope (replacing whats there).
180+
* This can be used as a shortcut to not set it manually on the Scope.
181+
*
182+
* @param spanContext Properties with which the span should be created
183+
* @param bindOnScope Determines if the started span will be set on the Scope
184+
*/
185+
startSpan(spanContext?: SpanContext, bindOnScope?: boolean): Span;
177186

178-
/** JSDoc */
187+
/**
188+
* This finishes the passed `Span`. If the `Span` has the property `transaction` set and it's bound on the
189+
* current Scope, an `transaction` Event will be sent to Sentry containing all finished Spans inbetween.
190+
* Returns either an `event.id` or `undefined` in case event wasn't sent.
191+
*
192+
* @param span `Span` instance that was created by {@link startSpan}
193+
*/
179194
finishSpan(span: Span): string | undefined;
180195
}

packages/types/src/span.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,43 @@ export interface Span {
88
toJSON(): object;
99
}
1010

11-
/** JSDoc */
11+
/** Interface holder all properties that can be set on a Span on creation. */
1212
export interface SpanContext {
13+
/**
14+
* Description of the Span.
15+
*/
1316
description?: string;
17+
/**
18+
* Operation of the Span.
19+
*/
1420
op?: string;
21+
/**
22+
* Parent Span ID
23+
*/
1524
parentSpanId?: string;
25+
/**
26+
* Has the sampling decision been made?
27+
*/
1628
sampled?: boolean;
29+
/**
30+
* Span ID
31+
*/
1732
spanId?: string;
33+
/**
34+
* Trace ID
35+
*/
1836
traceId?: string;
37+
/**
38+
* Transaction of the Span.
39+
*/
1940
transaction?: string;
41+
/**
42+
* Tags of the Span.
43+
*/
2044
tags?: { [key: string]: string };
45+
46+
/**
47+
* Data of the Span.
48+
*/
2149
data?: { [key: string]: any };
2250
}

packages/utils/src/misc.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,3 +335,10 @@ function _htmlElementAsString(elem: HTMLElement): string {
335335
}
336336
return out.join('');
337337
}
338+
339+
/**
340+
* Returns a timestamp in seconds with milliseconds precision.
341+
*/
342+
export function timestampWithMs(): number {
343+
return new Date().getTime() / 1000;
344+
}

0 commit comments

Comments
 (0)