mirror of
https://github.com/MarSeventh/CloudFlare-ImgBed.git
synced 2026-04-29 08:26:46 +00:00
init
This commit is contained in:
95
node_modules/@sentry/core/esm/tracing/dynamicSamplingContext.js
generated
vendored
Normal file
95
node_modules/@sentry/core/esm/tracing/dynamicSamplingContext.js
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
import { dropUndefinedKeys } from '@sentry/utils';
|
||||
import { DEFAULT_ENVIRONMENT } from '../constants.js';
|
||||
import { getClient, getCurrentScope } from '../exports.js';
|
||||
import { getRootSpan } from '../utils/getRootSpan.js';
|
||||
import { spanToJSON, spanIsSampled } from '../utils/spanUtils.js';
|
||||
|
||||
/**
|
||||
* Creates a dynamic sampling context from a client.
|
||||
*
|
||||
* Dispatches the `createDsc` lifecycle hook as a side effect.
|
||||
*/
|
||||
function getDynamicSamplingContextFromClient(
|
||||
trace_id,
|
||||
client,
|
||||
scope,
|
||||
) {
|
||||
const options = client.getOptions();
|
||||
|
||||
const { publicKey: public_key } = client.getDsn() || {};
|
||||
// TODO(v8): Remove segment from User
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const { segment: user_segment } = (scope && scope.getUser()) || {};
|
||||
|
||||
const dsc = dropUndefinedKeys({
|
||||
environment: options.environment || DEFAULT_ENVIRONMENT,
|
||||
release: options.release,
|
||||
user_segment,
|
||||
public_key,
|
||||
trace_id,
|
||||
}) ;
|
||||
|
||||
client.emit && client.emit('createDsc', dsc);
|
||||
|
||||
return dsc;
|
||||
}
|
||||
|
||||
/**
|
||||
* A Span with a frozen dynamic sampling context.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a dynamic sampling context from a span (and client and scope)
|
||||
*
|
||||
* @param span the span from which a few values like the root span name and sample rate are extracted.
|
||||
*
|
||||
* @returns a dynamic sampling context
|
||||
*/
|
||||
function getDynamicSamplingContextFromSpan(span) {
|
||||
const client = getClient();
|
||||
if (!client) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// passing emit=false here to only emit later once the DSC is actually populated
|
||||
const dsc = getDynamicSamplingContextFromClient(spanToJSON(span).trace_id || '', client, getCurrentScope());
|
||||
|
||||
// TODO (v8): Remove v7FrozenDsc as a Transaction will no longer have _frozenDynamicSamplingContext
|
||||
const txn = getRootSpan(span) ;
|
||||
if (!txn) {
|
||||
return dsc;
|
||||
}
|
||||
|
||||
// TODO (v8): Remove v7FrozenDsc as a Transaction will no longer have _frozenDynamicSamplingContext
|
||||
// For now we need to avoid breaking users who directly created a txn with a DSC, where this field is still set.
|
||||
// @see Transaction class constructor
|
||||
const v7FrozenDsc = txn && txn._frozenDynamicSamplingContext;
|
||||
if (v7FrozenDsc) {
|
||||
return v7FrozenDsc;
|
||||
}
|
||||
|
||||
// TODO (v8): Replace txn.metadata with txn.attributes[]
|
||||
// We can't do this yet because attributes aren't always set yet.
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const { sampleRate: maybeSampleRate, source } = txn.metadata;
|
||||
if (maybeSampleRate != null) {
|
||||
dsc.sample_rate = `${maybeSampleRate}`;
|
||||
}
|
||||
|
||||
// We don't want to have a transaction name in the DSC if the source is "url" because URLs might contain PII
|
||||
const jsonSpan = spanToJSON(txn);
|
||||
|
||||
// after JSON conversion, txn.name becomes jsonSpan.description
|
||||
if (source && source !== 'url') {
|
||||
dsc.transaction = jsonSpan.description;
|
||||
}
|
||||
|
||||
dsc.sampled = String(spanIsSampled(txn));
|
||||
|
||||
client.emit && client.emit('createDsc', dsc);
|
||||
|
||||
return dsc;
|
||||
}
|
||||
|
||||
export { getDynamicSamplingContextFromClient, getDynamicSamplingContextFromSpan };
|
||||
//# sourceMappingURL=dynamicSamplingContext.js.map
|
||||
1
node_modules/@sentry/core/esm/tracing/dynamicSamplingContext.js.map
generated
vendored
Normal file
1
node_modules/@sentry/core/esm/tracing/dynamicSamplingContext.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
38
node_modules/@sentry/core/esm/tracing/errors.js
generated
vendored
Normal file
38
node_modules/@sentry/core/esm/tracing/errors.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import { addGlobalErrorInstrumentationHandler, addGlobalUnhandledRejectionInstrumentationHandler, logger } from '@sentry/utils';
|
||||
import { DEBUG_BUILD } from '../debug-build.js';
|
||||
import { getActiveTransaction } from './utils.js';
|
||||
|
||||
let errorsInstrumented = false;
|
||||
|
||||
/**
|
||||
* Configures global error listeners
|
||||
*/
|
||||
function registerErrorInstrumentation() {
|
||||
if (errorsInstrumented) {
|
||||
return;
|
||||
}
|
||||
|
||||
errorsInstrumented = true;
|
||||
addGlobalErrorInstrumentationHandler(errorCallback);
|
||||
addGlobalUnhandledRejectionInstrumentationHandler(errorCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* If an error or unhandled promise occurs, we mark the active transaction as failed
|
||||
*/
|
||||
function errorCallback() {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const activeTransaction = getActiveTransaction();
|
||||
if (activeTransaction) {
|
||||
const status = 'internal_error';
|
||||
DEBUG_BUILD && logger.log(`[Tracing] Transaction: ${status} -> Global error occured`);
|
||||
activeTransaction.setStatus(status);
|
||||
}
|
||||
}
|
||||
|
||||
// The function name will be lost when bundling but we need to be able to identify this listener later to maintain the
|
||||
// node.js default exit behaviour
|
||||
errorCallback.tag = 'sentry_tracingErrorCallback';
|
||||
|
||||
export { registerErrorInstrumentation };
|
||||
//# sourceMappingURL=errors.js.map
|
||||
1
node_modules/@sentry/core/esm/tracing/errors.js.map
generated
vendored
Normal file
1
node_modules/@sentry/core/esm/tracing/errors.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"errors.js","sources":["../../../src/tracing/errors.ts"],"sourcesContent":["import {\n addGlobalErrorInstrumentationHandler,\n addGlobalUnhandledRejectionInstrumentationHandler,\n logger,\n} from '@sentry/utils';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { SpanStatusType } from './spanstatus';\nimport { getActiveTransaction } from './utils';\n\nlet errorsInstrumented = false;\n\n/**\n * Configures global error listeners\n */\nexport function registerErrorInstrumentation(): void {\n if (errorsInstrumented) {\n return;\n }\n\n errorsInstrumented = true;\n addGlobalErrorInstrumentationHandler(errorCallback);\n addGlobalUnhandledRejectionInstrumentationHandler(errorCallback);\n}\n\n/**\n * If an error or unhandled promise occurs, we mark the active transaction as failed\n */\nfunction errorCallback(): void {\n // eslint-disable-next-line deprecation/deprecation\n const activeTransaction = getActiveTransaction();\n if (activeTransaction) {\n const status: SpanStatusType = 'internal_error';\n DEBUG_BUILD && logger.log(`[Tracing] Transaction: ${status} -> Global error occured`);\n activeTransaction.setStatus(status);\n }\n}\n\n// The function name will be lost when bundling but we need to be able to identify this listener later to maintain the\n// node.js default exit behaviour\nerrorCallback.tag = 'sentry_tracingErrorCallback';\n"],"names":[],"mappings":";;;;AAUA,IAAI,kBAAA,GAAqB,KAAK,CAAA;AAC9B;AACA;AACA;AACA;AACO,SAAS,4BAA4B,GAAS;AACrD,EAAE,IAAI,kBAAkB,EAAE;AAC1B,IAAI,OAAM;AACV,GAAE;AACF;AACA,EAAE,kBAAA,GAAqB,IAAI,CAAA;AAC3B,EAAE,oCAAoC,CAAC,aAAa,CAAC,CAAA;AACrD,EAAE,iDAAiD,CAAC,aAAa,CAAC,CAAA;AAClE,CAAA;AACA;AACA;AACA;AACA;AACA,SAAS,aAAa,GAAS;AAC/B;AACA,EAAE,MAAM,iBAAA,GAAoB,oBAAoB,EAAE,CAAA;AAClD,EAAE,IAAI,iBAAiB,EAAE;AACzB,IAAI,MAAM,MAAM,GAAmB,gBAAgB,CAAA;AACnD,IAAI,WAAY,IAAG,MAAM,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAA;AACzF,IAAI,iBAAiB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;AACvC,GAAE;AACF,CAAA;AACA;AACA;AACA;AACA,aAAa,CAAC,GAAI,GAAE,6BAA6B;;;;"}
|
||||
154
node_modules/@sentry/core/esm/tracing/hubextensions.js
generated
vendored
Normal file
154
node_modules/@sentry/core/esm/tracing/hubextensions.js
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
import { logger } from '@sentry/utils';
|
||||
import { DEBUG_BUILD } from '../debug-build.js';
|
||||
import { getMainCarrier } from '../hub.js';
|
||||
import { spanToTraceHeader } from '../utils/spanUtils.js';
|
||||
import { registerErrorInstrumentation } from './errors.js';
|
||||
import { IdleTransaction } from './idletransaction.js';
|
||||
import { sampleTransaction } from './sampling.js';
|
||||
import { Transaction } from './transaction.js';
|
||||
|
||||
/** Returns all trace headers that are currently on the top scope. */
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
function traceHeaders() {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const scope = this.getScope();
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const span = scope.getSpan();
|
||||
|
||||
return span
|
||||
? {
|
||||
'sentry-trace': spanToTraceHeader(span),
|
||||
}
|
||||
: {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new transaction and adds a sampling decision if it doesn't yet have one.
|
||||
*
|
||||
* The Hub.startTransaction method delegates to this method to do its work, passing the Hub instance in as `this`, as if
|
||||
* it had been called on the hub directly. Exists as a separate function so that it can be injected into the class as an
|
||||
* "extension method."
|
||||
*
|
||||
* @param this: The Hub starting the transaction
|
||||
* @param transactionContext: Data used to configure the transaction
|
||||
* @param CustomSamplingContext: Optional data to be provided to the `tracesSampler` function (if any)
|
||||
*
|
||||
* @returns The new transaction
|
||||
*
|
||||
* @see {@link Hub.startTransaction}
|
||||
*/
|
||||
function _startTransaction(
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
|
||||
transactionContext,
|
||||
customSamplingContext,
|
||||
) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const client = this.getClient();
|
||||
const options = (client && client.getOptions()) || {};
|
||||
|
||||
const configInstrumenter = options.instrumenter || 'sentry';
|
||||
const transactionInstrumenter = transactionContext.instrumenter || 'sentry';
|
||||
|
||||
if (configInstrumenter !== transactionInstrumenter) {
|
||||
DEBUG_BUILD &&
|
||||
logger.error(
|
||||
`A transaction was started with instrumenter=\`${transactionInstrumenter}\`, but the SDK is configured with the \`${configInstrumenter}\` instrumenter.
|
||||
The transaction will not be sampled. Please use the ${configInstrumenter} instrumentation to start transactions.`,
|
||||
);
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
transactionContext.sampled = false;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
let transaction = new Transaction(transactionContext, this);
|
||||
transaction = sampleTransaction(transaction, options, {
|
||||
name: transactionContext.name,
|
||||
parentSampled: transactionContext.parentSampled,
|
||||
transactionContext,
|
||||
attributes: {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
...transactionContext.data,
|
||||
...transactionContext.attributes,
|
||||
},
|
||||
...customSamplingContext,
|
||||
});
|
||||
if (transaction.isRecording()) {
|
||||
transaction.initSpanRecorder(options._experiments && (options._experiments.maxSpans ));
|
||||
}
|
||||
if (client && client.emit) {
|
||||
client.emit('startTransaction', transaction);
|
||||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new idle transaction.
|
||||
*/
|
||||
function startIdleTransaction(
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
hub,
|
||||
transactionContext,
|
||||
idleTimeout,
|
||||
finalTimeout,
|
||||
onScope,
|
||||
customSamplingContext,
|
||||
heartbeatInterval,
|
||||
delayAutoFinishUntilSignal = false,
|
||||
) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const client = hub.getClient();
|
||||
const options = (client && client.getOptions()) || {};
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
let transaction = new IdleTransaction(
|
||||
transactionContext,
|
||||
hub,
|
||||
idleTimeout,
|
||||
finalTimeout,
|
||||
heartbeatInterval,
|
||||
onScope,
|
||||
delayAutoFinishUntilSignal,
|
||||
);
|
||||
transaction = sampleTransaction(transaction, options, {
|
||||
name: transactionContext.name,
|
||||
parentSampled: transactionContext.parentSampled,
|
||||
transactionContext,
|
||||
attributes: {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
...transactionContext.data,
|
||||
...transactionContext.attributes,
|
||||
},
|
||||
...customSamplingContext,
|
||||
});
|
||||
if (transaction.isRecording()) {
|
||||
transaction.initSpanRecorder(options._experiments && (options._experiments.maxSpans ));
|
||||
}
|
||||
if (client && client.emit) {
|
||||
client.emit('startTransaction', transaction);
|
||||
}
|
||||
return transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds tracing extensions to the global hub.
|
||||
*/
|
||||
function addTracingExtensions() {
|
||||
const carrier = getMainCarrier();
|
||||
if (!carrier.__SENTRY__) {
|
||||
return;
|
||||
}
|
||||
carrier.__SENTRY__.extensions = carrier.__SENTRY__.extensions || {};
|
||||
if (!carrier.__SENTRY__.extensions.startTransaction) {
|
||||
carrier.__SENTRY__.extensions.startTransaction = _startTransaction;
|
||||
}
|
||||
if (!carrier.__SENTRY__.extensions.traceHeaders) {
|
||||
carrier.__SENTRY__.extensions.traceHeaders = traceHeaders;
|
||||
}
|
||||
|
||||
registerErrorInstrumentation();
|
||||
}
|
||||
|
||||
export { addTracingExtensions, startIdleTransaction };
|
||||
//# sourceMappingURL=hubextensions.js.map
|
||||
1
node_modules/@sentry/core/esm/tracing/hubextensions.js.map
generated
vendored
Normal file
1
node_modules/@sentry/core/esm/tracing/hubextensions.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
403
node_modules/@sentry/core/esm/tracing/idletransaction.js
generated
vendored
Normal file
403
node_modules/@sentry/core/esm/tracing/idletransaction.js
generated
vendored
Normal file
@@ -0,0 +1,403 @@
|
||||
import { logger, timestampInSeconds } from '@sentry/utils';
|
||||
import { DEBUG_BUILD } from '../debug-build.js';
|
||||
import { spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils.js';
|
||||
import { SpanRecorder } from './span.js';
|
||||
import { Transaction } from './transaction.js';
|
||||
|
||||
const TRACING_DEFAULTS = {
|
||||
idleTimeout: 1000,
|
||||
finalTimeout: 30000,
|
||||
heartbeatInterval: 5000,
|
||||
};
|
||||
|
||||
const FINISH_REASON_TAG = 'finishReason';
|
||||
|
||||
const IDLE_TRANSACTION_FINISH_REASONS = [
|
||||
'heartbeatFailed',
|
||||
'idleTimeout',
|
||||
'documentHidden',
|
||||
'finalTimeout',
|
||||
'externalFinish',
|
||||
'cancelled',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
class IdleTransactionSpanRecorder extends SpanRecorder {
|
||||
constructor(
|
||||
_pushActivity,
|
||||
_popActivity,
|
||||
transactionSpanId,
|
||||
maxlen,
|
||||
) {
|
||||
super(maxlen);this._pushActivity = _pushActivity;this._popActivity = _popActivity;this.transactionSpanId = transactionSpanId; }
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
add(span) {
|
||||
// We should make sure we do not push and pop activities for
|
||||
// the transaction that this span recorder belongs to.
|
||||
if (span.spanContext().spanId !== this.transactionSpanId) {
|
||||
// We patch span.end() to pop an activity after setting an endTimestamp.
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const originalEnd = span.end;
|
||||
span.end = (...rest) => {
|
||||
this._popActivity(span.spanContext().spanId);
|
||||
return originalEnd.apply(span, rest);
|
||||
};
|
||||
|
||||
// We should only push new activities if the span does not have an end timestamp.
|
||||
if (spanToJSON(span).timestamp === undefined) {
|
||||
this._pushActivity(span.spanContext().spanId);
|
||||
}
|
||||
}
|
||||
|
||||
super.add(span);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An IdleTransaction is a transaction that automatically finishes. It does this by tracking child spans as activities.
|
||||
* You can have multiple IdleTransactions active, but if the `onScope` option is specified, the idle transaction will
|
||||
* put itself on the scope on creation.
|
||||
*/
|
||||
class IdleTransaction extends Transaction {
|
||||
// Activities store a list of active spans
|
||||
|
||||
// Track state of activities in previous heartbeat
|
||||
|
||||
// Amount of times heartbeat has counted. Will cause transaction to finish after 3 beats.
|
||||
|
||||
// We should not use heartbeat if we finished a transaction
|
||||
|
||||
// Idle timeout was canceled and we should finish the transaction with the last span end.
|
||||
|
||||
/**
|
||||
* Timer that tracks Transaction idleTimeout
|
||||
*/
|
||||
|
||||
/**
|
||||
* @deprecated Transactions will be removed in v8. Use spans instead.
|
||||
*/
|
||||
constructor(
|
||||
transactionContext,
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
_idleHub,
|
||||
/**
|
||||
* The time to wait in ms until the idle transaction will be finished. This timer is started each time
|
||||
* there are no active spans on this transaction.
|
||||
*/
|
||||
_idleTimeout = TRACING_DEFAULTS.idleTimeout,
|
||||
/**
|
||||
* The final value in ms that a transaction cannot exceed
|
||||
*/
|
||||
_finalTimeout = TRACING_DEFAULTS.finalTimeout,
|
||||
_heartbeatInterval = TRACING_DEFAULTS.heartbeatInterval,
|
||||
// Whether or not the transaction should put itself on the scope when it starts and pop itself off when it ends
|
||||
_onScope = false,
|
||||
/**
|
||||
* When set to `true`, will disable the idle timeout (`_idleTimeout` option) and heartbeat mechanisms (`_heartbeatInterval`
|
||||
* option) until the `sendAutoFinishSignal()` method is called. The final timeout mechanism (`_finalTimeout` option)
|
||||
* will not be affected by this option, meaning the transaction will definitely be finished when the final timeout is
|
||||
* reached, no matter what this option is configured to.
|
||||
*
|
||||
* Defaults to `false`.
|
||||
*/
|
||||
delayAutoFinishUntilSignal = false,
|
||||
) {
|
||||
super(transactionContext, _idleHub);this._idleHub = _idleHub;this._idleTimeout = _idleTimeout;this._finalTimeout = _finalTimeout;this._heartbeatInterval = _heartbeatInterval;this._onScope = _onScope;
|
||||
this.activities = {};
|
||||
this._heartbeatCounter = 0;
|
||||
this._finished = false;
|
||||
this._idleTimeoutCanceledPermanently = false;
|
||||
this._beforeFinishCallbacks = [];
|
||||
this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[4];
|
||||
this._autoFinishAllowed = !delayAutoFinishUntilSignal;
|
||||
|
||||
if (_onScope) {
|
||||
// We set the transaction here on the scope so error events pick up the trace
|
||||
// context and attach it to the error.
|
||||
DEBUG_BUILD && logger.log(`Setting idle transaction on scope. Span ID: ${this.spanContext().spanId}`);
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
_idleHub.getScope().setSpan(this);
|
||||
}
|
||||
|
||||
if (!delayAutoFinishUntilSignal) {
|
||||
this._restartIdleTimeout();
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (!this._finished) {
|
||||
this.setStatus('deadline_exceeded');
|
||||
this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[3];
|
||||
this.end();
|
||||
}
|
||||
}, this._finalTimeout);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
end(endTimestamp) {
|
||||
const endTimestampInS = spanTimeInputToSeconds(endTimestamp);
|
||||
|
||||
this._finished = true;
|
||||
this.activities = {};
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
if (this.op === 'ui.action.click') {
|
||||
this.setAttribute(FINISH_REASON_TAG, this._finishReason);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
if (this.spanRecorder) {
|
||||
DEBUG_BUILD &&
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
logger.log('[Tracing] finishing IdleTransaction', new Date(endTimestampInS * 1000).toISOString(), this.op);
|
||||
|
||||
for (const callback of this._beforeFinishCallbacks) {
|
||||
callback(this, endTimestampInS);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.spanRecorder.spans = this.spanRecorder.spans.filter((span) => {
|
||||
// If we are dealing with the transaction itself, we just return it
|
||||
if (span.spanContext().spanId === this.spanContext().spanId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We cancel all pending spans with status "cancelled" to indicate the idle transaction was finished early
|
||||
if (!spanToJSON(span).timestamp) {
|
||||
span.setStatus('cancelled');
|
||||
span.end(endTimestampInS);
|
||||
DEBUG_BUILD &&
|
||||
logger.log('[Tracing] cancelling span since transaction ended early', JSON.stringify(span, undefined, 2));
|
||||
}
|
||||
|
||||
const { start_timestamp: startTime, timestamp: endTime } = spanToJSON(span);
|
||||
const spanStartedBeforeTransactionFinish = startTime && startTime < endTimestampInS;
|
||||
|
||||
// Add a delta with idle timeout so that we prevent false positives
|
||||
const timeoutWithMarginOfError = (this._finalTimeout + this._idleTimeout) / 1000;
|
||||
const spanEndedBeforeFinalTimeout = endTime && startTime && endTime - startTime < timeoutWithMarginOfError;
|
||||
|
||||
if (DEBUG_BUILD) {
|
||||
const stringifiedSpan = JSON.stringify(span, undefined, 2);
|
||||
if (!spanStartedBeforeTransactionFinish) {
|
||||
logger.log('[Tracing] discarding Span since it happened after Transaction was finished', stringifiedSpan);
|
||||
} else if (!spanEndedBeforeFinalTimeout) {
|
||||
logger.log('[Tracing] discarding Span since it finished after Transaction final timeout', stringifiedSpan);
|
||||
}
|
||||
}
|
||||
|
||||
return spanStartedBeforeTransactionFinish && spanEndedBeforeFinalTimeout;
|
||||
});
|
||||
|
||||
DEBUG_BUILD && logger.log('[Tracing] flushing IdleTransaction');
|
||||
} else {
|
||||
DEBUG_BUILD && logger.log('[Tracing] No active IdleTransaction');
|
||||
}
|
||||
|
||||
// if `this._onScope` is `true`, the transaction put itself on the scope when it started
|
||||
if (this._onScope) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const scope = this._idleHub.getScope();
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
if (scope.getTransaction() === this) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
scope.setSpan(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
return super.end(endTimestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback function that gets executed before the transaction finishes.
|
||||
* Useful for cleanup or if you want to add any additional spans based on current context.
|
||||
*
|
||||
* This is exposed because users have no other way of running something before an idle transaction
|
||||
* finishes.
|
||||
*/
|
||||
registerBeforeFinishCallback(callback) {
|
||||
this._beforeFinishCallbacks.push(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
initSpanRecorder(maxlen) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
if (!this.spanRecorder) {
|
||||
const pushActivity = (id) => {
|
||||
if (this._finished) {
|
||||
return;
|
||||
}
|
||||
this._pushActivity(id);
|
||||
};
|
||||
const popActivity = (id) => {
|
||||
if (this._finished) {
|
||||
return;
|
||||
}
|
||||
this._popActivity(id);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.spanRecorder = new IdleTransactionSpanRecorder(pushActivity, popActivity, this.spanContext().spanId, maxlen);
|
||||
|
||||
// Start heartbeat so that transactions do not run forever.
|
||||
DEBUG_BUILD && logger.log('Starting heartbeat');
|
||||
this._pingHeartbeat();
|
||||
}
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.spanRecorder.add(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the existing idle timeout, if there is one.
|
||||
* @param restartOnChildSpanChange Default is `true`.
|
||||
* If set to false the transaction will end
|
||||
* with the last child span.
|
||||
*/
|
||||
cancelIdleTimeout(
|
||||
endTimestamp,
|
||||
{
|
||||
restartOnChildSpanChange,
|
||||
}
|
||||
|
||||
= {
|
||||
restartOnChildSpanChange: true,
|
||||
},
|
||||
) {
|
||||
this._idleTimeoutCanceledPermanently = restartOnChildSpanChange === false;
|
||||
if (this._idleTimeoutID) {
|
||||
clearTimeout(this._idleTimeoutID);
|
||||
this._idleTimeoutID = undefined;
|
||||
|
||||
if (Object.keys(this.activities).length === 0 && this._idleTimeoutCanceledPermanently) {
|
||||
this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5];
|
||||
this.end(endTimestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary method used to externally set the transaction's `finishReason`
|
||||
*
|
||||
* ** WARNING**
|
||||
* This is for the purpose of experimentation only and will be removed in the near future, do not use!
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
*/
|
||||
setFinishReason(reason) {
|
||||
this._finishReason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permits the IdleTransaction to automatically end itself via the idle timeout and heartbeat mechanisms when the `delayAutoFinishUntilSignal` option was set to `true`.
|
||||
*/
|
||||
sendAutoFinishSignal() {
|
||||
if (!this._autoFinishAllowed) {
|
||||
DEBUG_BUILD && logger.log('[Tracing] Received finish signal for idle transaction.');
|
||||
this._restartIdleTimeout();
|
||||
this._autoFinishAllowed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restarts idle timeout, if there is no running idle timeout it will start one.
|
||||
*/
|
||||
_restartIdleTimeout(endTimestamp) {
|
||||
this.cancelIdleTimeout();
|
||||
this._idleTimeoutID = setTimeout(() => {
|
||||
if (!this._finished && Object.keys(this.activities).length === 0) {
|
||||
this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[1];
|
||||
this.end(endTimestamp);
|
||||
}
|
||||
}, this._idleTimeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start tracking a specific activity.
|
||||
* @param spanId The span id that represents the activity
|
||||
*/
|
||||
_pushActivity(spanId) {
|
||||
this.cancelIdleTimeout(undefined, { restartOnChildSpanChange: !this._idleTimeoutCanceledPermanently });
|
||||
DEBUG_BUILD && logger.log(`[Tracing] pushActivity: ${spanId}`);
|
||||
this.activities[spanId] = true;
|
||||
DEBUG_BUILD && logger.log('[Tracing] new activities count', Object.keys(this.activities).length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an activity from usage
|
||||
* @param spanId The span id that represents the activity
|
||||
*/
|
||||
_popActivity(spanId) {
|
||||
if (this.activities[spanId]) {
|
||||
DEBUG_BUILD && logger.log(`[Tracing] popActivity ${spanId}`);
|
||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
delete this.activities[spanId];
|
||||
DEBUG_BUILD && logger.log('[Tracing] new activities count', Object.keys(this.activities).length);
|
||||
}
|
||||
|
||||
if (Object.keys(this.activities).length === 0) {
|
||||
const endTimestamp = timestampInSeconds();
|
||||
if (this._idleTimeoutCanceledPermanently) {
|
||||
if (this._autoFinishAllowed) {
|
||||
this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[5];
|
||||
this.end(endTimestamp);
|
||||
}
|
||||
} else {
|
||||
// We need to add the timeout here to have the real endtimestamp of the transaction
|
||||
// Remember timestampInSeconds is in seconds, timeout is in ms
|
||||
this._restartIdleTimeout(endTimestamp + this._idleTimeout / 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks when entries of this.activities are not changing for 3 beats.
|
||||
* If this occurs we finish the transaction.
|
||||
*/
|
||||
_beat() {
|
||||
// We should not be running heartbeat if the idle transaction is finished.
|
||||
if (this._finished) {
|
||||
return;
|
||||
}
|
||||
|
||||
const heartbeatString = Object.keys(this.activities).join('');
|
||||
|
||||
if (heartbeatString === this._prevHeartbeatString) {
|
||||
this._heartbeatCounter++;
|
||||
} else {
|
||||
this._heartbeatCounter = 1;
|
||||
}
|
||||
|
||||
this._prevHeartbeatString = heartbeatString;
|
||||
|
||||
if (this._heartbeatCounter >= 3) {
|
||||
if (this._autoFinishAllowed) {
|
||||
DEBUG_BUILD && logger.log('[Tracing] Transaction finished because of no change for 3 heart beats');
|
||||
this.setStatus('deadline_exceeded');
|
||||
this._finishReason = IDLE_TRANSACTION_FINISH_REASONS[0];
|
||||
this.end();
|
||||
}
|
||||
} else {
|
||||
this._pingHeartbeat();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pings the heartbeat
|
||||
*/
|
||||
_pingHeartbeat() {
|
||||
DEBUG_BUILD && logger.log(`pinging Heartbeat -> current counter: ${this._heartbeatCounter}`);
|
||||
setTimeout(() => {
|
||||
this._beat();
|
||||
}, this._heartbeatInterval);
|
||||
}
|
||||
}
|
||||
|
||||
export { IdleTransaction, IdleTransactionSpanRecorder, TRACING_DEFAULTS };
|
||||
//# sourceMappingURL=idletransaction.js.map
|
||||
1
node_modules/@sentry/core/esm/tracing/idletransaction.js.map
generated
vendored
Normal file
1
node_modules/@sentry/core/esm/tracing/idletransaction.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
16
node_modules/@sentry/core/esm/tracing/measurement.js
generated
vendored
Normal file
16
node_modules/@sentry/core/esm/tracing/measurement.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import { getActiveTransaction } from './utils.js';
|
||||
|
||||
/**
|
||||
* Adds a measurement to the current active transaction.
|
||||
*/
|
||||
function setMeasurement(name, value, unit) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const transaction = getActiveTransaction();
|
||||
if (transaction) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
transaction.setMeasurement(name, value, unit);
|
||||
}
|
||||
}
|
||||
|
||||
export { setMeasurement };
|
||||
//# sourceMappingURL=measurement.js.map
|
||||
1
node_modules/@sentry/core/esm/tracing/measurement.js.map
generated
vendored
Normal file
1
node_modules/@sentry/core/esm/tracing/measurement.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"measurement.js","sources":["../../../src/tracing/measurement.ts"],"sourcesContent":["import type { MeasurementUnit } from '@sentry/types';\n\nimport { getActiveTransaction } from './utils';\n\n/**\n * Adds a measurement to the current active transaction.\n */\nexport function setMeasurement(name: string, value: number, unit: MeasurementUnit): void {\n // eslint-disable-next-line deprecation/deprecation\n const transaction = getActiveTransaction();\n if (transaction) {\n // eslint-disable-next-line deprecation/deprecation\n transaction.setMeasurement(name, value, unit);\n }\n}\n"],"names":[],"mappings":";;AAIA;AACA;AACA;AACO,SAAS,cAAc,CAAC,IAAI,EAAU,KAAK,EAAU,IAAI,EAAyB;AACzF;AACA,EAAE,MAAM,WAAA,GAAc,oBAAoB,EAAE,CAAA;AAC5C,EAAE,IAAI,WAAW,EAAE;AACnB;AACA,IAAI,WAAW,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;AACjD,GAAE;AACF;;;;"}
|
||||
126
node_modules/@sentry/core/esm/tracing/sampling.js
generated
vendored
Normal file
126
node_modules/@sentry/core/esm/tracing/sampling.js
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
import { isNaN, logger } from '@sentry/utils';
|
||||
import { DEBUG_BUILD } from '../debug-build.js';
|
||||
import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE } from '../semanticAttributes.js';
|
||||
import { hasTracingEnabled } from '../utils/hasTracingEnabled.js';
|
||||
import { spanToJSON } from '../utils/spanUtils.js';
|
||||
|
||||
/**
|
||||
* Makes a sampling decision for the given transaction and stores it on the transaction.
|
||||
*
|
||||
* Called every time a transaction is created. Only transactions which emerge with a `sampled` value of `true` will be
|
||||
* sent to Sentry.
|
||||
*
|
||||
* This method muttes the given `transaction` and will set the `sampled` value on it.
|
||||
* It returns the same transaction, for convenience.
|
||||
*/
|
||||
function sampleTransaction(
|
||||
transaction,
|
||||
options,
|
||||
samplingContext,
|
||||
) {
|
||||
// nothing to do if tracing is not enabled
|
||||
if (!hasTracingEnabled(options)) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
transaction.sampled = false;
|
||||
return transaction;
|
||||
}
|
||||
|
||||
// if the user has forced a sampling decision by passing a `sampled` value in their transaction context, go with that
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
if (transaction.sampled !== undefined) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, Number(transaction.sampled));
|
||||
return transaction;
|
||||
}
|
||||
|
||||
// we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should
|
||||
// work; prefer the hook if so
|
||||
let sampleRate;
|
||||
if (typeof options.tracesSampler === 'function') {
|
||||
sampleRate = options.tracesSampler(samplingContext);
|
||||
transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, Number(sampleRate));
|
||||
} else if (samplingContext.parentSampled !== undefined) {
|
||||
sampleRate = samplingContext.parentSampled;
|
||||
} else if (typeof options.tracesSampleRate !== 'undefined') {
|
||||
sampleRate = options.tracesSampleRate;
|
||||
transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, Number(sampleRate));
|
||||
} else {
|
||||
// When `enableTracing === true`, we use a sample rate of 100%
|
||||
sampleRate = 1;
|
||||
transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, sampleRate);
|
||||
}
|
||||
|
||||
// Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The
|
||||
// only valid values are booleans or numbers between 0 and 1.)
|
||||
if (!isValidSampleRate(sampleRate)) {
|
||||
DEBUG_BUILD && logger.warn('[Tracing] Discarding transaction because of invalid sample rate.');
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
transaction.sampled = false;
|
||||
return transaction;
|
||||
}
|
||||
|
||||
// if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped
|
||||
if (!sampleRate) {
|
||||
DEBUG_BUILD &&
|
||||
logger.log(
|
||||
`[Tracing] Discarding transaction because ${
|
||||
typeof options.tracesSampler === 'function'
|
||||
? 'tracesSampler returned 0 or false'
|
||||
: 'a negative sampling decision was inherited or tracesSampleRate is set to 0'
|
||||
}`,
|
||||
);
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
transaction.sampled = false;
|
||||
return transaction;
|
||||
}
|
||||
|
||||
// Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is
|
||||
// a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false.
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
transaction.sampled = Math.random() < (sampleRate );
|
||||
|
||||
// if we're not going to keep it, we're done
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
if (!transaction.sampled) {
|
||||
DEBUG_BUILD &&
|
||||
logger.log(
|
||||
`[Tracing] Discarding transaction because it's not included in the random sample (sampling rate = ${Number(
|
||||
sampleRate,
|
||||
)})`,
|
||||
);
|
||||
return transaction;
|
||||
}
|
||||
|
||||
DEBUG_BUILD &&
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
logger.log(`[Tracing] starting ${transaction.op} transaction - ${spanToJSON(transaction).description}`);
|
||||
return transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given sample rate to make sure it is valid type and value (a boolean, or a number between 0 and 1).
|
||||
*/
|
||||
function isValidSampleRate(rate) {
|
||||
// we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if (isNaN(rate) || !(typeof rate === 'number' || typeof rate === 'boolean')) {
|
||||
DEBUG_BUILD &&
|
||||
logger.warn(
|
||||
`[Tracing] Given sample rate is invalid. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify(
|
||||
rate,
|
||||
)} of type ${JSON.stringify(typeof rate)}.`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false
|
||||
if (rate < 0 || rate > 1) {
|
||||
DEBUG_BUILD &&
|
||||
logger.warn(`[Tracing] Given sample rate is invalid. Sample rate must be between 0 and 1. Got ${rate}.`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export { isValidSampleRate, sampleTransaction };
|
||||
//# sourceMappingURL=sampling.js.map
|
||||
1
node_modules/@sentry/core/esm/tracing/sampling.js.map
generated
vendored
Normal file
1
node_modules/@sentry/core/esm/tracing/sampling.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
641
node_modules/@sentry/core/esm/tracing/span.js
generated
vendored
Normal file
641
node_modules/@sentry/core/esm/tracing/span.js
generated
vendored
Normal file
@@ -0,0 +1,641 @@
|
||||
import { uuid4, timestampInSeconds, logger, dropUndefinedKeys } from '@sentry/utils';
|
||||
import { DEBUG_BUILD } from '../debug-build.js';
|
||||
import { getMetricSummaryJsonForSpan } from '../metrics/metric-summary.js';
|
||||
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_PROFILE_ID } from '../semanticAttributes.js';
|
||||
import { getRootSpan } from '../utils/getRootSpan.js';
|
||||
import { TRACE_FLAG_SAMPLED, TRACE_FLAG_NONE, spanToJSON, spanTimeInputToSeconds, spanToTraceHeader, spanToTraceContext } from '../utils/spanUtils.js';
|
||||
import { setHttpStatus } from './spanstatus.js';
|
||||
|
||||
/**
|
||||
* Keeps track of finished spans for a given transaction
|
||||
* @internal
|
||||
* @hideconstructor
|
||||
* @hidden
|
||||
*/
|
||||
class SpanRecorder {
|
||||
|
||||
constructor(maxlen = 1000) {
|
||||
this._maxlen = maxlen;
|
||||
this.spans = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* This is just so that we don't run out of memory while recording a lot
|
||||
* of spans. At some point we just stop and flush out the start of the
|
||||
* trace tree (i.e.the first n spans with the smallest
|
||||
* start_timestamp).
|
||||
*/
|
||||
add(span) {
|
||||
if (this.spans.length > this._maxlen) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
span.spanRecorder = undefined;
|
||||
} else {
|
||||
this.spans.push(span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Span contains all data about a span
|
||||
*/
|
||||
class Span {
|
||||
/**
|
||||
* Tags for the span.
|
||||
* @deprecated Use `spanToJSON(span).atttributes` instead.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data for the span.
|
||||
* @deprecated Use `spanToJSON(span).atttributes` instead.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
/**
|
||||
* List of spans that were finalized
|
||||
*
|
||||
* @deprecated This property will no longer be public. Span recording will be handled internally.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @deprecated Use top level `Sentry.getRootSpan()` instead
|
||||
*/
|
||||
|
||||
/**
|
||||
* The instrumenter that created this span.
|
||||
*
|
||||
* TODO (v8): This can probably be replaced by an `instanceOf` check of the span class.
|
||||
* the instrumenter can only be sentry or otel so we can check the span instance
|
||||
* to verify which one it is and remove this field entirely.
|
||||
*
|
||||
* @deprecated This field will be removed.
|
||||
*/
|
||||
|
||||
/** Epoch timestamp in seconds when the span started. */
|
||||
|
||||
/** Epoch timestamp in seconds when the span ended. */
|
||||
|
||||
/** Internal keeper of the status */
|
||||
|
||||
/**
|
||||
* You should never call the constructor manually, always use `Sentry.startTransaction()`
|
||||
* or call `startChild()` on an existing span.
|
||||
* @internal
|
||||
* @hideconstructor
|
||||
* @hidden
|
||||
*/
|
||||
constructor(spanContext = {}) {
|
||||
this._traceId = spanContext.traceId || uuid4();
|
||||
this._spanId = spanContext.spanId || uuid4().substring(16);
|
||||
this._startTime = spanContext.startTimestamp || timestampInSeconds();
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.tags = spanContext.tags ? { ...spanContext.tags } : {};
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.data = spanContext.data ? { ...spanContext.data } : {};
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.instrumenter = spanContext.instrumenter || 'sentry';
|
||||
|
||||
this._attributes = {};
|
||||
this.setAttributes({
|
||||
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanContext.origin || 'manual',
|
||||
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: spanContext.op,
|
||||
...spanContext.attributes,
|
||||
});
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this._name = spanContext.name || spanContext.description;
|
||||
|
||||
if (spanContext.parentSpanId) {
|
||||
this._parentSpanId = spanContext.parentSpanId;
|
||||
}
|
||||
// We want to include booleans as well here
|
||||
if ('sampled' in spanContext) {
|
||||
this._sampled = spanContext.sampled;
|
||||
}
|
||||
if (spanContext.status) {
|
||||
this._status = spanContext.status;
|
||||
}
|
||||
if (spanContext.endTimestamp) {
|
||||
this._endTime = spanContext.endTimestamp;
|
||||
}
|
||||
if (spanContext.exclusiveTime !== undefined) {
|
||||
this._exclusiveTime = spanContext.exclusiveTime;
|
||||
}
|
||||
this._measurements = spanContext.measurements ? { ...spanContext.measurements } : {};
|
||||
}
|
||||
|
||||
// This rule conflicts with another eslint rule :(
|
||||
/* eslint-disable @typescript-eslint/member-ordering */
|
||||
|
||||
/**
|
||||
* An alias for `description` of the Span.
|
||||
* @deprecated Use `spanToJSON(span).description` instead.
|
||||
*/
|
||||
get name() {
|
||||
return this._name || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the name of the span.
|
||||
* @deprecated Use `spanToJSON(span).description` instead.
|
||||
*/
|
||||
set name(name) {
|
||||
this.updateName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the description of the Span.
|
||||
* @deprecated Use `spanToJSON(span).description` instead.
|
||||
*/
|
||||
get description() {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the description of the Span.
|
||||
* @deprecated Use `spanToJSON(span).description` instead.
|
||||
*/
|
||||
set description(description) {
|
||||
this._name = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ID of the trace.
|
||||
* @deprecated Use `spanContext().traceId` instead.
|
||||
*/
|
||||
get traceId() {
|
||||
return this._traceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ID of the trace.
|
||||
* @deprecated You cannot update the traceId of a span after span creation.
|
||||
*/
|
||||
set traceId(traceId) {
|
||||
this._traceId = traceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ID of the span.
|
||||
* @deprecated Use `spanContext().spanId` instead.
|
||||
*/
|
||||
get spanId() {
|
||||
return this._spanId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ID of the span.
|
||||
* @deprecated You cannot update the spanId of a span after span creation.
|
||||
*/
|
||||
set spanId(spanId) {
|
||||
this._spanId = spanId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @deprecated Use `startSpan` functions instead.
|
||||
*/
|
||||
set parentSpanId(string) {
|
||||
this._parentSpanId = string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @deprecated Use `spanToJSON(span).parent_span_id` instead.
|
||||
*/
|
||||
get parentSpanId() {
|
||||
return this._parentSpanId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was this span chosen to be sent as part of the sample?
|
||||
* @deprecated Use `isRecording()` instead.
|
||||
*/
|
||||
get sampled() {
|
||||
return this._sampled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was this span chosen to be sent as part of the sample?
|
||||
* @deprecated You cannot update the sampling decision of a span after span creation.
|
||||
*/
|
||||
set sampled(sampled) {
|
||||
this._sampled = sampled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attributes for the span.
|
||||
* @deprecated Use `spanToJSON(span).atttributes` instead.
|
||||
*/
|
||||
get attributes() {
|
||||
return this._attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attributes for the span.
|
||||
* @deprecated Use `setAttributes()` instead.
|
||||
*/
|
||||
set attributes(attributes) {
|
||||
this._attributes = attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamp in seconds (epoch time) indicating when the span started.
|
||||
* @deprecated Use `spanToJSON()` instead.
|
||||
*/
|
||||
get startTimestamp() {
|
||||
return this._startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamp in seconds (epoch time) indicating when the span started.
|
||||
* @deprecated In v8, you will not be able to update the span start time after creation.
|
||||
*/
|
||||
set startTimestamp(startTime) {
|
||||
this._startTime = startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamp in seconds when the span ended.
|
||||
* @deprecated Use `spanToJSON()` instead.
|
||||
*/
|
||||
get endTimestamp() {
|
||||
return this._endTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamp in seconds when the span ended.
|
||||
* @deprecated Set the end time via `span.end()` instead.
|
||||
*/
|
||||
set endTimestamp(endTime) {
|
||||
this._endTime = endTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* The status of the span.
|
||||
*
|
||||
* @deprecated Use `spanToJSON().status` instead to get the status.
|
||||
*/
|
||||
get status() {
|
||||
return this._status;
|
||||
}
|
||||
|
||||
/**
|
||||
* The status of the span.
|
||||
*
|
||||
* @deprecated Use `.setStatus()` instead to set or update the status.
|
||||
*/
|
||||
set status(status) {
|
||||
this._status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Operation of the span
|
||||
*
|
||||
* @deprecated Use `spanToJSON().op` to read the op instead.
|
||||
*/
|
||||
get op() {
|
||||
return this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Operation of the span
|
||||
*
|
||||
* @deprecated Use `startSpan()` functions to set or `span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'op')
|
||||
* to update the span instead.
|
||||
*/
|
||||
set op(op) {
|
||||
this.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, op);
|
||||
}
|
||||
|
||||
/**
|
||||
* The origin of the span, giving context about what created the span.
|
||||
*
|
||||
* @deprecated Use `spanToJSON().origin` to read the origin instead.
|
||||
*/
|
||||
get origin() {
|
||||
return this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] ;
|
||||
}
|
||||
|
||||
/**
|
||||
* The origin of the span, giving context about what created the span.
|
||||
*
|
||||
* @deprecated Use `startSpan()` functions to set the origin instead.
|
||||
*/
|
||||
set origin(origin) {
|
||||
this.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, origin);
|
||||
}
|
||||
|
||||
/* eslint-enable @typescript-eslint/member-ordering */
|
||||
|
||||
/** @inheritdoc */
|
||||
spanContext() {
|
||||
const { _spanId: spanId, _traceId: traceId, _sampled: sampled } = this;
|
||||
return {
|
||||
spanId,
|
||||
traceId,
|
||||
traceFlags: sampled ? TRACE_FLAG_SAMPLED : TRACE_FLAG_NONE,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new `Span` while setting the current `Span.id` as `parentSpanId`.
|
||||
* Also the `sampled` decision will be inherited.
|
||||
*
|
||||
* @deprecated Use `startSpan()`, `startSpanManual()` or `startInactiveSpan()` instead.
|
||||
*/
|
||||
startChild(
|
||||
spanContext,
|
||||
) {
|
||||
const childSpan = new Span({
|
||||
...spanContext,
|
||||
parentSpanId: this._spanId,
|
||||
sampled: this._sampled,
|
||||
traceId: this._traceId,
|
||||
});
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
childSpan.spanRecorder = this.spanRecorder;
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
if (childSpan.spanRecorder) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
childSpan.spanRecorder.add(childSpan);
|
||||
}
|
||||
|
||||
const rootSpan = getRootSpan(this);
|
||||
// TODO: still set span.transaction here until we have a more permanent solution
|
||||
// Probably similarly to the weakmap we hold in node-experimental
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
childSpan.transaction = rootSpan ;
|
||||
|
||||
if (DEBUG_BUILD && rootSpan) {
|
||||
const opStr = (spanContext && spanContext.op) || '< unknown op >';
|
||||
const nameStr = spanToJSON(childSpan).description || '< unknown name >';
|
||||
const idStr = rootSpan.spanContext().spanId;
|
||||
|
||||
const logMessage = `[Tracing] Starting '${opStr}' span on transaction '${nameStr}' (${idStr}).`;
|
||||
logger.log(logMessage);
|
||||
this._logMessage = logMessage;
|
||||
}
|
||||
|
||||
return childSpan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tag attribute on the current span.
|
||||
*
|
||||
* Can also be used to unset a tag, by passing `undefined`.
|
||||
*
|
||||
* @param key Tag key
|
||||
* @param value Tag value
|
||||
* @deprecated Use `setAttribute()` instead.
|
||||
*/
|
||||
setTag(key, value) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.tags = { ...this.tags, [key]: value };
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data attribute on the current span
|
||||
* @param key Data key
|
||||
* @param value Data value
|
||||
* @deprecated Use `setAttribute()` instead.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
setData(key, value) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.data = { ...this.data, [key]: value };
|
||||
return this;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
setAttribute(key, value) {
|
||||
if (value === undefined) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
delete this._attributes[key];
|
||||
} else {
|
||||
this._attributes[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
setAttributes(attributes) {
|
||||
Object.keys(attributes).forEach(key => this.setAttribute(key, attributes[key]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
setStatus(value) {
|
||||
this._status = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @deprecated Use top-level `setHttpStatus()` instead.
|
||||
*/
|
||||
setHttpStatus(httpStatus) {
|
||||
setHttpStatus(this, httpStatus);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @deprecated Use `.updateName()` instead.
|
||||
*/
|
||||
setName(name) {
|
||||
this.updateName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
updateName(name) {
|
||||
this._name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @deprecated Use `spanToJSON(span).status === 'ok'` instead.
|
||||
*/
|
||||
isSuccess() {
|
||||
return this._status === 'ok';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @deprecated Use `.end()` instead.
|
||||
*/
|
||||
finish(endTimestamp) {
|
||||
return this.end(endTimestamp);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
end(endTimestamp) {
|
||||
// If already ended, skip
|
||||
if (this._endTime) {
|
||||
return;
|
||||
}
|
||||
const rootSpan = getRootSpan(this);
|
||||
if (
|
||||
DEBUG_BUILD &&
|
||||
// Don't call this for transactions
|
||||
rootSpan &&
|
||||
rootSpan.spanContext().spanId !== this._spanId
|
||||
) {
|
||||
const logMessage = this._logMessage;
|
||||
if (logMessage) {
|
||||
logger.log((logMessage ).replace('Starting', 'Finishing'));
|
||||
}
|
||||
}
|
||||
|
||||
this._endTime = spanTimeInputToSeconds(endTimestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @deprecated Use `spanToTraceHeader()` instead.
|
||||
*/
|
||||
toTraceparent() {
|
||||
return spanToTraceHeader(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @deprecated Use `spanToJSON()` or access the fields directly instead.
|
||||
*/
|
||||
toContext() {
|
||||
return dropUndefinedKeys({
|
||||
data: this._getData(),
|
||||
description: this._name,
|
||||
endTimestamp: this._endTime,
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
op: this.op,
|
||||
parentSpanId: this._parentSpanId,
|
||||
sampled: this._sampled,
|
||||
spanId: this._spanId,
|
||||
startTimestamp: this._startTime,
|
||||
status: this._status,
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
tags: this.tags,
|
||||
traceId: this._traceId,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @deprecated Update the fields directly instead.
|
||||
*/
|
||||
updateWithContext(spanContext) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.data = spanContext.data || {};
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this._name = spanContext.name || spanContext.description;
|
||||
this._endTime = spanContext.endTimestamp;
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.op = spanContext.op;
|
||||
this._parentSpanId = spanContext.parentSpanId;
|
||||
this._sampled = spanContext.sampled;
|
||||
this._spanId = spanContext.spanId || this._spanId;
|
||||
this._startTime = spanContext.startTimestamp || this._startTime;
|
||||
this._status = spanContext.status;
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.tags = spanContext.tags || {};
|
||||
this._traceId = spanContext.traceId || this._traceId;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @deprecated Use `spanToTraceContext()` util function instead.
|
||||
*/
|
||||
getTraceContext() {
|
||||
return spanToTraceContext(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get JSON 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 `spanToJSON(span)` instead.
|
||||
*/
|
||||
getSpanJSON() {
|
||||
return dropUndefinedKeys({
|
||||
data: this._getData(),
|
||||
description: this._name,
|
||||
op: this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] ,
|
||||
parent_span_id: this._parentSpanId,
|
||||
span_id: this._spanId,
|
||||
start_timestamp: this._startTime,
|
||||
status: this._status,
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,
|
||||
timestamp: this._endTime,
|
||||
trace_id: this._traceId,
|
||||
origin: this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] ,
|
||||
_metrics_summary: getMetricSummaryJsonForSpan(this),
|
||||
profile_id: this._attributes[SEMANTIC_ATTRIBUTE_PROFILE_ID] ,
|
||||
exclusive_time: this._exclusiveTime,
|
||||
measurements: Object.keys(this._measurements).length > 0 ? this._measurements : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
isRecording() {
|
||||
return !this._endTime && !!this._sampled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the object to JSON.
|
||||
* @deprecated Use `spanToJSON(span)` instead.
|
||||
*/
|
||||
toJSON() {
|
||||
return this.getSpanJSON();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the merged data for this span.
|
||||
* For now, this combines `data` and `attributes` together,
|
||||
* until eventually we can ingest `attributes` directly.
|
||||
*/
|
||||
_getData()
|
||||
|
||||
{
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const { data, _attributes: attributes } = this;
|
||||
|
||||
const hasData = Object.keys(data).length > 0;
|
||||
const hasAttributes = Object.keys(attributes).length > 0;
|
||||
|
||||
if (!hasData && !hasAttributes) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (hasData && hasAttributes) {
|
||||
return {
|
||||
...data,
|
||||
...attributes,
|
||||
};
|
||||
}
|
||||
|
||||
return hasData ? data : attributes;
|
||||
}
|
||||
}
|
||||
|
||||
export { Span, SpanRecorder };
|
||||
//# sourceMappingURL=span.js.map
|
||||
1
node_modules/@sentry/core/esm/tracing/span.js.map
generated
vendored
Normal file
1
node_modules/@sentry/core/esm/tracing/span.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
123
node_modules/@sentry/core/esm/tracing/spanstatus.js
generated
vendored
Normal file
123
node_modules/@sentry/core/esm/tracing/spanstatus.js
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/** The status of an Span.
|
||||
*
|
||||
* @deprecated Use string literals - if you require type casting, cast to SpanStatusType type
|
||||
*/
|
||||
var SpanStatus; (function (SpanStatus) {
|
||||
/** The operation completed successfully. */
|
||||
const Ok = 'ok'; SpanStatus["Ok"] = Ok;
|
||||
/** Deadline expired before operation could complete. */
|
||||
const DeadlineExceeded = 'deadline_exceeded'; SpanStatus["DeadlineExceeded"] = DeadlineExceeded;
|
||||
/** 401 Unauthorized (actually does mean unauthenticated according to RFC 7235) */
|
||||
const Unauthenticated = 'unauthenticated'; SpanStatus["Unauthenticated"] = Unauthenticated;
|
||||
/** 403 Forbidden */
|
||||
const PermissionDenied = 'permission_denied'; SpanStatus["PermissionDenied"] = PermissionDenied;
|
||||
/** 404 Not Found. Some requested entity (file or directory) was not found. */
|
||||
const NotFound = 'not_found'; SpanStatus["NotFound"] = NotFound;
|
||||
/** 429 Too Many Requests */
|
||||
const ResourceExhausted = 'resource_exhausted'; SpanStatus["ResourceExhausted"] = ResourceExhausted;
|
||||
/** Client specified an invalid argument. 4xx. */
|
||||
const InvalidArgument = 'invalid_argument'; SpanStatus["InvalidArgument"] = InvalidArgument;
|
||||
/** 501 Not Implemented */
|
||||
const Unimplemented = 'unimplemented'; SpanStatus["Unimplemented"] = Unimplemented;
|
||||
/** 503 Service Unavailable */
|
||||
const Unavailable = 'unavailable'; SpanStatus["Unavailable"] = Unavailable;
|
||||
/** Other/generic 5xx. */
|
||||
const InternalError = 'internal_error'; SpanStatus["InternalError"] = InternalError;
|
||||
/** Unknown. Any non-standard HTTP status code. */
|
||||
const UnknownError = 'unknown_error'; SpanStatus["UnknownError"] = UnknownError;
|
||||
/** The operation was cancelled (typically by the user). */
|
||||
const Cancelled = 'cancelled'; SpanStatus["Cancelled"] = Cancelled;
|
||||
/** Already exists (409) */
|
||||
const AlreadyExists = 'already_exists'; SpanStatus["AlreadyExists"] = AlreadyExists;
|
||||
/** Operation was rejected because the system is not in a state required for the operation's */
|
||||
const FailedPrecondition = 'failed_precondition'; SpanStatus["FailedPrecondition"] = FailedPrecondition;
|
||||
/** The operation was aborted, typically due to a concurrency issue. */
|
||||
const Aborted = 'aborted'; SpanStatus["Aborted"] = Aborted;
|
||||
/** Operation was attempted past the valid range. */
|
||||
const OutOfRange = 'out_of_range'; SpanStatus["OutOfRange"] = OutOfRange;
|
||||
/** Unrecoverable data loss or corruption */
|
||||
const DataLoss = 'data_loss'; SpanStatus["DataLoss"] = DataLoss;
|
||||
})(SpanStatus || (SpanStatus = {}));
|
||||
|
||||
/**
|
||||
* Converts a HTTP status code into a {@link SpanStatusType}.
|
||||
*
|
||||
* @param httpStatus The HTTP response status code.
|
||||
* @returns The span status or unknown_error.
|
||||
*/
|
||||
function getSpanStatusFromHttpCode(httpStatus) {
|
||||
if (httpStatus < 400 && httpStatus >= 100) {
|
||||
return 'ok';
|
||||
}
|
||||
|
||||
if (httpStatus >= 400 && httpStatus < 500) {
|
||||
switch (httpStatus) {
|
||||
case 401:
|
||||
return 'unauthenticated';
|
||||
case 403:
|
||||
return 'permission_denied';
|
||||
case 404:
|
||||
return 'not_found';
|
||||
case 409:
|
||||
return 'already_exists';
|
||||
case 413:
|
||||
return 'failed_precondition';
|
||||
case 429:
|
||||
return 'resource_exhausted';
|
||||
default:
|
||||
return 'invalid_argument';
|
||||
}
|
||||
}
|
||||
|
||||
if (httpStatus >= 500 && httpStatus < 600) {
|
||||
switch (httpStatus) {
|
||||
case 501:
|
||||
return 'unimplemented';
|
||||
case 503:
|
||||
return 'unavailable';
|
||||
case 504:
|
||||
return 'deadline_exceeded';
|
||||
default:
|
||||
return 'internal_error';
|
||||
}
|
||||
}
|
||||
|
||||
return 'unknown_error';
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a HTTP status code into a {@link SpanStatusType}.
|
||||
*
|
||||
* @deprecated Use {@link spanStatusFromHttpCode} instead.
|
||||
* This export will be removed in v8 as the signature contains a typo.
|
||||
*
|
||||
* @param httpStatus The HTTP response status code.
|
||||
* @returns The span status or unknown_error.
|
||||
*/
|
||||
const spanStatusfromHttpCode = getSpanStatusFromHttpCode;
|
||||
|
||||
/**
|
||||
* Sets the Http status attributes on the current span based on the http code.
|
||||
* Additionally, the span's status is updated, depending on the http code.
|
||||
*/
|
||||
function setHttpStatus(span, httpStatus) {
|
||||
// TODO (v8): Remove these calls
|
||||
// Relay does not require us to send the status code as a tag
|
||||
// For now, just because users might expect it to land as a tag we keep sending it.
|
||||
// Same with data.
|
||||
// In v8, we replace both, simply with
|
||||
// span.setAttribute('http.response.status_code', httpStatus);
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
span.setTag('http.status_code', String(httpStatus));
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
span.setData('http.response.status_code', httpStatus);
|
||||
|
||||
const spanStatus = getSpanStatusFromHttpCode(httpStatus);
|
||||
if (spanStatus !== 'unknown_error') {
|
||||
span.setStatus(spanStatus);
|
||||
}
|
||||
}
|
||||
|
||||
export { SpanStatus, getSpanStatusFromHttpCode, setHttpStatus, spanStatusfromHttpCode };
|
||||
//# sourceMappingURL=spanstatus.js.map
|
||||
1
node_modules/@sentry/core/esm/tracing/spanstatus.js.map
generated
vendored
Normal file
1
node_modules/@sentry/core/esm/tracing/spanstatus.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
383
node_modules/@sentry/core/esm/tracing/trace.js
generated
vendored
Normal file
383
node_modules/@sentry/core/esm/tracing/trace.js
generated
vendored
Normal file
@@ -0,0 +1,383 @@
|
||||
import { tracingContextFromHeaders, logger, dropUndefinedKeys, addNonEnumerableProperty } from '@sentry/utils';
|
||||
import { DEBUG_BUILD } from '../debug-build.js';
|
||||
import { getCurrentHub, runWithAsyncContext, getIsolationScope } from '../hub.js';
|
||||
import { spanToJSON, spanIsSampled, spanTimeInputToSeconds } from '../utils/spanUtils.js';
|
||||
import './errors.js';
|
||||
import './spanstatus.js';
|
||||
import { getDynamicSamplingContextFromSpan } from './dynamicSamplingContext.js';
|
||||
import { getCurrentScope, withScope } from '../exports.js';
|
||||
import { handleCallbackErrors } from '../utils/handleCallbackErrors.js';
|
||||
import { hasTracingEnabled } from '../utils/hasTracingEnabled.js';
|
||||
|
||||
/**
|
||||
* Wraps a function with a transaction/span and finishes the span after the function is done.
|
||||
*
|
||||
* Note that if you have not enabled tracing extensions via `addTracingExtensions`
|
||||
* or you didn't set `tracesSampleRate`, this function will not generate spans
|
||||
* and the `span` returned from the callback will be undefined.
|
||||
*
|
||||
* This function is meant to be used internally and may break at any time. Use at your own risk.
|
||||
*
|
||||
* @internal
|
||||
* @private
|
||||
*
|
||||
* @deprecated Use `startSpan` instead.
|
||||
*/
|
||||
function trace(
|
||||
context,
|
||||
callback,
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
onError = () => {},
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
afterFinish = () => {},
|
||||
) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const hub = getCurrentHub();
|
||||
const scope = getCurrentScope();
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const parentSpan = scope.getSpan();
|
||||
|
||||
const spanContext = normalizeContext(context);
|
||||
const activeSpan = createChildSpanOrTransaction(hub, {
|
||||
parentSpan,
|
||||
spanContext,
|
||||
forceTransaction: false,
|
||||
scope,
|
||||
});
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
scope.setSpan(activeSpan);
|
||||
|
||||
return handleCallbackErrors(
|
||||
() => callback(activeSpan),
|
||||
error => {
|
||||
activeSpan && activeSpan.setStatus('internal_error');
|
||||
onError(error, activeSpan);
|
||||
},
|
||||
() => {
|
||||
activeSpan && activeSpan.end();
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
scope.setSpan(parentSpan);
|
||||
afterFinish();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a function with a transaction/span and finishes the span after the function is done.
|
||||
* The created span is the active span and will be used as parent by other spans created inside the function
|
||||
* and can be accessed via `Sentry.getSpan()`, as long as the function is executed while the scope is active.
|
||||
*
|
||||
* If you want to create a span that is not set as active, use {@link startInactiveSpan}.
|
||||
*
|
||||
* Note that if you have not enabled tracing extensions via `addTracingExtensions`
|
||||
* or you didn't set `tracesSampleRate`, this function will not generate spans
|
||||
* and the `span` returned from the callback will be undefined.
|
||||
*/
|
||||
function startSpan(context, callback) {
|
||||
const spanContext = normalizeContext(context);
|
||||
|
||||
return runWithAsyncContext(() => {
|
||||
return withScope(context.scope, scope => {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const hub = getCurrentHub();
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const parentSpan = scope.getSpan();
|
||||
|
||||
const shouldSkipSpan = context.onlyIfParent && !parentSpan;
|
||||
const activeSpan = shouldSkipSpan
|
||||
? undefined
|
||||
: createChildSpanOrTransaction(hub, {
|
||||
parentSpan,
|
||||
spanContext,
|
||||
forceTransaction: context.forceTransaction,
|
||||
scope,
|
||||
});
|
||||
|
||||
return handleCallbackErrors(
|
||||
() => callback(activeSpan),
|
||||
() => {
|
||||
// Only update the span status if it hasn't been changed yet
|
||||
if (activeSpan) {
|
||||
const { status } = spanToJSON(activeSpan);
|
||||
if (!status || status === 'ok') {
|
||||
activeSpan.setStatus('internal_error');
|
||||
}
|
||||
}
|
||||
},
|
||||
() => activeSpan && activeSpan.end(),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link startSpan} instead.
|
||||
*/
|
||||
const startActiveSpan = startSpan;
|
||||
|
||||
/**
|
||||
* Similar to `Sentry.startSpan`. Wraps a function with a transaction/span, but does not finish the span
|
||||
* after the function is done automatically. You'll have to call `span.end()` manually.
|
||||
*
|
||||
* The created span is the active span and will be used as parent by other spans created inside the function
|
||||
* and can be accessed via `Sentry.getActiveSpan()`, as long as the function is executed while the scope is active.
|
||||
*
|
||||
* Note that if you have not enabled tracing extensions via `addTracingExtensions`
|
||||
* or you didn't set `tracesSampleRate`, this function will not generate spans
|
||||
* and the `span` returned from the callback will be undefined.
|
||||
*/
|
||||
function startSpanManual(
|
||||
context,
|
||||
callback,
|
||||
) {
|
||||
const spanContext = normalizeContext(context);
|
||||
|
||||
return runWithAsyncContext(() => {
|
||||
return withScope(context.scope, scope => {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const hub = getCurrentHub();
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const parentSpan = scope.getSpan();
|
||||
|
||||
const shouldSkipSpan = context.onlyIfParent && !parentSpan;
|
||||
const activeSpan = shouldSkipSpan
|
||||
? undefined
|
||||
: createChildSpanOrTransaction(hub, {
|
||||
parentSpan,
|
||||
spanContext,
|
||||
forceTransaction: context.forceTransaction,
|
||||
scope,
|
||||
});
|
||||
|
||||
function finishAndSetSpan() {
|
||||
activeSpan && activeSpan.end();
|
||||
}
|
||||
|
||||
return handleCallbackErrors(
|
||||
() => callback(activeSpan, finishAndSetSpan),
|
||||
() => {
|
||||
// Only update the span status if it hasn't been changed yet, and the span is not yet finished
|
||||
if (activeSpan && activeSpan.isRecording()) {
|
||||
const { status } = spanToJSON(activeSpan);
|
||||
if (!status || status === 'ok') {
|
||||
activeSpan.setStatus('internal_error');
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a span. This span is not set as active, so will not get automatic instrumentation spans
|
||||
* as children or be able to be accessed via `Sentry.getSpan()`.
|
||||
*
|
||||
* If you want to create a span that is set as active, use {@link startSpan}.
|
||||
*
|
||||
* Note that if you have not enabled tracing extensions via `addTracingExtensions`
|
||||
* or you didn't set `tracesSampleRate` or `tracesSampler`, this function will not generate spans
|
||||
* and the `span` returned from the callback will be undefined.
|
||||
*/
|
||||
function startInactiveSpan(context) {
|
||||
if (!hasTracingEnabled()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const spanContext = normalizeContext(context);
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const hub = getCurrentHub();
|
||||
const parentSpan = context.scope
|
||||
? // eslint-disable-next-line deprecation/deprecation
|
||||
context.scope.getSpan()
|
||||
: getActiveSpan();
|
||||
|
||||
const shouldSkipSpan = context.onlyIfParent && !parentSpan;
|
||||
|
||||
if (shouldSkipSpan) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const scope = context.scope || getCurrentScope();
|
||||
|
||||
// Even though we don't actually want to make this span active on the current scope,
|
||||
// we need to make it active on a temporary scope that we use for event processing
|
||||
// as otherwise, it won't pick the correct span for the event when processing it
|
||||
const temporaryScope = (scope ).clone();
|
||||
|
||||
return createChildSpanOrTransaction(hub, {
|
||||
parentSpan,
|
||||
spanContext,
|
||||
forceTransaction: context.forceTransaction,
|
||||
scope: temporaryScope,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently active span.
|
||||
*/
|
||||
function getActiveSpan() {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
return getCurrentScope().getSpan();
|
||||
}
|
||||
|
||||
const continueTrace = (
|
||||
{
|
||||
sentryTrace,
|
||||
baggage,
|
||||
}
|
||||
|
||||
,
|
||||
callback,
|
||||
) => {
|
||||
// TODO(v8): Change this function so it doesn't do anything besides setting the propagation context on the current scope:
|
||||
/*
|
||||
return withScope((scope) => {
|
||||
const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);
|
||||
scope.setPropagationContext(propagationContext);
|
||||
return callback();
|
||||
})
|
||||
*/
|
||||
|
||||
const currentScope = getCurrentScope();
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
|
||||
sentryTrace,
|
||||
baggage,
|
||||
);
|
||||
|
||||
currentScope.setPropagationContext(propagationContext);
|
||||
|
||||
if (DEBUG_BUILD && traceparentData) {
|
||||
logger.log(`[Tracing] Continuing trace ${traceparentData.traceId}.`);
|
||||
}
|
||||
|
||||
const transactionContext = {
|
||||
...traceparentData,
|
||||
metadata: dropUndefinedKeys({
|
||||
dynamicSamplingContext,
|
||||
}),
|
||||
};
|
||||
|
||||
if (!callback) {
|
||||
return transactionContext;
|
||||
}
|
||||
|
||||
return runWithAsyncContext(() => {
|
||||
return callback(transactionContext);
|
||||
});
|
||||
};
|
||||
|
||||
function createChildSpanOrTransaction(
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
hub,
|
||||
{
|
||||
parentSpan,
|
||||
spanContext,
|
||||
forceTransaction,
|
||||
scope,
|
||||
}
|
||||
|
||||
,
|
||||
) {
|
||||
if (!hasTracingEnabled()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const isolationScope = getIsolationScope();
|
||||
|
||||
let span;
|
||||
if (parentSpan && !forceTransaction) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
span = parentSpan.startChild(spanContext);
|
||||
} else if (parentSpan) {
|
||||
// If we forced a transaction but have a parent span, make sure to continue from the parent span, not the scope
|
||||
const dsc = getDynamicSamplingContextFromSpan(parentSpan);
|
||||
const { traceId, spanId: parentSpanId } = parentSpan.spanContext();
|
||||
const sampled = spanIsSampled(parentSpan);
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
span = hub.startTransaction({
|
||||
traceId,
|
||||
parentSpanId,
|
||||
parentSampled: sampled,
|
||||
...spanContext,
|
||||
metadata: {
|
||||
dynamicSamplingContext: dsc,
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
...spanContext.metadata,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const { traceId, dsc, parentSpanId, sampled } = {
|
||||
...isolationScope.getPropagationContext(),
|
||||
...scope.getPropagationContext(),
|
||||
};
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
span = hub.startTransaction({
|
||||
traceId,
|
||||
parentSpanId,
|
||||
parentSampled: sampled,
|
||||
...spanContext,
|
||||
metadata: {
|
||||
dynamicSamplingContext: dsc,
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
...spanContext.metadata,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// We always set this as active span on the scope
|
||||
// In the case of this being an inactive span, we ensure to pass a detached scope in here in the first place
|
||||
// But by having this here, we can ensure that the lookup through `getCapturedScopesOnSpan` results in the correct scope & span combo
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
scope.setSpan(span);
|
||||
|
||||
setCapturedScopesOnSpan(span, scope, isolationScope);
|
||||
|
||||
return span;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (context.startTime) {
|
||||
const ctx = { ...context };
|
||||
ctx.startTimestamp = spanTimeInputToSeconds(context.startTime);
|
||||
delete ctx.startTime;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
const SCOPE_ON_START_SPAN_FIELD = '_sentryScope';
|
||||
const ISOLATION_SCOPE_ON_START_SPAN_FIELD = '_sentryIsolationScope';
|
||||
|
||||
function setCapturedScopesOnSpan(span, scope, isolationScope) {
|
||||
if (span) {
|
||||
addNonEnumerableProperty(span, ISOLATION_SCOPE_ON_START_SPAN_FIELD, isolationScope);
|
||||
addNonEnumerableProperty(span, SCOPE_ON_START_SPAN_FIELD, scope);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the scope and isolation scope off a span that were active when the span was started.
|
||||
*/
|
||||
function getCapturedScopesOnSpan(span) {
|
||||
return {
|
||||
scope: (span )[SCOPE_ON_START_SPAN_FIELD],
|
||||
isolationScope: (span )[ISOLATION_SCOPE_ON_START_SPAN_FIELD],
|
||||
};
|
||||
}
|
||||
|
||||
export { continueTrace, getActiveSpan, getCapturedScopesOnSpan, startActiveSpan, startInactiveSpan, startSpan, startSpanManual, trace };
|
||||
//# sourceMappingURL=trace.js.map
|
||||
1
node_modules/@sentry/core/esm/tracing/trace.js.map
generated
vendored
Normal file
1
node_modules/@sentry/core/esm/tracing/trace.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
350
node_modules/@sentry/core/esm/tracing/transaction.js
generated
vendored
Normal file
350
node_modules/@sentry/core/esm/tracing/transaction.js
generated
vendored
Normal file
@@ -0,0 +1,350 @@
|
||||
import { dropUndefinedKeys, logger } from '@sentry/utils';
|
||||
import { DEBUG_BUILD } from '../debug-build.js';
|
||||
import { getCurrentHub } from '../hub.js';
|
||||
import { getMetricSummaryJsonForSpan } from '../metrics/metric-summary.js';
|
||||
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE } from '../semanticAttributes.js';
|
||||
import { spanTimeInputToSeconds, spanToJSON, spanToTraceContext } from '../utils/spanUtils.js';
|
||||
import { getDynamicSamplingContextFromSpan } from './dynamicSamplingContext.js';
|
||||
import { Span, SpanRecorder } from './span.js';
|
||||
import { getCapturedScopesOnSpan } from './trace.js';
|
||||
|
||||
/** JSDoc */
|
||||
class Transaction extends Span {
|
||||
/**
|
||||
* The reference to the current hub.
|
||||
*/
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
|
||||
// DO NOT yet remove this property, it is used in a hack for v7 backwards compatibility.
|
||||
|
||||
/**
|
||||
* This constructor should never be called manually. Those instrumenting tracing should use
|
||||
* `Sentry.startTransaction()`, and internal methods should use `hub.startTransaction()`.
|
||||
* @internal
|
||||
* @hideconstructor
|
||||
* @hidden
|
||||
*
|
||||
* @deprecated Transactions will be removed in v8. Use spans instead.
|
||||
*/
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
constructor(transactionContext, hub) {
|
||||
super(transactionContext);
|
||||
this._contexts = {};
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this._hub = hub || getCurrentHub();
|
||||
|
||||
this._name = transactionContext.name || '';
|
||||
|
||||
this._metadata = {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
...transactionContext.metadata,
|
||||
};
|
||||
|
||||
this._trimEnd = transactionContext.trimEnd;
|
||||
|
||||
// this is because transactions are also spans, and spans have a transaction pointer
|
||||
// TODO (v8): Replace this with another way to set the root span
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.transaction = this;
|
||||
|
||||
// If Dynamic Sampling Context is provided during the creation of the transaction, we freeze it as it usually means
|
||||
// there is incoming Dynamic Sampling Context. (Either through an incoming request, a baggage meta-tag, or other means)
|
||||
const incomingDynamicSamplingContext = this._metadata.dynamicSamplingContext;
|
||||
if (incomingDynamicSamplingContext) {
|
||||
// We shallow copy this in case anything writes to the original reference of the passed in `dynamicSamplingContext`
|
||||
this._frozenDynamicSamplingContext = { ...incomingDynamicSamplingContext };
|
||||
}
|
||||
}
|
||||
|
||||
// This sadly conflicts with the getter/setter ordering :(
|
||||
/* eslint-disable @typescript-eslint/member-ordering */
|
||||
|
||||
/**
|
||||
* Getter for `name` property.
|
||||
* @deprecated Use `spanToJSON(span).description` instead.
|
||||
*/
|
||||
get name() {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for `name` property, which also sets `source` as custom.
|
||||
* @deprecated Use `updateName()` and `setMetadata()` instead.
|
||||
*/
|
||||
set name(newName) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.setName(newName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the metadata for this transaction.
|
||||
* @deprecated Use `spanGetMetadata(transaction)` instead.
|
||||
*/
|
||||
get metadata() {
|
||||
// We merge attributes in for backwards compatibility
|
||||
return {
|
||||
// Defaults
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
source: 'custom',
|
||||
spanMetadata: {},
|
||||
|
||||
// Legacy metadata
|
||||
...this._metadata,
|
||||
|
||||
// From attributes
|
||||
...(this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] && {
|
||||
source: this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] ,
|
||||
}),
|
||||
...(this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE] && {
|
||||
sampleRate: this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE] ,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the metadata for this transaction.
|
||||
* @deprecated Use `spanGetMetadata(transaction)` instead.
|
||||
*/
|
||||
set metadata(metadata) {
|
||||
this._metadata = metadata;
|
||||
}
|
||||
|
||||
/* eslint-enable @typescript-eslint/member-ordering */
|
||||
|
||||
/**
|
||||
* Setter for `name` property, which also sets `source` on the metadata.
|
||||
*
|
||||
* @deprecated Use `.updateName()` and `.setAttribute()` instead.
|
||||
*/
|
||||
setName(name, source = 'custom') {
|
||||
this._name = name;
|
||||
this.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
updateName(name) {
|
||||
this._name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches SpanRecorder to the span itself
|
||||
* @param maxlen maximum number of spans that can be recorded
|
||||
*/
|
||||
initSpanRecorder(maxlen = 1000) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
if (!this.spanRecorder) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.spanRecorder = new SpanRecorder(maxlen);
|
||||
}
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
this.spanRecorder.add(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the context of a transaction event.
|
||||
* @deprecated Use either `.setAttribute()`, or set the context on the scope before creating the transaction.
|
||||
*/
|
||||
setContext(key, context) {
|
||||
if (context === null) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
delete this._contexts[key];
|
||||
} else {
|
||||
this._contexts[key] = context;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @deprecated Use top-level `setMeasurement()` instead.
|
||||
*/
|
||||
setMeasurement(name, value, unit = '') {
|
||||
this._measurements[name] = { value, unit };
|
||||
}
|
||||
|
||||
/**
|
||||
* Store metadata on this transaction.
|
||||
* @deprecated Use attributes or store data on the scope instead.
|
||||
*/
|
||||
setMetadata(newMetadata) {
|
||||
this._metadata = { ...this._metadata, ...newMetadata };
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
end(endTimestamp) {
|
||||
const timestampInS = spanTimeInputToSeconds(endTimestamp);
|
||||
const transaction = this._finishTransaction(timestampInS);
|
||||
if (!transaction) {
|
||||
return undefined;
|
||||
}
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
return this._hub.captureEvent(transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
toContext() {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const spanContext = super.toContext();
|
||||
|
||||
return dropUndefinedKeys({
|
||||
...spanContext,
|
||||
name: this._name,
|
||||
trimEnd: this._trimEnd,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
updateWithContext(transactionContext) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
super.updateWithContext(transactionContext);
|
||||
|
||||
this._name = transactionContext.name || '';
|
||||
this._trimEnd = transactionContext.trimEnd;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @experimental
|
||||
*
|
||||
* @deprecated Use top-level `getDynamicSamplingContextFromSpan` instead.
|
||||
*/
|
||||
getDynamicSamplingContext() {
|
||||
return getDynamicSamplingContextFromSpan(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the current hub with a new one.
|
||||
* Used if you want another hub to finish the transaction.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
setHub(hub) {
|
||||
this._hub = hub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the profile id of the transaction.
|
||||
*/
|
||||
getProfileId() {
|
||||
if (this._contexts !== undefined && this._contexts['profile'] !== undefined) {
|
||||
return this._contexts['profile'].profile_id ;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish the transaction & prepare the event to send to Sentry.
|
||||
*/
|
||||
_finishTransaction(endTimestamp) {
|
||||
// This transaction is already finished, so we should not flush it again.
|
||||
if (this._endTime !== undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!this._name) {
|
||||
DEBUG_BUILD && logger.warn('Transaction has no name, falling back to `<unlabeled transaction>`.');
|
||||
this._name = '<unlabeled transaction>';
|
||||
}
|
||||
|
||||
// just sets the end timestamp
|
||||
super.end(endTimestamp);
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const client = this._hub.getClient();
|
||||
if (client && client.emit) {
|
||||
client.emit('finishTransaction', this);
|
||||
}
|
||||
|
||||
if (this._sampled !== true) {
|
||||
// At this point if `sampled !== true` we want to discard the transaction.
|
||||
DEBUG_BUILD && logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.');
|
||||
|
||||
if (client) {
|
||||
client.recordDroppedEvent('sample_rate', 'transaction');
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const finishedSpans = this.spanRecorder
|
||||
? // eslint-disable-next-line deprecation/deprecation
|
||||
this.spanRecorder.spans.filter(span => span !== this && spanToJSON(span).timestamp)
|
||||
: [];
|
||||
|
||||
if (this._trimEnd && finishedSpans.length > 0) {
|
||||
const endTimes = finishedSpans.map(span => spanToJSON(span).timestamp).filter(Boolean) ;
|
||||
this._endTime = endTimes.reduce((prev, current) => {
|
||||
return prev > current ? prev : current;
|
||||
});
|
||||
}
|
||||
|
||||
const { scope: capturedSpanScope, isolationScope: capturedSpanIsolationScope } = getCapturedScopesOnSpan(this);
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const { metadata } = this;
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const { source } = metadata;
|
||||
|
||||
const transaction = {
|
||||
contexts: {
|
||||
...this._contexts,
|
||||
// We don't want to override trace context
|
||||
trace: spanToTraceContext(this),
|
||||
},
|
||||
// TODO: Pass spans serialized via `spanToJSON()` here instead in v8.
|
||||
spans: finishedSpans,
|
||||
start_timestamp: this._startTime,
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
tags: this.tags,
|
||||
timestamp: this._endTime,
|
||||
transaction: this._name,
|
||||
type: 'transaction',
|
||||
sdkProcessingMetadata: {
|
||||
...metadata,
|
||||
capturedSpanScope,
|
||||
capturedSpanIsolationScope,
|
||||
...dropUndefinedKeys({
|
||||
dynamicSamplingContext: getDynamicSamplingContextFromSpan(this),
|
||||
}),
|
||||
},
|
||||
_metrics_summary: getMetricSummaryJsonForSpan(this),
|
||||
...(source && {
|
||||
transaction_info: {
|
||||
source,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
const hasMeasurements = Object.keys(this._measurements).length > 0;
|
||||
|
||||
if (hasMeasurements) {
|
||||
DEBUG_BUILD &&
|
||||
logger.log(
|
||||
'[Measurements] Adding measurements to transaction',
|
||||
JSON.stringify(this._measurements, undefined, 2),
|
||||
);
|
||||
transaction.measurements = this._measurements;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
DEBUG_BUILD && logger.log(`[Tracing] Finishing ${this.op} transaction: ${this._name}.`);
|
||||
|
||||
return transaction;
|
||||
}
|
||||
}
|
||||
|
||||
export { Transaction };
|
||||
//# sourceMappingURL=transaction.js.map
|
||||
1
node_modules/@sentry/core/esm/tracing/transaction.js.map
generated
vendored
Normal file
1
node_modules/@sentry/core/esm/tracing/transaction.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
35
node_modules/@sentry/core/esm/tracing/utils.js
generated
vendored
Normal file
35
node_modules/@sentry/core/esm/tracing/utils.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
import { extractTraceparentData as extractTraceparentData$1 } from '@sentry/utils';
|
||||
export { stripUrlQueryAndFragment } from '@sentry/utils';
|
||||
import { getCurrentHub } from '../hub.js';
|
||||
|
||||
/**
|
||||
* Grabs active transaction off scope.
|
||||
*
|
||||
* @deprecated You should not rely on the transaction, but just use `startSpan()` APIs instead.
|
||||
*/
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
function getActiveTransaction(maybeHub) {
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const hub = maybeHub || getCurrentHub();
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
const scope = hub.getScope();
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
return scope.getTransaction() ;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `extractTraceparentData` function and `TRACEPARENT_REGEXP` constant used
|
||||
* to be declared in this file. It was later moved into `@sentry/utils` as part of a
|
||||
* move to remove `@sentry/tracing` dependencies from `@sentry/node` (`extractTraceparentData`
|
||||
* is the only tracing function used by `@sentry/node`).
|
||||
*
|
||||
* These exports are kept here for backwards compatability's sake.
|
||||
*
|
||||
* See https://github.com/getsentry/sentry-javascript/issues/4642 for more details.
|
||||
*
|
||||
* @deprecated Import this function from `@sentry/utils` instead
|
||||
*/
|
||||
const extractTraceparentData = extractTraceparentData$1;
|
||||
|
||||
export { extractTraceparentData, getActiveTransaction };
|
||||
//# sourceMappingURL=utils.js.map
|
||||
1
node_modules/@sentry/core/esm/tracing/utils.js.map
generated
vendored
Normal file
1
node_modules/@sentry/core/esm/tracing/utils.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.js","sources":["../../../src/tracing/utils.ts"],"sourcesContent":["import type { Transaction } from '@sentry/types';\nimport { extractTraceparentData as _extractTraceparentData } from '@sentry/utils';\n\nimport type { Hub } from '../hub';\nimport { getCurrentHub } from '../hub';\n\n/**\n * Grabs active transaction off scope.\n *\n * @deprecated You should not rely on the transaction, but just use `startSpan()` APIs instead.\n */\n// eslint-disable-next-line deprecation/deprecation\nexport function getActiveTransaction<T extends Transaction>(maybeHub?: Hub): T | undefined {\n // eslint-disable-next-line deprecation/deprecation\n const hub = maybeHub || getCurrentHub();\n // eslint-disable-next-line deprecation/deprecation\n const scope = hub.getScope();\n // eslint-disable-next-line deprecation/deprecation\n return scope.getTransaction() as T | undefined;\n}\n\n// so it can be used in manual instrumentation without necessitating a hard dependency on @sentry/utils\nexport { stripUrlQueryAndFragment } from '@sentry/utils';\n\n/**\n * The `extractTraceparentData` function and `TRACEPARENT_REGEXP` constant used\n * to be declared in this file. It was later moved into `@sentry/utils` as part of a\n * move to remove `@sentry/tracing` dependencies from `@sentry/node` (`extractTraceparentData`\n * is the only tracing function used by `@sentry/node`).\n *\n * These exports are kept here for backwards compatability's sake.\n *\n * See https://github.com/getsentry/sentry-javascript/issues/4642 for more details.\n *\n * @deprecated Import this function from `@sentry/utils` instead\n */\nexport const extractTraceparentData = _extractTraceparentData;\n"],"names":["_extractTraceparentData"],"mappings":";;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,oBAAoB,CAAwB,QAAQ,EAAuB;AAC3F;AACA,EAAE,MAAM,GAAI,GAAE,YAAY,aAAa,EAAE,CAAA;AACzC;AACA,EAAE,MAAM,KAAM,GAAE,GAAG,CAAC,QAAQ,EAAE,CAAA;AAC9B;AACA,EAAE,OAAO,KAAK,CAAC,cAAc,EAAG,EAAA;AAChC,CAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,sBAAuB,GAAEA;;;;"}
|
||||
Reference in New Issue
Block a user