From 27555ebea4d1e323f67a4c458e79faa0c4fc3910 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 4 Jan 2024 16:35:48 +0100 Subject: [PATCH 1/4] feat(core): Allow to pass start/end timestamp for spans flexibly We allow the same formats as OpenTelemetry: * `number` (we handle both seconds and milliseconds) * `Date` * `[seconds, nanoseconds]` --- packages/core/src/tracing/idletransaction.ts | 10 ++--- packages/core/src/tracing/span.ts | 9 ++--- packages/core/src/tracing/trace.ts | 28 ++++++++------ packages/core/src/tracing/transaction.ts | 11 +++--- packages/core/src/utils/spanUtils.ts | 36 +++++++++++++++++- packages/core/test/lib/tracing/span.test.ts | 35 ++++++++++++++++++ packages/core/test/lib/tracing/trace.test.ts | 22 +++++++++++ .../core/test/lib/utils/spanUtils.test.ts | 37 ++++++++++++++++++- packages/types/src/index.ts | 2 +- packages/types/src/span.ts | 19 +++++++++- 10 files changed, 177 insertions(+), 32 deletions(-) diff --git a/packages/core/src/tracing/idletransaction.ts b/packages/core/src/tracing/idletransaction.ts index 458bd9281627..fdc1813e5b50 100644 --- a/packages/core/src/tracing/idletransaction.ts +++ b/packages/core/src/tracing/idletransaction.ts @@ -1,13 +1,13 @@ /* eslint-disable max-lines */ -import type { TransactionContext } from '@sentry/types'; +import type { SpanTimeInput, TransactionContext } from '@sentry/types'; import { logger, timestampInSeconds } from '@sentry/utils'; import { DEBUG_BUILD } from '../debug-build'; import type { Hub } from '../hub'; +import { spanTimeInputToSeconds } from '../utils/spanUtils'; import type { Span } from './span'; import { SpanRecorder } from './span'; import { Transaction } from './transaction'; -import { ensureTimestampInSeconds } from './utils'; export const TRACING_DEFAULTS = { idleTimeout: 1000, @@ -138,8 +138,8 @@ export class IdleTransaction extends Transaction { } /** {@inheritDoc} */ - public end(endTimestamp: number = timestampInSeconds()): string | undefined { - const endTimestampInS = ensureTimestampInSeconds(endTimestamp); + public end(endTimestamp?: SpanTimeInput): string | undefined { + const endTimestampInS = spanTimeInputToSeconds(endTimestamp); this._finished = true; this.activities = {}; @@ -153,7 +153,7 @@ export class IdleTransaction extends Transaction { logger.log('[Tracing] finishing IdleTransaction', new Date(endTimestampInS * 1000).toISOString(), this.op); for (const callback of this._beforeFinishCallbacks) { - callback(this, endTimestamp); + callback(this, endTimestampInS); } this.spanRecorder.spans = this.spanRecorder.spans.filter((span: Span) => { diff --git a/packages/core/src/tracing/span.ts b/packages/core/src/tracing/span.ts index e30f6e416675..c4e91a38f9c7 100644 --- a/packages/core/src/tracing/span.ts +++ b/packages/core/src/tracing/span.ts @@ -7,14 +7,14 @@ import type { SpanAttributes, SpanContext, SpanOrigin, + SpanTimeInput, TraceContext, Transaction, } from '@sentry/types'; import { dropUndefinedKeys, logger, timestampInSeconds, uuid4 } from '@sentry/utils'; import { DEBUG_BUILD } from '../debug-build'; -import { spanToTraceContext, spanToTraceHeader } from '../utils/spanUtils'; -import { ensureTimestampInSeconds } from './utils'; +import { spanTimeInputToSeconds, spanToTraceContext, spanToTraceHeader } from '../utils/spanUtils'; /** * Keeps track of finished spans for a given transaction @@ -300,7 +300,7 @@ export class Span implements SpanInterface { } /** @inheritdoc */ - public end(endTimestamp?: number): void { + public end(endTimestamp?: SpanTimeInput): void { if ( DEBUG_BUILD && // Don't call this for transactions @@ -313,8 +313,7 @@ export class Span implements SpanInterface { } } - this.endTimestamp = - typeof endTimestamp === 'number' ? ensureTimestampInSeconds(endTimestamp) : timestampInSeconds(); + this.endTimestamp = spanTimeInputToSeconds(endTimestamp); } /** diff --git a/packages/core/src/tracing/trace.ts b/packages/core/src/tracing/trace.ts index b5d49f4767a7..6f7420cca9e3 100644 --- a/packages/core/src/tracing/trace.ts +++ b/packages/core/src/tracing/trace.ts @@ -1,4 +1,4 @@ -import type { Span, TransactionContext } from '@sentry/types'; +import type { Span, SpanTimeInput, TransactionContext } from '@sentry/types'; import { dropUndefinedKeys, logger, tracingContextFromHeaders } from '@sentry/utils'; import { DEBUG_BUILD } from '../debug-build'; @@ -7,6 +7,12 @@ import type { Hub } from '../hub'; import { getCurrentHub } from '../hub'; import { handleCallbackErrors } from '../utils/handleCallbackErrors'; import { hasTracingEnabled } from '../utils/hasTracingEnabled'; +import { spanTimeInputToSeconds } from '../utils/spanUtils'; + +interface StartSpanOptions extends TransactionContext { + /** A manually specified start time for the created `Span` object. */ + startTime?: SpanTimeInput; +} /** * Wraps a function with a transaction/span and finishes the span after the function is done. @@ -65,7 +71,7 @@ export function trace( * or you didn't set `tracesSampleRate`, this function will not generate spans * and the `span` returned from the callback will be undefined. */ -export function startSpan(context: TransactionContext, callback: (span: Span | undefined) => T): T { +export function startSpan(context: StartSpanOptions, callback: (span: Span | undefined) => T): T { const ctx = normalizeContext(context); return withScope(scope => { @@ -105,7 +111,7 @@ export const startActiveSpan = startSpan; * and the `span` returned from the callback will be undefined. */ export function startSpanManual( - context: TransactionContext, + context: StartSpanOptions, callback: (span: Span | undefined, finish: () => void) => T, ): T { const ctx = normalizeContext(context); @@ -143,17 +149,12 @@ export function startSpanManual( * or you didn't set `tracesSampleRate` or `tracesSampler`, this function will not generate spans * and the `span` returned from the callback will be undefined. */ -export function startInactiveSpan(context: TransactionContext): Span | undefined { +export function startInactiveSpan(context: StartSpanOptions): Span | undefined { if (!hasTracingEnabled()) { return undefined; } - const ctx = { ...context }; - // If a name is set and a description is not, set the description to the name. - if (ctx.name !== undefined && ctx.description === undefined) { - ctx.description = ctx.name; - } - + const ctx = normalizeContext(context); const hub = getCurrentHub(); const parentSpan = getActiveSpan(); return parentSpan ? parentSpan.startChild(ctx) : hub.startTransaction(ctx); @@ -238,12 +239,17 @@ function createChildSpanOrTransaction( return parentSpan ? parentSpan.startChild(ctx) : hub.startTransaction(ctx); } -function normalizeContext(context: TransactionContext): TransactionContext { +function normalizeContext(context: StartSpanOptions): TransactionContext { const ctx = { ...context }; // If a name is set and a description is not, set the description to the name. if (ctx.name !== undefined && ctx.description === undefined) { ctx.description = ctx.name; } + if (context.startTime) { + ctx.startTimestamp = spanTimeInputToSeconds(context.startTime); + delete ctx.startTime; + } + return ctx; } diff --git a/packages/core/src/tracing/transaction.ts b/packages/core/src/tracing/transaction.ts index 4652ab160143..7142ec3419e7 100644 --- a/packages/core/src/tracing/transaction.ts +++ b/packages/core/src/tracing/transaction.ts @@ -4,20 +4,20 @@ import type { DynamicSamplingContext, MeasurementUnit, Measurements, + SpanTimeInput, Transaction as TransactionInterface, TransactionContext, TransactionEvent, TransactionMetadata, } from '@sentry/types'; -import { dropUndefinedKeys, logger, timestampInSeconds } from '@sentry/utils'; +import { dropUndefinedKeys, logger } from '@sentry/utils'; import { DEBUG_BUILD } from '../debug-build'; import type { Hub } from '../hub'; import { getCurrentHub } from '../hub'; -import { spanToTraceContext } from '../utils/spanUtils'; +import { spanTimeInputToSeconds, spanToTraceContext } from '../utils/spanUtils'; import { getDynamicSamplingContextFromClient } from './dynamicSamplingContext'; import { Span as SpanClass, SpanRecorder } from './span'; -import { ensureTimestampInSeconds } from './utils'; /** JSDoc */ export class Transaction extends SpanClass implements TransactionInterface { @@ -147,9 +147,8 @@ export class Transaction extends SpanClass implements TransactionInterface { /** * @inheritDoc */ - public end(endTimestamp?: number): string | undefined { - const timestampInS = - typeof endTimestamp === 'number' ? ensureTimestampInSeconds(endTimestamp) : timestampInSeconds(); + public end(endTimestamp?: SpanTimeInput): string | undefined { + const timestampInS = spanTimeInputToSeconds(endTimestamp); const transaction = this._finishTransaction(timestampInS); if (!transaction) { return undefined; diff --git a/packages/core/src/utils/spanUtils.ts b/packages/core/src/utils/spanUtils.ts index 2dae21a78fca..b32dc3f1d71f 100644 --- a/packages/core/src/utils/spanUtils.ts +++ b/packages/core/src/utils/spanUtils.ts @@ -1,5 +1,6 @@ -import type { Span, TraceContext } from '@sentry/types'; -import { dropUndefinedKeys, generateSentryTraceHeader } from '@sentry/utils'; +import type { Span, SpanTimeInput, TraceContext } from '@sentry/types'; +import { dropUndefinedKeys, generateSentryTraceHeader, timestampInSeconds } from '@sentry/utils'; +import { ensureTimestampInSeconds } from '../tracing/utils'; /** * Convert a span to a trace context, which can be sent as the `trace` context in an event. @@ -26,3 +27,34 @@ export function spanToTraceContext(span: Span): TraceContext { export function spanToTraceHeader(span: Span): string { return generateSentryTraceHeader(span.traceId, span.spanId, span.sampled); } + +/** + * Convert a span time input intp a timestamp in seconds. + */ +export function spanTimeInputToSeconds(input: SpanTimeInput | undefined): number { + if (typeof input === 'number') { + return ensureTimestampInSeconds(input); + } + + if (Array.isArray(input)) { + /** + * Defines High-Resolution Time. + * + * The first number, HrTime[0], is UNIX Epoch time in seconds since 00:00:00 UTC on 1 January 1970. + * The second number, HrTime[1], represents the partial second elapsed since Unix Epoch time represented by first number in nanoseconds. + * For example, 2021-01-01T12:30:10.150Z in UNIX Epoch time in milliseconds is represented as 1609504210150. + * The first number is calculated by converting and truncating the Epoch time in milliseconds to seconds: + * HrTime[0] = Math.trunc(1609504210150 / 1000) = 1609504210. + * The second number is calculated by converting the digits after the decimal point of the subtraction, (1609504210150 / 1000) - HrTime[0], to nanoseconds: + * HrTime[1] = Number((1609504210.150 - HrTime[0]).toFixed(9)) * 1e9 = 150000000. + * This is represented in HrTime format as [1609504210, 150000000]. + */ + return input[0] + input[1] / 1e9; + } + + if (input instanceof Date) { + return ensureTimestampInSeconds(input.getTime()); + } + + return timestampInSeconds(); +} diff --git a/packages/core/test/lib/tracing/span.test.ts b/packages/core/test/lib/tracing/span.test.ts index c0b13df647f6..d439d6eb6ab1 100644 --- a/packages/core/test/lib/tracing/span.test.ts +++ b/packages/core/test/lib/tracing/span.test.ts @@ -1,3 +1,4 @@ +import { timestampInSeconds } from '@sentry/utils'; import { Span } from '../../../src'; describe('span', () => { @@ -174,6 +175,40 @@ describe('span', () => { }); }); + describe('end', () => { + it('works without endTimestamp', () => { + const span = new Span(); + const now = timestampInSeconds(); + span.end(); + + expect(span.endTimestamp).toBeGreaterThanOrEqual(now); + }); + + it('works with endTimestamp in seconds', () => { + const span = new Span(); + const timestamp = timestampInSeconds() - 1; + span.end(timestamp); + + expect(span.endTimestamp).toEqual(timestamp); + }); + + it('works with endTimestamp in milliseconds', () => { + const span = new Span(); + const timestamp = Date.now() - 1000; + span.end(timestamp); + + expect(span.endTimestamp).toEqual(timestamp / 1000); + }); + + it('works with endTimestamp in array form', () => { + const span = new Span(); + const seconds = Math.floor(timestampInSeconds() - 1); + span.end([seconds, 0]); + + expect(span.endTimestamp).toEqual(seconds); + }); + }); + // Ensure that attributes & data are merged together describe('_getData', () => { it('works without data & attributes', () => { diff --git a/packages/core/test/lib/tracing/trace.test.ts b/packages/core/test/lib/tracing/trace.test.ts index 30eac02c881f..4659ae2e112f 100644 --- a/packages/core/test/lib/tracing/trace.test.ts +++ b/packages/core/test/lib/tracing/trace.test.ts @@ -160,6 +160,14 @@ describe('startSpan', () => { expect(ref.spanRecorder.spans[1].status).toEqual(isError ? 'internal_error' : undefined); }); + it('allows to pass a `startTime`', () => { + const start = startSpan({ name: 'outer', startTime: [1234, 0] }, span => { + return span?.startTimestamp; + }); + + expect(start).toEqual(1234); + }); + it('allows for span to be mutated', async () => { let ref: any = undefined; client.on('finishTransaction', transaction => { @@ -222,6 +230,15 @@ describe('startSpanManual', () => { expect(getCurrentScope()).toBe(initialScope); expect(initialScope.getSpan()).toBe(undefined); }); + + it('allows to pass a `startTime`', () => { + const start = startSpanManual({ name: 'outer', startTime: [1234, 0] }, span => { + span?.end(); + return span?.startTimestamp; + }); + + expect(start).toEqual(1234); + }); }); describe('startInactiveSpan', () => { @@ -248,6 +265,11 @@ describe('startInactiveSpan', () => { expect(initialScope.getSpan()).toBeUndefined(); }); + + it('allows to pass a `startTime`', () => { + const span = startInactiveSpan({ name: 'outer', startTime: [1234, 0] }); + expect(span?.startTimestamp).toEqual(1234); + }); }); describe('continueTrace', () => { diff --git a/packages/core/test/lib/utils/spanUtils.test.ts b/packages/core/test/lib/utils/spanUtils.test.ts index c2ed4dd0d4cd..a6d84cf31166 100644 --- a/packages/core/test/lib/utils/spanUtils.test.ts +++ b/packages/core/test/lib/utils/spanUtils.test.ts @@ -1,5 +1,6 @@ -import { TRACEPARENT_REGEXP } from '@sentry/utils'; +import { TRACEPARENT_REGEXP, timestampInSeconds } from '@sentry/utils'; import { Span, spanToTraceHeader } from '../../../src'; +import { spanTimeInputToSeconds } from '../../../src/utils/spanUtils'; describe('spanToTraceHeader', () => { test('simple', () => { @@ -11,3 +12,37 @@ describe('spanToTraceHeader', () => { expect(spanToTraceHeader(span)).toMatch(TRACEPARENT_REGEXP); }); }); + +describe('spanTimeInputToSeconds', () => { + it('works with undefined', () => { + const now = timestampInSeconds(); + expect(spanTimeInputToSeconds(undefined)).toBeGreaterThanOrEqual(now); + }); + + it('works with a timestamp in seconds', () => { + const timestamp = timestampInSeconds(); + expect(spanTimeInputToSeconds(timestamp)).toEqual(timestamp); + }); + + it('works with a timestamp in milliseconds', () => { + const timestamp = Date.now(); + expect(spanTimeInputToSeconds(timestamp)).toEqual(timestamp / 1000); + }); + + it('works with a Date object', () => { + const timestamp = new Date(); + expect(spanTimeInputToSeconds(timestamp)).toEqual(timestamp.getTime() / 1000); + }); + + it('works with a simple array', () => { + const seconds = Math.floor(timestampInSeconds()); + const timestamp: [number, number] = [seconds, 0]; + expect(spanTimeInputToSeconds(timestamp)).toEqual(seconds); + }); + + it('works with a array with nanoseconds', () => { + const seconds = Math.floor(timestampInSeconds()); + const timestamp: [number, number] = [seconds, 9000]; + expect(spanTimeInputToSeconds(timestamp)).toEqual(seconds + 0.000009); + }); +}); diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index c74715d0041e..655962f592fc 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -89,7 +89,7 @@ export type { // eslint-disable-next-line deprecation/deprecation export type { Severity, SeverityLevel } from './severity'; -export type { Span, SpanContext, SpanOrigin, SpanAttributeValue, SpanAttributes } from './span'; +export type { Span, SpanContext, SpanOrigin, SpanAttributeValue, SpanAttributes, SpanTimeInput } from './span'; export type { StackFrame } from './stackframe'; export type { Stacktrace, StackParser, StackLineParser, StackLineParserFn } from './stacktrace'; export type { TextEncoderInternal } from './textencoder'; diff --git a/packages/types/src/span.ts b/packages/types/src/span.ts index 3e625dc7dd9f..df26d2cca240 100644 --- a/packages/types/src/span.ts +++ b/packages/types/src/span.ts @@ -24,6 +24,23 @@ export type SpanAttributeValue = export type SpanAttributes = Record; +/** + * Defines High-Resolution Time. + * + * The first number, HrTime[0], is UNIX Epoch time in seconds since 00:00:00 UTC on 1 January 1970. + * The second number, HrTime[1], represents the partial second elapsed since Unix Epoch time represented by first number in nanoseconds. + * For example, 2021-01-01T12:30:10.150Z in UNIX Epoch time in milliseconds is represented as 1609504210150. + * The first number is calculated by converting and truncating the Epoch time in milliseconds to seconds: + * HrTime[0] = Math.trunc(1609504210150 / 1000) = 1609504210. + * The second number is calculated by converting the digits after the decimal point of the subtraction, (1609504210150 / 1000) - HrTime[0], to nanoseconds: + * HrTime[1] = Number((1609504210.150 - HrTime[0]).toFixed(9)) * 1e9 = 150000000. + * This is represented in HrTime format as [1609504210, 150000000]. + */ +export type HrTime = [number, number]; + +/** This type is aligned with the OpenTelemetry TimeInput type. */ +export type SpanTimeInput = HrTime | number | Date; + /** Interface holding all properties that can be set on a Span on creation. */ export interface SpanContext { /** @@ -159,7 +176,7 @@ export interface Span extends SpanContext { /** * End the current span. */ - end(endTimestamp?: number): void; + end(endTimestamp?: SpanTimeInput): void; /** * Sets the tag attribute on the current span. From a8050f5d29aed4c852cf49ca6574bcb2942a2541 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 4 Jan 2024 16:46:40 +0100 Subject: [PATCH 2/4] better licence --- packages/core/src/utils/spanUtils.ts | 13 +----------- packages/types/src/opentelemetry.ts | 31 ++++++++++++++++++++++++++++ packages/types/src/span.ts | 15 +------------- 3 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 packages/types/src/opentelemetry.ts diff --git a/packages/core/src/utils/spanUtils.ts b/packages/core/src/utils/spanUtils.ts index b32dc3f1d71f..28550ebec642 100644 --- a/packages/core/src/utils/spanUtils.ts +++ b/packages/core/src/utils/spanUtils.ts @@ -37,18 +37,7 @@ export function spanTimeInputToSeconds(input: SpanTimeInput | undefined): number } if (Array.isArray(input)) { - /** - * Defines High-Resolution Time. - * - * The first number, HrTime[0], is UNIX Epoch time in seconds since 00:00:00 UTC on 1 January 1970. - * The second number, HrTime[1], represents the partial second elapsed since Unix Epoch time represented by first number in nanoseconds. - * For example, 2021-01-01T12:30:10.150Z in UNIX Epoch time in milliseconds is represented as 1609504210150. - * The first number is calculated by converting and truncating the Epoch time in milliseconds to seconds: - * HrTime[0] = Math.trunc(1609504210150 / 1000) = 1609504210. - * The second number is calculated by converting the digits after the decimal point of the subtraction, (1609504210150 / 1000) - HrTime[0], to nanoseconds: - * HrTime[1] = Number((1609504210.150 - HrTime[0]).toFixed(9)) * 1e9 = 150000000. - * This is represented in HrTime format as [1609504210, 150000000]. - */ + // See {@link HrTime} for the array-based time format return input[0] + input[1] / 1e9; } diff --git a/packages/types/src/opentelemetry.ts b/packages/types/src/opentelemetry.ts new file mode 100644 index 000000000000..14ceaab0c087 --- /dev/null +++ b/packages/types/src/opentelemetry.ts @@ -0,0 +1,31 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This file contains vendored types from OpenTelemetry + +/** + * Defines High-Resolution Time. + * + * The first number, HrTime[0], is UNIX Epoch time in seconds since 00:00:00 UTC on 1 January 1970. + * The second number, HrTime[1], represents the partial second elapsed since Unix Epoch time represented by first number in nanoseconds. + * For example, 2021-01-01T12:30:10.150Z in UNIX Epoch time in milliseconds is represented as 1609504210150. + * The first number is calculated by converting and truncating the Epoch time in milliseconds to seconds: + * HrTime[0] = Math.trunc(1609504210150 / 1000) = 1609504210. + * The second number is calculated by converting the digits after the decimal point of the subtraction, (1609504210150 / 1000) - HrTime[0], to nanoseconds: + * HrTime[1] = Number((1609504210.150 - HrTime[0]).toFixed(9)) * 1e9 = 150000000. + * This is represented in HrTime format as [1609504210, 150000000]. + */ +export type HrTime = [number, number]; diff --git a/packages/types/src/span.ts b/packages/types/src/span.ts index df26d2cca240..840fcefe41ef 100644 --- a/packages/types/src/span.ts +++ b/packages/types/src/span.ts @@ -1,6 +1,7 @@ import type { TraceContext } from './context'; import type { Instrumenter } from './instrumenter'; import type { Primitive } from './misc'; +import type { HrTime } from './opentelemetry'; import type { Transaction } from './transaction'; type SpanOriginType = 'manual' | 'auto'; @@ -24,20 +25,6 @@ export type SpanAttributeValue = export type SpanAttributes = Record; -/** - * Defines High-Resolution Time. - * - * The first number, HrTime[0], is UNIX Epoch time in seconds since 00:00:00 UTC on 1 January 1970. - * The second number, HrTime[1], represents the partial second elapsed since Unix Epoch time represented by first number in nanoseconds. - * For example, 2021-01-01T12:30:10.150Z in UNIX Epoch time in milliseconds is represented as 1609504210150. - * The first number is calculated by converting and truncating the Epoch time in milliseconds to seconds: - * HrTime[0] = Math.trunc(1609504210150 / 1000) = 1609504210. - * The second number is calculated by converting the digits after the decimal point of the subtraction, (1609504210150 / 1000) - HrTime[0], to nanoseconds: - * HrTime[1] = Number((1609504210.150 - HrTime[0]).toFixed(9)) * 1e9 = 150000000. - * This is represented in HrTime format as [1609504210, 150000000]. - */ -export type HrTime = [number, number]; - /** This type is aligned with the OpenTelemetry TimeInput type. */ export type SpanTimeInput = HrTime | number | Date; From 86c500977dd0d4b03ed34b2930f7e973b899d22e Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Fri, 5 Jan 2024 10:14:17 +0100 Subject: [PATCH 3/4] fix circular dep check --- packages/core/src/tracing/utils.ts | 8 -------- packages/core/src/utils/spanUtils.ts | 9 ++++++++- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/core/src/tracing/utils.ts b/packages/core/src/tracing/utils.ts index 4c1d49780554..f1b4c0f1ae06 100644 --- a/packages/core/src/tracing/utils.ts +++ b/packages/core/src/tracing/utils.ts @@ -27,11 +27,3 @@ export { stripUrlQueryAndFragment } from '@sentry/utils'; * @deprecated Import this function from `@sentry/utils` instead */ export const extractTraceparentData = _extractTraceparentData; - -/** - * Converts a timestamp to second, if it was in milliseconds, or keeps it as second. - */ -export function ensureTimestampInSeconds(timestamp: number): number { - const isMs = timestamp > 9999999999; - return isMs ? timestamp / 1000 : timestamp; -} diff --git a/packages/core/src/utils/spanUtils.ts b/packages/core/src/utils/spanUtils.ts index 28550ebec642..9a99dd247bb6 100644 --- a/packages/core/src/utils/spanUtils.ts +++ b/packages/core/src/utils/spanUtils.ts @@ -1,6 +1,5 @@ import type { Span, SpanTimeInput, TraceContext } from '@sentry/types'; import { dropUndefinedKeys, generateSentryTraceHeader, timestampInSeconds } from '@sentry/utils'; -import { ensureTimestampInSeconds } from '../tracing/utils'; /** * Convert a span to a trace context, which can be sent as the `trace` context in an event. @@ -47,3 +46,11 @@ export function spanTimeInputToSeconds(input: SpanTimeInput | undefined): number return timestampInSeconds(); } + +/** + * Converts a timestamp to second, if it was in milliseconds, or keeps it as second. + */ +function ensureTimestampInSeconds(timestamp: number): number { + const isMs = timestamp > 9999999999; + return isMs ? timestamp / 1000 : timestamp; +} From b220a5fc7e8197829681799c647701e76273a0ff Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Fri, 5 Jan 2024 10:27:27 +0100 Subject: [PATCH 4/4] add comment --- packages/core/src/tracing/trace.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/core/src/tracing/trace.ts b/packages/core/src/tracing/trace.ts index 6f7420cca9e3..e31b27cfb6ff 100644 --- a/packages/core/src/tracing/trace.ts +++ b/packages/core/src/tracing/trace.ts @@ -239,6 +239,13 @@ function createChildSpanOrTransaction( return parentSpan ? parentSpan.startChild(ctx) : hub.startTransaction(ctx); } +/** + * This converts StartSpanOptions to TransactionContext. + * For the most part (for now) we accept the same options, + * but some of them need to be transformed. + * + * Eventually the StartSpanOptions will be more aligned with OpenTelemetry. + */ function normalizeContext(context: StartSpanOptions): TransactionContext { const ctx = { ...context }; // If a name is set and a description is not, set the description to the name.