@sentry/profiling-node 7.104.0 → 8.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/index.js +199 -767
- package/lib/index.js.map +1 -1
- package/lib/sentry_cpu_profiler-darwin-arm64-108.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-arm64-115.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-arm64-93.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-x64-108.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-x64-115.node +0 -0
- package/lib/sentry_cpu_profiler-darwin-x64-93.node +0 -0
- package/lib/sentry_cpu_profiler-win32-x64-108.node +0 -0
- package/lib/sentry_cpu_profiler-win32-x64-115.node +0 -0
- package/lib/sentry_cpu_profiler-win32-x64-93.node +0 -0
- package/lib/types/cpu_profiler.d.ts.map +1 -1
- package/lib/types/hubextensions.d.ts +1 -1
- package/lib/types/hubextensions.d.ts.map +1 -1
- package/lib/types/integration.d.ts.map +1 -1
- package/lib/types/utils.d.ts.map +1 -1
- package/lib/types-ts3.8/hubextensions.d.ts +1 -1
- package/package.json +6 -6
package/lib/index.js
CHANGED
|
@@ -108,24 +108,6 @@ const GLOBAL_OBJ =
|
|
|
108
108
|
})() ||
|
|
109
109
|
{};
|
|
110
110
|
|
|
111
|
-
/**
|
|
112
|
-
* Returns a global singleton contained in the global `__SENTRY__` object.
|
|
113
|
-
*
|
|
114
|
-
* If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory
|
|
115
|
-
* function and added to the `__SENTRY__` object.
|
|
116
|
-
*
|
|
117
|
-
* @param name name of the global singleton on __SENTRY__
|
|
118
|
-
* @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__`
|
|
119
|
-
* @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `GLOBAL_OBJ`'s return value
|
|
120
|
-
* @returns the singleton
|
|
121
|
-
*/
|
|
122
|
-
function getGlobalSingleton(name, creator, obj) {
|
|
123
|
-
const gbl = (obj || GLOBAL_OBJ) ;
|
|
124
|
-
const __SENTRY__ = (gbl.__SENTRY__ = gbl.__SENTRY__ || {});
|
|
125
|
-
const singleton = __SENTRY__[name] || (__SENTRY__[name] = creator());
|
|
126
|
-
return singleton;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
111
|
/**
|
|
130
112
|
* This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.
|
|
131
113
|
*
|
|
@@ -346,178 +328,6 @@ function uuid4() {
|
|
|
346
328
|
);
|
|
347
329
|
}
|
|
348
330
|
|
|
349
|
-
/**
|
|
350
|
-
* Checks whether the given input is already an array, and if it isn't, wraps it in one.
|
|
351
|
-
*
|
|
352
|
-
* @param maybeArray Input to turn into an array, if necessary
|
|
353
|
-
* @returns The input, if already an array, or an array with the input as the only element, if not
|
|
354
|
-
*/
|
|
355
|
-
function arrayify(maybeArray) {
|
|
356
|
-
return Array.isArray(maybeArray) ? maybeArray : [maybeArray];
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
360
|
-
|
|
361
|
-
/** SyncPromise internal states */
|
|
362
|
-
var States; (function (States) {
|
|
363
|
-
/** Pending */
|
|
364
|
-
const PENDING = 0; States[States["PENDING"] = PENDING] = "PENDING";
|
|
365
|
-
/** Resolved / OK */
|
|
366
|
-
const RESOLVED = 1; States[States["RESOLVED"] = RESOLVED] = "RESOLVED";
|
|
367
|
-
/** Rejected / Error */
|
|
368
|
-
const REJECTED = 2; States[States["REJECTED"] = REJECTED] = "REJECTED";
|
|
369
|
-
})(States || (States = {}));
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* Thenable class that behaves like a Promise and follows it's interface
|
|
373
|
-
* but is not async internally
|
|
374
|
-
*/
|
|
375
|
-
class SyncPromise {
|
|
376
|
-
|
|
377
|
-
constructor(
|
|
378
|
-
executor,
|
|
379
|
-
) {SyncPromise.prototype.__init.call(this);SyncPromise.prototype.__init2.call(this);SyncPromise.prototype.__init3.call(this);SyncPromise.prototype.__init4.call(this);
|
|
380
|
-
this._state = States.PENDING;
|
|
381
|
-
this._handlers = [];
|
|
382
|
-
|
|
383
|
-
try {
|
|
384
|
-
executor(this._resolve, this._reject);
|
|
385
|
-
} catch (e) {
|
|
386
|
-
this._reject(e);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
/** JSDoc */
|
|
391
|
-
then(
|
|
392
|
-
onfulfilled,
|
|
393
|
-
onrejected,
|
|
394
|
-
) {
|
|
395
|
-
return new SyncPromise((resolve, reject) => {
|
|
396
|
-
this._handlers.push([
|
|
397
|
-
false,
|
|
398
|
-
result => {
|
|
399
|
-
if (!onfulfilled) {
|
|
400
|
-
// TODO: ¯\_(ツ)_/¯
|
|
401
|
-
// TODO: FIXME
|
|
402
|
-
resolve(result );
|
|
403
|
-
} else {
|
|
404
|
-
try {
|
|
405
|
-
resolve(onfulfilled(result));
|
|
406
|
-
} catch (e) {
|
|
407
|
-
reject(e);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
},
|
|
411
|
-
reason => {
|
|
412
|
-
if (!onrejected) {
|
|
413
|
-
reject(reason);
|
|
414
|
-
} else {
|
|
415
|
-
try {
|
|
416
|
-
resolve(onrejected(reason));
|
|
417
|
-
} catch (e) {
|
|
418
|
-
reject(e);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
},
|
|
422
|
-
]);
|
|
423
|
-
this._executeHandlers();
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
/** JSDoc */
|
|
428
|
-
catch(
|
|
429
|
-
onrejected,
|
|
430
|
-
) {
|
|
431
|
-
return this.then(val => val, onrejected);
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/** JSDoc */
|
|
435
|
-
finally(onfinally) {
|
|
436
|
-
return new SyncPromise((resolve, reject) => {
|
|
437
|
-
let val;
|
|
438
|
-
let isRejected;
|
|
439
|
-
|
|
440
|
-
return this.then(
|
|
441
|
-
value => {
|
|
442
|
-
isRejected = false;
|
|
443
|
-
val = value;
|
|
444
|
-
if (onfinally) {
|
|
445
|
-
onfinally();
|
|
446
|
-
}
|
|
447
|
-
},
|
|
448
|
-
reason => {
|
|
449
|
-
isRejected = true;
|
|
450
|
-
val = reason;
|
|
451
|
-
if (onfinally) {
|
|
452
|
-
onfinally();
|
|
453
|
-
}
|
|
454
|
-
},
|
|
455
|
-
).then(() => {
|
|
456
|
-
if (isRejected) {
|
|
457
|
-
reject(val);
|
|
458
|
-
return;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
resolve(val );
|
|
462
|
-
});
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
/** JSDoc */
|
|
467
|
-
__init() {this._resolve = (value) => {
|
|
468
|
-
this._setResult(States.RESOLVED, value);
|
|
469
|
-
};}
|
|
470
|
-
|
|
471
|
-
/** JSDoc */
|
|
472
|
-
__init2() {this._reject = (reason) => {
|
|
473
|
-
this._setResult(States.REJECTED, reason);
|
|
474
|
-
};}
|
|
475
|
-
|
|
476
|
-
/** JSDoc */
|
|
477
|
-
__init3() {this._setResult = (state, value) => {
|
|
478
|
-
if (this._state !== States.PENDING) {
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
if (isThenable(value)) {
|
|
483
|
-
void (value ).then(this._resolve, this._reject);
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
this._state = state;
|
|
488
|
-
this._value = value;
|
|
489
|
-
|
|
490
|
-
this._executeHandlers();
|
|
491
|
-
};}
|
|
492
|
-
|
|
493
|
-
/** JSDoc */
|
|
494
|
-
__init4() {this._executeHandlers = () => {
|
|
495
|
-
if (this._state === States.PENDING) {
|
|
496
|
-
return;
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
const cachedHandlers = this._handlers.slice();
|
|
500
|
-
this._handlers = [];
|
|
501
|
-
|
|
502
|
-
cachedHandlers.forEach(handler => {
|
|
503
|
-
if (handler[0]) {
|
|
504
|
-
return;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
if (this._state === States.RESOLVED) {
|
|
508
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
509
|
-
handler[1](this._value );
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
if (this._state === States.REJECTED) {
|
|
513
|
-
handler[2](this._value);
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
handler[0] = true;
|
|
517
|
-
});
|
|
518
|
-
};}
|
|
519
|
-
}
|
|
520
|
-
|
|
521
331
|
const ONE_SECOND_IN_MS = 1000;
|
|
522
332
|
|
|
523
333
|
/**
|
|
@@ -657,59 +467,42 @@ function forEachEnvelopeItem(
|
|
|
657
467
|
}
|
|
658
468
|
|
|
659
469
|
/**
|
|
660
|
-
*
|
|
470
|
+
* @private Private API with no semver guarantees!
|
|
661
471
|
*
|
|
662
|
-
*
|
|
472
|
+
* Strategy used to track async context.
|
|
663
473
|
*/
|
|
664
|
-
const DEBUG_BUILD$1 = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);
|
|
665
474
|
|
|
666
475
|
/**
|
|
667
|
-
*
|
|
476
|
+
* Returns the global shim registry.
|
|
668
477
|
*
|
|
669
|
-
*
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
478
|
+
* FIXME: This function is problematic, because despite always returning a valid Carrier,
|
|
479
|
+
* it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check
|
|
480
|
+
* at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there.
|
|
481
|
+
**/
|
|
482
|
+
function getMainCarrier() {
|
|
483
|
+
// This ensures a Sentry carrier exists
|
|
484
|
+
getSentryCarrier(GLOBAL_OBJ);
|
|
485
|
+
return GLOBAL_OBJ;
|
|
486
|
+
}
|
|
674
487
|
|
|
675
|
-
/**
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
488
|
+
/** Will either get the existing sentry carrier, or create a new one. */
|
|
489
|
+
function getSentryCarrier(carrier) {
|
|
490
|
+
if (!carrier.__SENTRY__) {
|
|
491
|
+
carrier.__SENTRY__ = {
|
|
492
|
+
extensions: {},
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
return carrier.__SENTRY__;
|
|
681
496
|
}
|
|
682
497
|
|
|
683
498
|
/**
|
|
684
|
-
*
|
|
499
|
+
* This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.
|
|
500
|
+
*
|
|
501
|
+
* ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.
|
|
685
502
|
*/
|
|
686
|
-
|
|
687
|
-
processors,
|
|
688
|
-
event,
|
|
689
|
-
hint,
|
|
690
|
-
index = 0,
|
|
691
|
-
) {
|
|
692
|
-
return new SyncPromise((resolve, reject) => {
|
|
693
|
-
const processor = processors[index];
|
|
694
|
-
if (event === null || typeof processor !== 'function') {
|
|
695
|
-
resolve(event);
|
|
696
|
-
} else {
|
|
697
|
-
const result = processor({ ...event }, hint) ;
|
|
698
|
-
|
|
699
|
-
DEBUG_BUILD && processor.id && result === null && logger.log(`Event processor "${processor.id}" dropped event`);
|
|
503
|
+
const DEBUG_BUILD$1 = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);
|
|
700
504
|
|
|
701
|
-
|
|
702
|
-
void result
|
|
703
|
-
.then(final => notifyEventProcessors(processors, final, hint, index + 1).then(resolve))
|
|
704
|
-
.then(null, reject);
|
|
705
|
-
} else {
|
|
706
|
-
void notifyEventProcessors(processors, result, hint, index + 1)
|
|
707
|
-
.then(resolve)
|
|
708
|
-
.then(null, reject);
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
});
|
|
712
|
-
}
|
|
505
|
+
const DEFAULT_ENVIRONMENT = 'production';
|
|
713
506
|
|
|
714
507
|
/**
|
|
715
508
|
* Creates a new `Session` object by setting certain default parameters. If optional @param context
|
|
@@ -867,312 +660,20 @@ function sessionToJSON(session) {
|
|
|
867
660
|
});
|
|
868
661
|
}
|
|
869
662
|
|
|
870
|
-
const TRACE_FLAG_SAMPLED = 0x1;
|
|
871
|
-
|
|
872
|
-
/**
|
|
873
|
-
* Convert a span to a trace context, which can be sent as the `trace` context in an event.
|
|
874
|
-
*/
|
|
875
|
-
function spanToTraceContext(span) {
|
|
876
|
-
const { spanId: span_id, traceId: trace_id } = span.spanContext();
|
|
877
|
-
const { data, op, parent_span_id, status, tags, origin } = spanToJSON(span);
|
|
878
|
-
|
|
879
|
-
return dropUndefinedKeys({
|
|
880
|
-
data,
|
|
881
|
-
op,
|
|
882
|
-
parent_span_id,
|
|
883
|
-
span_id,
|
|
884
|
-
status,
|
|
885
|
-
tags,
|
|
886
|
-
trace_id,
|
|
887
|
-
origin,
|
|
888
|
-
});
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
/**
|
|
892
|
-
* Convert a span to a JSON representation.
|
|
893
|
-
* Note that all fields returned here are optional and need to be guarded against.
|
|
894
|
-
*
|
|
895
|
-
* Note: Because of this, we currently have a circular type dependency (which we opted out of in package.json).
|
|
896
|
-
* This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility.
|
|
897
|
-
* And `spanToJSON` needs the Span class from `span.ts` to check here.
|
|
898
|
-
* TODO v8: When we remove the deprecated stuff from `span.ts`, we can remove the circular dependency again.
|
|
899
|
-
*/
|
|
900
|
-
function spanToJSON(span) {
|
|
901
|
-
if (spanIsSpanClass(span)) {
|
|
902
|
-
return span.getSpanJSON();
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
// Fallback: We also check for `.toJSON()` here...
|
|
906
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
907
|
-
if (typeof span.toJSON === 'function') {
|
|
908
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
909
|
-
return span.toJSON();
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
return {};
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
/**
|
|
916
|
-
* Sadly, due to circular dependency checks we cannot actually import the Span class here and check for instanceof.
|
|
917
|
-
* :( So instead we approximate this by checking if it has the `getSpanJSON` method.
|
|
918
|
-
*/
|
|
919
|
-
function spanIsSpanClass(span) {
|
|
920
|
-
return typeof (span ).getSpanJSON === 'function';
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
/**
|
|
924
|
-
* Returns true if a span is sampled.
|
|
925
|
-
* In most cases, you should just use `span.isRecording()` instead.
|
|
926
|
-
* However, this has a slightly different semantic, as it also returns false if the span is finished.
|
|
927
|
-
* So in the case where this distinction is important, use this method.
|
|
928
|
-
*/
|
|
929
|
-
function spanIsSampled(span) {
|
|
930
|
-
// We align our trace flags with the ones OpenTelemetry use
|
|
931
|
-
// So we also check for sampled the same way they do.
|
|
932
|
-
const { traceFlags } = span.spanContext();
|
|
933
|
-
// eslint-disable-next-line no-bitwise
|
|
934
|
-
return Boolean(traceFlags & TRACE_FLAG_SAMPLED);
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
/**
|
|
938
|
-
* Get the currently active client.
|
|
939
|
-
*/
|
|
940
|
-
function getClient() {
|
|
941
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
942
|
-
return getCurrentHub().getClient();
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
/**
|
|
946
|
-
* Get the currently active scope.
|
|
947
|
-
*/
|
|
948
|
-
function getCurrentScope() {
|
|
949
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
950
|
-
return getCurrentHub().getScope();
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
/**
|
|
954
|
-
* Returns the root span of a given span.
|
|
955
|
-
*
|
|
956
|
-
* As long as we use `Transaction`s internally, the returned root span
|
|
957
|
-
* will be a `Transaction` but be aware that this might change in the future.
|
|
958
|
-
*
|
|
959
|
-
* If the given span has no root span or transaction, `undefined` is returned.
|
|
960
|
-
*/
|
|
961
|
-
function getRootSpan(span) {
|
|
962
|
-
// TODO (v8): Remove this check and just return span
|
|
963
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
964
|
-
return span.transaction;
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
/**
|
|
968
|
-
* Creates a dynamic sampling context from a client.
|
|
969
|
-
*
|
|
970
|
-
* Dispatches the `createDsc` lifecycle hook as a side effect.
|
|
971
|
-
*/
|
|
972
|
-
function getDynamicSamplingContextFromClient(
|
|
973
|
-
trace_id,
|
|
974
|
-
client,
|
|
975
|
-
scope,
|
|
976
|
-
) {
|
|
977
|
-
const options = client.getOptions();
|
|
978
|
-
|
|
979
|
-
const { publicKey: public_key } = client.getDsn() || {};
|
|
980
|
-
// TODO(v8): Remove segment from User
|
|
981
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
982
|
-
const { segment: user_segment } = (scope && scope.getUser()) || {};
|
|
983
|
-
|
|
984
|
-
const dsc = dropUndefinedKeys({
|
|
985
|
-
environment: options.environment || DEFAULT_ENVIRONMENT,
|
|
986
|
-
release: options.release,
|
|
987
|
-
user_segment,
|
|
988
|
-
public_key,
|
|
989
|
-
trace_id,
|
|
990
|
-
}) ;
|
|
991
|
-
|
|
992
|
-
client.emit && client.emit('createDsc', dsc);
|
|
993
|
-
|
|
994
|
-
return dsc;
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
/**
|
|
998
|
-
* A Span with a frozen dynamic sampling context.
|
|
999
|
-
*/
|
|
1000
|
-
|
|
1001
|
-
/**
|
|
1002
|
-
* Creates a dynamic sampling context from a span (and client and scope)
|
|
1003
|
-
*
|
|
1004
|
-
* @param span the span from which a few values like the root span name and sample rate are extracted.
|
|
1005
|
-
*
|
|
1006
|
-
* @returns a dynamic sampling context
|
|
1007
|
-
*/
|
|
1008
|
-
function getDynamicSamplingContextFromSpan(span) {
|
|
1009
|
-
const client = getClient();
|
|
1010
|
-
if (!client) {
|
|
1011
|
-
return {};
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
// passing emit=false here to only emit later once the DSC is actually populated
|
|
1015
|
-
const dsc = getDynamicSamplingContextFromClient(spanToJSON(span).trace_id || '', client, getCurrentScope());
|
|
1016
|
-
|
|
1017
|
-
// TODO (v8): Remove v7FrozenDsc as a Transaction will no longer have _frozenDynamicSamplingContext
|
|
1018
|
-
const txn = getRootSpan(span) ;
|
|
1019
|
-
if (!txn) {
|
|
1020
|
-
return dsc;
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
// TODO (v8): Remove v7FrozenDsc as a Transaction will no longer have _frozenDynamicSamplingContext
|
|
1024
|
-
// For now we need to avoid breaking users who directly created a txn with a DSC, where this field is still set.
|
|
1025
|
-
// @see Transaction class constructor
|
|
1026
|
-
const v7FrozenDsc = txn && txn._frozenDynamicSamplingContext;
|
|
1027
|
-
if (v7FrozenDsc) {
|
|
1028
|
-
return v7FrozenDsc;
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
// TODO (v8): Replace txn.metadata with txn.attributes[]
|
|
1032
|
-
// We can't do this yet because attributes aren't always set yet.
|
|
1033
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
1034
|
-
const { sampleRate: maybeSampleRate, source } = txn.metadata;
|
|
1035
|
-
if (maybeSampleRate != null) {
|
|
1036
|
-
dsc.sample_rate = `${maybeSampleRate}`;
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
// We don't want to have a transaction name in the DSC if the source is "url" because URLs might contain PII
|
|
1040
|
-
const jsonSpan = spanToJSON(txn);
|
|
1041
|
-
|
|
1042
|
-
// after JSON conversion, txn.name becomes jsonSpan.description
|
|
1043
|
-
if (source && source !== 'url') {
|
|
1044
|
-
dsc.transaction = jsonSpan.description;
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
dsc.sampled = String(spanIsSampled(txn));
|
|
1048
|
-
|
|
1049
|
-
client.emit && client.emit('createDsc', dsc);
|
|
1050
|
-
|
|
1051
|
-
return dsc;
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
/**
|
|
1055
|
-
* Applies data from the scope to the event and runs all event processors on it.
|
|
1056
|
-
*/
|
|
1057
|
-
function applyScopeDataToEvent(event, data) {
|
|
1058
|
-
const { fingerprint, span, breadcrumbs, sdkProcessingMetadata } = data;
|
|
1059
|
-
|
|
1060
|
-
// Apply general data
|
|
1061
|
-
applyDataToEvent(event, data);
|
|
1062
|
-
|
|
1063
|
-
// We want to set the trace context for normal events only if there isn't already
|
|
1064
|
-
// a trace context on the event. There is a product feature in place where we link
|
|
1065
|
-
// errors with transaction and it relies on that.
|
|
1066
|
-
if (span) {
|
|
1067
|
-
applySpanToEvent(event, span);
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
applyFingerprintToEvent(event, fingerprint);
|
|
1071
|
-
applyBreadcrumbsToEvent(event, breadcrumbs);
|
|
1072
|
-
applySdkMetadataToEvent(event, sdkProcessingMetadata);
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
function applyDataToEvent(event, data) {
|
|
1076
|
-
const {
|
|
1077
|
-
extra,
|
|
1078
|
-
tags,
|
|
1079
|
-
user,
|
|
1080
|
-
contexts,
|
|
1081
|
-
level,
|
|
1082
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
1083
|
-
transactionName,
|
|
1084
|
-
} = data;
|
|
1085
|
-
|
|
1086
|
-
const cleanedExtra = dropUndefinedKeys(extra);
|
|
1087
|
-
if (cleanedExtra && Object.keys(cleanedExtra).length) {
|
|
1088
|
-
event.extra = { ...cleanedExtra, ...event.extra };
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
const cleanedTags = dropUndefinedKeys(tags);
|
|
1092
|
-
if (cleanedTags && Object.keys(cleanedTags).length) {
|
|
1093
|
-
event.tags = { ...cleanedTags, ...event.tags };
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
const cleanedUser = dropUndefinedKeys(user);
|
|
1097
|
-
if (cleanedUser && Object.keys(cleanedUser).length) {
|
|
1098
|
-
event.user = { ...cleanedUser, ...event.user };
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
const cleanedContexts = dropUndefinedKeys(contexts);
|
|
1102
|
-
if (cleanedContexts && Object.keys(cleanedContexts).length) {
|
|
1103
|
-
event.contexts = { ...cleanedContexts, ...event.contexts };
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
if (level) {
|
|
1107
|
-
event.level = level;
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
if (transactionName) {
|
|
1111
|
-
event.transaction = transactionName;
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
function applyBreadcrumbsToEvent(event, breadcrumbs) {
|
|
1116
|
-
const mergedBreadcrumbs = [...(event.breadcrumbs || []), ...breadcrumbs];
|
|
1117
|
-
event.breadcrumbs = mergedBreadcrumbs.length ? mergedBreadcrumbs : undefined;
|
|
1118
|
-
}
|
|
1119
|
-
|
|
1120
|
-
function applySdkMetadataToEvent(event, sdkProcessingMetadata) {
|
|
1121
|
-
event.sdkProcessingMetadata = {
|
|
1122
|
-
...event.sdkProcessingMetadata,
|
|
1123
|
-
...sdkProcessingMetadata,
|
|
1124
|
-
};
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
function applySpanToEvent(event, span) {
|
|
1128
|
-
event.contexts = { trace: spanToTraceContext(span), ...event.contexts };
|
|
1129
|
-
const rootSpan = getRootSpan(span);
|
|
1130
|
-
if (rootSpan) {
|
|
1131
|
-
event.sdkProcessingMetadata = {
|
|
1132
|
-
dynamicSamplingContext: getDynamicSamplingContextFromSpan(span),
|
|
1133
|
-
...event.sdkProcessingMetadata,
|
|
1134
|
-
};
|
|
1135
|
-
const transactionName = spanToJSON(rootSpan).description;
|
|
1136
|
-
if (transactionName) {
|
|
1137
|
-
event.tags = { transaction: transactionName, ...event.tags };
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
/**
|
|
1143
|
-
* Applies fingerprint from the scope to the event if there's one,
|
|
1144
|
-
* uses message if there's one instead or get rid of empty fingerprint
|
|
1145
|
-
*/
|
|
1146
|
-
function applyFingerprintToEvent(event, fingerprint) {
|
|
1147
|
-
// Make sure it's an array first and we actually have something in place
|
|
1148
|
-
event.fingerprint = event.fingerprint ? arrayify(event.fingerprint) : [];
|
|
1149
|
-
|
|
1150
|
-
// If we have something on the scope, then merge it with event
|
|
1151
|
-
if (fingerprint) {
|
|
1152
|
-
event.fingerprint = event.fingerprint.concat(fingerprint);
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
// If we have no data at all, remove empty array default
|
|
1156
|
-
if (event.fingerprint && !event.fingerprint.length) {
|
|
1157
|
-
delete event.fingerprint;
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
663
|
/**
|
|
1162
664
|
* Default value for maximum number of breadcrumbs added to an event.
|
|
1163
665
|
*/
|
|
1164
666
|
const DEFAULT_MAX_BREADCRUMBS = 100;
|
|
1165
667
|
|
|
1166
668
|
/**
|
|
1167
|
-
* Holds additional event information.
|
|
1168
|
-
* called by the client before an event will be sent.
|
|
669
|
+
* Holds additional event information.
|
|
1169
670
|
*/
|
|
1170
671
|
class Scope {
|
|
1171
672
|
/** Flag if notifying is happening. */
|
|
1172
673
|
|
|
1173
674
|
/** Callback for client to receive scope changes. */
|
|
1174
675
|
|
|
1175
|
-
/** Callback list that will be called
|
|
676
|
+
/** Callback list that will be called during event processing. */
|
|
1176
677
|
|
|
1177
678
|
/** Array of breadcrumbs. */
|
|
1178
679
|
|
|
@@ -1196,7 +697,6 @@ class Scope {
|
|
|
1196
697
|
/** Fingerprint */
|
|
1197
698
|
|
|
1198
699
|
/** Severity */
|
|
1199
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
1200
700
|
|
|
1201
701
|
/**
|
|
1202
702
|
* Transaction Name
|
|
@@ -1270,7 +770,7 @@ class Scope {
|
|
|
1270
770
|
* It is generally recommended to use the global function `Sentry.getClient()` instead, unless you know what you are doing.
|
|
1271
771
|
*/
|
|
1272
772
|
getClient() {
|
|
1273
|
-
return this._client;
|
|
773
|
+
return this._client ;
|
|
1274
774
|
}
|
|
1275
775
|
|
|
1276
776
|
/**
|
|
@@ -1299,7 +799,6 @@ class Scope {
|
|
|
1299
799
|
email: undefined,
|
|
1300
800
|
id: undefined,
|
|
1301
801
|
ip_address: undefined,
|
|
1302
|
-
segment: undefined,
|
|
1303
802
|
username: undefined,
|
|
1304
803
|
};
|
|
1305
804
|
|
|
@@ -1387,10 +886,7 @@ class Scope {
|
|
|
1387
886
|
/**
|
|
1388
887
|
* @inheritDoc
|
|
1389
888
|
*/
|
|
1390
|
-
setLevel(
|
|
1391
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
1392
|
-
level,
|
|
1393
|
-
) {
|
|
889
|
+
setLevel(level) {
|
|
1394
890
|
this._level = level;
|
|
1395
891
|
this._notifyScopeListeners();
|
|
1396
892
|
return this;
|
|
@@ -1448,10 +944,15 @@ class Scope {
|
|
|
1448
944
|
// Often, this span (if it exists at all) will be a transaction, but it's not guaranteed to be. Regardless, it will
|
|
1449
945
|
// have a pointer to the currently-active transaction.
|
|
1450
946
|
const span = this._span;
|
|
947
|
+
|
|
1451
948
|
// Cannot replace with getRootSpan because getRootSpan returns a span, not a transaction
|
|
1452
949
|
// Also, this method will be removed anyway.
|
|
1453
950
|
// eslint-disable-next-line deprecation/deprecation
|
|
1454
|
-
|
|
951
|
+
if (span && (span ).transaction) {
|
|
952
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
953
|
+
return (span ).transaction;
|
|
954
|
+
}
|
|
955
|
+
return undefined;
|
|
1455
956
|
}
|
|
1456
957
|
|
|
1457
958
|
/**
|
|
@@ -1534,6 +1035,7 @@ class Scope {
|
|
|
1534
1035
|
* @inheritDoc
|
|
1535
1036
|
*/
|
|
1536
1037
|
clear() {
|
|
1038
|
+
// client is not cleared here on purpose!
|
|
1537
1039
|
this._breadcrumbs = [];
|
|
1538
1040
|
this._tags = {};
|
|
1539
1041
|
this._extra = {};
|
|
@@ -1653,32 +1155,6 @@ class Scope {
|
|
|
1653
1155
|
};
|
|
1654
1156
|
}
|
|
1655
1157
|
|
|
1656
|
-
/**
|
|
1657
|
-
* Applies data from the scope to the event and runs all event processors on it.
|
|
1658
|
-
*
|
|
1659
|
-
* @param event Event
|
|
1660
|
-
* @param hint Object containing additional information about the original exception, for use by the event processors.
|
|
1661
|
-
* @hidden
|
|
1662
|
-
* @deprecated Use `applyScopeDataToEvent()` directly
|
|
1663
|
-
*/
|
|
1664
|
-
applyToEvent(
|
|
1665
|
-
event,
|
|
1666
|
-
hint = {},
|
|
1667
|
-
additionalEventProcessors = [],
|
|
1668
|
-
) {
|
|
1669
|
-
applyScopeDataToEvent(event, this.getScopeData());
|
|
1670
|
-
|
|
1671
|
-
// TODO (v8): Update this order to be: Global > Client > Scope
|
|
1672
|
-
const eventProcessors = [
|
|
1673
|
-
...additionalEventProcessors,
|
|
1674
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
1675
|
-
...getGlobalEventProcessors(),
|
|
1676
|
-
...this._eventProcessors,
|
|
1677
|
-
];
|
|
1678
|
-
|
|
1679
|
-
return notifyEventProcessors(eventProcessors, event, hint);
|
|
1680
|
-
}
|
|
1681
|
-
|
|
1682
1158
|
/**
|
|
1683
1159
|
* Add data which will be accessible during event processing but won't get sent to Sentry
|
|
1684
1160
|
*/
|
|
@@ -1811,7 +1287,7 @@ function generatePropagationContext() {
|
|
|
1811
1287
|
};
|
|
1812
1288
|
}
|
|
1813
1289
|
|
|
1814
|
-
const SDK_VERSION = '
|
|
1290
|
+
const SDK_VERSION = '8.0.0-alpha.2';
|
|
1815
1291
|
|
|
1816
1292
|
/**
|
|
1817
1293
|
* API compatibility version of this hub.
|
|
@@ -1829,14 +1305,17 @@ const API_VERSION = parseFloat(SDK_VERSION);
|
|
|
1829
1305
|
*/
|
|
1830
1306
|
const DEFAULT_BREADCRUMBS = 100;
|
|
1831
1307
|
|
|
1308
|
+
/**
|
|
1309
|
+
* A layer in the process stack.
|
|
1310
|
+
* @hidden
|
|
1311
|
+
*/
|
|
1312
|
+
|
|
1832
1313
|
/**
|
|
1833
1314
|
* @inheritDoc
|
|
1834
1315
|
*/
|
|
1835
1316
|
class Hub {
|
|
1836
1317
|
/** Is a {@link Layer}[] containing the client and scope */
|
|
1837
1318
|
|
|
1838
|
-
/** Contains the last event id of a captured event. */
|
|
1839
|
-
|
|
1840
1319
|
/**
|
|
1841
1320
|
* Creates a new instance of the hub, will push one {@link Layer} into the
|
|
1842
1321
|
* internal stack on creation.
|
|
@@ -2065,7 +1544,7 @@ class Hub {
|
|
|
2065
1544
|
* @deprecated Use `Sentry.captureException()` instead.
|
|
2066
1545
|
*/
|
|
2067
1546
|
captureException(exception, hint) {
|
|
2068
|
-
const eventId =
|
|
1547
|
+
const eventId = hint && hint.event_id ? hint.event_id : uuid4();
|
|
2069
1548
|
const syntheticException = new Error('Sentry syntheticException');
|
|
2070
1549
|
// eslint-disable-next-line deprecation/deprecation
|
|
2071
1550
|
this.getScope().captureException(exception, {
|
|
@@ -2083,13 +1562,8 @@ class Hub {
|
|
|
2083
1562
|
*
|
|
2084
1563
|
* @deprecated Use `Sentry.captureMessage()` instead.
|
|
2085
1564
|
*/
|
|
2086
|
-
captureMessage(
|
|
2087
|
-
|
|
2088
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
2089
|
-
level,
|
|
2090
|
-
hint,
|
|
2091
|
-
) {
|
|
2092
|
-
const eventId = (this._lastEventId = hint && hint.event_id ? hint.event_id : uuid4());
|
|
1565
|
+
captureMessage(message, level, hint) {
|
|
1566
|
+
const eventId = hint && hint.event_id ? hint.event_id : uuid4();
|
|
2093
1567
|
const syntheticException = new Error(message);
|
|
2094
1568
|
// eslint-disable-next-line deprecation/deprecation
|
|
2095
1569
|
this.getScope().captureMessage(message, level, {
|
|
@@ -2109,23 +1583,11 @@ class Hub {
|
|
|
2109
1583
|
*/
|
|
2110
1584
|
captureEvent(event, hint) {
|
|
2111
1585
|
const eventId = hint && hint.event_id ? hint.event_id : uuid4();
|
|
2112
|
-
if (!event.type) {
|
|
2113
|
-
this._lastEventId = eventId;
|
|
2114
|
-
}
|
|
2115
1586
|
// eslint-disable-next-line deprecation/deprecation
|
|
2116
1587
|
this.getScope().captureEvent(event, { ...hint, event_id: eventId });
|
|
2117
1588
|
return eventId;
|
|
2118
1589
|
}
|
|
2119
1590
|
|
|
2120
|
-
/**
|
|
2121
|
-
* @inheritDoc
|
|
2122
|
-
*
|
|
2123
|
-
* @deprecated This will be removed in v8.
|
|
2124
|
-
*/
|
|
2125
|
-
lastEventId() {
|
|
2126
|
-
return this._lastEventId;
|
|
2127
|
-
}
|
|
2128
|
-
|
|
2129
1591
|
/**
|
|
2130
1592
|
* @inheritDoc
|
|
2131
1593
|
*
|
|
@@ -2133,7 +1595,7 @@ class Hub {
|
|
|
2133
1595
|
*/
|
|
2134
1596
|
addBreadcrumb(breadcrumb, hint) {
|
|
2135
1597
|
// eslint-disable-next-line deprecation/deprecation
|
|
2136
|
-
const {
|
|
1598
|
+
const { client } = this.getStackTop();
|
|
2137
1599
|
|
|
2138
1600
|
if (!client) return;
|
|
2139
1601
|
|
|
@@ -2150,19 +1612,10 @@ class Hub {
|
|
|
2150
1612
|
|
|
2151
1613
|
if (finalBreadcrumb === null) return;
|
|
2152
1614
|
|
|
2153
|
-
|
|
2154
|
-
client.emit('beforeAddBreadcrumb', finalBreadcrumb, hint);
|
|
2155
|
-
}
|
|
2156
|
-
|
|
2157
|
-
// TODO(v8): I know this comment doesn't make much sense because the hub will be deprecated but I still wanted to
|
|
2158
|
-
// write it down. In theory, we would have to add the breadcrumbs to the isolation scope here, however, that would
|
|
2159
|
-
// duplicate all of the breadcrumbs. There was the possibility of adding breadcrumbs to both, the isolation scope
|
|
2160
|
-
// and the normal scope, and deduplicating it down the line in the event processing pipeline. However, that would
|
|
2161
|
-
// have been very fragile, because the breadcrumb objects would have needed to keep their identity all throughout
|
|
2162
|
-
// the event processing pipeline.
|
|
2163
|
-
// In the new implementation, the top level `Sentry.addBreadcrumb()` should ONLY write to the isolation scope.
|
|
1615
|
+
client.emit('beforeAddBreadcrumb', finalBreadcrumb, hint);
|
|
2164
1616
|
|
|
2165
|
-
|
|
1617
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
1618
|
+
this.getIsolationScope().addBreadcrumb(finalBreadcrumb, maxBreadcrumbs);
|
|
2166
1619
|
}
|
|
2167
1620
|
|
|
2168
1621
|
/**
|
|
@@ -2170,9 +1623,6 @@ class Hub {
|
|
|
2170
1623
|
* @deprecated Use `Sentry.setUser()` instead.
|
|
2171
1624
|
*/
|
|
2172
1625
|
setUser(user) {
|
|
2173
|
-
// TODO(v8): The top level `Sentry.setUser()` function should write ONLY to the isolation scope.
|
|
2174
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
2175
|
-
this.getScope().setUser(user);
|
|
2176
1626
|
// eslint-disable-next-line deprecation/deprecation
|
|
2177
1627
|
this.getIsolationScope().setUser(user);
|
|
2178
1628
|
}
|
|
@@ -2182,9 +1632,6 @@ class Hub {
|
|
|
2182
1632
|
* @deprecated Use `Sentry.setTags()` instead.
|
|
2183
1633
|
*/
|
|
2184
1634
|
setTags(tags) {
|
|
2185
|
-
// TODO(v8): The top level `Sentry.setTags()` function should write ONLY to the isolation scope.
|
|
2186
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
2187
|
-
this.getScope().setTags(tags);
|
|
2188
1635
|
// eslint-disable-next-line deprecation/deprecation
|
|
2189
1636
|
this.getIsolationScope().setTags(tags);
|
|
2190
1637
|
}
|
|
@@ -2194,9 +1641,6 @@ class Hub {
|
|
|
2194
1641
|
* @deprecated Use `Sentry.setExtras()` instead.
|
|
2195
1642
|
*/
|
|
2196
1643
|
setExtras(extras) {
|
|
2197
|
-
// TODO(v8): The top level `Sentry.setExtras()` function should write ONLY to the isolation scope.
|
|
2198
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
2199
|
-
this.getScope().setExtras(extras);
|
|
2200
1644
|
// eslint-disable-next-line deprecation/deprecation
|
|
2201
1645
|
this.getIsolationScope().setExtras(extras);
|
|
2202
1646
|
}
|
|
@@ -2206,9 +1650,6 @@ class Hub {
|
|
|
2206
1650
|
* @deprecated Use `Sentry.setTag()` instead.
|
|
2207
1651
|
*/
|
|
2208
1652
|
setTag(key, value) {
|
|
2209
|
-
// TODO(v8): The top level `Sentry.setTag()` function should write ONLY to the isolation scope.
|
|
2210
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
2211
|
-
this.getScope().setTag(key, value);
|
|
2212
1653
|
// eslint-disable-next-line deprecation/deprecation
|
|
2213
1654
|
this.getIsolationScope().setTag(key, value);
|
|
2214
1655
|
}
|
|
@@ -2218,9 +1659,6 @@ class Hub {
|
|
|
2218
1659
|
* @deprecated Use `Sentry.setExtra()` instead.
|
|
2219
1660
|
*/
|
|
2220
1661
|
setExtra(key, extra) {
|
|
2221
|
-
// TODO(v8): The top level `Sentry.setExtra()` function should write ONLY to the isolation scope.
|
|
2222
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
2223
|
-
this.getScope().setExtra(key, extra);
|
|
2224
1662
|
// eslint-disable-next-line deprecation/deprecation
|
|
2225
1663
|
this.getIsolationScope().setExtra(key, extra);
|
|
2226
1664
|
}
|
|
@@ -2231,40 +1669,10 @@ class Hub {
|
|
|
2231
1669
|
*/
|
|
2232
1670
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2233
1671
|
setContext(name, context) {
|
|
2234
|
-
// TODO(v8): The top level `Sentry.setContext()` function should write ONLY to the isolation scope.
|
|
2235
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
2236
|
-
this.getScope().setContext(name, context);
|
|
2237
1672
|
// eslint-disable-next-line deprecation/deprecation
|
|
2238
1673
|
this.getIsolationScope().setContext(name, context);
|
|
2239
1674
|
}
|
|
2240
1675
|
|
|
2241
|
-
/**
|
|
2242
|
-
* @inheritDoc
|
|
2243
|
-
*
|
|
2244
|
-
* @deprecated Use `getScope()` directly.
|
|
2245
|
-
*/
|
|
2246
|
-
configureScope(callback) {
|
|
2247
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
2248
|
-
const { scope, client } = this.getStackTop();
|
|
2249
|
-
if (client) {
|
|
2250
|
-
callback(scope);
|
|
2251
|
-
}
|
|
2252
|
-
}
|
|
2253
|
-
|
|
2254
|
-
/**
|
|
2255
|
-
* @inheritDoc
|
|
2256
|
-
*/
|
|
2257
|
-
run(callback) {
|
|
2258
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
2259
|
-
const oldHub = makeMain(this);
|
|
2260
|
-
try {
|
|
2261
|
-
callback(this);
|
|
2262
|
-
} finally {
|
|
2263
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
2264
|
-
makeMain(oldHub);
|
|
2265
|
-
}
|
|
2266
|
-
}
|
|
2267
|
-
|
|
2268
1676
|
/**
|
|
2269
1677
|
* @inheritDoc
|
|
2270
1678
|
* @deprecated Use `Sentry.getClient().getIntegrationByName()` instead.
|
|
@@ -2277,7 +1685,7 @@ class Hub {
|
|
|
2277
1685
|
// eslint-disable-next-line deprecation/deprecation
|
|
2278
1686
|
return client.getIntegration(integration);
|
|
2279
1687
|
} catch (_oO) {
|
|
2280
|
-
DEBUG_BUILD && logger.warn(`Cannot retrieve integration ${integration.id} from the current Hub`);
|
|
1688
|
+
DEBUG_BUILD$1 && logger.warn(`Cannot retrieve integration ${integration.id} from the current Hub`);
|
|
2281
1689
|
return null;
|
|
2282
1690
|
}
|
|
2283
1691
|
}
|
|
@@ -2304,7 +1712,7 @@ class Hub {
|
|
|
2304
1712
|
startTransaction(context, customSamplingContext) {
|
|
2305
1713
|
const result = this._callExtensionMethod('startTransaction', context, customSamplingContext);
|
|
2306
1714
|
|
|
2307
|
-
if (DEBUG_BUILD && !result) {
|
|
1715
|
+
if (DEBUG_BUILD$1 && !result) {
|
|
2308
1716
|
// eslint-disable-next-line deprecation/deprecation
|
|
2309
1717
|
const client = this.getClient();
|
|
2310
1718
|
if (!client) {
|
|
@@ -2322,14 +1730,6 @@ Sentry.init({...});
|
|
|
2322
1730
|
return result;
|
|
2323
1731
|
}
|
|
2324
1732
|
|
|
2325
|
-
/**
|
|
2326
|
-
* @inheritDoc
|
|
2327
|
-
* @deprecated Use `spanToTraceHeader()` instead.
|
|
2328
|
-
*/
|
|
2329
|
-
traceHeaders() {
|
|
2330
|
-
return this._callExtensionMethod('traceHeaders');
|
|
2331
|
-
}
|
|
2332
|
-
|
|
2333
1733
|
/**
|
|
2334
1734
|
* @inheritDoc
|
|
2335
1735
|
*
|
|
@@ -2432,43 +1832,14 @@ Sentry.init({...});
|
|
|
2432
1832
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2433
1833
|
_callExtensionMethod(method, ...args) {
|
|
2434
1834
|
const carrier = getMainCarrier();
|
|
2435
|
-
const sentry = carrier
|
|
2436
|
-
if (sentry
|
|
1835
|
+
const sentry = getSentryCarrier(carrier);
|
|
1836
|
+
if (sentry.extensions && typeof sentry.extensions[method] === 'function') {
|
|
2437
1837
|
return sentry.extensions[method].apply(this, args);
|
|
2438
1838
|
}
|
|
2439
|
-
DEBUG_BUILD && logger.warn(`Extension method ${method} couldn't be found, doing nothing.`);
|
|
1839
|
+
DEBUG_BUILD$1 && logger.warn(`Extension method ${method} couldn't be found, doing nothing.`);
|
|
2440
1840
|
}
|
|
2441
1841
|
}
|
|
2442
1842
|
|
|
2443
|
-
/**
|
|
2444
|
-
* Returns the global shim registry.
|
|
2445
|
-
*
|
|
2446
|
-
* FIXME: This function is problematic, because despite always returning a valid Carrier,
|
|
2447
|
-
* it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check
|
|
2448
|
-
* at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there.
|
|
2449
|
-
**/
|
|
2450
|
-
function getMainCarrier() {
|
|
2451
|
-
GLOBAL_OBJ.__SENTRY__ = GLOBAL_OBJ.__SENTRY__ || {
|
|
2452
|
-
extensions: {},
|
|
2453
|
-
hub: undefined,
|
|
2454
|
-
};
|
|
2455
|
-
return GLOBAL_OBJ;
|
|
2456
|
-
}
|
|
2457
|
-
|
|
2458
|
-
/**
|
|
2459
|
-
* Replaces the current main hub with the passed one on the global object
|
|
2460
|
-
*
|
|
2461
|
-
* @returns The old replaced hub
|
|
2462
|
-
*
|
|
2463
|
-
* @deprecated Use `setCurrentClient()` instead.
|
|
2464
|
-
*/
|
|
2465
|
-
function makeMain(hub) {
|
|
2466
|
-
const registry = getMainCarrier();
|
|
2467
|
-
const oldHub = getHubFromCarrier(registry);
|
|
2468
|
-
setHubOnCarrier(registry, hub);
|
|
2469
|
-
return oldHub;
|
|
2470
|
-
}
|
|
2471
|
-
|
|
2472
1843
|
/**
|
|
2473
1844
|
* Returns the default hub instance.
|
|
2474
1845
|
*
|
|
@@ -2480,67 +1851,141 @@ function makeMain(hub) {
|
|
|
2480
1851
|
*/
|
|
2481
1852
|
function getCurrentHub() {
|
|
2482
1853
|
// Get main carrier (global for every environment)
|
|
2483
|
-
const
|
|
1854
|
+
const carrier = getMainCarrier();
|
|
1855
|
+
|
|
1856
|
+
const acs = getAsyncContextStrategy(carrier);
|
|
1857
|
+
return acs.getCurrentHub() || getGlobalHub();
|
|
1858
|
+
}
|
|
2484
1859
|
|
|
2485
|
-
|
|
2486
|
-
|
|
1860
|
+
let defaultCurrentScope;
|
|
1861
|
+
let defaultIsolationScope;
|
|
2487
1862
|
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
1863
|
+
/** Get the default current scope. */
|
|
1864
|
+
function getDefaultCurrentScope() {
|
|
1865
|
+
if (!defaultCurrentScope) {
|
|
1866
|
+
defaultCurrentScope = new Scope();
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
return defaultCurrentScope;
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
/** Get the default isolation scope. */
|
|
1873
|
+
function getDefaultIsolationScope() {
|
|
1874
|
+
if (!defaultIsolationScope) {
|
|
1875
|
+
defaultIsolationScope = new Scope();
|
|
2491
1876
|
}
|
|
2492
1877
|
|
|
2493
|
-
|
|
2494
|
-
return getGlobalHub(registry);
|
|
1878
|
+
return defaultIsolationScope;
|
|
2495
1879
|
}
|
|
2496
1880
|
|
|
2497
|
-
|
|
1881
|
+
/**
|
|
1882
|
+
* Get the global hub.
|
|
1883
|
+
* This will be removed during the v8 cycle and is only here to make migration easier.
|
|
1884
|
+
*/
|
|
1885
|
+
function getGlobalHub() {
|
|
1886
|
+
const registry = getMainCarrier();
|
|
1887
|
+
const sentry = getSentryCarrier(registry) ;
|
|
1888
|
+
|
|
2498
1889
|
// If there's no hub, or its an old API, assign a new one
|
|
1890
|
+
if (sentry.hub) {
|
|
1891
|
+
return sentry.hub;
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
1895
|
+
sentry.hub = new Hub(undefined, getDefaultCurrentScope(), getDefaultIsolationScope());
|
|
1896
|
+
return sentry.hub;
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
/**
|
|
1900
|
+
* Get the current async context strategy.
|
|
1901
|
+
* If none has been setup, the default will be used.
|
|
1902
|
+
*/
|
|
1903
|
+
function getAsyncContextStrategy(carrier) {
|
|
1904
|
+
const sentry = getSentryCarrier(carrier);
|
|
1905
|
+
|
|
1906
|
+
if (sentry.acs) {
|
|
1907
|
+
return sentry.acs;
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
// Otherwise, use the default one
|
|
1911
|
+
return getHubStackAsyncContextStrategy();
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
function withScope(callback) {
|
|
1915
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
1916
|
+
return getGlobalHub().withScope(callback);
|
|
1917
|
+
}
|
|
2499
1918
|
|
|
2500
|
-
|
|
2501
|
-
|
|
1919
|
+
function withSetScope(scope, callback) {
|
|
1920
|
+
const hub = getGlobalHub() ;
|
|
1921
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
1922
|
+
return hub.withScope(() => {
|
|
2502
1923
|
// eslint-disable-next-line deprecation/deprecation
|
|
2503
|
-
|
|
2504
|
-
|
|
1924
|
+
hub.getStackTop().scope = scope ;
|
|
1925
|
+
return callback(scope);
|
|
1926
|
+
});
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
function withIsolationScope(callback) {
|
|
1930
|
+
// eslint-disable-next-line deprecation/deprecation
|
|
1931
|
+
return getGlobalHub().withScope(() => {
|
|
2505
1932
|
// eslint-disable-next-line deprecation/deprecation
|
|
2506
|
-
|
|
2507
|
-
}
|
|
1933
|
+
return callback(getGlobalHub().getIsolationScope());
|
|
1934
|
+
});
|
|
1935
|
+
}
|
|
2508
1936
|
|
|
2509
|
-
|
|
2510
|
-
|
|
1937
|
+
/* eslint-disable deprecation/deprecation */
|
|
1938
|
+
function getHubStackAsyncContextStrategy() {
|
|
1939
|
+
return {
|
|
1940
|
+
getCurrentHub: getGlobalHub,
|
|
1941
|
+
withIsolationScope,
|
|
1942
|
+
withScope,
|
|
1943
|
+
withSetScope,
|
|
1944
|
+
withSetIsolationScope: (_isolationScope, callback) => {
|
|
1945
|
+
return withIsolationScope(callback);
|
|
1946
|
+
},
|
|
1947
|
+
getCurrentScope: () => getGlobalHub().getScope(),
|
|
1948
|
+
getIsolationScope: () => getGlobalHub().getIsolationScope(),
|
|
1949
|
+
};
|
|
2511
1950
|
}
|
|
2512
1951
|
|
|
2513
1952
|
/**
|
|
2514
|
-
*
|
|
2515
|
-
*
|
|
1953
|
+
* Convert a span to a JSON representation.
|
|
1954
|
+
* Note that all fields returned here are optional and need to be guarded against.
|
|
1955
|
+
*
|
|
1956
|
+
* Note: Because of this, we currently have a circular type dependency (which we opted out of in package.json).
|
|
1957
|
+
* This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility.
|
|
1958
|
+
* And `spanToJSON` needs the Span class from `span.ts` to check here.
|
|
2516
1959
|
*/
|
|
2517
|
-
function
|
|
2518
|
-
|
|
1960
|
+
function spanToJSON(span) {
|
|
1961
|
+
if (spanIsSentrySpan(span)) {
|
|
1962
|
+
return span.getSpanJSON();
|
|
1963
|
+
}
|
|
1964
|
+
|
|
1965
|
+
// Fallback: We also check for `.toJSON()` here...
|
|
1966
|
+
if (typeof (span ).toJSON === 'function') {
|
|
1967
|
+
return (span ).toJSON();
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
// TODO: Also handle OTEL spans here!
|
|
1971
|
+
|
|
1972
|
+
return {};
|
|
2519
1973
|
}
|
|
2520
1974
|
|
|
2521
1975
|
/**
|
|
2522
|
-
*
|
|
2523
|
-
*
|
|
2524
|
-
* @param carrier object
|
|
2525
|
-
* @hidden
|
|
1976
|
+
* Sadly, due to circular dependency checks we cannot actually import the Span class here and check for instanceof.
|
|
1977
|
+
* :( So instead we approximate this by checking if it has the `getSpanJSON` method.
|
|
2526
1978
|
*/
|
|
2527
|
-
function
|
|
2528
|
-
|
|
2529
|
-
return getGlobalSingleton('hub', () => new Hub(), carrier);
|
|
1979
|
+
function spanIsSentrySpan(span) {
|
|
1980
|
+
return typeof (span ).getSpanJSON === 'function';
|
|
2530
1981
|
}
|
|
2531
1982
|
|
|
2532
1983
|
/**
|
|
2533
|
-
* This will
|
|
2534
|
-
*
|
|
2535
|
-
*
|
|
2536
|
-
* @returns A boolean indicating success or failure
|
|
1984
|
+
* This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.
|
|
1985
|
+
*
|
|
1986
|
+
* ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.
|
|
2537
1987
|
*/
|
|
2538
|
-
|
|
2539
|
-
if (!carrier) return false;
|
|
2540
|
-
const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {});
|
|
2541
|
-
__SENTRY__.hub = hub;
|
|
2542
|
-
return true;
|
|
2543
|
-
}
|
|
1988
|
+
const DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);
|
|
2544
1989
|
|
|
2545
1990
|
const stdlib = detectLibc.familySync();
|
|
2546
1991
|
const platform = process.env['BUILD_PLATFORM'] || os.platform();
|
|
@@ -2563,7 +2008,6 @@ function importCppBindingsModule() {
|
|
|
2563
2008
|
const binaryPath = path.join(path.resolve(process$1.env['SENTRY_PROFILER_BINARY_DIR']), `sentry_cpu_profiler-${identifier}`);
|
|
2564
2009
|
return require(`${binaryPath}.node`);
|
|
2565
2010
|
}
|
|
2566
|
-
/* eslint-disable no-fallthrough */
|
|
2567
2011
|
// We need the fallthrough so that in the end, we can fallback to the require dynamice require.
|
|
2568
2012
|
// This is for cases where precompiled binaries were not provided, but may have been compiled from source.
|
|
2569
2013
|
if (platform === 'darwin') {
|
|
@@ -2659,14 +2103,14 @@ const PrivateCpuProfilerBindings = importCppBindingsModule();
|
|
|
2659
2103
|
const CpuProfilerBindings = {
|
|
2660
2104
|
startProfiling(name) {
|
|
2661
2105
|
if (!PrivateCpuProfilerBindings) {
|
|
2662
|
-
DEBUG_BUILD
|
|
2106
|
+
DEBUG_BUILD && logger.log('[Profiling] Bindings not loaded, ignoring call to startProfiling.');
|
|
2663
2107
|
return;
|
|
2664
2108
|
}
|
|
2665
2109
|
return PrivateCpuProfilerBindings.startProfiling(name);
|
|
2666
2110
|
},
|
|
2667
2111
|
stopProfiling(name) {
|
|
2668
2112
|
if (!PrivateCpuProfilerBindings) {
|
|
2669
|
-
DEBUG_BUILD
|
|
2113
|
+
DEBUG_BUILD &&
|
|
2670
2114
|
logger.log('[Profiling] Bindings not loaded or profile was never started, ignoring call to stopProfiling.');
|
|
2671
2115
|
return null;
|
|
2672
2116
|
}
|
|
@@ -2677,7 +2121,6 @@ const CpuProfilerBindings = {
|
|
|
2677
2121
|
/* eslint-disable max-lines */
|
|
2678
2122
|
// We require the file because if we import it, it will be included in the bundle.
|
|
2679
2123
|
// I guess tsc does not check file contents when it's imported.
|
|
2680
|
-
// eslint-disable-next-line
|
|
2681
2124
|
const THREAD_ID_STRING = String(worker_threads.threadId);
|
|
2682
2125
|
const THREAD_NAME = worker_threads.isMainThread ? 'main' : 'worker';
|
|
2683
2126
|
const FORMAT_VERSION = '1';
|
|
@@ -2831,7 +2274,7 @@ function createProfilePayload(cpuProfile, { release, environment, event_id, tran
|
|
|
2831
2274
|
// All profiles and transactions are rejected if this is the case and we want to
|
|
2832
2275
|
// warn users that this is happening if they enable debug flag
|
|
2833
2276
|
if (trace_id && trace_id.length !== 32) {
|
|
2834
|
-
DEBUG_BUILD
|
|
2277
|
+
DEBUG_BUILD && logger.log(`[Profiling] Invalid traceId: ${trace_id} on profiled event`);
|
|
2835
2278
|
}
|
|
2836
2279
|
const enrichedThreadProfile = enrichWithThreadInformation(cpuProfile);
|
|
2837
2280
|
const profile = {
|
|
@@ -2927,7 +2370,7 @@ function maybeRemoveProfileFromSdkMetadata(event) {
|
|
|
2927
2370
|
function isValidSampleRate(rate) {
|
|
2928
2371
|
// we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck
|
|
2929
2372
|
if ((typeof rate !== 'number' && typeof rate !== 'boolean') || (typeof rate === 'number' && isNaN(rate))) {
|
|
2930
|
-
DEBUG_BUILD
|
|
2373
|
+
DEBUG_BUILD &&
|
|
2931
2374
|
logger.warn(`[Profiling] Invalid sample rate. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify(rate)} of type ${JSON.stringify(typeof rate)}.`);
|
|
2932
2375
|
return false;
|
|
2933
2376
|
}
|
|
@@ -2937,7 +2380,7 @@ function isValidSampleRate(rate) {
|
|
|
2937
2380
|
}
|
|
2938
2381
|
// in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false
|
|
2939
2382
|
if (rate < 0 || rate > 1) {
|
|
2940
|
-
DEBUG_BUILD
|
|
2383
|
+
DEBUG_BUILD && logger.warn(`[Profiling] Invalid sample rate. Sample rate must be between 0 and 1. Got ${rate}.`);
|
|
2941
2384
|
return false;
|
|
2942
2385
|
}
|
|
2943
2386
|
return true;
|
|
@@ -2949,7 +2392,7 @@ function isValidSampleRate(rate) {
|
|
|
2949
2392
|
*/
|
|
2950
2393
|
function isValidProfile(profile) {
|
|
2951
2394
|
if (profile.samples.length <= 1) {
|
|
2952
|
-
DEBUG_BUILD
|
|
2395
|
+
DEBUG_BUILD &&
|
|
2953
2396
|
// Log a warning if the profile has less than 2 samples so users can know why
|
|
2954
2397
|
// they are not seeing any profiling data and we cant avoid the back and forth
|
|
2955
2398
|
// of asking them to provide us with a dump of the profile data.
|
|
@@ -3082,12 +2525,12 @@ function maybeProfileTransaction(client, transaction, customSamplingContext) {
|
|
|
3082
2525
|
}
|
|
3083
2526
|
// Client and options are required for profiling
|
|
3084
2527
|
if (!client) {
|
|
3085
|
-
DEBUG_BUILD
|
|
2528
|
+
DEBUG_BUILD && logger.log('[Profiling] Profiling disabled, no client found.');
|
|
3086
2529
|
return;
|
|
3087
2530
|
}
|
|
3088
2531
|
const options = client.getOptions();
|
|
3089
2532
|
if (!options) {
|
|
3090
|
-
DEBUG_BUILD
|
|
2533
|
+
DEBUG_BUILD && logger.log('[Profiling] Profiling disabled, no options found.');
|
|
3091
2534
|
return;
|
|
3092
2535
|
}
|
|
3093
2536
|
const profilesSampler = options.profilesSampler;
|
|
@@ -3100,12 +2543,12 @@ function maybeProfileTransaction(client, transaction, customSamplingContext) {
|
|
|
3100
2543
|
// Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The
|
|
3101
2544
|
// only valid values are booleans or numbers between 0 and 1.)
|
|
3102
2545
|
if (!isValidSampleRate(profilesSampleRate)) {
|
|
3103
|
-
DEBUG_BUILD
|
|
2546
|
+
DEBUG_BUILD && logger.warn('[Profiling] Discarding profile because of invalid sample rate.');
|
|
3104
2547
|
return;
|
|
3105
2548
|
}
|
|
3106
2549
|
// if the function returned 0 (or false), or if `profileSampleRate` is 0, it's a sign the profile should be dropped
|
|
3107
2550
|
if (!profilesSampleRate) {
|
|
3108
|
-
DEBUG_BUILD
|
|
2551
|
+
DEBUG_BUILD &&
|
|
3109
2552
|
logger.log(`[Profiling] Discarding profile because ${typeof profilesSampler === 'function'
|
|
3110
2553
|
? 'profileSampler returned 0 or false'
|
|
3111
2554
|
: 'a negative sampling decision was inherited or profileSampleRate is set to 0'}`);
|
|
@@ -3116,15 +2559,13 @@ function maybeProfileTransaction(client, transaction, customSamplingContext) {
|
|
|
3116
2559
|
const sampled = profilesSampleRate === true ? true : Math.random() < profilesSampleRate;
|
|
3117
2560
|
// Check if we should sample this profile
|
|
3118
2561
|
if (!sampled) {
|
|
3119
|
-
DEBUG_BUILD
|
|
2562
|
+
DEBUG_BUILD &&
|
|
3120
2563
|
logger.log(`[Profiling] Discarding profile because it's not included in the random sample (sampling rate = ${Number(profilesSampleRate)})`);
|
|
3121
2564
|
return;
|
|
3122
2565
|
}
|
|
3123
2566
|
const profile_id = uuid4();
|
|
3124
2567
|
CpuProfilerBindings.startProfiling(profile_id);
|
|
3125
|
-
DEBUG_BUILD
|
|
3126
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
3127
|
-
logger.log(`[Profiling] started profiling transaction: ${transaction.name}`);
|
|
2568
|
+
DEBUG_BUILD && logger.log(`[Profiling] started profiling transaction: ${spanToJSON(transaction).description}`);
|
|
3128
2569
|
// set transaction context - do this regardless if profiling fails down the line
|
|
3129
2570
|
// so that we can still see the profile_id in the transaction context
|
|
3130
2571
|
return profile_id;
|
|
@@ -3141,15 +2582,11 @@ function stopTransactionProfile(transaction, profile_id) {
|
|
|
3141
2582
|
return null;
|
|
3142
2583
|
}
|
|
3143
2584
|
const profile = CpuProfilerBindings.stopProfiling(profile_id);
|
|
3144
|
-
DEBUG_BUILD
|
|
3145
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
3146
|
-
logger.log(`[Profiling] stopped profiling of transaction: ${transaction.name}`);
|
|
2585
|
+
DEBUG_BUILD && logger.log(`[Profiling] stopped profiling of transaction: ${spanToJSON(transaction).description}`);
|
|
3147
2586
|
// In case of an overlapping transaction, stopProfiling may return null and silently ignore the overlapping profile.
|
|
3148
2587
|
if (!profile) {
|
|
3149
|
-
DEBUG_BUILD
|
|
3150
|
-
logger.log(
|
|
3151
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
3152
|
-
`[Profiling] profiler returned null profile for: ${transaction.name}`, 'this may indicate an overlapping transaction or a call to stopProfiling with a profile title that was never started');
|
|
2588
|
+
DEBUG_BUILD &&
|
|
2589
|
+
logger.log(`[Profiling] profiler returned null profile for: ${spanToJSON(transaction).description}`, 'this may indicate an overlapping transaction or a call to stopProfiling with a profile title that was never started');
|
|
3153
2590
|
return null;
|
|
3154
2591
|
}
|
|
3155
2592
|
// Assign profile_id to the profile
|
|
@@ -3189,18 +2626,16 @@ function __PRIVATE__wrapStartTransactionWithProfiling(startTransaction) {
|
|
|
3189
2626
|
const maxProfileDurationMs = (options._experiments && options._experiments['maxProfileDurationMs']) || MAX_PROFILE_DURATION_MS;
|
|
3190
2627
|
// Enqueue a timeout to prevent profiles from running over max duration.
|
|
3191
2628
|
let maxDurationTimeoutID = global.setTimeout(() => {
|
|
3192
|
-
DEBUG_BUILD
|
|
3193
|
-
|
|
3194
|
-
logger.log('[Profiling] max profile duration elapsed, stopping profiling for:', transaction.name);
|
|
2629
|
+
DEBUG_BUILD &&
|
|
2630
|
+
logger.log('[Profiling] max profile duration elapsed, stopping profiling for:', spanToJSON(transaction).description);
|
|
3195
2631
|
profile = stopTransactionProfile(transaction, profile_id);
|
|
3196
2632
|
}, maxProfileDurationMs);
|
|
3197
2633
|
// We need to reference the original finish call to avoid creating an infinite loop
|
|
3198
|
-
|
|
3199
|
-
const originalFinish = transaction.finish.bind(transaction);
|
|
2634
|
+
const originalEnd = transaction.end.bind(transaction);
|
|
3200
2635
|
// Wrap the transaction finish method to stop profiling and set the profile on the transaction.
|
|
3201
|
-
function
|
|
2636
|
+
function profilingWrappedTransactionEnd() {
|
|
3202
2637
|
if (!profile_id) {
|
|
3203
|
-
return
|
|
2638
|
+
return originalEnd();
|
|
3204
2639
|
}
|
|
3205
2640
|
// We stop the handler first to ensure that the timeout is cleared and the profile is stopped.
|
|
3206
2641
|
if (maxDurationTimeoutID) {
|
|
@@ -3215,10 +2650,9 @@ function __PRIVATE__wrapStartTransactionWithProfiling(startTransaction) {
|
|
|
3215
2650
|
// @ts-expect-error profile is not part of metadata
|
|
3216
2651
|
// eslint-disable-next-line deprecation/deprecation
|
|
3217
2652
|
transaction.setMetadata({ profile });
|
|
3218
|
-
return
|
|
2653
|
+
return originalEnd();
|
|
3219
2654
|
}
|
|
3220
|
-
|
|
3221
|
-
transaction.finish = profilingWrappedTransactionFinish;
|
|
2655
|
+
transaction.end = profilingWrappedTransactionEnd;
|
|
3222
2656
|
return transaction;
|
|
3223
2657
|
};
|
|
3224
2658
|
}
|
|
@@ -3230,15 +2664,15 @@ function __PRIVATE__wrapStartTransactionWithProfiling(startTransaction) {
|
|
|
3230
2664
|
function _addProfilingExtensionMethods() {
|
|
3231
2665
|
const carrier = getMainCarrier();
|
|
3232
2666
|
if (!carrier.__SENTRY__) {
|
|
3233
|
-
DEBUG_BUILD
|
|
2667
|
+
DEBUG_BUILD && logger.log("[Profiling] Can't find main carrier, profiling won't work.");
|
|
3234
2668
|
return;
|
|
3235
2669
|
}
|
|
3236
2670
|
carrier.__SENTRY__.extensions = carrier.__SENTRY__.extensions || {};
|
|
3237
2671
|
if (!carrier.__SENTRY__.extensions['startTransaction']) {
|
|
3238
|
-
DEBUG_BUILD
|
|
2672
|
+
DEBUG_BUILD && logger.log('[Profiling] startTransaction does not exists, profiling will not work.');
|
|
3239
2673
|
return;
|
|
3240
2674
|
}
|
|
3241
|
-
DEBUG_BUILD
|
|
2675
|
+
DEBUG_BUILD && logger.log('[Profiling] startTransaction exists, patching it with profiling functionality...');
|
|
3242
2676
|
carrier.__SENTRY__.extensions['startTransaction'] = __PRIVATE__wrapStartTransactionWithProfiling(
|
|
3243
2677
|
// This is patched by sentry/tracing, we are going to re-patch it...
|
|
3244
2678
|
carrier.__SENTRY__.extensions['startTransaction']);
|
|
@@ -3294,9 +2728,8 @@ class ProfilingIntegration {
|
|
|
3294
2728
|
}
|
|
3295
2729
|
// Enqueue a timeout to prevent profiles from running over max duration.
|
|
3296
2730
|
PROFILE_TIMEOUTS[profile_id] = global.setTimeout(() => {
|
|
3297
|
-
DEBUG_BUILD
|
|
3298
|
-
|
|
3299
|
-
logger.log('[Profiling] max profile duration elapsed, stopping profiling for:', transaction.name);
|
|
2731
|
+
DEBUG_BUILD &&
|
|
2732
|
+
logger.log('[Profiling] max profile duration elapsed, stopping profiling for:', spanToJSON(transaction).description);
|
|
3300
2733
|
const profile = stopTransactionProfile(transaction, profile_id);
|
|
3301
2734
|
if (profile) {
|
|
3302
2735
|
addToProfileQueue(profile);
|
|
@@ -3344,18 +2777,17 @@ class ProfilingIntegration {
|
|
|
3344
2777
|
}
|
|
3345
2778
|
// Remove the profile from the transaction context before sending, relay will take care of the rest.
|
|
3346
2779
|
if (profileContext) {
|
|
3347
|
-
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
3348
2780
|
(_b = profiledTransaction.contexts) === null || _b === void 0 ? true : delete _b['profile'];
|
|
3349
2781
|
}
|
|
3350
2782
|
// We need to find both a profile and a transaction event for the same profile_id.
|
|
3351
2783
|
const profileIndex = PROFILE_QUEUE.findIndex(p => p.profile_id === profile_id);
|
|
3352
2784
|
if (profileIndex === -1) {
|
|
3353
|
-
DEBUG_BUILD
|
|
2785
|
+
DEBUG_BUILD && logger.log(`[Profiling] Could not retrieve profile for transaction: ${profile_id}`);
|
|
3354
2786
|
continue;
|
|
3355
2787
|
}
|
|
3356
2788
|
const cpuProfile = PROFILE_QUEUE[profileIndex];
|
|
3357
2789
|
if (!cpuProfile) {
|
|
3358
|
-
DEBUG_BUILD
|
|
2790
|
+
DEBUG_BUILD && logger.log(`[Profiling] Could not retrieve profile for transaction: ${profile_id}`);
|
|
3359
2791
|
continue;
|
|
3360
2792
|
}
|
|
3361
2793
|
// Remove the profile from the queue.
|
|
@@ -3400,24 +2832,24 @@ class ProfilingIntegration {
|
|
|
3400
2832
|
// eslint-disable-next-line deprecation/deprecation
|
|
3401
2833
|
const client = hub.getClient();
|
|
3402
2834
|
if (!client) {
|
|
3403
|
-
DEBUG_BUILD
|
|
2835
|
+
DEBUG_BUILD &&
|
|
3404
2836
|
logger.log('[Profiling] getClient did not return a Client, removing profile from event and forwarding to next event processors.');
|
|
3405
2837
|
return maybeRemoveProfileFromSdkMetadata(event);
|
|
3406
2838
|
}
|
|
3407
2839
|
const dsn = client.getDsn();
|
|
3408
2840
|
if (!dsn) {
|
|
3409
|
-
DEBUG_BUILD
|
|
2841
|
+
DEBUG_BUILD &&
|
|
3410
2842
|
logger.log('[Profiling] getDsn did not return a Dsn, removing profile from event and forwarding to next event processors.');
|
|
3411
2843
|
return maybeRemoveProfileFromSdkMetadata(event);
|
|
3412
2844
|
}
|
|
3413
2845
|
const transport = client.getTransport();
|
|
3414
2846
|
if (!transport) {
|
|
3415
|
-
DEBUG_BUILD
|
|
2847
|
+
DEBUG_BUILD &&
|
|
3416
2848
|
logger.log('[Profiling] getTransport did not return a Transport, removing profile from event and forwarding to next event processors.');
|
|
3417
2849
|
return maybeRemoveProfileFromSdkMetadata(event);
|
|
3418
2850
|
}
|
|
3419
2851
|
// If all required components are available, we construct a profiling event envelope and send it to Sentry.
|
|
3420
|
-
DEBUG_BUILD
|
|
2852
|
+
DEBUG_BUILD && logger.log('[Profiling] Preparing envelope and sending a profiling event');
|
|
3421
2853
|
const envelope = createProfilingEventEnvelope(event, dsn);
|
|
3422
2854
|
if (envelope) {
|
|
3423
2855
|
// Fire and forget, we don't want to block the main event processing flow.
|