repro-nest 0.0.208 → 0.0.209
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/dist/index.d.ts +7 -5
- package/dist/index.js +110 -36
- package/package.json +1 -1
- package/src/index.ts +115 -40
- package/tracer/index.js +2 -0
- package/tracer/runtime.js +34 -46
package/dist/index.d.ts
CHANGED
|
@@ -25,17 +25,19 @@
|
|
|
25
25
|
/// <reference types="mongoose/types/inferrawdoctype" />
|
|
26
26
|
import type { Request, Response, NextFunction } from 'express';
|
|
27
27
|
import type { Schema } from 'mongoose';
|
|
28
|
+
type SpanContext = {
|
|
29
|
+
traceId: string | null;
|
|
30
|
+
spanId: string | number | null;
|
|
31
|
+
parentSpanId: string | number | null;
|
|
32
|
+
depth: number | null;
|
|
33
|
+
};
|
|
28
34
|
type TracerApi = {
|
|
29
35
|
init?: (opts: any) => void;
|
|
30
36
|
tracer?: {
|
|
31
37
|
on: (fn: (ev: any) => void) => () => void;
|
|
32
|
-
getCurrentTraceContext?: () => {
|
|
33
|
-
traceId: any;
|
|
34
|
-
spanId: any;
|
|
35
|
-
depth?: number;
|
|
36
|
-
};
|
|
37
38
|
};
|
|
38
39
|
getCurrentTraceId?: () => string | null;
|
|
40
|
+
getCurrentSpanContext?: () => SpanContext | null;
|
|
39
41
|
patchHttp?: () => void;
|
|
40
42
|
setFunctionLogsEnabled?: (enabled: boolean) => void;
|
|
41
43
|
};
|
package/dist/index.js
CHANGED
|
@@ -439,13 +439,6 @@ function initReproTracing(opts) {
|
|
|
439
439
|
const initOpts = { ...defaultTracerInitOpts(), ...rest };
|
|
440
440
|
tracerPkg.init?.(initOpts);
|
|
441
441
|
tracerPkg.patchHttp?.();
|
|
442
|
-
// Ensure tracer exposes current trace context on the on-event API when available.
|
|
443
|
-
try {
|
|
444
|
-
if (!tracerPkg.tracer?.getCurrentTraceContext && tracerPkg.getCurrentTraceContext) {
|
|
445
|
-
tracerPkg.tracer.getCurrentTraceContext = tracerPkg.getCurrentTraceContext;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
catch { }
|
|
449
442
|
applyTraceLogPreference(tracerPkg);
|
|
450
443
|
__TRACER_READY = true;
|
|
451
444
|
patchAllKnownMongooseInstances();
|
|
@@ -466,6 +459,42 @@ exports.initReproTracing = initReproTracing;
|
|
|
466
459
|
/** Optional helper if users want to check it. */
|
|
467
460
|
function isReproTracingEnabled() { return __TRACER_READY; }
|
|
468
461
|
exports.isReproTracingEnabled = isReproTracingEnabled;
|
|
462
|
+
function captureSpanContextFromTracer() {
|
|
463
|
+
try {
|
|
464
|
+
const ctx = __TRACER__?.getCurrentSpanContext?.();
|
|
465
|
+
if (ctx) {
|
|
466
|
+
const span = {
|
|
467
|
+
traceId: ctx.traceId ?? __TRACER__?.getCurrentTraceId?.() ?? null,
|
|
468
|
+
spanId: ctx.spanId ?? null,
|
|
469
|
+
parentSpanId: ctx.parentSpanId ?? null,
|
|
470
|
+
depth: ctx.depth ?? null,
|
|
471
|
+
};
|
|
472
|
+
if (span.traceId || span.spanId !== null || span.parentSpanId !== null) {
|
|
473
|
+
return span;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
else if (__TRACER__?.getCurrentTraceId) {
|
|
477
|
+
const traceId = __TRACER__?.getCurrentTraceId?.() ?? null;
|
|
478
|
+
if (traceId) {
|
|
479
|
+
return { traceId, spanId: null, parentSpanId: null, depth: null };
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
catch { }
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
function attachSpanContext(target, span) {
|
|
487
|
+
if (!target)
|
|
488
|
+
return target;
|
|
489
|
+
const ctx = span ?? captureSpanContextFromTracer();
|
|
490
|
+
if (ctx) {
|
|
491
|
+
try {
|
|
492
|
+
target.spanContext = ctx;
|
|
493
|
+
}
|
|
494
|
+
catch { }
|
|
495
|
+
}
|
|
496
|
+
return target;
|
|
497
|
+
}
|
|
469
498
|
const als = new async_hooks_1.AsyncLocalStorage();
|
|
470
499
|
const getCtx = () => als.getStore() || {};
|
|
471
500
|
function currentClockSkewMs() {
|
|
@@ -807,8 +836,7 @@ const SESSION_DRAIN_TIMEOUT_MS = (() => {
|
|
|
807
836
|
if (Number.isFinite(env) && env >= 0)
|
|
808
837
|
return env;
|
|
809
838
|
// Bound wait for draining sessions to avoid lost flushes when a request hangs.
|
|
810
|
-
|
|
811
|
-
return 60000;
|
|
839
|
+
return 10000;
|
|
812
840
|
})();
|
|
813
841
|
function isThenable(value) {
|
|
814
842
|
return value != null && typeof value === 'object' && typeof value.then === 'function';
|
|
@@ -1335,9 +1363,6 @@ function reproMiddleware(cfg) {
|
|
|
1335
1363
|
if (ev.args !== undefined) {
|
|
1336
1364
|
evt.args = sanitizeTraceArgs(ev.args);
|
|
1337
1365
|
}
|
|
1338
|
-
if (ev.receiver !== undefined) {
|
|
1339
|
-
evt.receiver = sanitizeTraceValue(ev.receiver);
|
|
1340
|
-
}
|
|
1341
1366
|
if (ev.returnValue !== undefined) {
|
|
1342
1367
|
evt.returnValue = sanitizeTraceValue(ev.returnValue);
|
|
1343
1368
|
}
|
|
@@ -1547,6 +1572,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1547
1572
|
wasNew: this.isNew,
|
|
1548
1573
|
before,
|
|
1549
1574
|
collection: resolveCollectionOrWarn(this, 'doc'),
|
|
1575
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1550
1576
|
};
|
|
1551
1577
|
next();
|
|
1552
1578
|
});
|
|
@@ -1560,13 +1586,21 @@ function reproMongoosePlugin(cfg) {
|
|
|
1560
1586
|
const before = meta.before ?? null;
|
|
1561
1587
|
const after = this.toObject({ depopulate: true });
|
|
1562
1588
|
const collection = meta.collection || resolveCollectionOrWarn(this, 'doc');
|
|
1589
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer();
|
|
1563
1590
|
const query = meta.wasNew
|
|
1564
1591
|
? { op: 'insertOne', doc: after }
|
|
1565
1592
|
: { filter: { _id: this._id }, update: buildMinimalUpdate(before, after), options: { upsert: false } };
|
|
1566
1593
|
post(cfg.apiBase, cfg.tenantId, cfg.appId, cfg.appSecret, getCtx().sid, {
|
|
1567
1594
|
entries: [{
|
|
1568
1595
|
actionId: getCtx().aid,
|
|
1569
|
-
db: [{
|
|
1596
|
+
db: [attachSpanContext({
|
|
1597
|
+
collection,
|
|
1598
|
+
pk: { _id: this._id },
|
|
1599
|
+
before,
|
|
1600
|
+
after,
|
|
1601
|
+
op: meta.wasNew ? 'insert' : 'update',
|
|
1602
|
+
query,
|
|
1603
|
+
}, spanContext)],
|
|
1570
1604
|
t: alignedNow(),
|
|
1571
1605
|
}]
|
|
1572
1606
|
});
|
|
@@ -1582,6 +1616,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1582
1616
|
this.__repro_before = await model.findOne(filter).lean().exec();
|
|
1583
1617
|
this.setOptions({ new: true });
|
|
1584
1618
|
this.__repro_collection = resolveCollectionOrWarn(this, 'query');
|
|
1619
|
+
this.__repro_spanContext = captureSpanContextFromTracer();
|
|
1585
1620
|
}
|
|
1586
1621
|
catch { }
|
|
1587
1622
|
next();
|
|
@@ -1593,11 +1628,18 @@ function reproMongoosePlugin(cfg) {
|
|
|
1593
1628
|
const before = this.__repro_before ?? null;
|
|
1594
1629
|
const after = res ?? null;
|
|
1595
1630
|
const collection = this.__repro_collection || resolveCollectionOrWarn(this, 'query');
|
|
1631
|
+
const spanContext = this.__repro_spanContext || captureSpanContextFromTracer();
|
|
1596
1632
|
const pk = after?._id ?? before?._id;
|
|
1597
1633
|
post(cfg.apiBase, cfg.tenantId, cfg.appId, cfg.appSecret, getCtx().sid, {
|
|
1598
1634
|
entries: [{
|
|
1599
1635
|
actionId: getCtx().aid,
|
|
1600
|
-
db: [{
|
|
1636
|
+
db: [attachSpanContext({
|
|
1637
|
+
collection,
|
|
1638
|
+
pk: { _id: pk },
|
|
1639
|
+
before,
|
|
1640
|
+
after,
|
|
1641
|
+
op: after && before ? 'update' : after ? 'insert' : 'update',
|
|
1642
|
+
}, spanContext)],
|
|
1601
1643
|
t: alignedNow()
|
|
1602
1644
|
}]
|
|
1603
1645
|
});
|
|
@@ -1612,6 +1654,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1612
1654
|
this.__repro_before = await this.model.findOne(filter).lean().exec();
|
|
1613
1655
|
this.__repro_collection = resolveCollectionOrWarn(this, 'query');
|
|
1614
1656
|
this.__repro_filter = filter;
|
|
1657
|
+
this.__repro_spanContext = captureSpanContextFromTracer();
|
|
1615
1658
|
}
|
|
1616
1659
|
catch { }
|
|
1617
1660
|
next();
|
|
@@ -1625,10 +1668,18 @@ function reproMongoosePlugin(cfg) {
|
|
|
1625
1668
|
return;
|
|
1626
1669
|
const collection = this.__repro_collection || resolveCollectionOrWarn(this, 'query');
|
|
1627
1670
|
const filter = this.__repro_filter ?? { _id: before._id };
|
|
1671
|
+
const spanContext = this.__repro_spanContext || captureSpanContextFromTracer();
|
|
1628
1672
|
post(cfg.apiBase, cfg.tenantId, cfg.appId, cfg.appSecret, getCtx().sid, {
|
|
1629
1673
|
entries: [{
|
|
1630
1674
|
actionId: getCtx().aid,
|
|
1631
|
-
db: [{
|
|
1675
|
+
db: [attachSpanContext({
|
|
1676
|
+
collection,
|
|
1677
|
+
pk: { _id: before._id },
|
|
1678
|
+
before,
|
|
1679
|
+
after: null,
|
|
1680
|
+
op: 'delete',
|
|
1681
|
+
query: { filter },
|
|
1682
|
+
}, spanContext)],
|
|
1632
1683
|
t: alignedNow()
|
|
1633
1684
|
}]
|
|
1634
1685
|
});
|
|
@@ -1666,6 +1717,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1666
1717
|
t0: Date.now(),
|
|
1667
1718
|
collection: this?.model?.collection?.name || 'unknown',
|
|
1668
1719
|
op,
|
|
1720
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1669
1721
|
filter: sanitizeDbValue(this.getFilter?.() ?? this._conditions ?? undefined),
|
|
1670
1722
|
update: sanitizeDbValue(this.getUpdate?.() ?? this._update ?? undefined),
|
|
1671
1723
|
projection: sanitizeDbValue(this.projection?.() ?? this._fields ?? undefined),
|
|
@@ -1673,7 +1725,12 @@ function reproMongoosePlugin(cfg) {
|
|
|
1673
1725
|
};
|
|
1674
1726
|
}
|
|
1675
1727
|
catch {
|
|
1676
|
-
this.__repro_qmeta = {
|
|
1728
|
+
this.__repro_qmeta = {
|
|
1729
|
+
t0: Date.now(),
|
|
1730
|
+
collection: 'unknown',
|
|
1731
|
+
op,
|
|
1732
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1733
|
+
};
|
|
1677
1734
|
}
|
|
1678
1735
|
next();
|
|
1679
1736
|
});
|
|
@@ -1683,6 +1740,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1683
1740
|
return;
|
|
1684
1741
|
const meta = this.__repro_qmeta || { t0: Date.now(), collection: 'unknown', op };
|
|
1685
1742
|
const resultMeta = summarizeQueryResult(op, res);
|
|
1743
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer();
|
|
1686
1744
|
emitDbQuery(cfg, sid, aid, {
|
|
1687
1745
|
collection: meta.collection,
|
|
1688
1746
|
op,
|
|
@@ -1690,6 +1748,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1690
1748
|
resultMeta,
|
|
1691
1749
|
durMs: Date.now() - meta.t0,
|
|
1692
1750
|
t: alignedNow(),
|
|
1751
|
+
spanContext,
|
|
1693
1752
|
});
|
|
1694
1753
|
});
|
|
1695
1754
|
}
|
|
@@ -1702,10 +1761,15 @@ function reproMongoosePlugin(cfg) {
|
|
|
1702
1761
|
t0: Date.now(),
|
|
1703
1762
|
collection: this?.collection?.name || this?.model?.collection?.name || 'unknown',
|
|
1704
1763
|
docs: sanitizeDbValue(docs),
|
|
1764
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1705
1765
|
};
|
|
1706
1766
|
}
|
|
1707
1767
|
catch {
|
|
1708
|
-
this.__repro_insert_meta = {
|
|
1768
|
+
this.__repro_insert_meta = {
|
|
1769
|
+
t0: Date.now(),
|
|
1770
|
+
collection: 'unknown',
|
|
1771
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1772
|
+
};
|
|
1709
1773
|
}
|
|
1710
1774
|
next();
|
|
1711
1775
|
});
|
|
@@ -1715,6 +1779,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1715
1779
|
return;
|
|
1716
1780
|
const meta = this.__repro_insert_meta || { t0: Date.now(), collection: 'unknown' };
|
|
1717
1781
|
const resultMeta = Array.isArray(docs) ? { inserted: docs.length } : summarizeQueryResult('insertMany', docs);
|
|
1782
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer();
|
|
1718
1783
|
emitDbQuery(cfg, sid, aid, {
|
|
1719
1784
|
collection: meta.collection,
|
|
1720
1785
|
op: 'insertMany',
|
|
@@ -1722,6 +1787,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1722
1787
|
resultMeta,
|
|
1723
1788
|
durMs: Date.now() - meta.t0,
|
|
1724
1789
|
t: alignedNow(),
|
|
1790
|
+
spanContext,
|
|
1725
1791
|
});
|
|
1726
1792
|
});
|
|
1727
1793
|
schema.pre('bulkWrite', { document: false, query: false }, function (next, ops) {
|
|
@@ -1730,10 +1796,15 @@ function reproMongoosePlugin(cfg) {
|
|
|
1730
1796
|
t0: Date.now(),
|
|
1731
1797
|
collection: this?.collection?.name || this?.model?.collection?.name || 'unknown',
|
|
1732
1798
|
ops: sanitizeDbValue(ops),
|
|
1799
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1733
1800
|
};
|
|
1734
1801
|
}
|
|
1735
1802
|
catch {
|
|
1736
|
-
this.__repro_bulk_meta = {
|
|
1803
|
+
this.__repro_bulk_meta = {
|
|
1804
|
+
t0: Date.now(),
|
|
1805
|
+
collection: 'unknown',
|
|
1806
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1807
|
+
};
|
|
1737
1808
|
}
|
|
1738
1809
|
next();
|
|
1739
1810
|
});
|
|
@@ -1744,6 +1815,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1744
1815
|
const meta = this.__repro_bulk_meta || { t0: Date.now(), collection: 'unknown' };
|
|
1745
1816
|
const bulkResult = summarizeBulkResult(res);
|
|
1746
1817
|
const resultMeta = { ...bulkResult, result: sanitizeResultForMeta(res?.result ?? res) };
|
|
1818
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer();
|
|
1747
1819
|
emitDbQuery(cfg, sid, aid, {
|
|
1748
1820
|
collection: meta.collection,
|
|
1749
1821
|
op: 'bulkWrite',
|
|
@@ -1751,6 +1823,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1751
1823
|
resultMeta,
|
|
1752
1824
|
durMs: Date.now() - meta.t0,
|
|
1753
1825
|
t: alignedNow(),
|
|
1826
|
+
spanContext,
|
|
1754
1827
|
});
|
|
1755
1828
|
});
|
|
1756
1829
|
// Aggregate middleware (non-intrusive)
|
|
@@ -1762,11 +1835,17 @@ function reproMongoosePlugin(cfg) {
|
|
|
1762
1835
|
this?._model?.collection?.name ||
|
|
1763
1836
|
(this?.model && this.model.collection?.name) ||
|
|
1764
1837
|
'unknown',
|
|
1838
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1765
1839
|
pipeline: sanitizeDbValue(this.pipeline?.() ?? this._pipeline ?? undefined),
|
|
1766
1840
|
};
|
|
1767
1841
|
}
|
|
1768
1842
|
catch {
|
|
1769
|
-
this.__repro_aggmeta = {
|
|
1843
|
+
this.__repro_aggmeta = {
|
|
1844
|
+
t0: Date.now(),
|
|
1845
|
+
collection: 'unknown',
|
|
1846
|
+
pipeline: undefined,
|
|
1847
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1848
|
+
};
|
|
1770
1849
|
}
|
|
1771
1850
|
next();
|
|
1772
1851
|
});
|
|
@@ -1776,6 +1855,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1776
1855
|
return;
|
|
1777
1856
|
const meta = this.__repro_aggmeta || { t0: Date.now(), collection: 'unknown' };
|
|
1778
1857
|
const resultMeta = summarizeQueryResult('aggregate', res);
|
|
1858
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer();
|
|
1779
1859
|
emitDbQuery(cfg, sid, aid, {
|
|
1780
1860
|
collection: meta.collection,
|
|
1781
1861
|
op: 'aggregate',
|
|
@@ -1783,6 +1863,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1783
1863
|
resultMeta,
|
|
1784
1864
|
durMs: Date.now() - meta.t0,
|
|
1785
1865
|
t: alignedNow(),
|
|
1866
|
+
spanContext,
|
|
1786
1867
|
});
|
|
1787
1868
|
});
|
|
1788
1869
|
};
|
|
@@ -1899,26 +1980,19 @@ function dehydrateComplexValue(value) {
|
|
|
1899
1980
|
function emitDbQuery(cfg, sid, aid, payload) {
|
|
1900
1981
|
if (!sid)
|
|
1901
1982
|
return;
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1983
|
+
const dbEntry = attachSpanContext({
|
|
1984
|
+
collection: payload.collection,
|
|
1985
|
+
op: payload.op,
|
|
1986
|
+
query: payload.query ?? undefined,
|
|
1987
|
+
resultMeta: payload.resultMeta ?? undefined,
|
|
1988
|
+
durMs: payload.durMs ?? undefined,
|
|
1989
|
+
pk: null, before: null, after: null,
|
|
1990
|
+
error: payload.error ?? undefined,
|
|
1991
|
+
}, payload?.spanContext);
|
|
1908
1992
|
post(cfg.apiBase, cfg.tenantId, cfg.appId, cfg.appSecret, sid, {
|
|
1909
1993
|
entries: [{
|
|
1910
1994
|
actionId: aid ?? null,
|
|
1911
|
-
db: [
|
|
1912
|
-
collection: payload.collection,
|
|
1913
|
-
op: payload.op,
|
|
1914
|
-
query: payload.query ?? undefined,
|
|
1915
|
-
resultMeta: payload.resultMeta ?? undefined,
|
|
1916
|
-
durMs: payload.durMs ?? undefined,
|
|
1917
|
-
traceId: traceCtx?.traceId ?? null,
|
|
1918
|
-
spanId: traceCtx?.spanId ?? null,
|
|
1919
|
-
pk: null, before: null, after: null,
|
|
1920
|
-
error: payload.error ?? undefined,
|
|
1921
|
-
}],
|
|
1995
|
+
db: [dbEntry],
|
|
1922
1996
|
t: payload.t,
|
|
1923
1997
|
}]
|
|
1924
1998
|
});
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -172,13 +172,18 @@ function patchAllKnownMongooseInstances() {
|
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
// ====== tiny, safe tracer auto-init (no node_modules patches) ======
|
|
175
|
+
type SpanContext = {
|
|
176
|
+
traceId: string | null;
|
|
177
|
+
spanId: string | number | null;
|
|
178
|
+
parentSpanId: string | number | null;
|
|
179
|
+
depth: number | null;
|
|
180
|
+
};
|
|
181
|
+
|
|
175
182
|
type TracerApi = {
|
|
176
183
|
init?: (opts: any) => void;
|
|
177
|
-
tracer?: {
|
|
178
|
-
on: (fn: (ev: any) => void) => () => void;
|
|
179
|
-
getCurrentTraceContext?: () => { traceId: any; spanId: any; depth?: number };
|
|
180
|
-
};
|
|
184
|
+
tracer?: { on: (fn: (ev: any) => void) => () => void };
|
|
181
185
|
getCurrentTraceId?: () => string | null;
|
|
186
|
+
getCurrentSpanContext?: () => SpanContext | null;
|
|
182
187
|
patchHttp?: () => void; // optional in your tracer
|
|
183
188
|
setFunctionLogsEnabled?: (enabled: boolean) => void;
|
|
184
189
|
};
|
|
@@ -213,7 +218,6 @@ type TraceEventRecord = {
|
|
|
213
218
|
spanId?: string | number | null;
|
|
214
219
|
parentSpanId?: string | number | null;
|
|
215
220
|
args?: any;
|
|
216
|
-
receiver?: any;
|
|
217
221
|
returnValue?: any;
|
|
218
222
|
threw?: boolean;
|
|
219
223
|
error?: any;
|
|
@@ -626,12 +630,6 @@ export function initReproTracing(opts?: ReproTracingInitOptions) {
|
|
|
626
630
|
const initOpts = { ...defaultTracerInitOpts(), ...(rest as TracerInitOpts) };
|
|
627
631
|
tracerPkg.init?.(initOpts);
|
|
628
632
|
tracerPkg.patchHttp?.();
|
|
629
|
-
// Ensure tracer exposes current trace context on the on-event API when available.
|
|
630
|
-
try {
|
|
631
|
-
if (!tracerPkg.tracer?.getCurrentTraceContext && (tracerPkg as any).getCurrentTraceContext) {
|
|
632
|
-
(tracerPkg.tracer as any).getCurrentTraceContext = (tracerPkg as any).getCurrentTraceContext;
|
|
633
|
-
}
|
|
634
|
-
} catch {}
|
|
635
633
|
applyTraceLogPreference(tracerPkg);
|
|
636
634
|
__TRACER_READY = true;
|
|
637
635
|
patchAllKnownMongooseInstances();
|
|
@@ -650,6 +648,38 @@ export function initReproTracing(opts?: ReproTracingInitOptions) {
|
|
|
650
648
|
/** Optional helper if users want to check it. */
|
|
651
649
|
export function isReproTracingEnabled() { return __TRACER_READY; }
|
|
652
650
|
|
|
651
|
+
function captureSpanContextFromTracer(): SpanContext | null {
|
|
652
|
+
try {
|
|
653
|
+
const ctx = __TRACER__?.getCurrentSpanContext?.();
|
|
654
|
+
if (ctx) {
|
|
655
|
+
const span: SpanContext = {
|
|
656
|
+
traceId: ctx.traceId ?? __TRACER__?.getCurrentTraceId?.() ?? null,
|
|
657
|
+
spanId: ctx.spanId ?? null,
|
|
658
|
+
parentSpanId: ctx.parentSpanId ?? null,
|
|
659
|
+
depth: ctx.depth ?? null,
|
|
660
|
+
};
|
|
661
|
+
if (span.traceId || span.spanId !== null || span.parentSpanId !== null) {
|
|
662
|
+
return span;
|
|
663
|
+
}
|
|
664
|
+
} else if (__TRACER__?.getCurrentTraceId) {
|
|
665
|
+
const traceId = __TRACER__?.getCurrentTraceId?.() ?? null;
|
|
666
|
+
if (traceId) {
|
|
667
|
+
return { traceId, spanId: null, parentSpanId: null, depth: null };
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
} catch {}
|
|
671
|
+
return null;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
function attachSpanContext<T extends Record<string, any>>(target: T, span?: SpanContext | null): T {
|
|
675
|
+
if (!target) return target;
|
|
676
|
+
const ctx = span ?? captureSpanContextFromTracer();
|
|
677
|
+
if (ctx) {
|
|
678
|
+
try { (target as any).spanContext = ctx; } catch {}
|
|
679
|
+
}
|
|
680
|
+
return target;
|
|
681
|
+
}
|
|
682
|
+
|
|
653
683
|
type Ctx = { sid?: string; aid?: string; clockSkewMs?: number };
|
|
654
684
|
const als = new AsyncLocalStorage<Ctx>();
|
|
655
685
|
const getCtx = () => als.getStore() || {};
|
|
@@ -1033,8 +1063,7 @@ const SESSION_DRAIN_TIMEOUT_MS = (() => {
|
|
|
1033
1063
|
const env = Number(process.env.SESSION_DRAIN_TIMEOUT_MS);
|
|
1034
1064
|
if (Number.isFinite(env) && env >= 0) return env;
|
|
1035
1065
|
// Bound wait for draining sessions to avoid lost flushes when a request hangs.
|
|
1036
|
-
|
|
1037
|
-
return 60000;
|
|
1066
|
+
return 10000;
|
|
1038
1067
|
})();
|
|
1039
1068
|
|
|
1040
1069
|
function isThenable(value: any): value is PromiseLike<any> {
|
|
@@ -1543,9 +1572,6 @@ export function reproMiddleware(cfg: ReproMiddlewareConfig) {
|
|
|
1543
1572
|
if (ev.args !== undefined) {
|
|
1544
1573
|
evt.args = sanitizeTraceArgs(ev.args);
|
|
1545
1574
|
}
|
|
1546
|
-
if (ev.receiver !== undefined) {
|
|
1547
|
-
evt.receiver = sanitizeTraceValue(ev.receiver);
|
|
1548
|
-
}
|
|
1549
1575
|
if (ev.returnValue !== undefined) {
|
|
1550
1576
|
evt.returnValue = sanitizeTraceValue(ev.returnValue);
|
|
1551
1577
|
}
|
|
@@ -1759,6 +1785,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1759
1785
|
wasNew: this.isNew,
|
|
1760
1786
|
before,
|
|
1761
1787
|
collection: resolveCollectionOrWarn(this, 'doc'),
|
|
1788
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1762
1789
|
};
|
|
1763
1790
|
next();
|
|
1764
1791
|
});
|
|
@@ -1772,6 +1799,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1772
1799
|
const before = meta.before ?? null;
|
|
1773
1800
|
const after = this.toObject({ depopulate: true });
|
|
1774
1801
|
const collection = meta.collection || resolveCollectionOrWarn(this, 'doc');
|
|
1802
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer();
|
|
1775
1803
|
|
|
1776
1804
|
const query = meta.wasNew
|
|
1777
1805
|
? { op: 'insertOne', doc: after }
|
|
@@ -1780,7 +1808,14 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1780
1808
|
post(cfg.apiBase, cfg.tenantId, cfg.appId, cfg.appSecret, (getCtx() as Ctx).sid!, {
|
|
1781
1809
|
entries: [{
|
|
1782
1810
|
actionId: (getCtx() as Ctx).aid!,
|
|
1783
|
-
db: [{
|
|
1811
|
+
db: [attachSpanContext({
|
|
1812
|
+
collection,
|
|
1813
|
+
pk: { _id: (this as any)._id },
|
|
1814
|
+
before,
|
|
1815
|
+
after,
|
|
1816
|
+
op: meta.wasNew ? 'insert' : 'update',
|
|
1817
|
+
query,
|
|
1818
|
+
}, spanContext)],
|
|
1784
1819
|
t: alignedNow(),
|
|
1785
1820
|
}]
|
|
1786
1821
|
});
|
|
@@ -1796,6 +1831,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1796
1831
|
(this as any).__repro_before = await model.findOne(filter).lean().exec();
|
|
1797
1832
|
this.setOptions({ new: true });
|
|
1798
1833
|
(this as any).__repro_collection = resolveCollectionOrWarn(this, 'query');
|
|
1834
|
+
(this as any).__repro_spanContext = captureSpanContextFromTracer();
|
|
1799
1835
|
} catch {}
|
|
1800
1836
|
next();
|
|
1801
1837
|
});
|
|
@@ -1807,12 +1843,19 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1807
1843
|
const before = (this as any).__repro_before ?? null;
|
|
1808
1844
|
const after = res ?? null;
|
|
1809
1845
|
const collection = (this as any).__repro_collection || resolveCollectionOrWarn(this, 'query');
|
|
1846
|
+
const spanContext = (this as any).__repro_spanContext || captureSpanContextFromTracer();
|
|
1810
1847
|
const pk = after?._id ?? before?._id;
|
|
1811
1848
|
|
|
1812
1849
|
post(cfg.apiBase, cfg.tenantId, cfg.appId, cfg.appSecret, (getCtx() as Ctx).sid!, {
|
|
1813
1850
|
entries: [{
|
|
1814
1851
|
actionId: (getCtx() as Ctx).aid!,
|
|
1815
|
-
db: [{
|
|
1852
|
+
db: [attachSpanContext({
|
|
1853
|
+
collection,
|
|
1854
|
+
pk: { _id: pk },
|
|
1855
|
+
before,
|
|
1856
|
+
after,
|
|
1857
|
+
op: after && before ? 'update' : after ? 'insert' : 'update',
|
|
1858
|
+
}, spanContext)],
|
|
1816
1859
|
t: alignedNow()
|
|
1817
1860
|
}]
|
|
1818
1861
|
});
|
|
@@ -1826,6 +1869,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1826
1869
|
(this as any).__repro_before = await (this.model as Model<any>).findOne(filter).lean().exec();
|
|
1827
1870
|
(this as any).__repro_collection = resolveCollectionOrWarn(this, 'query');
|
|
1828
1871
|
(this as any).__repro_filter = filter;
|
|
1872
|
+
(this as any).__repro_spanContext = captureSpanContextFromTracer();
|
|
1829
1873
|
} catch {}
|
|
1830
1874
|
next();
|
|
1831
1875
|
});
|
|
@@ -1836,10 +1880,18 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1836
1880
|
if (!before) return;
|
|
1837
1881
|
const collection = (this as any).__repro_collection || resolveCollectionOrWarn(this, 'query');
|
|
1838
1882
|
const filter = (this as any).__repro_filter ?? { _id: before._id };
|
|
1883
|
+
const spanContext = (this as any).__repro_spanContext || captureSpanContextFromTracer();
|
|
1839
1884
|
post(cfg.apiBase, cfg.tenantId, cfg.appId, cfg.appSecret, (getCtx() as Ctx).sid!, {
|
|
1840
1885
|
entries: [{
|
|
1841
1886
|
actionId: (getCtx() as Ctx).aid!,
|
|
1842
|
-
db: [{
|
|
1887
|
+
db: [attachSpanContext({
|
|
1888
|
+
collection,
|
|
1889
|
+
pk: { _id: before._id },
|
|
1890
|
+
before,
|
|
1891
|
+
after: null,
|
|
1892
|
+
op: 'delete',
|
|
1893
|
+
query: { filter },
|
|
1894
|
+
}, spanContext)],
|
|
1843
1895
|
t: alignedNow()
|
|
1844
1896
|
}]
|
|
1845
1897
|
});
|
|
@@ -1881,13 +1933,19 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1881
1933
|
t0: Date.now(),
|
|
1882
1934
|
collection: this?.model?.collection?.name || 'unknown',
|
|
1883
1935
|
op,
|
|
1936
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1884
1937
|
filter: sanitizeDbValue(this.getFilter?.() ?? this._conditions ?? undefined),
|
|
1885
1938
|
update: sanitizeDbValue(this.getUpdate?.() ?? this._update ?? undefined),
|
|
1886
1939
|
projection: sanitizeDbValue(this.projection?.() ?? this._fields ?? undefined),
|
|
1887
1940
|
options: sanitizeDbValue(this.getOptions?.() ?? this.options ?? undefined),
|
|
1888
1941
|
};
|
|
1889
1942
|
} catch {
|
|
1890
|
-
(this as any).__repro_qmeta = {
|
|
1943
|
+
(this as any).__repro_qmeta = {
|
|
1944
|
+
t0: Date.now(),
|
|
1945
|
+
collection: 'unknown',
|
|
1946
|
+
op,
|
|
1947
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1948
|
+
};
|
|
1891
1949
|
}
|
|
1892
1950
|
next();
|
|
1893
1951
|
});
|
|
@@ -1898,6 +1956,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1898
1956
|
|
|
1899
1957
|
const meta = (this as any).__repro_qmeta || { t0: Date.now(), collection: 'unknown', op };
|
|
1900
1958
|
const resultMeta = summarizeQueryResult(op, res);
|
|
1959
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer();
|
|
1901
1960
|
|
|
1902
1961
|
emitDbQuery(cfg, sid, aid, {
|
|
1903
1962
|
collection: meta.collection,
|
|
@@ -1906,6 +1965,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1906
1965
|
resultMeta,
|
|
1907
1966
|
durMs: Date.now() - meta.t0,
|
|
1908
1967
|
t: alignedNow(),
|
|
1968
|
+
spanContext,
|
|
1909
1969
|
});
|
|
1910
1970
|
});
|
|
1911
1971
|
}
|
|
@@ -1920,9 +1980,14 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1920
1980
|
t0: Date.now(),
|
|
1921
1981
|
collection: this?.collection?.name || this?.model?.collection?.name || 'unknown',
|
|
1922
1982
|
docs: sanitizeDbValue(docs),
|
|
1983
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1923
1984
|
};
|
|
1924
1985
|
} catch {
|
|
1925
|
-
(this as any).__repro_insert_meta = {
|
|
1986
|
+
(this as any).__repro_insert_meta = {
|
|
1987
|
+
t0: Date.now(),
|
|
1988
|
+
collection: 'unknown',
|
|
1989
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1990
|
+
};
|
|
1926
1991
|
}
|
|
1927
1992
|
next();
|
|
1928
1993
|
} as any);
|
|
@@ -1932,6 +1997,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1932
1997
|
if (!sid) return;
|
|
1933
1998
|
const meta = (this as any).__repro_insert_meta || { t0: Date.now(), collection: 'unknown' };
|
|
1934
1999
|
const resultMeta = Array.isArray(docs) ? { inserted: docs.length } : summarizeQueryResult('insertMany', docs);
|
|
2000
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer();
|
|
1935
2001
|
|
|
1936
2002
|
emitDbQuery(cfg, sid, aid, {
|
|
1937
2003
|
collection: meta.collection,
|
|
@@ -1940,6 +2006,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1940
2006
|
resultMeta,
|
|
1941
2007
|
durMs: Date.now() - meta.t0,
|
|
1942
2008
|
t: alignedNow(),
|
|
2009
|
+
spanContext,
|
|
1943
2010
|
});
|
|
1944
2011
|
} as any);
|
|
1945
2012
|
|
|
@@ -1949,9 +2016,14 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1949
2016
|
t0: Date.now(),
|
|
1950
2017
|
collection: this?.collection?.name || this?.model?.collection?.name || 'unknown',
|
|
1951
2018
|
ops: sanitizeDbValue(ops),
|
|
2019
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1952
2020
|
};
|
|
1953
2021
|
} catch {
|
|
1954
|
-
(this as any).__repro_bulk_meta = {
|
|
2022
|
+
(this as any).__repro_bulk_meta = {
|
|
2023
|
+
t0: Date.now(),
|
|
2024
|
+
collection: 'unknown',
|
|
2025
|
+
spanContext: captureSpanContextFromTracer(),
|
|
2026
|
+
};
|
|
1955
2027
|
}
|
|
1956
2028
|
next();
|
|
1957
2029
|
} as any);
|
|
@@ -1962,6 +2034,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1962
2034
|
const meta = (this as any).__repro_bulk_meta || { t0: Date.now(), collection: 'unknown' };
|
|
1963
2035
|
const bulkResult = summarizeBulkResult(res);
|
|
1964
2036
|
const resultMeta = { ...bulkResult, result: sanitizeResultForMeta(res?.result ?? res) };
|
|
2037
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer();
|
|
1965
2038
|
|
|
1966
2039
|
emitDbQuery(cfg, sid, aid, {
|
|
1967
2040
|
collection: meta.collection,
|
|
@@ -1970,6 +2043,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1970
2043
|
resultMeta,
|
|
1971
2044
|
durMs: Date.now() - meta.t0,
|
|
1972
2045
|
t: alignedNow(),
|
|
2046
|
+
spanContext,
|
|
1973
2047
|
});
|
|
1974
2048
|
} as any);
|
|
1975
2049
|
|
|
@@ -1983,10 +2057,16 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1983
2057
|
this?._model?.collection?.name ||
|
|
1984
2058
|
(this?.model && this.model.collection?.name) ||
|
|
1985
2059
|
'unknown',
|
|
2060
|
+
spanContext: captureSpanContextFromTracer(),
|
|
1986
2061
|
pipeline: sanitizeDbValue(this.pipeline?.() ?? this._pipeline ?? undefined),
|
|
1987
2062
|
};
|
|
1988
2063
|
} catch {
|
|
1989
|
-
(this as any).__repro_aggmeta = {
|
|
2064
|
+
(this as any).__repro_aggmeta = {
|
|
2065
|
+
t0: Date.now(),
|
|
2066
|
+
collection: 'unknown',
|
|
2067
|
+
pipeline: undefined,
|
|
2068
|
+
spanContext: captureSpanContextFromTracer(),
|
|
2069
|
+
};
|
|
1990
2070
|
}
|
|
1991
2071
|
next();
|
|
1992
2072
|
});
|
|
@@ -1997,6 +2077,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
1997
2077
|
|
|
1998
2078
|
const meta = (this as any).__repro_aggmeta || { t0: Date.now(), collection: 'unknown' };
|
|
1999
2079
|
const resultMeta = summarizeQueryResult('aggregate', res);
|
|
2080
|
+
const spanContext = meta.spanContext || captureSpanContextFromTracer();
|
|
2000
2081
|
|
|
2001
2082
|
emitDbQuery(cfg, sid, aid, {
|
|
2002
2083
|
collection: meta.collection,
|
|
@@ -2005,6 +2086,7 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
2005
2086
|
resultMeta,
|
|
2006
2087
|
durMs: Date.now() - meta.t0,
|
|
2007
2088
|
t: alignedNow(),
|
|
2089
|
+
spanContext,
|
|
2008
2090
|
});
|
|
2009
2091
|
});
|
|
2010
2092
|
};
|
|
@@ -2114,26 +2196,19 @@ function dehydrateComplexValue(value: any) {
|
|
|
2114
2196
|
|
|
2115
2197
|
function emitDbQuery(cfg: any, sid?: string, aid?: string, payload?: any) {
|
|
2116
2198
|
if (!sid) return;
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2199
|
+
const dbEntry = attachSpanContext({
|
|
2200
|
+
collection: payload.collection,
|
|
2201
|
+
op: payload.op,
|
|
2202
|
+
query: payload.query ?? undefined,
|
|
2203
|
+
resultMeta: payload.resultMeta ?? undefined,
|
|
2204
|
+
durMs: payload.durMs ?? undefined,
|
|
2205
|
+
pk: null, before: null, after: null,
|
|
2206
|
+
error: payload.error ?? undefined,
|
|
2207
|
+
}, payload?.spanContext);
|
|
2123
2208
|
post(cfg.apiBase, cfg.tenantId, cfg.appId, cfg.appSecret, sid, {
|
|
2124
2209
|
entries: [{
|
|
2125
2210
|
actionId: aid ?? null,
|
|
2126
|
-
db: [
|
|
2127
|
-
collection: payload.collection,
|
|
2128
|
-
op: payload.op,
|
|
2129
|
-
query: payload.query ?? undefined,
|
|
2130
|
-
resultMeta: payload.resultMeta ?? undefined,
|
|
2131
|
-
durMs: payload.durMs ?? undefined,
|
|
2132
|
-
traceId: traceCtx?.traceId ?? null,
|
|
2133
|
-
spanId: traceCtx?.spanId ?? null,
|
|
2134
|
-
pk: null, before: null, after: null,
|
|
2135
|
-
error: payload.error ?? undefined,
|
|
2136
|
-
}],
|
|
2211
|
+
db: [dbEntry],
|
|
2137
2212
|
t: payload.t,
|
|
2138
2213
|
}]
|
|
2139
2214
|
});
|
package/tracer/index.js
CHANGED
|
@@ -9,6 +9,7 @@ const {
|
|
|
9
9
|
printV8,
|
|
10
10
|
patchConsole,
|
|
11
11
|
getCurrentTraceId,
|
|
12
|
+
getCurrentSpanContext,
|
|
12
13
|
setFunctionLogsEnabled
|
|
13
14
|
} = require('./runtime');
|
|
14
15
|
const { installCJS } = require('./cjs-hook');
|
|
@@ -60,6 +61,7 @@ function api(){
|
|
|
60
61
|
tracer: trace,
|
|
61
62
|
withTrace: trace.withTrace,
|
|
62
63
|
getCurrentTraceId,
|
|
64
|
+
getCurrentSpanContext,
|
|
63
65
|
setFunctionLogsEnabled,
|
|
64
66
|
};
|
|
65
67
|
}
|
package/tracer/runtime.js
CHANGED
|
@@ -100,17 +100,6 @@ function popSpan(ctx) {
|
|
|
100
100
|
const trace = {
|
|
101
101
|
on(fn){ listeners.add(fn); return () => listeners.delete(fn); },
|
|
102
102
|
withTrace(id, fn, depth = 0){ return als.run({ traceId: id, depth }, fn); },
|
|
103
|
-
getCurrentTraceContext(){
|
|
104
|
-
const store = als.getStore();
|
|
105
|
-
if (!store) return { traceId: null, spanId: null, depth: 0 };
|
|
106
|
-
const spanStack = Array.isArray(store.__repro_span_stack) ? store.__repro_span_stack : [];
|
|
107
|
-
const top = spanStack.length ? spanStack[spanStack.length - 1] : null;
|
|
108
|
-
return {
|
|
109
|
-
traceId: store.traceId || null,
|
|
110
|
-
spanId: top ? top.id ?? null : null,
|
|
111
|
-
depth: typeof store.depth === 'number' ? store.depth : (top?.depth ?? 0),
|
|
112
|
-
};
|
|
113
|
-
},
|
|
114
103
|
enter(fn, meta, detail){
|
|
115
104
|
const parentSpanIdOverride = meta && Object.prototype.hasOwnProperty.call(meta, 'parentSpanId')
|
|
116
105
|
? meta.parentSpanId
|
|
@@ -143,7 +132,6 @@ const trace = {
|
|
|
143
132
|
traceId: ctx.traceId,
|
|
144
133
|
depth: ctx.depth,
|
|
145
134
|
args: detail?.args,
|
|
146
|
-
receiver: detail?.receiver,
|
|
147
135
|
spanId: span.id,
|
|
148
136
|
parentSpanId: span.parentId
|
|
149
137
|
});
|
|
@@ -171,8 +159,7 @@ const trace = {
|
|
|
171
159
|
returnValue: detail?.returnValue,
|
|
172
160
|
error: detail?.error,
|
|
173
161
|
threw: detail?.threw === true,
|
|
174
|
-
unawaited: detail?.unawaited === true || frameUnawaited
|
|
175
|
-
receiver: detail?.receiver
|
|
162
|
+
unawaited: detail?.unawaited === true || frameUnawaited
|
|
176
163
|
};
|
|
177
164
|
|
|
178
165
|
const promiseTaggedUnawaited = !!(baseDetail.returnValue && baseDetail.returnValue[SYM_UNAWAITED]);
|
|
@@ -192,9 +179,6 @@ const trace = {
|
|
|
192
179
|
unawaited: overrides.hasOwnProperty('unawaited')
|
|
193
180
|
? overrides.unawaited
|
|
194
181
|
: forceUnawaited,
|
|
195
|
-
receiver: overrides.hasOwnProperty('receiver')
|
|
196
|
-
? overrides.receiver
|
|
197
|
-
: baseDetail.receiver,
|
|
198
182
|
args: overrides.hasOwnProperty('args')
|
|
199
183
|
? overrides.args
|
|
200
184
|
: baseDetail.args
|
|
@@ -215,7 +199,6 @@ const trace = {
|
|
|
215
199
|
threw: finalDetail.threw === true,
|
|
216
200
|
error: finalDetail.error,
|
|
217
201
|
args: finalDetail.args,
|
|
218
|
-
receiver: finalDetail.receiver,
|
|
219
202
|
unawaited: finalDetail.unawaited === true
|
|
220
203
|
});
|
|
221
204
|
};
|
|
@@ -492,24 +475,6 @@ function forkAlsStoreForUnawaited(baseStore) {
|
|
|
492
475
|
return cloned;
|
|
493
476
|
}
|
|
494
477
|
|
|
495
|
-
// Only capture receiver/collection snapshots for common array iteration helpers to keep noise low.
|
|
496
|
-
const RECEIVER_METHOD_NAMES = new Set([
|
|
497
|
-
// Array iterators
|
|
498
|
-
'map', 'forEach', 'filter', 'find', 'findIndex', 'findLast', 'findLastIndex',
|
|
499
|
-
'some', 'every', 'reduce', 'reduceRight', 'flatMap', 'flat',
|
|
500
|
-
// Set / Map mutators
|
|
501
|
-
'add', 'delete', 'clear', 'set'
|
|
502
|
-
]);
|
|
503
|
-
|
|
504
|
-
function shouldCaptureReceiver(label, receiver) {
|
|
505
|
-
if (!label || receiver === null || receiver === undefined) return false;
|
|
506
|
-
const method = String(label).split('.').pop() || '';
|
|
507
|
-
if (!RECEIVER_METHOD_NAMES.has(method)) return false;
|
|
508
|
-
if (Array.isArray(receiver)) return true;
|
|
509
|
-
if (typeof receiver === 'object' && typeof receiver[Symbol.iterator] === 'function') return true;
|
|
510
|
-
return false;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
478
|
// ========= Generic call-site shim (used by Babel transform) =========
|
|
514
479
|
// Decides whether to emit a top-level event based on callee origin tags.
|
|
515
480
|
// No hardcoded library names or file paths.
|
|
@@ -631,15 +596,13 @@ if (!global.__repro_call) {
|
|
|
631
596
|
? (label && label.length ? label : fn.name)
|
|
632
597
|
: '(anonymous)';
|
|
633
598
|
const sourceFile = fn[SYM_SRC_FILE];
|
|
634
|
-
const receiverForTrace = shouldCaptureReceiver(label, thisArg) ? thisArg : undefined;
|
|
635
599
|
const meta = {
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
line: callLine ?? null,
|
|
600
|
+
file: sourceFile || callFile || null,
|
|
601
|
+
line: sourceFile ? null : (callLine || null),
|
|
639
602
|
parentSpanId: forcedParentSpanId
|
|
640
603
|
};
|
|
641
604
|
|
|
642
|
-
trace.enter(name, meta, { args
|
|
605
|
+
trace.enter(name, meta, { args });
|
|
643
606
|
// After entering, snapshot a clean store that captures the parent + this call’s span,
|
|
644
607
|
// so callbacks invoked during the callee run are isolated per invocation.
|
|
645
608
|
const snapshotForArgs = cloneStore(als.getStore());
|
|
@@ -654,8 +617,7 @@ if (!global.__repro_call) {
|
|
|
654
617
|
const exitDetailBase = {
|
|
655
618
|
returnValue: out,
|
|
656
619
|
args,
|
|
657
|
-
unawaited: shouldForceExit
|
|
658
|
-
receiver: receiverForTrace
|
|
620
|
+
unawaited: shouldForceExit
|
|
659
621
|
};
|
|
660
622
|
|
|
661
623
|
if (shouldForceExit) markPromiseUnawaited(out);
|
|
@@ -697,8 +659,7 @@ if (!global.__repro_call) {
|
|
|
697
659
|
args,
|
|
698
660
|
threw,
|
|
699
661
|
error,
|
|
700
|
-
unawaited: shouldForceExit
|
|
701
|
-
receiver: receiverForTrace
|
|
662
|
+
unawaited: shouldForceExit
|
|
702
663
|
};
|
|
703
664
|
runExit(detail);
|
|
704
665
|
return value;
|
|
@@ -718,7 +679,7 @@ if (!global.__repro_call) {
|
|
|
718
679
|
runExit(exitDetailBase);
|
|
719
680
|
return out;
|
|
720
681
|
} catch (e) {
|
|
721
|
-
trace.exit({ fn: name, file: meta.file, line: meta.line }, { threw: true, error: e, args
|
|
682
|
+
trace.exit({ fn: name, file: meta.file, line: meta.line }, { threw: true, error: e, args });
|
|
722
683
|
throw e;
|
|
723
684
|
} finally {
|
|
724
685
|
if (pendingMarker) {
|
|
@@ -880,6 +841,32 @@ function getCurrentTraceId() {
|
|
|
880
841
|
return s && s.traceId || null;
|
|
881
842
|
}
|
|
882
843
|
|
|
844
|
+
function getCurrentSpanContext() {
|
|
845
|
+
try {
|
|
846
|
+
const store = als.getStore();
|
|
847
|
+
if (!store) return null;
|
|
848
|
+
|
|
849
|
+
const stack = Array.isArray(store.__repro_span_stack) ? store.__repro_span_stack : [];
|
|
850
|
+
const top = stack.length ? stack[stack.length - 1] : null;
|
|
851
|
+
const spanId = top && top.id != null ? top.id : null;
|
|
852
|
+
const parentSpanId = top && top.parentId != null
|
|
853
|
+
? top.parentId
|
|
854
|
+
: (stack.length >= 2 ? (stack[stack.length - 2]?.id ?? null) : null);
|
|
855
|
+
const depth = top && top.depth != null
|
|
856
|
+
? top.depth
|
|
857
|
+
: (typeof store.depth === 'number'
|
|
858
|
+
? store.depth
|
|
859
|
+
: (stack.length ? stack.length : null));
|
|
860
|
+
|
|
861
|
+
const traceId = store.traceId || null;
|
|
862
|
+
|
|
863
|
+
if (spanId === null && parentSpanId === null && traceId === null) return null;
|
|
864
|
+
return { traceId, spanId, parentSpanId, depth: depth == null ? null : depth };
|
|
865
|
+
} catch {
|
|
866
|
+
return null;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
|
|
883
870
|
// ---- Promise propagation fallback: ensure continuations run with the captured store ----
|
|
884
871
|
let PROMISE_PATCHED = false;
|
|
885
872
|
function patchPromise() {
|
|
@@ -924,6 +911,7 @@ module.exports = {
|
|
|
924
911
|
printV8,
|
|
925
912
|
patchConsole,
|
|
926
913
|
getCurrentTraceId,
|
|
914
|
+
getCurrentSpanContext,
|
|
927
915
|
setFunctionLogsEnabled,
|
|
928
916
|
// export symbols so the require hook can tag function origins
|
|
929
917
|
SYM_SRC_FILE,
|