@sentry/core
Version:
Base implementation for all Sentry JavaScript SDKs
1 lines • 14.8 kB
Source Map (JSON)
{"version":3,"file":"transaction.js","sources":["../../../src/tracing/transaction.ts"],"sourcesContent":["import type {\n Context,\n Contexts,\n DynamicSamplingContext,\n Event,\n Measurements,\n MeasurementUnit,\n Transaction as TransactionInterface,\n TransactionContext,\n TransactionMetadata,\n} from '@sentry/types';\nimport { dropUndefinedKeys, logger } from '@sentry/utils';\n\nimport { DEFAULT_ENVIRONMENT } from '../constants';\nimport type { Hub } from '../hub';\nimport { getCurrentHub } from '../hub';\nimport { Span as SpanClass, SpanRecorder } from './span';\n\n/** JSDoc */\nexport class Transaction extends SpanClass implements TransactionInterface {\n public metadata: TransactionMetadata;\n\n /**\n * The reference to the current hub.\n */\n public readonly _hub: Hub;\n\n private _name: string;\n\n private _measurements: Measurements = {};\n\n private _contexts: Contexts = {};\n\n private _trimEnd?: boolean;\n\n private _frozenDynamicSamplingContext: Readonly<Partial<DynamicSamplingContext>> | undefined = undefined;\n\n /**\n * This constructor should never be called manually. Those instrumenting tracing should use\n * `Sentry.startTransaction()`, and internal methods should use `hub.startTransaction()`.\n * @internal\n * @hideconstructor\n * @hidden\n */\n public constructor(transactionContext: TransactionContext, hub?: Hub) {\n super(transactionContext);\n\n this._hub = hub || getCurrentHub();\n\n this._name = transactionContext.name || '';\n\n this.metadata = {\n source: 'custom',\n ...transactionContext.metadata,\n spanMetadata: {},\n };\n\n this._trimEnd = transactionContext.trimEnd;\n\n // this is because transactions are also spans, and spans have a transaction pointer\n this.transaction = this;\n\n // If Dynamic Sampling Context is provided during the creation of the transaction, we freeze it as it usually means\n // there is incoming Dynamic Sampling Context. (Either through an incoming request, a baggage meta-tag, or other means)\n const incomingDynamicSamplingContext = this.metadata.dynamicSamplingContext;\n if (incomingDynamicSamplingContext) {\n // We shallow copy this in case anything writes to the original reference of the passed in `dynamicSamplingContext`\n this._frozenDynamicSamplingContext = { ...incomingDynamicSamplingContext };\n }\n }\n\n /** Getter for `name` property */\n public get name(): string {\n return this._name;\n }\n\n /** Setter for `name` property, which also sets `source` as custom */\n public set name(newName: string) {\n this.setName(newName);\n }\n\n /**\n * JSDoc\n */\n public setName(name: string, source: TransactionMetadata['source'] = 'custom'): void {\n this._name = name;\n this.metadata.source = source;\n }\n\n /**\n * Attaches SpanRecorder to the span itself\n * @param maxlen maximum number of spans that can be recorded\n */\n public initSpanRecorder(maxlen: number = 1000): void {\n if (!this.spanRecorder) {\n this.spanRecorder = new SpanRecorder(maxlen);\n }\n this.spanRecorder.add(this);\n }\n\n /**\n * @inheritDoc\n */\n public setContext(key: string, context: Context | null): void {\n if (context === null) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete this._contexts[key];\n } else {\n this._contexts[key] = context;\n }\n }\n\n /**\n * @inheritDoc\n */\n public setMeasurement(name: string, value: number, unit: MeasurementUnit = ''): void {\n this._measurements[name] = { value, unit };\n }\n\n /**\n * @inheritDoc\n */\n public setMetadata(newMetadata: Partial<TransactionMetadata>): void {\n this.metadata = { ...this.metadata, ...newMetadata };\n }\n\n /**\n * @inheritDoc\n */\n public finish(endTimestamp?: number): string | undefined {\n // This transaction is already finished, so we should not flush it again.\n if (this.endTimestamp !== undefined) {\n return undefined;\n }\n\n if (!this.name) {\n __DEBUG_BUILD__ && logger.warn('Transaction has no name, falling back to `<unlabeled transaction>`.');\n this.name = '<unlabeled transaction>';\n }\n\n // just sets the end timestamp\n super.finish(endTimestamp);\n\n const client = this._hub.getClient();\n if (client && client.emit) {\n client.emit('finishTransaction', this);\n }\n\n if (this.sampled !== true) {\n // At this point if `sampled !== true` we want to discard the transaction.\n __DEBUG_BUILD__ && logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.');\n\n if (client) {\n client.recordDroppedEvent('sample_rate', 'transaction');\n }\n\n return undefined;\n }\n\n const finishedSpans = this.spanRecorder ? this.spanRecorder.spans.filter(s => s !== this && s.endTimestamp) : [];\n\n if (this._trimEnd && finishedSpans.length > 0) {\n this.endTimestamp = finishedSpans.reduce((prev: SpanClass, current: SpanClass) => {\n if (prev.endTimestamp && current.endTimestamp) {\n return prev.endTimestamp > current.endTimestamp ? prev : current;\n }\n return prev;\n }).endTimestamp;\n }\n\n const metadata = this.metadata;\n\n const transaction: Event = {\n contexts: {\n ...this._contexts,\n // We don't want to override trace context\n trace: this.getTraceContext(),\n },\n spans: finishedSpans,\n start_timestamp: this.startTimestamp,\n tags: this.tags,\n timestamp: this.endTimestamp,\n transaction: this.name,\n type: 'transaction',\n sdkProcessingMetadata: {\n ...metadata,\n dynamicSamplingContext: this.getDynamicSamplingContext(),\n },\n ...(metadata.source && {\n transaction_info: {\n source: metadata.source,\n },\n }),\n };\n\n const hasMeasurements = Object.keys(this._measurements).length > 0;\n\n if (hasMeasurements) {\n __DEBUG_BUILD__ &&\n logger.log(\n '[Measurements] Adding measurements to transaction',\n JSON.stringify(this._measurements, undefined, 2),\n );\n transaction.measurements = this._measurements;\n }\n\n __DEBUG_BUILD__ && logger.log(`[Tracing] Finishing ${this.op} transaction: ${this.name}.`);\n\n return this._hub.captureEvent(transaction);\n }\n\n /**\n * @inheritDoc\n */\n public toContext(): TransactionContext {\n const spanContext = super.toContext();\n\n return dropUndefinedKeys({\n ...spanContext,\n name: this.name,\n trimEnd: this._trimEnd,\n });\n }\n\n /**\n * @inheritDoc\n */\n public updateWithContext(transactionContext: TransactionContext): this {\n super.updateWithContext(transactionContext);\n\n this.name = transactionContext.name || '';\n\n this._trimEnd = transactionContext.trimEnd;\n\n return this;\n }\n\n /**\n * @inheritdoc\n *\n * @experimental\n */\n public getDynamicSamplingContext(): Readonly<Partial<DynamicSamplingContext>> {\n if (this._frozenDynamicSamplingContext) {\n return this._frozenDynamicSamplingContext;\n }\n\n const hub: Hub = this._hub || getCurrentHub();\n const client = hub && hub.getClient();\n\n if (!client) return {};\n\n const { environment, release } = client.getOptions() || {};\n const { publicKey: public_key } = client.getDsn() || {};\n\n const maybeSampleRate = this.metadata.sampleRate;\n const sample_rate = maybeSampleRate !== undefined ? maybeSampleRate.toString() : undefined;\n\n const scope = hub.getScope();\n const { segment: user_segment } = (scope && scope.getUser()) || {};\n\n const source = this.metadata.source;\n\n // We don't want to have a transaction name in the DSC if the source is \"url\" because URLs might contain PII\n const transaction = source && source !== 'url' ? this.name : undefined;\n\n const dsc = dropUndefinedKeys({\n environment: environment || DEFAULT_ENVIRONMENT,\n release,\n transaction,\n user_segment,\n public_key,\n trace_id: this.traceId,\n sample_rate,\n });\n\n // Uncomment if we want to make DSC immutable\n // this._frozenDynamicSamplingContext = dsc;\n\n return dsc;\n }\n}\n"],"names":["SpanClass"],"mappings":"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"}