Skip to content
Draft
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
18 changes: 9 additions & 9 deletions .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ module.exports = [
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'replayCanvasIntegration'),
gzip: true,
limit: '85.55 KB',
limit: '86 KB',
},
{
name: '@sentry/browser (incl. Tracing, Replay, Feedback)',
Expand All @@ -103,7 +103,7 @@ module.exports = [
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'sendFeedback'),
gzip: true,
limit: '31 KB',
limit: '32 KB',
},
{
name: '@sentry/browser (incl. FeedbackAsync)',
Expand Down Expand Up @@ -148,43 +148,43 @@ module.exports = [
import: createImport('init', 'ErrorBoundary', 'reactRouterV6BrowserTracingIntegration'),
ignore: ['react/jsx-runtime'],
gzip: true,
limit: '44.5 KB',
limit: '45 KB',
},
// Vue SDK (ESM)
{
name: '@sentry/vue',
path: 'packages/vue/build/esm/index.js',
import: createImport('init'),
gzip: true,
limit: '30 KB',
limit: '31 KB',
},
{
name: '@sentry/vue (incl. Tracing)',
path: 'packages/vue/build/esm/index.js',
import: createImport('init', 'browserTracingIntegration'),
gzip: true,
limit: '44.1 KB',
limit: '45 KB',
},
// Svelte SDK (ESM)
{
name: '@sentry/svelte',
path: 'packages/svelte/build/esm/index.js',
import: createImport('init'),
gzip: true,
limit: '25.5 KB',
limit: '26 KB',
},
// Browser CDN bundles
{
name: 'CDN Bundle',
path: createCDNPath('bundle.min.js'),
gzip: true,
limit: '28 KB',
limit: '29 KB',
},
{
name: 'CDN Bundle (incl. Tracing)',
path: createCDNPath('bundle.tracing.min.js'),
gzip: true,
limit: '43 KB',
limit: '44 KB',
},
{
name: 'CDN Bundle (incl. Logs, Metrics)',
Expand All @@ -196,7 +196,7 @@ module.exports = [
name: 'CDN Bundle (incl. Tracing, Logs, Metrics)',
path: createCDNPath('bundle.tracing.logs.metrics.min.js'),
gzip: true,
limit: '44 KB',
limit: '45 KB',
},
{
name: 'CDN Bundle (incl. Replay, Logs, Metrics)',
Expand Down
27 changes: 25 additions & 2 deletions packages/core/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ import type { RequestEventData } from './types-hoist/request';
import type { SdkMetadata } from './types-hoist/sdkmetadata';
import type { Session, SessionAggregates } from './types-hoist/session';
import type { SeverityLevel } from './types-hoist/severity';
import type { Span, SpanAttributes, SpanContextData, SpanJSON } from './types-hoist/span';
import type { Span, SpanAttributes, SpanContextData, SpanJSON, StreamedSpanJSON } from './types-hoist/span';
import type { StartSpanOptions } from './types-hoist/startSpanOptions';
import type { Transport, TransportMakeRequestResponse } from './types-hoist/transport';
import { isStreamedBeforeSendSpanCallback } from './utils/beforeSendSpan';
import { createClientReportEnvelope } from './utils/clientreport';
import { debug } from './utils/debug-logger';
import { dsnToString, makeDsn } from './utils/dsn';
Expand Down Expand Up @@ -608,6 +609,16 @@ export abstract class Client<O extends ClientOptions = ClientOptions> {
*/
public on(hook: 'spanEnd', callback: (span: Span) => void): () => void;

/**
* Register a callback for when a span JSON is processed, to add some data to the span JSON.
*/
public on(hook: 'processSpan', callback: (streamedSpanJSON: StreamedSpanJSON) => void): () => void;

/**
* Register a callback for when a segment span JSON is processed, to add some data to the segment span JSON.
*/
public on(hook: 'processSegmentSpan', callback: (streamedSpanJSON: StreamedSpanJSON) => void): () => void;

/**
* Register a callback for when an idle span is allowed to auto-finish.
* @returns {() => void} A function that, when executed, removes the registered callback.
Expand Down Expand Up @@ -880,6 +891,16 @@ export abstract class Client<O extends ClientOptions = ClientOptions> {
/** Fire a hook whenever a span ends. */
public emit(hook: 'spanEnd', span: Span): void;

/**
* Register a callback for when a span JSON is processed, to add some data to the span JSON.
*/
public emit(hook: 'processSpan', streamedSpanJSON: StreamedSpanJSON): void;

/**
* Register a callback for when a segment span JSON is processed, to add some data to the segment span JSON.
*/
public emit(hook: 'processSegmentSpan', streamedSpanJSON: StreamedSpanJSON): void;

/**
* Fire a hook indicating that an idle span is allowed to auto finish.
*/
Expand Down Expand Up @@ -1498,7 +1519,9 @@ function processBeforeSend(
event: Event,
hint: EventHint,
): PromiseLike<Event | null> | Event | null {
const { beforeSend, beforeSendTransaction, beforeSendSpan, ignoreSpans } = options;
const { beforeSend, beforeSendTransaction, ignoreSpans } = options;
const beforeSendSpan = !isStreamedBeforeSendSpanCallback(options.beforeSendSpan) && options.beforeSendSpan;

let processedEvent = event;

if (isErrorEvent(processedEvent) && beforeSend) {
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/envelope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { Event } from './types-hoist/event';
import type { SdkInfo } from './types-hoist/sdkinfo';
import type { SdkMetadata } from './types-hoist/sdkmetadata';
import type { Session, SessionAggregates } from './types-hoist/session';
import { isStreamedBeforeSendSpanCallback } from './utils/beforeSendSpan';
import { dsnToString } from './utils/dsn';
import {
createEnvelope,
Expand Down Expand Up @@ -152,7 +153,7 @@ export function createSpanEnvelope(spans: [SentrySpan, ...SentrySpan[]], client?
const convertToSpanJSON = beforeSendSpan
? (span: SentrySpan) => {
const spanJson = spanToJSON(span);
const processedSpan = beforeSendSpan(spanJson);
const processedSpan = !isStreamedBeforeSendSpanCallback(beforeSendSpan) ? beforeSendSpan(spanJson) : spanJson;

if (!processedSpan) {
showSpanDropWarning();
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export { prepareEvent } from './utils/prepareEvent';
export type { ExclusiveEventHintOrCaptureContext } from './utils/prepareEvent';
export { createCheckInEnvelope } from './checkin';
export { hasSpansEnabled } from './utils/hasSpansEnabled';
export { withStreamedSpan } from './utils/beforeSendSpan';
export { isSentryRequestUrl } from './utils/isSentryRequestUrl';
export { handleCallbackErrors } from './utils/handleCallbackErrors';
export { parameterize, fmt } from './utils/parameterize';
Expand All @@ -78,11 +79,13 @@ export {
convertSpanLinksForEnvelope,
spanToTraceHeader,
spanToJSON,
spanToStreamedSpanJSON,
spanIsSampled,
spanToTraceContext,
getSpanDescendants,
getStatusMessage,
getRootSpan,
INTERNAL_getSegmentSpan,
getActiveSpan,
addChildSpanToSpan,
spanTimeInputToSeconds,
Expand Down Expand Up @@ -384,6 +387,7 @@ export type {
ProfileChunkEnvelope,
ProfileChunkItem,
SpanEnvelope,
StreamedSpanEnvelope,
SpanItem,
LogEnvelope,
MetricEnvelope,
Expand Down Expand Up @@ -451,6 +455,7 @@ export type {
SpanJSON,
SpanContextData,
TraceFlag,
StreamedSpanJSON,
} from './types-hoist/span';
export type { SpanStatus } from './types-hoist/spanStatus';
export type { Log, LogSeverityLevel } from './types-hoist/log';
Expand Down
28 changes: 25 additions & 3 deletions packages/core/src/semanticAttributes.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Use this attribute to represent the source of a span.
* Should be one of: custom, url, route, view, component, task, unknown
*
* Use this attribute to represent the source of a span name.
* Must be one of: custom, url, route, view, component, task
* TODO(v11): rename this to sentry.span.source'
*/
export const SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = 'sentry.source';

Expand Down Expand Up @@ -40,6 +40,28 @@ export const SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT = 'sentry.measurement_un
/** The value of a measurement, which may be stored as a TimedEvent. */
export const SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE = 'sentry.measurement_value';

/** The release version of the application */
export const SEMANTIC_ATTRIBUTE_SENTRY_RELEASE = 'sentry.release';
/** The environment name (e.g., "production", "staging", "development") */
export const SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT = 'sentry.environment';
/** The segment name (e.g., "GET /users") */
export const SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME = 'sentry.segment.name';
/** The id of the segment that this span belongs to. */
export const SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID = 'sentry.segment.id';
/** The name of the Sentry SDK (e.g., "sentry.php", "sentry.javascript") */
export const SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME = 'sentry.sdk.name';
/** The version of the Sentry SDK */
export const SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION = 'sentry.sdk.version';

/** The user ID (gated by sendDefaultPii) */
export const SEMANTIC_ATTRIBUTE_USER_ID = 'user.id';
/** The user email (gated by sendDefaultPii) */
export const SEMANTIC_ATTRIBUTE_USER_EMAIL = 'user.email';
/** The user IP address (gated by sendDefaultPii) */
export const SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS = 'user.ip_address';
/** The user username (gated by sendDefaultPii) */
export const SEMANTIC_ATTRIBUTE_USER_USERNAME = 'user.name';

/**
* A custom span name set by users guaranteed to be taken over any automatically
* inferred name. This attribute is removed before the span is sent.
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/tracing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ export {
export { setMeasurement, timedEventsToMeasurements } from './measurement';
export { sampleSpan } from './sampling';
export { logSpanEnd, logSpanStart } from './logSpans';

// Span Streaming
export { captureSpan } from './spans/captureSpan';
28 changes: 28 additions & 0 deletions packages/core/src/tracing/sentrySpan.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable max-lines */
import { getClient, getCurrentScope } from '../currentScopes';
import { DEBUG_BUILD } from '../debug-build';
import { createSpanEnvelope } from '../envelope';
Expand All @@ -21,6 +22,7 @@ import type {
SpanJSON,
SpanOrigin,
SpanTimeInput,
StreamedSpanJSON,
} from '../types-hoist/span';
import type { SpanStatus } from '../types-hoist/spanStatus';
import type { TimedEvent } from '../types-hoist/timedEvent';
Expand All @@ -29,8 +31,10 @@ import { generateSpanId, generateTraceId } from '../utils/propagationContext';
import {
convertSpanLinksForEnvelope,
getRootSpan,
getSimpleStatusMessage,
getSpanDescendants,
getStatusMessage,
getStreamedSpanLinks,
spanTimeInputToSeconds,
spanToJSON,
spanToTransactionTraceContext,
Expand Down Expand Up @@ -241,6 +245,30 @@ export class SentrySpan implements Span {
};
}

/**
* Get {@link StreamedSpanJSON} representation of this span.
*
* @hidden
* @internal This method is purely for internal purposes and should not be used outside
* of SDK code. If you need to get a JSON representation of a span,
* use `spanToStreamedSpanJSON(span)` instead.
*/
public getStreamedSpanJSON(): StreamedSpanJSON {
return {
name: this._name ?? '',
span_id: this._spanId,
trace_id: this._traceId,
parent_span_id: this._parentSpanId,
start_timestamp: this._startTime,
// just in case _endTime is not set, we use the start time (i.e. duration 0)
end_timestamp: this._endTime ?? this._startTime,
is_segment: this._isStandaloneSpan || this === getRootSpan(this),
status: getSimpleStatusMessage(this._status),
attributes: this._attributes,
links: getStreamedSpanLinks(this._links),
};
}

/** @inheritdoc */
public isRecording(): boolean {
return !this._endTime && !!this._sampled;
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/tracing/spans/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
For now, all span streaming related tracing code is in this sub directory.
Once we get rid of transaction-based tracing, we can clean up and flatten the entire tracing directory.
Loading