UNPKG

@sentry/core

Version:
1 lines 14.9 kB
{"version":3,"file":"hubextensions.js","sources":["../../../src/tracing/hubextensions.ts"],"sourcesContent":["import type { ClientOptions, CustomSamplingContext, Options, SamplingContext, TransactionContext } from '@sentry/types';\nimport { isNaN, logger } from '@sentry/utils';\n\nimport type { Hub } from '../hub';\nimport { getMainCarrier } from '../hub';\nimport { hasTracingEnabled } from '../utils/hasTracingEnabled';\nimport { registerErrorInstrumentation } from './errors';\nimport { IdleTransaction } from './idletransaction';\nimport { Transaction } from './transaction';\n\n/** Returns all trace headers that are currently on the top scope. */\nfunction traceHeaders(this: Hub): { [key: string]: string } {\n const scope = this.getScope();\n if (scope) {\n const span = scope.getSpan();\n if (span) {\n return {\n 'sentry-trace': span.toTraceparent(),\n };\n }\n }\n return {};\n}\n\n/**\n * Makes a sampling decision for the given transaction and stores it on the transaction.\n *\n * Called every time a transaction is created. Only transactions which emerge with a `sampled` value of `true` will be\n * sent to Sentry.\n *\n * @param transaction: The transaction needing a sampling decision\n * @param options: The current client's options, so we can access `tracesSampleRate` and/or `tracesSampler`\n * @param samplingContext: Default and user-provided data which may be used to help make the decision\n *\n * @returns The given transaction with its `sampled` value set\n */\nfunction sample<T extends Transaction>(\n transaction: T,\n options: Pick<Options, 'tracesSampleRate' | 'tracesSampler' | 'enableTracing'>,\n samplingContext: SamplingContext,\n): T {\n // nothing to do if tracing is not enabled\n if (!hasTracingEnabled(options)) {\n transaction.sampled = false;\n return transaction;\n }\n\n // if the user has forced a sampling decision by passing a `sampled` value in their transaction context, go with that\n if (transaction.sampled !== undefined) {\n transaction.setMetadata({\n sampleRate: Number(transaction.sampled),\n });\n return transaction;\n }\n\n // we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should\n // work; prefer the hook if so\n let sampleRate;\n if (typeof options.tracesSampler === 'function') {\n sampleRate = options.tracesSampler(samplingContext);\n transaction.setMetadata({\n sampleRate: Number(sampleRate),\n });\n } else if (samplingContext.parentSampled !== undefined) {\n sampleRate = samplingContext.parentSampled;\n } else if (typeof options.tracesSampleRate !== 'undefined') {\n sampleRate = options.tracesSampleRate;\n transaction.setMetadata({\n sampleRate: Number(sampleRate),\n });\n } else {\n // When `enableTracing === true`, we use a sample rate of 100%\n sampleRate = 1;\n transaction.setMetadata({\n sampleRate,\n });\n }\n\n // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The\n // only valid values are booleans or numbers between 0 and 1.)\n if (!isValidSampleRate(sampleRate)) {\n __DEBUG_BUILD__ && logger.warn('[Tracing] Discarding transaction because of invalid sample rate.');\n transaction.sampled = false;\n return transaction;\n }\n\n // if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped\n if (!sampleRate) {\n __DEBUG_BUILD__ &&\n logger.log(\n `[Tracing] Discarding transaction because ${\n typeof options.tracesSampler === 'function'\n ? 'tracesSampler returned 0 or false'\n : 'a negative sampling decision was inherited or tracesSampleRate is set to 0'\n }`,\n );\n transaction.sampled = false;\n return transaction;\n }\n\n // Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is\n // a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false.\n transaction.sampled = Math.random() < (sampleRate as number | boolean);\n\n // if we're not going to keep it, we're done\n if (!transaction.sampled) {\n __DEBUG_BUILD__ &&\n logger.log(\n `[Tracing] Discarding transaction because it's not included in the random sample (sampling rate = ${Number(\n sampleRate,\n )})`,\n );\n return transaction;\n }\n\n __DEBUG_BUILD__ && logger.log(`[Tracing] starting ${transaction.op} transaction - ${transaction.name}`);\n return transaction;\n}\n\n/**\n * Checks the given sample rate to make sure it is valid type and value (a boolean, or a number between 0 and 1).\n */\nfunction isValidSampleRate(rate: unknown): boolean {\n // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (isNaN(rate) || !(typeof rate === 'number' || typeof rate === 'boolean')) {\n __DEBUG_BUILD__ &&\n logger.warn(\n `[Tracing] Given sample rate is invalid. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify(\n rate,\n )} of type ${JSON.stringify(typeof rate)}.`,\n );\n return false;\n }\n\n // in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false\n if (rate < 0 || rate > 1) {\n __DEBUG_BUILD__ &&\n logger.warn(`[Tracing] Given sample rate is invalid. Sample rate must be between 0 and 1. Got ${rate}.`);\n return false;\n }\n return true;\n}\n\n/**\n * Creates a new transaction and adds a sampling decision if it doesn't yet have one.\n *\n * The Hub.startTransaction method delegates to this method to do its work, passing the Hub instance in as `this`, as if\n * it had been called on the hub directly. Exists as a separate function so that it can be injected into the class as an\n * \"extension method.\"\n *\n * @param this: The Hub starting the transaction\n * @param transactionContext: Data used to configure the transaction\n * @param CustomSamplingContext: Optional data to be provided to the `tracesSampler` function (if any)\n *\n * @returns The new transaction\n *\n * @see {@link Hub.startTransaction}\n */\nfunction _startTransaction(\n this: Hub,\n transactionContext: TransactionContext,\n customSamplingContext?: CustomSamplingContext,\n): Transaction {\n const client = this.getClient();\n const options: Partial<ClientOptions> = (client && client.getOptions()) || {};\n\n const configInstrumenter = options.instrumenter || 'sentry';\n const transactionInstrumenter = transactionContext.instrumenter || 'sentry';\n\n if (configInstrumenter !== transactionInstrumenter) {\n __DEBUG_BUILD__ &&\n logger.error(\n `A transaction was started with instrumenter=\\`${transactionInstrumenter}\\`, but the SDK is configured with the \\`${configInstrumenter}\\` instrumenter.\nThe transaction will not be sampled. Please use the ${configInstrumenter} instrumentation to start transactions.`,\n );\n\n transactionContext.sampled = false;\n }\n\n let transaction = new Transaction(transactionContext, this);\n transaction = sample(transaction, options, {\n parentSampled: transactionContext.parentSampled,\n transactionContext,\n ...customSamplingContext,\n });\n if (transaction.sampled) {\n transaction.initSpanRecorder(options._experiments && (options._experiments.maxSpans as number));\n }\n if (client && client.emit) {\n client.emit('startTransaction', transaction);\n }\n return transaction;\n}\n\n/**\n * Create new idle transaction.\n */\nexport function startIdleTransaction(\n hub: Hub,\n transactionContext: TransactionContext,\n idleTimeout: number,\n finalTimeout: number,\n onScope?: boolean,\n customSamplingContext?: CustomSamplingContext,\n heartbeatInterval?: number,\n): IdleTransaction {\n const client = hub.getClient();\n const options: Partial<ClientOptions> = (client && client.getOptions()) || {};\n\n let transaction = new IdleTransaction(transactionContext, hub, idleTimeout, finalTimeout, heartbeatInterval, onScope);\n transaction = sample(transaction, options, {\n parentSampled: transactionContext.parentSampled,\n transactionContext,\n ...customSamplingContext,\n });\n if (transaction.sampled) {\n transaction.initSpanRecorder(options._experiments && (options._experiments.maxSpans as number));\n }\n if (client && client.emit) {\n client.emit('startTransaction', transaction);\n }\n return transaction;\n}\n\n/**\n * Adds tracing extensions to the global hub.\n */\nexport function addTracingExtensions(): void {\n const carrier = getMainCarrier();\n if (!carrier.__SENTRY__) {\n return;\n }\n carrier.__SENTRY__.extensions = carrier.__SENTRY__.extensions || {};\n if (!carrier.__SENTRY__.extensions.startTransaction) {\n carrier.__SENTRY__.extensions.startTransaction = _startTransaction;\n }\n if (!carrier.__SENTRY__.extensions.traceHeaders) {\n carrier.__SENTRY__.extensions.traceHeaders = traceHeaders;\n }\n\n registerErrorInstrumentation();\n}\n"],"names":[],"mappings":";;;;;;;AAUA;AACA,SAAA,YAAA,GAAA;AACA,EAAA,MAAA,KAAA,GAAA,IAAA,CAAA,QAAA,EAAA,CAAA;AACA,EAAA,IAAA,KAAA,EAAA;AACA,IAAA,MAAA,IAAA,GAAA,KAAA,CAAA,OAAA,EAAA,CAAA;AACA,IAAA,IAAA,IAAA,EAAA;AACA,MAAA,OAAA;AACA,QAAA,cAAA,EAAA,IAAA,CAAA,aAAA,EAAA;AACA,OAAA,CAAA;AACA,KAAA;AACA,GAAA;AACA,EAAA,OAAA,EAAA,CAAA;AACA,CAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,MAAA;AACA,EAAA,WAAA;AACA,EAAA,OAAA;AACA,EAAA,eAAA;AACA,EAAA;AACA;AACA,EAAA,IAAA,CAAA,iBAAA,CAAA,OAAA,CAAA,EAAA;AACA,IAAA,WAAA,CAAA,OAAA,GAAA,KAAA,CAAA;AACA,IAAA,OAAA,WAAA,CAAA;AACA,GAAA;AACA;AACA;AACA,EAAA,IAAA,WAAA,CAAA,OAAA,KAAA,SAAA,EAAA;AACA,IAAA,WAAA,CAAA,WAAA,CAAA;AACA,MAAA,UAAA,EAAA,MAAA,CAAA,WAAA,CAAA,OAAA,CAAA;AACA,KAAA,CAAA,CAAA;AACA,IAAA,OAAA,WAAA,CAAA;AACA,GAAA;AACA;AACA;AACA;AACA,EAAA,IAAA,UAAA,CAAA;AACA,EAAA,IAAA,OAAA,OAAA,CAAA,aAAA,KAAA,UAAA,EAAA;AACA,IAAA,UAAA,GAAA,OAAA,CAAA,aAAA,CAAA,eAAA,CAAA,CAAA;AACA,IAAA,WAAA,CAAA,WAAA,CAAA;AACA,MAAA,UAAA,EAAA,MAAA,CAAA,UAAA,CAAA;AACA,KAAA,CAAA,CAAA;AACA,GAAA,MAAA,IAAA,eAAA,CAAA,aAAA,KAAA,SAAA,EAAA;AACA,IAAA,UAAA,GAAA,eAAA,CAAA,aAAA,CAAA;AACA,GAAA,MAAA,IAAA,OAAA,OAAA,CAAA,gBAAA,KAAA,WAAA,EAAA;AACA,IAAA,UAAA,GAAA,OAAA,CAAA,gBAAA,CAAA;AACA,IAAA,WAAA,CAAA,WAAA,CAAA;AACA,MAAA,UAAA,EAAA,MAAA,CAAA,UAAA,CAAA;AACA,KAAA,CAAA,CAAA;AACA,GAAA,MAAA;AACA;AACA,IAAA,UAAA,GAAA,CAAA,CAAA;AACA,IAAA,WAAA,CAAA,WAAA,CAAA;AACA,MAAA,UAAA;AACA,KAAA,CAAA,CAAA;AACA,GAAA;AACA;AACA;AACA;AACA,EAAA,IAAA,CAAA,iBAAA,CAAA,UAAA,CAAA,EAAA;AACA,IAAA,iEAAA,MAAA,CAAA,IAAA,CAAA,kEAAA,CAAA,CAAA;AACA,IAAA,WAAA,CAAA,OAAA,GAAA,KAAA,CAAA;AACA,IAAA,OAAA,WAAA,CAAA;AACA,GAAA;AACA;AACA;AACA,EAAA,IAAA,CAAA,UAAA,EAAA;AACA,IAAA,CAAA,OAAA,gBAAA,KAAA,WAAA,IAAA,gBAAA;AACA,MAAA,MAAA,CAAA,GAAA;AACA,QAAA,CAAA,yCAAA;AACA,UAAA,OAAA,OAAA,CAAA,aAAA,KAAA,UAAA;AACA,cAAA,mCAAA;AACA,cAAA,4EAAA;AACA,SAAA,CAAA;AACA,OAAA,CAAA;AACA,IAAA,WAAA,CAAA,OAAA,GAAA,KAAA,CAAA;AACA,IAAA,OAAA,WAAA,CAAA;AACA,GAAA;AACA;AACA;AACA;AACA,EAAA,WAAA,CAAA,OAAA,GAAA,IAAA,CAAA,MAAA,EAAA,IAAA,UAAA,EAAA,CAAA;AACA;AACA;AACA,EAAA,IAAA,CAAA,WAAA,CAAA,OAAA,EAAA;AACA,IAAA,CAAA,OAAA,gBAAA,KAAA,WAAA,IAAA,gBAAA;AACA,MAAA,MAAA,CAAA,GAAA;AACA,QAAA,CAAA,iGAAA,EAAA,MAAA;AACA,UAAA,UAAA;AACA,SAAA,CAAA,CAAA,CAAA;AACA,OAAA,CAAA;AACA,IAAA,OAAA,WAAA,CAAA;AACA,GAAA;AACA;AACA,EAAA,CAAA,OAAA,gBAAA,KAAA,WAAA,IAAA,gBAAA,KAAA,MAAA,CAAA,GAAA,CAAA,CAAA,mBAAA,EAAA,WAAA,CAAA,EAAA,CAAA,eAAA,EAAA,WAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA;AACA,EAAA,OAAA,WAAA,CAAA;AACA,CAAA;AACA;AACA;AACA;AACA;AACA,SAAA,iBAAA,CAAA,IAAA,EAAA;AACA;AACA;AACA,EAAA,IAAA,KAAA,CAAA,IAAA,CAAA,IAAA,EAAA,OAAA,IAAA,KAAA,QAAA,IAAA,OAAA,IAAA,KAAA,SAAA,CAAA,EAAA;AACA,IAAA,CAAA,OAAA,gBAAA,KAAA,WAAA,IAAA,gBAAA;AACA,MAAA,MAAA,CAAA,IAAA;AACA,QAAA,CAAA,uGAAA,EAAA,IAAA,CAAA,SAAA;AACA,UAAA,IAAA;AACA,SAAA,CAAA,SAAA,EAAA,IAAA,CAAA,SAAA,CAAA,OAAA,IAAA,CAAA,CAAA,CAAA,CAAA;AACA,OAAA,CAAA;AACA,IAAA,OAAA,KAAA,CAAA;AACA,GAAA;AACA;AACA;AACA,EAAA,IAAA,IAAA,GAAA,CAAA,IAAA,IAAA,GAAA,CAAA,EAAA;AACA,IAAA,CAAA,OAAA,gBAAA,KAAA,WAAA,IAAA,gBAAA;AACA,MAAA,MAAA,CAAA,IAAA,CAAA,CAAA,iFAAA,EAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AACA,IAAA,OAAA,KAAA,CAAA;AACA,GAAA;AACA,EAAA,OAAA,IAAA,CAAA;AACA,CAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,iBAAA;;AAEA,EAAA,kBAAA;AACA,EAAA,qBAAA;AACA,EAAA;AACA,EAAA,MAAA,MAAA,GAAA,IAAA,CAAA,SAAA,EAAA,CAAA;AACA,EAAA,MAAA,OAAA,GAAA,CAAA,MAAA,IAAA,MAAA,CAAA,UAAA,EAAA,KAAA,EAAA,CAAA;AACA;AACA,EAAA,MAAA,kBAAA,GAAA,OAAA,CAAA,YAAA,IAAA,QAAA,CAAA;AACA,EAAA,MAAA,uBAAA,GAAA,kBAAA,CAAA,YAAA,IAAA,QAAA,CAAA;AACA;AACA,EAAA,IAAA,kBAAA,KAAA,uBAAA,EAAA;AACA,IAAA,CAAA,OAAA,gBAAA,KAAA,WAAA,IAAA,gBAAA;AACA,MAAA,MAAA,CAAA,KAAA;AACA,QAAA,CAAA,8CAAA,EAAA,uBAAA,CAAA,yCAAA,EAAA,kBAAA,CAAA;AACA,oDAAA,EAAA,kBAAA,CAAA,uCAAA,CAAA;AACA,OAAA,CAAA;AACA;AACA,IAAA,kBAAA,CAAA,OAAA,GAAA,KAAA,CAAA;AACA,GAAA;AACA;AACA,EAAA,IAAA,WAAA,GAAA,IAAA,WAAA,CAAA,kBAAA,EAAA,IAAA,CAAA,CAAA;AACA,EAAA,WAAA,GAAA,MAAA,CAAA,WAAA,EAAA,OAAA,EAAA;AACA,IAAA,aAAA,EAAA,kBAAA,CAAA,aAAA;AACA,IAAA,kBAAA;AACA,IAAA,GAAA,qBAAA;AACA,GAAA,CAAA,CAAA;AACA,EAAA,IAAA,WAAA,CAAA,OAAA,EAAA;AACA,IAAA,WAAA,CAAA,gBAAA,CAAA,OAAA,CAAA,YAAA,KAAA,OAAA,CAAA,YAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AACA,GAAA;AACA,EAAA,IAAA,MAAA,IAAA,MAAA,CAAA,IAAA,EAAA;AACA,IAAA,MAAA,CAAA,IAAA,CAAA,kBAAA,EAAA,WAAA,CAAA,CAAA;AACA,GAAA;AACA,EAAA,OAAA,WAAA,CAAA;AACA,CAAA;AACA;AACA;AACA;AACA;AACA,SAAA,oBAAA;AACA,EAAA,GAAA;AACA,EAAA,kBAAA;AACA,EAAA,WAAA;AACA,EAAA,YAAA;AACA,EAAA,OAAA;AACA,EAAA,qBAAA;AACA,EAAA,iBAAA;AACA,EAAA;AACA,EAAA,MAAA,MAAA,GAAA,GAAA,CAAA,SAAA,EAAA,CAAA;AACA,EAAA,MAAA,OAAA,GAAA,CAAA,MAAA,IAAA,MAAA,CAAA,UAAA,EAAA,KAAA,EAAA,CAAA;AACA;AACA,EAAA,IAAA,WAAA,GAAA,IAAA,eAAA,CAAA,kBAAA,EAAA,GAAA,EAAA,WAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,OAAA,CAAA,CAAA;AACA,EAAA,WAAA,GAAA,MAAA,CAAA,WAAA,EAAA,OAAA,EAAA;AACA,IAAA,aAAA,EAAA,kBAAA,CAAA,aAAA;AACA,IAAA,kBAAA;AACA,IAAA,GAAA,qBAAA;AACA,GAAA,CAAA,CAAA;AACA,EAAA,IAAA,WAAA,CAAA,OAAA,EAAA;AACA,IAAA,WAAA,CAAA,gBAAA,CAAA,OAAA,CAAA,YAAA,KAAA,OAAA,CAAA,YAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AACA,GAAA;AACA,EAAA,IAAA,MAAA,IAAA,MAAA,CAAA,IAAA,EAAA;AACA,IAAA,MAAA,CAAA,IAAA,CAAA,kBAAA,EAAA,WAAA,CAAA,CAAA;AACA,GAAA;AACA,EAAA,OAAA,WAAA,CAAA;AACA,CAAA;AACA;AACA;AACA;AACA;AACA,SAAA,oBAAA,GAAA;AACA,EAAA,MAAA,OAAA,GAAA,cAAA,EAAA,CAAA;AACA,EAAA,IAAA,CAAA,OAAA,CAAA,UAAA,EAAA;AACA,IAAA,OAAA;AACA,GAAA;AACA,EAAA,OAAA,CAAA,UAAA,CAAA,UAAA,GAAA,OAAA,CAAA,UAAA,CAAA,UAAA,IAAA,EAAA,CAAA;AACA,EAAA,IAAA,CAAA,OAAA,CAAA,UAAA,CAAA,UAAA,CAAA,gBAAA,EAAA;AACA,IAAA,OAAA,CAAA,UAAA,CAAA,UAAA,CAAA,gBAAA,GAAA,iBAAA,CAAA;AACA,GAAA;AACA,EAAA,IAAA,CAAA,OAAA,CAAA,UAAA,CAAA,UAAA,CAAA,YAAA,EAAA;AACA,IAAA,OAAA,CAAA,UAAA,CAAA,UAAA,CAAA,YAAA,GAAA,YAAA,CAAA;AACA,GAAA;AACA;AACA,EAAA,4BAAA,EAAA,CAAA;AACA;;;;"}