@sentry/tracing
Advanced tools
Comparing version 6.13.0-beta.0 to 6.13.0-beta.1
import { Hub } from '@sentry/hub'; | ||
import { EventProcessor, Integration, Transaction, TransactionContext } from '@sentry/types'; | ||
import { MetricsInstrumentationOptions } from './metrics'; | ||
import { RequestInstrumentationOptions } from './request'; | ||
@@ -44,2 +45,10 @@ export declare const DEFAULT_MAX_TRANSACTION_DURATION_SECONDS = 600; | ||
/** | ||
* _metricOptions allows the user to send options to change how metrics are collected. | ||
* | ||
* _metricOptions is currently experimental. | ||
* | ||
* Default: undefined | ||
*/ | ||
_metricOptions?: Partial<MetricsInstrumentationOptions>; | ||
/** | ||
* beforeNavigate is called before a pageload/navigation transaction is created and allows users to modify transaction | ||
@@ -91,9 +100,9 @@ * context data, or drop the transaction entirely (by setting `sampled = false` in the context). | ||
/** | ||
* Gets transaction context data from `sentry-trace` and `tracestate` <meta> tags. | ||
* Gets transaction context from a sentry-trace meta. | ||
* | ||
* @returns Transaction context data or undefined neither tag exists or has valid data | ||
* @returns Transaction context data from the header or undefined if there's no header or the header is malformed | ||
*/ | ||
export declare function extractTraceDataFromMetaTags(): Partial<TransactionContext> | undefined; | ||
export declare function getHeaderContext(): Partial<TransactionContext> | undefined; | ||
/** Returns the value of a meta tag */ | ||
export declare function getMetaContent(metaName: string): string | null; | ||
//# sourceMappingURL=browsertracing.d.ts.map |
@@ -27,3 +27,2 @@ Object.defineProperty(exports, "__esModule", { value: true }); | ||
this.name = BrowserTracing.id; | ||
this._metrics = new metrics_1.MetricsInstrumentation(); | ||
this._emitOptionsWarning = false; | ||
@@ -42,2 +41,3 @@ var tracingOrigins = request_1.defaultRequestInstrumentationOptions.tracingOrigins; | ||
this.options = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, DEFAULT_BROWSER_TRACING_OPTIONS), _options), { tracingOrigins: tracingOrigins }); | ||
this._metrics = new metrics_1.MetricsInstrumentation(tslib_1.__assign(tslib_1.__assign({}, metrics_1.DEFAULT_METRICS_INSTR_OPTIONS), this.options._metricOptions)); | ||
} | ||
@@ -71,3 +71,3 @@ /** | ||
var _a = this.options, beforeNavigate = _a.beforeNavigate, idleTimeout = _a.idleTimeout, maxTransactionDuration = _a.maxTransactionDuration; | ||
var parentContextFromHeader = context.op === 'pageload' ? extractTraceDataFromMetaTags() : undefined; | ||
var parentContextFromHeader = context.op === 'pageload' ? getHeaderContext() : undefined; | ||
var expandedContext = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, context), parentContextFromHeader), { trimEnd: true }); | ||
@@ -99,18 +99,14 @@ var modifiedContext = typeof beforeNavigate === 'function' ? beforeNavigate(expandedContext) : expandedContext; | ||
/** | ||
* Gets transaction context data from `sentry-trace` and `tracestate` <meta> tags. | ||
* Gets transaction context from a sentry-trace meta. | ||
* | ||
* @returns Transaction context data or undefined neither tag exists or has valid data | ||
* @returns Transaction context data from the header or undefined if there's no header or the header is malformed | ||
*/ | ||
function extractTraceDataFromMetaTags() { | ||
var _a, _b; | ||
var sentrytraceValue = getMetaContent('sentry-trace'); | ||
var tracestateValue = getMetaContent('tracestate'); | ||
var sentrytraceData = sentrytraceValue ? utils_2.extractSentrytraceData(sentrytraceValue) : undefined; | ||
var tracestateData = tracestateValue ? utils_2.extractTracestateData(tracestateValue) : undefined; | ||
if (sentrytraceData || ((_a = tracestateData) === null || _a === void 0 ? void 0 : _a.sentry) || ((_b = tracestateData) === null || _b === void 0 ? void 0 : _b.thirdparty)) { | ||
return tslib_1.__assign(tslib_1.__assign({}, sentrytraceData), (tracestateData && { metadata: { tracestate: tracestateData } })); | ||
function getHeaderContext() { | ||
var header = getMetaContent('sentry-trace'); | ||
if (header) { | ||
return utils_2.extractTraceparentData(header); | ||
} | ||
return undefined; | ||
} | ||
exports.extractTraceDataFromMetaTags = extractTraceDataFromMetaTags; | ||
exports.getHeaderContext = getHeaderContext; | ||
/** Returns the value of a meta tag */ | ||
@@ -117,0 +113,0 @@ function getMetaContent(metaName) { |
import { SpanContext } from '@sentry/types'; | ||
import { Span } from '../span'; | ||
import { Transaction } from '../transaction'; | ||
/** | ||
* Exports a way to add options to our metric collection. Currently experimental. | ||
*/ | ||
export interface MetricsInstrumentationOptions { | ||
_reportAllChanges: boolean; | ||
} | ||
export declare const DEFAULT_METRICS_INSTR_OPTIONS: MetricsInstrumentationOptions; | ||
/** Class tracking metrics */ | ||
@@ -10,3 +17,3 @@ export declare class MetricsInstrumentation { | ||
private _clsEntry; | ||
constructor(); | ||
constructor(_options: MetricsInstrumentationOptions); | ||
/** Add performance related spans to a transaction */ | ||
@@ -13,0 +20,0 @@ addPerformanceEntries(transaction: Transaction): void; |
@@ -10,5 +10,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); | ||
var global = utils_1.getGlobalObject(); | ||
exports.DEFAULT_METRICS_INSTR_OPTIONS = { | ||
_reportAllChanges: false, | ||
}; | ||
/** Class tracking metrics */ | ||
var MetricsInstrumentation = /** @class */ (function () { | ||
function MetricsInstrumentation() { | ||
function MetricsInstrumentation(_options) { | ||
var _a, _b; | ||
@@ -22,3 +25,3 @@ this._measurements = {}; | ||
this._trackCLS(); | ||
this._trackLCP(); | ||
this._trackLCP(_options._reportAllChanges); | ||
this._trackFID(); | ||
@@ -236,3 +239,3 @@ } | ||
/** Starts tracking the Largest Contentful Paint on the current page. */ | ||
MetricsInstrumentation.prototype._trackLCP = function () { | ||
MetricsInstrumentation.prototype._trackLCP = function (reportAllChanges) { | ||
var _this = this; | ||
@@ -250,3 +253,3 @@ getLCP_1.getLCP(function (metric) { | ||
_this._lcpEntry = entry; | ||
}); | ||
}, reportAllChanges); | ||
}; | ||
@@ -253,0 +256,0 @@ /** Starts tracking the First Input Delay on the current page. */ |
@@ -1,2 +0,2 @@ | ||
import { Span } from '@sentry/types'; | ||
import { Span } from '../span'; | ||
export declare const DEFAULT_TRACING_ORIGINS: (string | RegExp)[]; | ||
@@ -3,0 +3,0 @@ /** Options for Request Instrumentation */ |
@@ -96,21 +96,17 @@ Object.defineProperty(exports, "__esModule", { value: true }); | ||
} | ||
var traceHeaders = span.getTraceHeaders(); | ||
if (headers) { | ||
if ('append' in headers && typeof headers.append === 'function') { | ||
headers.append('sentry-trace', traceHeaders['sentry-trace']); | ||
if (traceHeaders.tracestate) { | ||
headers.append('tracestate', traceHeaders.tracestate); | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
if (typeof headers.append === 'function') { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
headers.append('sentry-trace', span.toTraceparent()); | ||
} | ||
else if (Array.isArray(headers)) { | ||
// TODO use the nicer version below once we stop supporting Node 6 | ||
// headers = [...headers, ...Object.entries(traceHeaders)]; | ||
headers = tslib_1.__spread(headers, [['sentry-trace', traceHeaders['sentry-trace']], ['tracestate', traceHeaders.tracestate]]); | ||
headers = tslib_1.__spread(headers, [['sentry-trace', span.toTraceparent()]]); | ||
} | ||
else { | ||
headers = tslib_1.__assign(tslib_1.__assign({}, headers), traceHeaders); | ||
headers = tslib_1.__assign(tslib_1.__assign({}, headers), { 'sentry-trace': span.toTraceparent() }); | ||
} | ||
} | ||
else { | ||
headers = traceHeaders; | ||
headers = { 'sentry-trace': span.toTraceparent() }; | ||
} | ||
@@ -154,7 +150,3 @@ options.headers = headers; | ||
try { | ||
var sentryHeaders = span.getTraceHeaders(); | ||
handlerData.xhr.setRequestHeader('sentry-trace', sentryHeaders['sentry-trace']); | ||
if (sentryHeaders.tracestate) { | ||
handlerData.xhr.setRequestHeader('tracestate', sentryHeaders.tracestate); | ||
} | ||
handlerData.xhr.setRequestHeader('sentry-trace', span.toTraceparent()); | ||
} | ||
@@ -161,0 +153,0 @@ catch (_) { |
@@ -10,2 +10,15 @@ Object.defineProperty(exports, "__esModule", { value: true }); | ||
var utils_2 = require("./utils"); | ||
/** Returns all trace headers that are currently on the top scope. */ | ||
function traceHeaders() { | ||
var scope = this.getScope(); | ||
if (scope) { | ||
var span = scope.getSpan(); | ||
if (span) { | ||
return { | ||
'sentry-trace': span.toTraceparent(), | ||
}; | ||
} | ||
} | ||
return {}; | ||
} | ||
/** | ||
@@ -159,2 +172,5 @@ * Makes a sampling decision for the given transaction and stores it on the transaction. | ||
} | ||
if (!carrier.__SENTRY__.extensions.traceHeaders) { | ||
carrier.__SENTRY__.extensions.traceHeaders = traceHeaders; | ||
} | ||
} | ||
@@ -161,0 +177,0 @@ exports._addTracingExtensions = _addTracingExtensions; |
@@ -19,3 +19,3 @@ import { BrowserTracing } from './browser'; | ||
export { addExtensionMethods }; | ||
export { extractSentrytraceData, extractTracestateData, getActiveTransaction, hasTracingEnabled, SENTRY_TRACE_REGEX, stripUrlQueryAndFragment, } from './utils'; | ||
export { extractTraceparentData, getActiveTransaction, hasTracingEnabled, stripUrlQueryAndFragment, TRACEPARENT_REGEXP, } from './utils'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -26,8 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); | ||
var utils_1 = require("./utils"); | ||
exports.extractSentrytraceData = utils_1.extractSentrytraceData; | ||
exports.extractTracestateData = utils_1.extractTracestateData; | ||
exports.extractTraceparentData = utils_1.extractTraceparentData; | ||
exports.getActiveTransaction = utils_1.getActiveTransaction; | ||
exports.hasTracingEnabled = utils_1.hasTracingEnabled; | ||
exports.SENTRY_TRACE_REGEX = utils_1.SENTRY_TRACE_REGEX; | ||
exports.stripUrlQueryAndFragment = utils_1.stripUrlQueryAndFragment; | ||
exports.TRACEPARENT_REGEXP = utils_1.TRACEPARENT_REGEXP; | ||
//# sourceMappingURL=index.js.map |
@@ -1,5 +0,5 @@ | ||
export { Express } from './express'; | ||
export { Postgres } from './postgres'; | ||
export { Mysql } from './mysql'; | ||
export { Mongo } from './mongo'; | ||
export { Express } from './node/express'; | ||
export { Postgres } from './node/postgres'; | ||
export { Mysql } from './node/mysql'; | ||
export { Mongo } from './node/mongo'; | ||
//# sourceMappingURL=index.d.ts.map |
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var express_1 = require("./express"); | ||
var express_1 = require("./node/express"); | ||
exports.Express = express_1.Express; | ||
var postgres_1 = require("./postgres"); | ||
var postgres_1 = require("./node/postgres"); | ||
exports.Postgres = postgres_1.Postgres; | ||
var mysql_1 = require("./mysql"); | ||
var mysql_1 = require("./node/mysql"); | ||
exports.Mysql = mysql_1.Mysql; | ||
var mongo_1 = require("./mongo"); | ||
var mongo_1 = require("./node/mongo"); | ||
exports.Mongo = mongo_1.Mongo; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
import { Primitive, Span as SpanInterface, SpanContext, TraceHeaders, Transaction } from '@sentry/types'; | ||
import { Primitive, Span as SpanInterface, SpanContext, Transaction } from '@sentry/types'; | ||
import { SpanStatus } from './spanstatus'; | ||
@@ -137,6 +137,2 @@ /** | ||
*/ | ||
getTraceHeaders(): TraceHeaders; | ||
/** | ||
* @inheritDoc | ||
*/ | ||
getTraceContext(): { | ||
@@ -175,18 +171,3 @@ data?: { | ||
}; | ||
/** | ||
* Create a new Sentry tracestate header entry (i.e. `sentry=xxxxxx`) | ||
* | ||
* @returns The new Sentry tracestate entry, or undefined if there's no client or no dsn | ||
*/ | ||
protected _getNewTracestate(): string | undefined; | ||
/** | ||
* Return a traceparent-compatible header string. | ||
*/ | ||
private _toSentrytrace; | ||
/** | ||
* Return a tracestate-compatible header string, including both sentry and third-party data (if any). Returns | ||
* undefined if there is no client or no DSN. | ||
*/ | ||
private _toTracestate; | ||
} | ||
//# sourceMappingURL=span.d.ts.map |
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
/* eslint-disable max-lines */ | ||
var hub_1 = require("@sentry/hub"); | ||
var utils_1 = require("@sentry/utils"); | ||
var spanstatus_1 = require("./spanstatus"); | ||
var utils_2 = require("./utils"); | ||
/** | ||
@@ -82,3 +79,3 @@ * Keeps track of finished spans for a given transaction | ||
} | ||
// check this way instead of the normal way to make sure we don't miss cases where sampled = false | ||
// We want to include booleans as well here | ||
if ('sampled' in spanContext) { | ||
@@ -179,4 +176,7 @@ this.sampled = spanContext.sampled; | ||
Span.prototype.toTraceparent = function () { | ||
utils_1.logger.warn('Direct use of `span.toTraceparent` is deprecated. Use `span.getTraceHeaders` instead.'); | ||
return this._toSentrytrace(); | ||
var sampledString = ''; | ||
if (this.sampled !== undefined) { | ||
sampledString = this.sampled ? '-1' : '-0'; | ||
} | ||
return this.traceId + "-" + this.spanId + sampledString; | ||
}; | ||
@@ -222,14 +222,2 @@ /** | ||
*/ | ||
Span.prototype.getTraceHeaders = function () { | ||
var _a, _b; | ||
// if this span is part of a transaction, but that transaction doesn't yet have a tracestate value, create one | ||
if (this.transaction && !((_b = (_a = this.transaction) === null || _a === void 0 ? void 0 : _a.metadata.tracestate) === null || _b === void 0 ? void 0 : _b.sentry)) { | ||
this.transaction.metadata.tracestate = tslib_1.__assign(tslib_1.__assign({}, this.transaction.metadata.tracestate), { sentry: this._getNewTracestate() }); | ||
} | ||
var tracestate = this._toTracestate(); | ||
return tslib_1.__assign({ 'sentry-trace': this._toSentrytrace() }, (tracestate && { tracestate: tracestate })); | ||
}; | ||
/** | ||
* @inheritDoc | ||
*/ | ||
Span.prototype.getTraceContext = function () { | ||
@@ -264,58 +252,2 @@ return utils_1.dropUndefinedKeys({ | ||
}; | ||
/** | ||
* Create a new Sentry tracestate header entry (i.e. `sentry=xxxxxx`) | ||
* | ||
* @returns The new Sentry tracestate entry, or undefined if there's no client or no dsn | ||
*/ | ||
Span.prototype._getNewTracestate = function () { | ||
var _a, _b, _c, _d; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any | ||
var hub = ((_a = this.transaction) === null || _a === void 0 ? void 0 : _a._hub) || hub_1.getCurrentHub(); | ||
var client = hub.getClient(); | ||
var _e = ((_b = hub.getScope()) === null || _b === void 0 ? void 0 : _b.getUser()) || {}, userId = _e.id, userSegment = _e.segment; | ||
var dsn = (_c = client) === null || _c === void 0 ? void 0 : _c.getDsn(); | ||
if (!client || !dsn) { | ||
return; | ||
} | ||
var _f = client.getOptions() || {}, environment = _f.environment, release = _f.release; | ||
// only define a `user` object if there's going to be something in it (note: prettier insists on removing the | ||
// parentheses, but since it's easy to misinterpret this, imagine `()` around `userId || userSegment`) | ||
var user = userId || userSegment ? { id: userId, segment: userSegment } : undefined; | ||
// TODO - the only reason we need the non-null assertion on `dsn.publicKey` (below) is because `dsn.publicKey` has | ||
// to be optional while we transition from `dsn.user` -> `dsn.publicKey`. Once `dsn.user` is removed, we can make | ||
// `dsn.publicKey` required and remove the `!`. | ||
return "sentry=" + utils_2.computeTracestateValue({ | ||
trace_id: this.traceId, | ||
environment: environment, | ||
release: release, | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
public_key: dsn.publicKey, | ||
user: user, | ||
transaction: (_d = this.transaction) === null || _d === void 0 ? void 0 : _d.name, | ||
}); | ||
}; | ||
/** | ||
* Return a traceparent-compatible header string. | ||
*/ | ||
Span.prototype._toSentrytrace = function () { | ||
var sampledString = ''; | ||
if (this.sampled !== undefined) { | ||
sampledString = this.sampled ? '-1' : '-0'; | ||
} | ||
return this.traceId + "-" + this.spanId + sampledString; | ||
}; | ||
/** | ||
* Return a tracestate-compatible header string, including both sentry and third-party data (if any). Returns | ||
* undefined if there is no client or no DSN. | ||
*/ | ||
Span.prototype._toTracestate = function () { | ||
var _a, _b, _c, _d, _e, _f; | ||
// if this is an orphan span, create a new tracestate value | ||
var sentryTracestate = ((_c = (_b = (_a = this.transaction) === null || _a === void 0 ? void 0 : _a.metadata) === null || _b === void 0 ? void 0 : _b.tracestate) === null || _c === void 0 ? void 0 : _c.sentry) || this._getNewTracestate(); | ||
var thirdpartyTracestate = (_f = (_e = (_d = this.transaction) === null || _d === void 0 ? void 0 : _d.metadata) === null || _e === void 0 ? void 0 : _e.tracestate) === null || _f === void 0 ? void 0 : _f.thirdparty; | ||
// if there's third-party data, add a leading comma; otherwise, convert from `undefined` to the empty string, so the | ||
// end result doesn’t come out as `sentry=xxxxxundefined` | ||
thirdpartyTracestate = thirdpartyTracestate ? "," + thirdpartyTracestate : ''; | ||
return "" + sentryTracestate + thirdpartyTracestate; | ||
}; | ||
return Span; | ||
@@ -322,0 +254,0 @@ }()); |
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var hub_1 = require("@sentry/hub"); | ||
var types_1 = require("@sentry/types"); | ||
var utils_1 = require("@sentry/utils"); | ||
@@ -19,9 +20,13 @@ var span_1 = require("./span"); | ||
_this._measurements = {}; | ||
/** | ||
* The reference to the current hub. | ||
*/ | ||
_this._hub = hub_1.getCurrentHub(); | ||
if (utils_1.isInstanceOf(hub, hub_1.Hub)) { | ||
_this._hub = hub; | ||
} | ||
_this.name = transactionContext.name || ''; | ||
_this.metadata = transactionContext.metadata || {}; | ||
_this._trimEnd = transactionContext.trimEnd; | ||
_this._hub = hub || hub_1.getCurrentHub(); | ||
// this is because transactions are also spans, and spans have a transaction pointer (it doesn't get set in `super` | ||
// because theoretically you can create a span without a transaction, though at the moment it doesn't do you much | ||
// good) | ||
// this is because transactions are also spans, and spans have a transaction pointer | ||
_this.transaction = _this; | ||
@@ -66,3 +71,3 @@ return _this; | ||
var _this = this; | ||
var _a; | ||
var _a, _b, _c; | ||
// This transaction is already finished, so we should not flush it again. | ||
@@ -81,2 +86,4 @@ if (this.endTimestamp !== undefined) { | ||
utils_1.logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.'); | ||
(_c = (_a = this._hub | ||
.getClient()) === null || _a === void 0 ? void 0 : (_b = _a.getTransport()).recordLostEvent) === null || _c === void 0 ? void 0 : _c.call(_b, types_1.Outcome.SampleRate, 'transaction'); | ||
return undefined; | ||
@@ -93,6 +100,2 @@ } | ||
} | ||
// ensure that we have a tracestate to attach to the envelope header | ||
if (!((_a = this.metadata.tracestate) === null || _a === void 0 ? void 0 : _a.sentry)) { | ||
this.metadata.tracestate = tslib_1.__assign(tslib_1.__assign({}, this.metadata.tracestate), { sentry: this._getNewTracestate() }); | ||
} | ||
var transaction = { | ||
@@ -99,0 +102,0 @@ contexts: { |
import { Hub } from '@sentry/hub'; | ||
import { Options, TraceparentData, Transaction } from '@sentry/types'; | ||
export declare const SENTRY_TRACE_REGEX: RegExp; | ||
export declare const TRACEPARENT_REGEXP: RegExp; | ||
/** | ||
@@ -13,17 +13,7 @@ * Determines if tracing is currently enabled. | ||
* | ||
* @param header Traceparent string | ||
* @param traceparent Traceparent string | ||
* | ||
* @returns Object containing data from the header, or undefined if traceparent string is malformed | ||
*/ | ||
export declare function extractSentrytraceData(header: string): TraceparentData | undefined; | ||
/** | ||
* Extract data from an incoming `tracestate` header | ||
* | ||
* @param header | ||
* @returns Object containing data from the header | ||
*/ | ||
export declare function extractTracestateData(header: string): { | ||
sentry?: string; | ||
thirdparty?: string; | ||
}; | ||
export declare function extractTraceparentData(traceparent: string): TraceparentData | undefined; | ||
/** Grabs active transaction off scope, if any */ | ||
@@ -42,20 +32,2 @@ export declare function getActiveTransaction<T extends Transaction>(hub?: Hub): T | undefined; | ||
export { stripUrlQueryAndFragment } from '@sentry/utils'; | ||
declare type SentryTracestateData = { | ||
trace_id: string; | ||
environment?: string; | ||
release?: string; | ||
public_key: string; | ||
user?: { | ||
id?: string; | ||
segment?: string; | ||
}; | ||
transaction?: string; | ||
}; | ||
/** | ||
* Compute the value of a Sentry tracestate header. | ||
* | ||
* @throws SentryError (because using the logger creates a circular dependency) | ||
* @returns the base64-encoded header value | ||
*/ | ||
export declare function computeTracestateValue(data: SentryTracestateData): string; | ||
//# sourceMappingURL=utils.d.ts.map |
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var hub_1 = require("@sentry/hub"); | ||
var utils_1 = require("@sentry/utils"); | ||
exports.SENTRY_TRACE_REGEX = new RegExp('^[ \\t]*' + // whitespace | ||
exports.TRACEPARENT_REGEXP = new RegExp('^[ \\t]*' + // whitespace | ||
'([0-9a-f]{32})?' + // trace_id | ||
@@ -10,30 +8,2 @@ '-?([0-9a-f]{16})?' + // span_id | ||
'[ \\t]*$'); | ||
// This is a normal base64 regex, modified to reflect that fact that we strip the trailing = or == off | ||
var BASE64_STRIPPED_REGEX = new RegExp( | ||
// for our purposes, we want to test against the entire string, so enforce that there's nothing before the main regex | ||
"^" + | ||
// any of the characters in the base64 "alphabet", in multiples of 4 | ||
'([a-zA-Z0-9+/]{4})*' + | ||
// either nothing or 2 or 3 base64-alphabet characters (see | ||
// https://en.wikipedia.org/wiki/Base64#Decoding_Base64_without_padding | ||
// for why there's never only 1 extra character) | ||
'([a-zA-Z0-9+/]{2,3})?' + | ||
// see above re: matching entire string | ||
"$"); | ||
// comma-delimited list of entries of the form `xxx=yyy` | ||
var tracestateEntry = '[^=]+=[^=]+'; | ||
var TRACESTATE_ENTRIES_REGEX = new RegExp( | ||
// one or more xxxxx=yyyy entries | ||
"^(" + tracestateEntry + ")+" + | ||
// each entry except the last must be followed by a comma | ||
'(,|$)'); | ||
// this doesn't check that the value is valid, just that there's something there of the form `sentry=xxxx` | ||
var SENTRY_TRACESTATE_ENTRY_REGEX = new RegExp( | ||
// either sentry is the first entry or there's stuff immediately before it, ending in a commma (this prevents matching | ||
// something like `coolsentry=xxx`) | ||
'(?:^|.+,)' + | ||
// sentry's part, not including the potential comma | ||
'(sentry=[^,]*)' + | ||
// either there's a comma and another vendor's entry or we end | ||
'(?:,.+|$)'); | ||
/** | ||
@@ -57,8 +27,8 @@ * Determines if tracing is currently enabled. | ||
* | ||
* @param header Traceparent string | ||
* @param traceparent Traceparent string | ||
* | ||
* @returns Object containing data from the header, or undefined if traceparent string is malformed | ||
*/ | ||
function extractSentrytraceData(header) { | ||
var matches = header.match(exports.SENTRY_TRACE_REGEX); | ||
function extractTraceparentData(traceparent) { | ||
var matches = traceparent.match(exports.TRACEPARENT_REGEXP); | ||
if (matches) { | ||
@@ -80,39 +50,3 @@ var parentSampled = void 0; | ||
} | ||
exports.extractSentrytraceData = extractSentrytraceData; | ||
/** | ||
* Extract data from an incoming `tracestate` header | ||
* | ||
* @param header | ||
* @returns Object containing data from the header | ||
*/ | ||
function extractTracestateData(header) { | ||
var _a; | ||
var sentryEntry, thirdPartyEntry, before, after; | ||
// find sentry's entry, if any | ||
var sentryMatch = SENTRY_TRACESTATE_ENTRY_REGEX.exec(header); | ||
if (sentryMatch !== null) { | ||
sentryEntry = sentryMatch[1]; | ||
// remove the commas after the split so we don't end up with `xxx=yyy,,zzz=qqq` (double commas) when we put them | ||
// back together | ||
_a = tslib_1.__read(header.split(sentryEntry).map(function (s) { return s.replace(/^,*|,*$/g, ''); }), 2), before = _a[0], after = _a[1]; | ||
// extract sentry's value from its entry and test to make sure it's valid; if it isn't, discard the entire entry | ||
// so that a new one will be created by the Transaction constructor | ||
var sentryValue = sentryEntry.replace('sentry=', ''); | ||
if (!BASE64_STRIPPED_REGEX.test(sentryValue)) { | ||
sentryEntry = undefined; | ||
} | ||
} | ||
else { | ||
// this could just as well be `before`; we just need to get the thirdparty data into one or the other since | ||
// there's no valid Sentry entry | ||
after = header; | ||
} | ||
// if either thirdparty part is invalid or empty, remove it before gluing them together | ||
var validThirdpartyEntries = [before, after].filter(function (x) { return TRACESTATE_ENTRIES_REGEX.test(x || ''); }); | ||
if (validThirdpartyEntries.length) { | ||
thirdPartyEntry = validThirdpartyEntries.join(','); | ||
} | ||
return { sentry: sentryEntry, thirdparty: thirdPartyEntry }; | ||
} | ||
exports.extractTracestateData = extractTracestateData; | ||
exports.extractTraceparentData = extractTraceparentData; | ||
/** Grabs active transaction off scope, if any */ | ||
@@ -142,29 +76,4 @@ function getActiveTransaction(hub) { | ||
// so it can be used in manual instrumentation without necessitating a hard dependency on @sentry/utils | ||
var utils_2 = require("@sentry/utils"); | ||
exports.stripUrlQueryAndFragment = utils_2.stripUrlQueryAndFragment; | ||
/** | ||
* Compute the value of a Sentry tracestate header. | ||
* | ||
* @throws SentryError (because using the logger creates a circular dependency) | ||
* @returns the base64-encoded header value | ||
*/ | ||
function computeTracestateValue(data) { | ||
// `JSON.stringify` will drop keys with undefined values, but not ones with null values, so this prevents | ||
// these values from being dropped if they haven't been set by `Sentry.init` | ||
// See https://www.w3.org/TR/trace-context/#tracestate-header-field-values | ||
// The spec for tracestate header values calls for a string of the form | ||
// | ||
// identifier1=value1,identifier2=value2,... | ||
// | ||
// which means the value can't include any equals signs, since they already have meaning. Equals signs are commonly | ||
// used to pad the end of base64 values though, so to avoid confusion, we strip them off. (Most languages' base64 | ||
// decoding functions (including those in JS) are able to function without the padding.) | ||
try { | ||
return utils_1.unicodeToBase64(JSON.stringify(utils_1.dropUndefinedKeys(data))).replace(/={1,2}$/, ''); | ||
} | ||
catch (err) { | ||
throw new utils_1.SentryError("[Tracing] Error computing tracestate value from data: " + err + "\nData: " + data); | ||
} | ||
} | ||
exports.computeTracestateValue = computeTracestateValue; | ||
var utils_1 = require("@sentry/utils"); | ||
exports.stripUrlQueryAndFragment = utils_1.stripUrlQueryAndFragment; | ||
//# sourceMappingURL=utils.js.map |
import { Hub } from '@sentry/hub'; | ||
import { EventProcessor, Integration, Transaction, TransactionContext } from '@sentry/types'; | ||
import { MetricsInstrumentationOptions } from './metrics'; | ||
import { RequestInstrumentationOptions } from './request'; | ||
@@ -44,2 +45,10 @@ export declare const DEFAULT_MAX_TRANSACTION_DURATION_SECONDS = 600; | ||
/** | ||
* _metricOptions allows the user to send options to change how metrics are collected. | ||
* | ||
* _metricOptions is currently experimental. | ||
* | ||
* Default: undefined | ||
*/ | ||
_metricOptions?: Partial<MetricsInstrumentationOptions>; | ||
/** | ||
* beforeNavigate is called before a pageload/navigation transaction is created and allows users to modify transaction | ||
@@ -91,9 +100,9 @@ * context data, or drop the transaction entirely (by setting `sampled = false` in the context). | ||
/** | ||
* Gets transaction context data from `sentry-trace` and `tracestate` <meta> tags. | ||
* Gets transaction context from a sentry-trace meta. | ||
* | ||
* @returns Transaction context data or undefined neither tag exists or has valid data | ||
* @returns Transaction context data from the header or undefined if there's no header or the header is malformed | ||
*/ | ||
export declare function extractTraceDataFromMetaTags(): Partial<TransactionContext> | undefined; | ||
export declare function getHeaderContext(): Partial<TransactionContext> | undefined; | ||
/** Returns the value of a meta tag */ | ||
export declare function getMetaContent(metaName: string): string | null; | ||
//# sourceMappingURL=browsertracing.d.ts.map |
@@ -6,5 +6,5 @@ import { __assign } from "tslib"; | ||
import { SpanStatus } from '../spanstatus'; | ||
import { extractSentrytraceData, extractTracestateData, secToMs } from '../utils'; | ||
import { extractTraceparentData, secToMs } from '../utils'; | ||
import { registerBackgroundTabDetection } from './backgroundtab'; | ||
import { MetricsInstrumentation } from './metrics'; | ||
import { DEFAULT_METRICS_INSTR_OPTIONS, MetricsInstrumentation } from './metrics'; | ||
import { defaultRequestInstrumentationOptions, instrumentOutgoingRequests, } from './request'; | ||
@@ -27,3 +27,2 @@ import { instrumentRoutingWithDefaults } from './router'; | ||
this.name = BrowserTracing.id; | ||
this._metrics = new MetricsInstrumentation(); | ||
this._emitOptionsWarning = false; | ||
@@ -42,2 +41,3 @@ var tracingOrigins = defaultRequestInstrumentationOptions.tracingOrigins; | ||
this.options = __assign(__assign(__assign({}, DEFAULT_BROWSER_TRACING_OPTIONS), _options), { tracingOrigins: tracingOrigins }); | ||
this._metrics = new MetricsInstrumentation(__assign(__assign({}, DEFAULT_METRICS_INSTR_OPTIONS), this.options._metricOptions)); | ||
} | ||
@@ -71,3 +71,3 @@ /** | ||
var _a = this.options, beforeNavigate = _a.beforeNavigate, idleTimeout = _a.idleTimeout, maxTransactionDuration = _a.maxTransactionDuration; | ||
var parentContextFromHeader = context.op === 'pageload' ? extractTraceDataFromMetaTags() : undefined; | ||
var parentContextFromHeader = context.op === 'pageload' ? getHeaderContext() : undefined; | ||
var expandedContext = __assign(__assign(__assign({}, context), parentContextFromHeader), { trimEnd: true }); | ||
@@ -99,14 +99,10 @@ var modifiedContext = typeof beforeNavigate === 'function' ? beforeNavigate(expandedContext) : expandedContext; | ||
/** | ||
* Gets transaction context data from `sentry-trace` and `tracestate` <meta> tags. | ||
* Gets transaction context from a sentry-trace meta. | ||
* | ||
* @returns Transaction context data or undefined neither tag exists or has valid data | ||
* @returns Transaction context data from the header or undefined if there's no header or the header is malformed | ||
*/ | ||
export function extractTraceDataFromMetaTags() { | ||
var _a, _b; | ||
var sentrytraceValue = getMetaContent('sentry-trace'); | ||
var tracestateValue = getMetaContent('tracestate'); | ||
var sentrytraceData = sentrytraceValue ? extractSentrytraceData(sentrytraceValue) : undefined; | ||
var tracestateData = tracestateValue ? extractTracestateData(tracestateValue) : undefined; | ||
if (sentrytraceData || ((_a = tracestateData) === null || _a === void 0 ? void 0 : _a.sentry) || ((_b = tracestateData) === null || _b === void 0 ? void 0 : _b.thirdparty)) { | ||
return __assign(__assign({}, sentrytraceData), (tracestateData && { metadata: { tracestate: tracestateData } })); | ||
export function getHeaderContext() { | ||
var header = getMetaContent('sentry-trace'); | ||
if (header) { | ||
return extractTraceparentData(header); | ||
} | ||
@@ -113,0 +109,0 @@ return undefined; |
import { SpanContext } from '@sentry/types'; | ||
import { Span } from '../span'; | ||
import { Transaction } from '../transaction'; | ||
/** | ||
* Exports a way to add options to our metric collection. Currently experimental. | ||
*/ | ||
export interface MetricsInstrumentationOptions { | ||
_reportAllChanges: boolean; | ||
} | ||
export declare const DEFAULT_METRICS_INSTR_OPTIONS: MetricsInstrumentationOptions; | ||
/** Class tracking metrics */ | ||
@@ -10,3 +17,3 @@ export declare class MetricsInstrumentation { | ||
private _clsEntry; | ||
constructor(); | ||
constructor(_options: MetricsInstrumentationOptions); | ||
/** Add performance related spans to a transaction */ | ||
@@ -13,0 +20,0 @@ addPerformanceEntries(transaction: Transaction): void; |
@@ -9,5 +9,8 @@ import { __assign, __rest } from "tslib"; | ||
var global = getGlobalObject(); | ||
export var DEFAULT_METRICS_INSTR_OPTIONS = { | ||
_reportAllChanges: false, | ||
}; | ||
/** Class tracking metrics */ | ||
var MetricsInstrumentation = /** @class */ (function () { | ||
function MetricsInstrumentation() { | ||
function MetricsInstrumentation(_options) { | ||
var _a, _b; | ||
@@ -21,3 +24,3 @@ this._measurements = {}; | ||
this._trackCLS(); | ||
this._trackLCP(); | ||
this._trackLCP(_options._reportAllChanges); | ||
this._trackFID(); | ||
@@ -235,3 +238,3 @@ } | ||
/** Starts tracking the Largest Contentful Paint on the current page. */ | ||
MetricsInstrumentation.prototype._trackLCP = function () { | ||
MetricsInstrumentation.prototype._trackLCP = function (reportAllChanges) { | ||
var _this = this; | ||
@@ -249,3 +252,3 @@ getLCP(function (metric) { | ||
_this._lcpEntry = entry; | ||
}); | ||
}, reportAllChanges); | ||
}; | ||
@@ -252,0 +255,0 @@ /** Starts tracking the First Input Delay on the current page. */ |
@@ -1,2 +0,2 @@ | ||
import { Span } from '@sentry/types'; | ||
import { Span } from '../span'; | ||
export declare const DEFAULT_TRACING_ORIGINS: (string | RegExp)[]; | ||
@@ -3,0 +3,0 @@ /** Options for Request Instrumentation */ |
@@ -94,21 +94,17 @@ import { __assign, __read, __spread } from "tslib"; | ||
} | ||
var traceHeaders = span.getTraceHeaders(); | ||
if (headers) { | ||
if ('append' in headers && typeof headers.append === 'function') { | ||
headers.append('sentry-trace', traceHeaders['sentry-trace']); | ||
if (traceHeaders.tracestate) { | ||
headers.append('tracestate', traceHeaders.tracestate); | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
if (typeof headers.append === 'function') { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
headers.append('sentry-trace', span.toTraceparent()); | ||
} | ||
else if (Array.isArray(headers)) { | ||
// TODO use the nicer version below once we stop supporting Node 6 | ||
// headers = [...headers, ...Object.entries(traceHeaders)]; | ||
headers = __spread(headers, [['sentry-trace', traceHeaders['sentry-trace']], ['tracestate', traceHeaders.tracestate]]); | ||
headers = __spread(headers, [['sentry-trace', span.toTraceparent()]]); | ||
} | ||
else { | ||
headers = __assign(__assign({}, headers), traceHeaders); | ||
headers = __assign(__assign({}, headers), { 'sentry-trace': span.toTraceparent() }); | ||
} | ||
} | ||
else { | ||
headers = traceHeaders; | ||
headers = { 'sentry-trace': span.toTraceparent() }; | ||
} | ||
@@ -151,7 +147,3 @@ options.headers = headers; | ||
try { | ||
var sentryHeaders = span.getTraceHeaders(); | ||
handlerData.xhr.setRequestHeader('sentry-trace', sentryHeaders['sentry-trace']); | ||
if (sentryHeaders.tracestate) { | ||
handlerData.xhr.setRequestHeader('tracestate', sentryHeaders.tracestate); | ||
} | ||
handlerData.xhr.setRequestHeader('sentry-trace', span.toTraceparent()); | ||
} | ||
@@ -158,0 +150,0 @@ catch (_) { |
@@ -9,2 +9,15 @@ import { __assign, __read, __spread } from "tslib"; | ||
import { hasTracingEnabled } from './utils'; | ||
/** Returns all trace headers that are currently on the top scope. */ | ||
function traceHeaders() { | ||
var scope = this.getScope(); | ||
if (scope) { | ||
var span = scope.getSpan(); | ||
if (span) { | ||
return { | ||
'sentry-trace': span.toTraceparent(), | ||
}; | ||
} | ||
} | ||
return {}; | ||
} | ||
/** | ||
@@ -157,2 +170,5 @@ * Makes a sampling decision for the given transaction and stores it on the transaction. | ||
} | ||
if (!carrier.__SENTRY__.extensions.traceHeaders) { | ||
carrier.__SENTRY__.extensions.traceHeaders = traceHeaders; | ||
} | ||
} | ||
@@ -159,0 +175,0 @@ /** |
@@ -19,3 +19,3 @@ import { BrowserTracing } from './browser'; | ||
export { addExtensionMethods }; | ||
export { extractSentrytraceData, extractTracestateData, getActiveTransaction, hasTracingEnabled, SENTRY_TRACE_REGEX, stripUrlQueryAndFragment, } from './utils'; | ||
export { extractTraceparentData, getActiveTransaction, hasTracingEnabled, stripUrlQueryAndFragment, TRACEPARENT_REGEXP, } from './utils'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -18,3 +18,3 @@ import { __assign } from "tslib"; | ||
export { addExtensionMethods }; | ||
export { extractSentrytraceData, extractTracestateData, getActiveTransaction, hasTracingEnabled, SENTRY_TRACE_REGEX, stripUrlQueryAndFragment, } from './utils'; | ||
export { extractTraceparentData, getActiveTransaction, hasTracingEnabled, stripUrlQueryAndFragment, TRACEPARENT_REGEXP, } from './utils'; | ||
//# sourceMappingURL=index.js.map |
@@ -1,5 +0,5 @@ | ||
export { Express } from './express'; | ||
export { Postgres } from './postgres'; | ||
export { Mysql } from './mysql'; | ||
export { Mongo } from './mongo'; | ||
export { Express } from './node/express'; | ||
export { Postgres } from './node/postgres'; | ||
export { Mysql } from './node/mysql'; | ||
export { Mongo } from './node/mongo'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,5 +0,5 @@ | ||
export { Express } from './express'; | ||
export { Postgres } from './postgres'; | ||
export { Mysql } from './mysql'; | ||
export { Mongo } from './mongo'; | ||
export { Express } from './node/express'; | ||
export { Postgres } from './node/postgres'; | ||
export { Mysql } from './node/mysql'; | ||
export { Mongo } from './node/mongo'; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
import { Primitive, Span as SpanInterface, SpanContext, TraceHeaders, Transaction } from '@sentry/types'; | ||
import { Primitive, Span as SpanInterface, SpanContext, Transaction } from '@sentry/types'; | ||
import { SpanStatus } from './spanstatus'; | ||
@@ -137,6 +137,2 @@ /** | ||
*/ | ||
getTraceHeaders(): TraceHeaders; | ||
/** | ||
* @inheritDoc | ||
*/ | ||
getTraceContext(): { | ||
@@ -175,18 +171,3 @@ data?: { | ||
}; | ||
/** | ||
* Create a new Sentry tracestate header entry (i.e. `sentry=xxxxxx`) | ||
* | ||
* @returns The new Sentry tracestate entry, or undefined if there's no client or no dsn | ||
*/ | ||
protected _getNewTracestate(): string | undefined; | ||
/** | ||
* Return a traceparent-compatible header string. | ||
*/ | ||
private _toSentrytrace; | ||
/** | ||
* Return a tracestate-compatible header string, including both sentry and third-party data (if any). Returns | ||
* undefined if there is no client or no DSN. | ||
*/ | ||
private _toTracestate; | ||
} | ||
//# sourceMappingURL=span.d.ts.map |
import { __assign } from "tslib"; | ||
/* eslint-disable max-lines */ | ||
import { getCurrentHub } from '@sentry/hub'; | ||
import { dropUndefinedKeys, logger, timestampWithMs, uuid4 } from '@sentry/utils'; | ||
import { dropUndefinedKeys, timestampWithMs, uuid4 } from '@sentry/utils'; | ||
import { SpanStatus } from './spanstatus'; | ||
import { computeTracestateValue } from './utils'; | ||
/** | ||
@@ -81,3 +78,3 @@ * Keeps track of finished spans for a given transaction | ||
} | ||
// check this way instead of the normal way to make sure we don't miss cases where sampled = false | ||
// We want to include booleans as well here | ||
if ('sampled' in spanContext) { | ||
@@ -178,4 +175,7 @@ this.sampled = spanContext.sampled; | ||
Span.prototype.toTraceparent = function () { | ||
logger.warn('Direct use of `span.toTraceparent` is deprecated. Use `span.getTraceHeaders` instead.'); | ||
return this._toSentrytrace(); | ||
var sampledString = ''; | ||
if (this.sampled !== undefined) { | ||
sampledString = this.sampled ? '-1' : '-0'; | ||
} | ||
return this.traceId + "-" + this.spanId + sampledString; | ||
}; | ||
@@ -221,14 +221,2 @@ /** | ||
*/ | ||
Span.prototype.getTraceHeaders = function () { | ||
var _a, _b; | ||
// if this span is part of a transaction, but that transaction doesn't yet have a tracestate value, create one | ||
if (this.transaction && !((_b = (_a = this.transaction) === null || _a === void 0 ? void 0 : _a.metadata.tracestate) === null || _b === void 0 ? void 0 : _b.sentry)) { | ||
this.transaction.metadata.tracestate = __assign(__assign({}, this.transaction.metadata.tracestate), { sentry: this._getNewTracestate() }); | ||
} | ||
var tracestate = this._toTracestate(); | ||
return __assign({ 'sentry-trace': this._toSentrytrace() }, (tracestate && { tracestate: tracestate })); | ||
}; | ||
/** | ||
* @inheritDoc | ||
*/ | ||
Span.prototype.getTraceContext = function () { | ||
@@ -263,58 +251,2 @@ return dropUndefinedKeys({ | ||
}; | ||
/** | ||
* Create a new Sentry tracestate header entry (i.e. `sentry=xxxxxx`) | ||
* | ||
* @returns The new Sentry tracestate entry, or undefined if there's no client or no dsn | ||
*/ | ||
Span.prototype._getNewTracestate = function () { | ||
var _a, _b, _c, _d; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any | ||
var hub = ((_a = this.transaction) === null || _a === void 0 ? void 0 : _a._hub) || getCurrentHub(); | ||
var client = hub.getClient(); | ||
var _e = ((_b = hub.getScope()) === null || _b === void 0 ? void 0 : _b.getUser()) || {}, userId = _e.id, userSegment = _e.segment; | ||
var dsn = (_c = client) === null || _c === void 0 ? void 0 : _c.getDsn(); | ||
if (!client || !dsn) { | ||
return; | ||
} | ||
var _f = client.getOptions() || {}, environment = _f.environment, release = _f.release; | ||
// only define a `user` object if there's going to be something in it (note: prettier insists on removing the | ||
// parentheses, but since it's easy to misinterpret this, imagine `()` around `userId || userSegment`) | ||
var user = userId || userSegment ? { id: userId, segment: userSegment } : undefined; | ||
// TODO - the only reason we need the non-null assertion on `dsn.publicKey` (below) is because `dsn.publicKey` has | ||
// to be optional while we transition from `dsn.user` -> `dsn.publicKey`. Once `dsn.user` is removed, we can make | ||
// `dsn.publicKey` required and remove the `!`. | ||
return "sentry=" + computeTracestateValue({ | ||
trace_id: this.traceId, | ||
environment: environment, | ||
release: release, | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
public_key: dsn.publicKey, | ||
user: user, | ||
transaction: (_d = this.transaction) === null || _d === void 0 ? void 0 : _d.name, | ||
}); | ||
}; | ||
/** | ||
* Return a traceparent-compatible header string. | ||
*/ | ||
Span.prototype._toSentrytrace = function () { | ||
var sampledString = ''; | ||
if (this.sampled !== undefined) { | ||
sampledString = this.sampled ? '-1' : '-0'; | ||
} | ||
return this.traceId + "-" + this.spanId + sampledString; | ||
}; | ||
/** | ||
* Return a tracestate-compatible header string, including both sentry and third-party data (if any). Returns | ||
* undefined if there is no client or no DSN. | ||
*/ | ||
Span.prototype._toTracestate = function () { | ||
var _a, _b, _c, _d, _e, _f; | ||
// if this is an orphan span, create a new tracestate value | ||
var sentryTracestate = ((_c = (_b = (_a = this.transaction) === null || _a === void 0 ? void 0 : _a.metadata) === null || _b === void 0 ? void 0 : _b.tracestate) === null || _c === void 0 ? void 0 : _c.sentry) || this._getNewTracestate(); | ||
var thirdpartyTracestate = (_f = (_e = (_d = this.transaction) === null || _d === void 0 ? void 0 : _d.metadata) === null || _e === void 0 ? void 0 : _e.tracestate) === null || _f === void 0 ? void 0 : _f.thirdparty; | ||
// if there's third-party data, add a leading comma; otherwise, convert from `undefined` to the empty string, so the | ||
// end result doesn’t come out as `sentry=xxxxxundefined` | ||
thirdpartyTracestate = thirdpartyTracestate ? "," + thirdpartyTracestate : ''; | ||
return "" + sentryTracestate + thirdpartyTracestate; | ||
}; | ||
return Span; | ||
@@ -321,0 +253,0 @@ }()); |
import { __assign, __extends } from "tslib"; | ||
import { getCurrentHub } from '@sentry/hub'; | ||
import { dropUndefinedKeys, logger } from '@sentry/utils'; | ||
import { getCurrentHub, Hub } from '@sentry/hub'; | ||
import { Outcome, } from '@sentry/types'; | ||
import { dropUndefinedKeys, isInstanceOf, logger } from '@sentry/utils'; | ||
import { Span as SpanClass, SpanRecorder } from './span'; | ||
@@ -18,9 +19,13 @@ /** JSDoc */ | ||
_this._measurements = {}; | ||
/** | ||
* The reference to the current hub. | ||
*/ | ||
_this._hub = getCurrentHub(); | ||
if (isInstanceOf(hub, Hub)) { | ||
_this._hub = hub; | ||
} | ||
_this.name = transactionContext.name || ''; | ||
_this.metadata = transactionContext.metadata || {}; | ||
_this._trimEnd = transactionContext.trimEnd; | ||
_this._hub = hub || getCurrentHub(); | ||
// this is because transactions are also spans, and spans have a transaction pointer (it doesn't get set in `super` | ||
// because theoretically you can create a span without a transaction, though at the moment it doesn't do you much | ||
// good) | ||
// this is because transactions are also spans, and spans have a transaction pointer | ||
_this.transaction = _this; | ||
@@ -65,3 +70,3 @@ return _this; | ||
var _this = this; | ||
var _a; | ||
var _a, _b, _c; | ||
// This transaction is already finished, so we should not flush it again. | ||
@@ -80,2 +85,4 @@ if (this.endTimestamp !== undefined) { | ||
logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.'); | ||
(_c = (_a = this._hub | ||
.getClient()) === null || _a === void 0 ? void 0 : (_b = _a.getTransport()).recordLostEvent) === null || _c === void 0 ? void 0 : _c.call(_b, Outcome.SampleRate, 'transaction'); | ||
return undefined; | ||
@@ -92,6 +99,2 @@ } | ||
} | ||
// ensure that we have a tracestate to attach to the envelope header | ||
if (!((_a = this.metadata.tracestate) === null || _a === void 0 ? void 0 : _a.sentry)) { | ||
this.metadata.tracestate = __assign(__assign({}, this.metadata.tracestate), { sentry: this._getNewTracestate() }); | ||
} | ||
var transaction = { | ||
@@ -98,0 +101,0 @@ contexts: { |
import { Hub } from '@sentry/hub'; | ||
import { Options, TraceparentData, Transaction } from '@sentry/types'; | ||
export declare const SENTRY_TRACE_REGEX: RegExp; | ||
export declare const TRACEPARENT_REGEXP: RegExp; | ||
/** | ||
@@ -13,17 +13,7 @@ * Determines if tracing is currently enabled. | ||
* | ||
* @param header Traceparent string | ||
* @param traceparent Traceparent string | ||
* | ||
* @returns Object containing data from the header, or undefined if traceparent string is malformed | ||
*/ | ||
export declare function extractSentrytraceData(header: string): TraceparentData | undefined; | ||
/** | ||
* Extract data from an incoming `tracestate` header | ||
* | ||
* @param header | ||
* @returns Object containing data from the header | ||
*/ | ||
export declare function extractTracestateData(header: string): { | ||
sentry?: string; | ||
thirdparty?: string; | ||
}; | ||
export declare function extractTraceparentData(traceparent: string): TraceparentData | undefined; | ||
/** Grabs active transaction off scope, if any */ | ||
@@ -42,20 +32,2 @@ export declare function getActiveTransaction<T extends Transaction>(hub?: Hub): T | undefined; | ||
export { stripUrlQueryAndFragment } from '@sentry/utils'; | ||
declare type SentryTracestateData = { | ||
trace_id: string; | ||
environment?: string; | ||
release?: string; | ||
public_key: string; | ||
user?: { | ||
id?: string; | ||
segment?: string; | ||
}; | ||
transaction?: string; | ||
}; | ||
/** | ||
* Compute the value of a Sentry tracestate header. | ||
* | ||
* @throws SentryError (because using the logger creates a circular dependency) | ||
* @returns the base64-encoded header value | ||
*/ | ||
export declare function computeTracestateValue(data: SentryTracestateData): string; | ||
//# sourceMappingURL=utils.d.ts.map |
@@ -1,5 +0,3 @@ | ||
import { __read } from "tslib"; | ||
import { getCurrentHub } from '@sentry/hub'; | ||
import { dropUndefinedKeys, SentryError, unicodeToBase64 } from '@sentry/utils'; | ||
export var SENTRY_TRACE_REGEX = new RegExp('^[ \\t]*' + // whitespace | ||
export var TRACEPARENT_REGEXP = new RegExp('^[ \\t]*' + // whitespace | ||
'([0-9a-f]{32})?' + // trace_id | ||
@@ -9,30 +7,2 @@ '-?([0-9a-f]{16})?' + // span_id | ||
'[ \\t]*$'); | ||
// This is a normal base64 regex, modified to reflect that fact that we strip the trailing = or == off | ||
var BASE64_STRIPPED_REGEX = new RegExp( | ||
// for our purposes, we want to test against the entire string, so enforce that there's nothing before the main regex | ||
"^" + | ||
// any of the characters in the base64 "alphabet", in multiples of 4 | ||
'([a-zA-Z0-9+/]{4})*' + | ||
// either nothing or 2 or 3 base64-alphabet characters (see | ||
// https://en.wikipedia.org/wiki/Base64#Decoding_Base64_without_padding | ||
// for why there's never only 1 extra character) | ||
'([a-zA-Z0-9+/]{2,3})?' + | ||
// see above re: matching entire string | ||
"$"); | ||
// comma-delimited list of entries of the form `xxx=yyy` | ||
var tracestateEntry = '[^=]+=[^=]+'; | ||
var TRACESTATE_ENTRIES_REGEX = new RegExp( | ||
// one or more xxxxx=yyyy entries | ||
"^(" + tracestateEntry + ")+" + | ||
// each entry except the last must be followed by a comma | ||
'(,|$)'); | ||
// this doesn't check that the value is valid, just that there's something there of the form `sentry=xxxx` | ||
var SENTRY_TRACESTATE_ENTRY_REGEX = new RegExp( | ||
// either sentry is the first entry or there's stuff immediately before it, ending in a commma (this prevents matching | ||
// something like `coolsentry=xxx`) | ||
'(?:^|.+,)' + | ||
// sentry's part, not including the potential comma | ||
'(sentry=[^,]*)' + | ||
// either there's a comma and another vendor's entry or we end | ||
'(?:,.+|$)'); | ||
/** | ||
@@ -55,8 +25,8 @@ * Determines if tracing is currently enabled. | ||
* | ||
* @param header Traceparent string | ||
* @param traceparent Traceparent string | ||
* | ||
* @returns Object containing data from the header, or undefined if traceparent string is malformed | ||
*/ | ||
export function extractSentrytraceData(header) { | ||
var matches = header.match(SENTRY_TRACE_REGEX); | ||
export function extractTraceparentData(traceparent) { | ||
var matches = traceparent.match(TRACEPARENT_REGEXP); | ||
if (matches) { | ||
@@ -78,37 +48,2 @@ var parentSampled = void 0; | ||
} | ||
/** | ||
* Extract data from an incoming `tracestate` header | ||
* | ||
* @param header | ||
* @returns Object containing data from the header | ||
*/ | ||
export function extractTracestateData(header) { | ||
var _a; | ||
var sentryEntry, thirdPartyEntry, before, after; | ||
// find sentry's entry, if any | ||
var sentryMatch = SENTRY_TRACESTATE_ENTRY_REGEX.exec(header); | ||
if (sentryMatch !== null) { | ||
sentryEntry = sentryMatch[1]; | ||
// remove the commas after the split so we don't end up with `xxx=yyy,,zzz=qqq` (double commas) when we put them | ||
// back together | ||
_a = __read(header.split(sentryEntry).map(function (s) { return s.replace(/^,*|,*$/g, ''); }), 2), before = _a[0], after = _a[1]; | ||
// extract sentry's value from its entry and test to make sure it's valid; if it isn't, discard the entire entry | ||
// so that a new one will be created by the Transaction constructor | ||
var sentryValue = sentryEntry.replace('sentry=', ''); | ||
if (!BASE64_STRIPPED_REGEX.test(sentryValue)) { | ||
sentryEntry = undefined; | ||
} | ||
} | ||
else { | ||
// this could just as well be `before`; we just need to get the thirdparty data into one or the other since | ||
// there's no valid Sentry entry | ||
after = header; | ||
} | ||
// if either thirdparty part is invalid or empty, remove it before gluing them together | ||
var validThirdpartyEntries = [before, after].filter(function (x) { return TRACESTATE_ENTRIES_REGEX.test(x || ''); }); | ||
if (validThirdpartyEntries.length) { | ||
thirdPartyEntry = validThirdpartyEntries.join(','); | ||
} | ||
return { sentry: sentryEntry, thirdparty: thirdPartyEntry }; | ||
} | ||
/** Grabs active transaction off scope, if any */ | ||
@@ -136,26 +71,2 @@ export function getActiveTransaction(hub) { | ||
export { stripUrlQueryAndFragment } from '@sentry/utils'; | ||
/** | ||
* Compute the value of a Sentry tracestate header. | ||
* | ||
* @throws SentryError (because using the logger creates a circular dependency) | ||
* @returns the base64-encoded header value | ||
*/ | ||
export function computeTracestateValue(data) { | ||
// `JSON.stringify` will drop keys with undefined values, but not ones with null values, so this prevents | ||
// these values from being dropped if they haven't been set by `Sentry.init` | ||
// See https://www.w3.org/TR/trace-context/#tracestate-header-field-values | ||
// The spec for tracestate header values calls for a string of the form | ||
// | ||
// identifier1=value1,identifier2=value2,... | ||
// | ||
// which means the value can't include any equals signs, since they already have meaning. Equals signs are commonly | ||
// used to pad the end of base64 values though, so to avoid confusion, we strip them off. (Most languages' base64 | ||
// decoding functions (including those in JS) are able to function without the padding.) | ||
try { | ||
return unicodeToBase64(JSON.stringify(dropUndefinedKeys(data))).replace(/={1,2}$/, ''); | ||
} | ||
catch (err) { | ||
throw new SentryError("[Tracing] Error computing tracestate value from data: " + err + "\nData: " + data); | ||
} | ||
} | ||
//# sourceMappingURL=utils.js.map |
{ | ||
"name": "@sentry/tracing", | ||
"version": "6.13.0-beta.0", | ||
"version": "6.13.0-beta.1", | ||
"description": "Extensions for Sentry AM", | ||
@@ -19,11 +19,11 @@ "repository": "git://github.com/getsentry/sentry-javascript.git", | ||
"dependencies": { | ||
"@sentry/hub": "6.13.0-beta.0", | ||
"@sentry/minimal": "6.13.0-beta.0", | ||
"@sentry/types": "6.13.0-beta.0", | ||
"@sentry/utils": "6.13.0-beta.0", | ||
"@sentry/hub": "6.13.0-beta.1", | ||
"@sentry/minimal": "6.13.0-beta.1", | ||
"@sentry/types": "6.13.0-beta.1", | ||
"@sentry/utils": "6.13.0-beta.1", | ||
"tslib": "^1.9.3" | ||
}, | ||
"devDependencies": { | ||
"@sentry-internal/eslint-config-sdk": "6.13.0-beta.0", | ||
"@sentry/browser": "6.13.0-beta.0", | ||
"@sentry-internal/eslint-config-sdk": "6.13.0-beta.1", | ||
"@sentry/browser": "6.13.0-beta.1", | ||
"@types/express": "^4.17.1", | ||
@@ -30,0 +30,0 @@ "@types/jsdom": "^16.2.3", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
2304611
16728
+ Added@sentry/hub@6.13.0-beta.1(transitive)
+ Added@sentry/minimal@6.13.0-beta.1(transitive)
+ Added@sentry/types@6.13.0-beta.1(transitive)
+ Added@sentry/utils@6.13.0-beta.1(transitive)
- Removed@sentry/hub@6.13.0-beta.0(transitive)
- Removed@sentry/minimal@6.13.0-beta.0(transitive)
- Removed@sentry/types@6.13.0-beta.0(transitive)
- Removed@sentry/utils@6.13.0-beta.0(transitive)
Updated@sentry/hub@6.13.0-beta.1
Updated@sentry/types@6.13.0-beta.1
Updated@sentry/utils@6.13.0-beta.1