@reproapp/node-sdk 0.0.45 → 0.0.47
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 +11 -2
- package/dist/index.js +269 -126
- package/dist/ingest/client.js +11 -0
- package/dist/privacy.d.ts +1 -0
- package/dist/privacy.js +306 -7
- package/package.json +3 -3
- package/src/index.ts +396 -111
- package/src/ingest/client.ts +13 -0
- package/src/privacy.ts +409 -7
- package/test/ingest-high-priority-fairness.test.js +76 -0
- package/test/policy-capture-attestation.test.js +234 -0
- package/test/policy-session-completion.testcontainers.test.js +271 -0
- package/test/privacy-policy-index.test.js +194 -0
- package/test/sdk-background-timeout-isolation.test.js +39 -0
- package/test/trace-batch-size.test.js +4 -0
- package/test/trace-source-exclude.test.js +222 -0
- package/tracer/cjs-hook.js +56 -37
package/dist/index.js
CHANGED
|
@@ -332,6 +332,7 @@ function refreshDisabledFunctionTraceRules() {
|
|
|
332
332
|
let disabledFunctionTraceRules = computeDisabledFunctionTraceRules();
|
|
333
333
|
let disabledFunctionTypePatterns = [];
|
|
334
334
|
let disabledTraceFilePatterns = [];
|
|
335
|
+
let excludedInstrumentationFilePatterns = [];
|
|
335
336
|
let __TRACE_LOG_PREF = null;
|
|
336
337
|
let __FULL_VALUE_CAPTURE_ENABLED = true;
|
|
337
338
|
function setInterceptorTracingEnabled(enabled) {
|
|
@@ -415,7 +416,7 @@ function matchesRule(rule, event) {
|
|
|
415
416
|
const wrapperPattern = rule.wrapper ?? rule.wrapperClass ?? rule.className ?? rule.owner;
|
|
416
417
|
if (!matchesPattern(event.wrapperClass, wrapperPattern))
|
|
417
418
|
return false;
|
|
418
|
-
if (!
|
|
419
|
+
if (!matchesTraceFile(event, rule.file))
|
|
419
420
|
return false;
|
|
420
421
|
if (!matchesPattern(event.line == null ? null : String(event.line), rule.line))
|
|
421
422
|
return false;
|
|
@@ -430,9 +431,23 @@ function matchesRule(rule, event) {
|
|
|
430
431
|
return false;
|
|
431
432
|
return true;
|
|
432
433
|
}
|
|
434
|
+
function matchesTraceFile(event, pattern, defaultWhenEmpty = true) {
|
|
435
|
+
if (pattern === undefined || pattern === null)
|
|
436
|
+
return defaultWhenEmpty;
|
|
437
|
+
const candidates = [event.file, event.sourceFile].filter((value) => typeof value === 'string' && value.length > 0);
|
|
438
|
+
if (!candidates.length) {
|
|
439
|
+
return matchesPattern(null, pattern, defaultWhenEmpty);
|
|
440
|
+
}
|
|
441
|
+
return candidates.some((value) => matchesPattern(value, pattern, false));
|
|
442
|
+
}
|
|
433
443
|
function shouldDropTraceEvent(event) {
|
|
434
444
|
if (disabledTraceFilePatterns.length) {
|
|
435
|
-
if (
|
|
445
|
+
if (matchesTraceFile(event, disabledTraceFilePatterns, false)) {
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
if (excludedInstrumentationFilePatterns.length) {
|
|
450
|
+
if (matchesTraceFile(event, excludedInstrumentationFilePatterns, false)) {
|
|
436
451
|
return true;
|
|
437
452
|
}
|
|
438
453
|
}
|
|
@@ -599,6 +614,9 @@ function initReproTracing(opts) {
|
|
|
599
614
|
if (hasOwn(options, 'disableTraceFiles')) {
|
|
600
615
|
setDisabledTraceFiles(options.disableTraceFiles ?? null);
|
|
601
616
|
}
|
|
617
|
+
if (hasOwn(options, 'exclude')) {
|
|
618
|
+
excludedInstrumentationFilePatterns = normalizePatternArray(options.exclude);
|
|
619
|
+
}
|
|
602
620
|
if (hasOwn(options, 'logFunctionCalls') && typeof options.logFunctionCalls === 'boolean') {
|
|
603
621
|
setReproTraceLogsEnabled(options.logFunctionCalls);
|
|
604
622
|
}
|
|
@@ -611,7 +629,17 @@ function initReproTracing(opts) {
|
|
|
611
629
|
__TRACER__ = tracerPkg;
|
|
612
630
|
applyTraceLogPreference(tracerPkg);
|
|
613
631
|
const { disableFunctionTraces: _disableFunctionTraces, disableFunctionTypes: _disableFunctionTypes, disableTraceFiles: _disableTraceFiles, fullValueCapture: _fullValueCapture, logFunctionCalls: _logFunctionCalls, traceInterceptors: _traceInterceptors, ...rest } = options;
|
|
614
|
-
const
|
|
632
|
+
const defaults = defaultTracerInitOpts();
|
|
633
|
+
const overrides = rest;
|
|
634
|
+
const initOpts = {
|
|
635
|
+
...defaults,
|
|
636
|
+
...overrides,
|
|
637
|
+
include: overrides.include ?? defaults.include,
|
|
638
|
+
exclude: [
|
|
639
|
+
...(defaults.exclude ?? []),
|
|
640
|
+
...(overrides.exclude ?? []),
|
|
641
|
+
],
|
|
642
|
+
};
|
|
615
643
|
tracerPkg.init?.(initOpts);
|
|
616
644
|
tracerPkg.patchHttp?.();
|
|
617
645
|
applyTraceLogPreference(tracerPkg);
|
|
@@ -736,6 +764,7 @@ function traceEventCandidateFromRecord(event) {
|
|
|
736
764
|
fn: event.fn,
|
|
737
765
|
wrapperClass: inferWrapperClassFromFn(event.fn),
|
|
738
766
|
file: event.file ?? null,
|
|
767
|
+
sourceFile: sourceFileForLibrary,
|
|
739
768
|
line: event.line ?? null,
|
|
740
769
|
depth: event.depth,
|
|
741
770
|
library: inferLibraryNameFromFile(sourceFileForLibrary ?? event.file),
|
|
@@ -788,15 +817,44 @@ function attachSpanContext(target, span) {
|
|
|
788
817
|
}
|
|
789
818
|
return target;
|
|
790
819
|
}
|
|
791
|
-
function createRequestCaptureScope(requestRid, transport) {
|
|
820
|
+
function createRequestCaptureScope(requestRid, transport, cfg) {
|
|
821
|
+
const privacy = cfg ? getRuntimePrivacyState(cfg).policy ?? null : null;
|
|
822
|
+
const privacyMode = cfg && shouldCapturePrivacyRaw(cfg)
|
|
823
|
+
? 'raw'
|
|
824
|
+
: privacy
|
|
825
|
+
? 'policy'
|
|
826
|
+
: 'fallback';
|
|
792
827
|
return {
|
|
793
828
|
requestRid,
|
|
794
829
|
transport,
|
|
795
|
-
|
|
830
|
+
// Every scope represents one captured transport request. This is an
|
|
831
|
+
// observed expectation, not a count of successful enqueue operations.
|
|
832
|
+
backendRequestCount: 1,
|
|
796
833
|
traceBatchCount: 0,
|
|
797
834
|
dbChangeCount: 0,
|
|
798
835
|
emailEventCount: 0,
|
|
836
|
+
captureFailures: [],
|
|
837
|
+
privacyMode,
|
|
838
|
+
privacyPolicyFingerprint: privacy?.fingerprint,
|
|
839
|
+
privacyStatementCount: privacy?.statements.length ?? 0,
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
function recordRequestCaptureFailure(scope, stage, target, reason) {
|
|
843
|
+
if (!scope)
|
|
844
|
+
return;
|
|
845
|
+
const normalized = {
|
|
846
|
+
stage: String(stage || 'capture').slice(0, 80),
|
|
847
|
+
target: String(target || 'unknown').slice(0, 120),
|
|
848
|
+
reason: String(reason || 'capture_failed').slice(0, 120),
|
|
799
849
|
};
|
|
850
|
+
if (scope.captureFailures.some((failure) => failure.stage === normalized.stage &&
|
|
851
|
+
failure.target === normalized.target &&
|
|
852
|
+
failure.reason === normalized.reason)) {
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
if (scope.captureFailures.length < 25) {
|
|
856
|
+
scope.captureFailures.push(normalized);
|
|
857
|
+
}
|
|
800
858
|
}
|
|
801
859
|
function buildRequestCaptureManifestPayload(scope, traceBatchTotal, closedAtMs) {
|
|
802
860
|
const expectedTraceBatches = Math.max(0, Math.trunc(traceBatchTotal));
|
|
@@ -819,6 +877,19 @@ function buildRequestCaptureManifestPayload(scope, traceBatchTotal, closedAtMs)
|
|
|
819
877
|
to: expectedTraceBatches - 1,
|
|
820
878
|
}
|
|
821
879
|
: undefined,
|
|
880
|
+
privacy: {
|
|
881
|
+
mode: scope.privacyMode,
|
|
882
|
+
status: scope.captureFailures.length > 0
|
|
883
|
+
? 'failed'
|
|
884
|
+
: scope.privacyMode === 'raw'
|
|
885
|
+
? 'bypassed'
|
|
886
|
+
: 'applied',
|
|
887
|
+
policyFingerprint: scope.privacyPolicyFingerprint,
|
|
888
|
+
statementCount: scope.privacyStatementCount,
|
|
889
|
+
},
|
|
890
|
+
captureFailures: scope.captureFailures.length
|
|
891
|
+
? scope.captureFailures.map((failure) => ({ ...failure }))
|
|
892
|
+
: undefined,
|
|
822
893
|
closedAt,
|
|
823
894
|
};
|
|
824
895
|
}
|
|
@@ -995,12 +1066,6 @@ const SDK_BACKGROUND_MAX_DEFER_MS = (() => {
|
|
|
995
1066
|
return Math.trunc(env);
|
|
996
1067
|
return Number.POSITIVE_INFINITY;
|
|
997
1068
|
})();
|
|
998
|
-
const SDK_BACKGROUND_WORK_TIMEOUT_MS = (() => {
|
|
999
|
-
const env = Number(process.env.REPRO_SDK_BACKGROUND_WORK_TIMEOUT_MS);
|
|
1000
|
-
if (Number.isFinite(env) && env >= 0)
|
|
1001
|
-
return Math.trunc(env);
|
|
1002
|
-
return 20000;
|
|
1003
|
-
})();
|
|
1004
1069
|
const TRACE_MATERIALIZE_OFFTHREAD_ENABLED = (() => {
|
|
1005
1070
|
const env = String(process.env.REPRO_TRACE_MATERIALIZE_OFFTHREAD || '').trim().toLowerCase();
|
|
1006
1071
|
if (!env)
|
|
@@ -1349,28 +1414,9 @@ function scheduleSdkBackgroundDrain(delayMs = 0) {
|
|
|
1349
1414
|
catch { }
|
|
1350
1415
|
}
|
|
1351
1416
|
async function runSdkBackgroundWork(work) {
|
|
1352
|
-
|
|
1353
|
-
await work();
|
|
1354
|
-
return;
|
|
1355
|
-
}
|
|
1356
|
-
let timeout = null;
|
|
1357
|
-
const workPromise = Promise.resolve()
|
|
1417
|
+
await Promise.resolve()
|
|
1358
1418
|
.then(work)
|
|
1359
1419
|
.catch(() => undefined);
|
|
1360
|
-
const timeoutPromise = new Promise((resolve) => {
|
|
1361
|
-
timeout = setTimeout(resolve, SDK_BACKGROUND_WORK_TIMEOUT_MS);
|
|
1362
|
-
try {
|
|
1363
|
-
timeout.unref?.();
|
|
1364
|
-
}
|
|
1365
|
-
catch { }
|
|
1366
|
-
});
|
|
1367
|
-
await Promise.race([workPromise, timeoutPromise]);
|
|
1368
|
-
if (timeout) {
|
|
1369
|
-
try {
|
|
1370
|
-
clearTimeout(timeout);
|
|
1371
|
-
}
|
|
1372
|
-
catch { }
|
|
1373
|
-
}
|
|
1374
1420
|
}
|
|
1375
1421
|
async function drainQueuedIngestBeforeBackgroundWork() {
|
|
1376
1422
|
(0, client_1.kickIngestQueueDrain)();
|
|
@@ -2229,7 +2275,7 @@ const TRACE_MAX_BATCHES_PER_REQUEST = (() => {
|
|
|
2229
2275
|
const env = Number(process.env.REPRO_TRACE_MAX_BATCHES_PER_REQUEST);
|
|
2230
2276
|
if (Number.isFinite(env) && env > 0)
|
|
2231
2277
|
return Math.trunc(env);
|
|
2232
|
-
return
|
|
2278
|
+
return Math.ceil(TRACE_MAX_EVENTS_PER_REQUEST / TRACE_BATCH_SIZE);
|
|
2233
2279
|
})();
|
|
2234
2280
|
const TRACE_FLUSH_DELAY_MS = 20;
|
|
2235
2281
|
// Choose how to order trace events in payloads.
|
|
@@ -2799,7 +2845,7 @@ async function materializePendingTraceEvents(events, params) {
|
|
|
2799
2845
|
previewValue: evt.args,
|
|
2800
2846
|
capture: captureContext,
|
|
2801
2847
|
metadata: traceValueMetadata,
|
|
2802
|
-
});
|
|
2848
|
+
}, params.captureScope);
|
|
2803
2849
|
if (argsValueCapture?.entry) {
|
|
2804
2850
|
attachTraceValueEntry(evt, argsValueCapture.entry);
|
|
2805
2851
|
}
|
|
@@ -2821,7 +2867,7 @@ async function materializePendingTraceEvents(events, params) {
|
|
|
2821
2867
|
previewValue: evt.returnValue,
|
|
2822
2868
|
capture: captureContext,
|
|
2823
2869
|
metadata: traceValueMetadata,
|
|
2824
|
-
});
|
|
2870
|
+
}, params.captureScope);
|
|
2825
2871
|
if (returnValueCapture?.entry) {
|
|
2826
2872
|
attachTraceValueEntry(evt, returnValueCapture.entry);
|
|
2827
2873
|
}
|
|
@@ -2843,7 +2889,7 @@ async function materializePendingTraceEvents(events, params) {
|
|
|
2843
2889
|
previewValue: evt.error,
|
|
2844
2890
|
capture: captureContext,
|
|
2845
2891
|
metadata: traceValueMetadata,
|
|
2846
|
-
});
|
|
2892
|
+
}, params.captureScope);
|
|
2847
2893
|
if (errorValueCapture?.entry) {
|
|
2848
2894
|
attachTraceValueEntry(evt, errorValueCapture.entry);
|
|
2849
2895
|
}
|
|
@@ -2857,8 +2903,21 @@ async function materializePendingTraceEvents(events, params) {
|
|
|
2857
2903
|
}
|
|
2858
2904
|
function stripPendingTraceValues(events, reason) {
|
|
2859
2905
|
for (const evt of events) {
|
|
2860
|
-
|
|
2906
|
+
const pending = evt.__reproPending;
|
|
2907
|
+
if (!pending)
|
|
2861
2908
|
continue;
|
|
2909
|
+
if (pending.argsRaw !== undefined) {
|
|
2910
|
+
evt.args = makeOmittedValue(reason);
|
|
2911
|
+
evt.argsValueCapture = { status: 'failed-policy' };
|
|
2912
|
+
}
|
|
2913
|
+
if (pending.returnValueRaw !== undefined) {
|
|
2914
|
+
evt.returnValue = makeOmittedValue(reason);
|
|
2915
|
+
evt.returnValueCapture = { status: 'failed-policy' };
|
|
2916
|
+
}
|
|
2917
|
+
if (pending.errorRaw !== undefined) {
|
|
2918
|
+
evt.error = makeOmittedValue(reason);
|
|
2919
|
+
evt.errorValueCapture = { status: 'failed-policy' };
|
|
2920
|
+
}
|
|
2862
2921
|
delete evt.__reproPending;
|
|
2863
2922
|
}
|
|
2864
2923
|
return events;
|
|
@@ -2879,6 +2938,7 @@ async function materializePendingTraceEventsAsync(events, params) {
|
|
|
2879
2938
|
});
|
|
2880
2939
|
}
|
|
2881
2940
|
catch {
|
|
2941
|
+
recordRequestCaptureFailure(params.captureScope ?? getCtx().captureScope, 'privacy.trace', 'trace.values', 'main_thread_materialization_failed');
|
|
2882
2942
|
return stripPendingTraceValues(events, 'main_thread_failed');
|
|
2883
2943
|
}
|
|
2884
2944
|
}
|
|
@@ -2898,9 +2958,6 @@ async function materializePendingTraceEventsAsync(events, params) {
|
|
|
2898
2958
|
});
|
|
2899
2959
|
}
|
|
2900
2960
|
catch (err) {
|
|
2901
|
-
if (isTraceMaterializerTimeoutError(err)) {
|
|
2902
|
-
return stripPendingTraceValues(events, 'worker_timeout');
|
|
2903
|
-
}
|
|
2904
2961
|
try {
|
|
2905
2962
|
return await materializePendingTraceEvents(events, {
|
|
2906
2963
|
...params,
|
|
@@ -2908,7 +2965,10 @@ async function materializePendingTraceEventsAsync(events, params) {
|
|
|
2908
2965
|
});
|
|
2909
2966
|
}
|
|
2910
2967
|
catch {
|
|
2911
|
-
|
|
2968
|
+
recordRequestCaptureFailure(params.captureScope ?? getCtx().captureScope, 'privacy.trace', 'trace.values', isTraceMaterializerTimeoutError(err)
|
|
2969
|
+
? 'worker_timeout_fallback_failed'
|
|
2970
|
+
: 'worker_and_fallback_failed');
|
|
2971
|
+
return stripPendingTraceValues(events, isTraceMaterializerTimeoutError(err) ? 'worker_timeout_fallback_failed' : 'worker_failed');
|
|
2912
2972
|
}
|
|
2913
2973
|
}
|
|
2914
2974
|
}
|
|
@@ -3375,7 +3435,7 @@ function limitRawInlinePrivacyValue(target, value) {
|
|
|
3375
3435
|
const limited = limitInlinePrivacyValue(target, value);
|
|
3376
3436
|
return limited.skipped ? limited : null;
|
|
3377
3437
|
}
|
|
3378
|
-
function materializeInlinePrivacyValue(target, value, cfg, req, trace, masking, privacy, db) {
|
|
3438
|
+
function materializeInlinePrivacyValue(target, value, cfg, req, trace, masking, privacy, db, captureScope) {
|
|
3379
3439
|
if (value === undefined) {
|
|
3380
3440
|
return { value };
|
|
3381
3441
|
}
|
|
@@ -3387,6 +3447,7 @@ function materializeInlinePrivacyValue(target, value, cfg, req, trace, masking,
|
|
|
3387
3447
|
return { value: valueAfterPrivacy };
|
|
3388
3448
|
}
|
|
3389
3449
|
catch {
|
|
3450
|
+
recordRequestCaptureFailure(captureScope ?? getCtx().captureScope, 'privacy.inline', target, 'privacy_transform_failed');
|
|
3390
3451
|
return {
|
|
3391
3452
|
value: undefined,
|
|
3392
3453
|
skipped: {
|
|
@@ -3397,7 +3458,7 @@ function materializeInlinePrivacyValue(target, value, cfg, req, trace, masking,
|
|
|
3397
3458
|
};
|
|
3398
3459
|
}
|
|
3399
3460
|
}
|
|
3400
|
-
async function materializeInlinePrivacyValueAsync(target, value, cfg, req, trace, masking, privacy, db) {
|
|
3461
|
+
async function materializeInlinePrivacyValueAsync(target, value, cfg, req, trace, masking, privacy, db, captureScope) {
|
|
3401
3462
|
if (value === undefined) {
|
|
3402
3463
|
return { value };
|
|
3403
3464
|
}
|
|
@@ -3409,6 +3470,7 @@ async function materializeInlinePrivacyValueAsync(target, value, cfg, req, trace
|
|
|
3409
3470
|
return { value: valueAfterPrivacy };
|
|
3410
3471
|
}
|
|
3411
3472
|
catch {
|
|
3473
|
+
recordRequestCaptureFailure(captureScope ?? getCtx().captureScope, 'privacy.inline', target, 'privacy_transform_failed');
|
|
3412
3474
|
return {
|
|
3413
3475
|
value: undefined,
|
|
3414
3476
|
skipped: {
|
|
@@ -4301,6 +4363,13 @@ function chunkTraceEventsForTransport(events, requestRid, actionId) {
|
|
|
4301
4363
|
if (sizedBatches.length >= TRACE_MAX_BATCHES_PER_REQUEST) {
|
|
4302
4364
|
break;
|
|
4303
4365
|
}
|
|
4366
|
+
if (current.length >= TRACE_BATCH_SIZE) {
|
|
4367
|
+
sizedBatches.push(current);
|
|
4368
|
+
current = [];
|
|
4369
|
+
if (sizedBatches.length >= TRACE_MAX_BATCHES_PER_REQUEST) {
|
|
4370
|
+
break;
|
|
4371
|
+
}
|
|
4372
|
+
}
|
|
4304
4373
|
const candidate = current.concat(event);
|
|
4305
4374
|
const batchIndex = sizedBatches.length;
|
|
4306
4375
|
const estimatedBytes = estimateTraceBatchSerializedBytes(candidate, requestRid, actionId, batchIndex);
|
|
@@ -4432,8 +4501,15 @@ function maybeCaptureRequestValue(params, sink) {
|
|
|
4432
4501
|
}
|
|
4433
4502
|
return result.captureRef;
|
|
4434
4503
|
}
|
|
4435
|
-
async function maybeCaptureRequestValueAsync(params, sink) {
|
|
4436
|
-
|
|
4504
|
+
async function maybeCaptureRequestValueAsync(params, sink, captureScope) {
|
|
4505
|
+
let result;
|
|
4506
|
+
try {
|
|
4507
|
+
result = await createCapturedValueEntryAsync(params);
|
|
4508
|
+
}
|
|
4509
|
+
catch {
|
|
4510
|
+
recordRequestCaptureFailure(captureScope ?? getCtx().captureScope, 'privacy.full_value', params.target, 'privacy_transform_failed');
|
|
4511
|
+
return { status: 'failed-policy' };
|
|
4512
|
+
}
|
|
4437
4513
|
if (!result)
|
|
4438
4514
|
return undefined;
|
|
4439
4515
|
if (result.entry) {
|
|
@@ -4444,8 +4520,14 @@ async function maybeCaptureRequestValueAsync(params, sink) {
|
|
|
4444
4520
|
function maybeCaptureTraceValue(params) {
|
|
4445
4521
|
return createCapturedValueEntry(params);
|
|
4446
4522
|
}
|
|
4447
|
-
async function maybeCaptureTraceValueAsync(params) {
|
|
4448
|
-
|
|
4523
|
+
async function maybeCaptureTraceValueAsync(params, captureScope) {
|
|
4524
|
+
try {
|
|
4525
|
+
return await createCapturedValueEntryAsync(params);
|
|
4526
|
+
}
|
|
4527
|
+
catch {
|
|
4528
|
+
recordRequestCaptureFailure(captureScope ?? getCtx().captureScope, 'privacy.full_value', params.target, 'privacy_transform_failed');
|
|
4529
|
+
return { captureRef: { status: 'failed-policy' } };
|
|
4530
|
+
}
|
|
4449
4531
|
}
|
|
4450
4532
|
function maybeCaptureDbValue(params, sink) {
|
|
4451
4533
|
const result = createCapturedValueEntry(params);
|
|
@@ -4456,8 +4538,15 @@ function maybeCaptureDbValue(params, sink) {
|
|
|
4456
4538
|
}
|
|
4457
4539
|
return result.captureRef;
|
|
4458
4540
|
}
|
|
4459
|
-
async function maybeCaptureDbValueAsync(params, sink) {
|
|
4460
|
-
|
|
4541
|
+
async function maybeCaptureDbValueAsync(params, sink, captureScope) {
|
|
4542
|
+
let result;
|
|
4543
|
+
try {
|
|
4544
|
+
result = await createCapturedValueEntryAsync(params);
|
|
4545
|
+
}
|
|
4546
|
+
catch {
|
|
4547
|
+
recordRequestCaptureFailure(captureScope ?? getCtx().captureScope, 'privacy.full_value', params.target, 'privacy_transform_failed');
|
|
4548
|
+
return { status: 'failed-policy' };
|
|
4549
|
+
}
|
|
4461
4550
|
if (!result)
|
|
4462
4551
|
return undefined;
|
|
4463
4552
|
if (result.entry) {
|
|
@@ -4483,15 +4572,22 @@ function buildResultMetaFullValueCandidates(resultMetaRaw, resultMetaSource) {
|
|
|
4483
4572
|
pushUniqueCaptureCandidate(candidates, resultMetaSource);
|
|
4484
4573
|
return candidates;
|
|
4485
4574
|
}
|
|
4486
|
-
async function maybeCaptureDbValueFromCandidatesAsync(params, sink) {
|
|
4575
|
+
async function maybeCaptureDbValueFromCandidatesAsync(params, sink, captureScope) {
|
|
4487
4576
|
let skippedRef;
|
|
4488
4577
|
for (const rawValue of params.rawValues) {
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4578
|
+
let result;
|
|
4579
|
+
try {
|
|
4580
|
+
result = await createCapturedValueEntryAsync({
|
|
4581
|
+
target: params.target,
|
|
4582
|
+
rawValue,
|
|
4583
|
+
previewValue: params.previewValue,
|
|
4584
|
+
capture: params.capture,
|
|
4585
|
+
});
|
|
4586
|
+
}
|
|
4587
|
+
catch {
|
|
4588
|
+
recordRequestCaptureFailure(captureScope ?? getCtx().captureScope, 'privacy.full_value', params.target, 'privacy_transform_failed');
|
|
4589
|
+
return { status: 'failed-policy' };
|
|
4590
|
+
}
|
|
4495
4591
|
if (!result)
|
|
4496
4592
|
continue;
|
|
4497
4593
|
if (result.entry) {
|
|
@@ -4661,7 +4757,7 @@ function reproMiddleware(cfg) {
|
|
|
4661
4757
|
const resolvePrivacy = () => getRuntimePrivacyState(captureCfg).policy ?? null;
|
|
4662
4758
|
const clockSkewMs = headerTs !== null ? headerTs - requestStartRaw : 0;
|
|
4663
4759
|
const rid = nextRequestId(requestEpochMs);
|
|
4664
|
-
const captureScope = createRequestCaptureScope(rid, 'http');
|
|
4760
|
+
const captureScope = createRequestCaptureScope(rid, 'http', captureCfg);
|
|
4665
4761
|
emitRequestCaptureStart(captureCfg, sid, aid, captureScope, requestEpochMs);
|
|
4666
4762
|
const t0 = requestStartRaw;
|
|
4667
4763
|
const url = req.originalUrl || req.url || '/';
|
|
@@ -4864,15 +4960,18 @@ function reproMiddleware(cfg) {
|
|
|
4864
4960
|
const activePrivacy = resolvePrivacy();
|
|
4865
4961
|
const requestBodyRaw = req.body;
|
|
4866
4962
|
const requestBodyMaterialization = limitRawInlinePrivacyValue('request.body', requestBodyRaw)
|
|
4867
|
-
?? await materializeInlinePrivacyValueAsync('request.body', sanitizeRequestSnapshot(requestBodyRaw), captureCfg, maskReq, endpointTraceCtx, masking, activePrivacy);
|
|
4963
|
+
?? await materializeInlinePrivacyValueAsync('request.body', sanitizeRequestSnapshot(requestBodyRaw), captureCfg, maskReq, endpointTraceCtx, masking, activePrivacy, undefined, captureScope);
|
|
4868
4964
|
const requestBody = requestBodyMaterialization.value;
|
|
4869
|
-
const
|
|
4870
|
-
const
|
|
4871
|
-
const
|
|
4965
|
+
const requestParamsMaterialization = await materializeInlinePrivacyValueAsync('request.params', sanitizeRequestSnapshot(req.params), captureCfg, maskReq, endpointTraceCtx, masking, activePrivacy, undefined, captureScope);
|
|
4966
|
+
const requestParams = requestParamsMaterialization.value;
|
|
4967
|
+
const requestQueryMaterialization = await materializeInlinePrivacyValueAsync('request.query', sanitizeRequestSnapshot(req.query), captureCfg, maskReq, endpointTraceCtx, masking, activePrivacy, undefined, captureScope);
|
|
4968
|
+
const requestQuery = requestQueryMaterialization.value;
|
|
4969
|
+
const requestHeadersMaterialization = await materializeInlinePrivacyValueAsync('request.headers', requestHeaders, captureCfg, maskReq, endpointTraceCtx, masking, activePrivacy, undefined, captureScope);
|
|
4970
|
+
const maskedHeaders = requestHeadersMaterialization.value;
|
|
4872
4971
|
const responseBodyMaterialization = capturedBody === undefined
|
|
4873
4972
|
? { value: undefined }
|
|
4874
4973
|
: limitRawInlinePrivacyValue('response.body', capturedBody)
|
|
4875
|
-
?? await materializeInlinePrivacyValueAsync('response.body', sanitizeRequestSnapshot(capturedBody), captureCfg, maskReq, endpointTraceCtx, masking, activePrivacy);
|
|
4974
|
+
?? await materializeInlinePrivacyValueAsync('response.body', sanitizeRequestSnapshot(capturedBody), captureCfg, maskReq, endpointTraceCtx, masking, activePrivacy, undefined, captureScope);
|
|
4876
4975
|
const responseBody = responseBodyMaterialization.value;
|
|
4877
4976
|
const requestValueEntries = [];
|
|
4878
4977
|
const bodyValueCapture = requestBodyRaw === undefined
|
|
@@ -4889,7 +4988,7 @@ function reproMiddleware(cfg) {
|
|
|
4889
4988
|
masking,
|
|
4890
4989
|
privacy: activePrivacy,
|
|
4891
4990
|
},
|
|
4892
|
-
}, requestValueEntries);
|
|
4991
|
+
}, requestValueEntries, captureScope);
|
|
4893
4992
|
const paramsValueCapture = await maybeCaptureRequestValueAsync({
|
|
4894
4993
|
target: 'request.params',
|
|
4895
4994
|
rawValue: req.params,
|
|
@@ -4902,7 +5001,7 @@ function reproMiddleware(cfg) {
|
|
|
4902
5001
|
masking,
|
|
4903
5002
|
privacy: activePrivacy,
|
|
4904
5003
|
},
|
|
4905
|
-
}, requestValueEntries);
|
|
5004
|
+
}, requestValueEntries, captureScope);
|
|
4906
5005
|
const queryValueCapture = await maybeCaptureRequestValueAsync({
|
|
4907
5006
|
target: 'request.query',
|
|
4908
5007
|
rawValue: req.query,
|
|
@@ -4915,7 +5014,7 @@ function reproMiddleware(cfg) {
|
|
|
4915
5014
|
masking,
|
|
4916
5015
|
privacy: activePrivacy,
|
|
4917
5016
|
},
|
|
4918
|
-
}, requestValueEntries);
|
|
5017
|
+
}, requestValueEntries, captureScope);
|
|
4919
5018
|
const headersValueCapture = await maybeCaptureRequestValueAsync({
|
|
4920
5019
|
target: 'request.headers',
|
|
4921
5020
|
rawValue: req.headers,
|
|
@@ -4928,7 +5027,7 @@ function reproMiddleware(cfg) {
|
|
|
4928
5027
|
masking,
|
|
4929
5028
|
privacy: activePrivacy,
|
|
4930
5029
|
},
|
|
4931
|
-
}, requestValueEntries);
|
|
5030
|
+
}, requestValueEntries, captureScope);
|
|
4932
5031
|
const respBodyValueCapture = capturedBody === undefined
|
|
4933
5032
|
? undefined
|
|
4934
5033
|
: await maybeCaptureRequestValueAsync({
|
|
@@ -4943,7 +5042,7 @@ function reproMiddleware(cfg) {
|
|
|
4943
5042
|
masking,
|
|
4944
5043
|
privacy: activePrivacy,
|
|
4945
5044
|
},
|
|
4946
|
-
}, requestValueEntries);
|
|
5045
|
+
}, requestValueEntries, captureScope);
|
|
4947
5046
|
const responseDurationMs = finishedAt !== null && Number.isFinite(finishedAt)
|
|
4948
5047
|
? Math.max(0, finishedAt - t0)
|
|
4949
5048
|
: Date.now() - t0;
|
|
@@ -5005,10 +5104,38 @@ function reproMiddleware(cfg) {
|
|
|
5005
5104
|
t: requestEpochMs,
|
|
5006
5105
|
}]
|
|
5007
5106
|
});
|
|
5008
|
-
captureScope.backendRequestCount += 1;
|
|
5009
5107
|
}
|
|
5010
5108
|
catch {
|
|
5011
|
-
|
|
5109
|
+
recordRequestCaptureFailure(captureScope, 'request.capture', 'backend_request', 'request_materialization_failed');
|
|
5110
|
+
// Preserve non-sensitive request metadata so the manifest cannot
|
|
5111
|
+
// silently turn a failed policy capture into a zero-request scope.
|
|
5112
|
+
post(captureCfg, sid, {
|
|
5113
|
+
entries: [{
|
|
5114
|
+
actionId: aid,
|
|
5115
|
+
request: {
|
|
5116
|
+
rid,
|
|
5117
|
+
method: req.method,
|
|
5118
|
+
url,
|
|
5119
|
+
path,
|
|
5120
|
+
status: res.statusCode,
|
|
5121
|
+
durMs: finishedAt !== null && Number.isFinite(finishedAt)
|
|
5122
|
+
? Math.max(0, finishedAt - t0)
|
|
5123
|
+
: Date.now() - t0,
|
|
5124
|
+
key,
|
|
5125
|
+
bodyMaterialization: {
|
|
5126
|
+
status: 'skipped',
|
|
5127
|
+
reason: 'request_materialization_failed',
|
|
5128
|
+
target: 'request.body',
|
|
5129
|
+
},
|
|
5130
|
+
respBodyMaterialization: {
|
|
5131
|
+
status: 'skipped',
|
|
5132
|
+
reason: 'request_materialization_failed',
|
|
5133
|
+
target: 'response.body',
|
|
5134
|
+
},
|
|
5135
|
+
},
|
|
5136
|
+
t: requestEpochMs,
|
|
5137
|
+
}],
|
|
5138
|
+
});
|
|
5012
5139
|
}
|
|
5013
5140
|
};
|
|
5014
5141
|
const emitRequestCaptureManifest = (traceBatchTotal) => {
|
|
@@ -5122,6 +5249,7 @@ function reproMiddleware(cfg) {
|
|
|
5122
5249
|
maskReq,
|
|
5123
5250
|
masking,
|
|
5124
5251
|
resolvePrivacy,
|
|
5252
|
+
captureScope,
|
|
5125
5253
|
});
|
|
5126
5254
|
const baseEvents = balanceTraceEvents(materializedEvents.slice());
|
|
5127
5255
|
const orderedEvents = TRACE_ORDER_MODE === 'tree'
|
|
@@ -5136,12 +5264,14 @@ function reproMiddleware(cfg) {
|
|
|
5136
5264
|
}
|
|
5137
5265
|
}
|
|
5138
5266
|
catch {
|
|
5267
|
+
recordRequestCaptureFailure(captureScope, 'trace.capture', 'trace.batches', 'trace_capture_failed');
|
|
5139
5268
|
captureScope.traceBatchCount = 0;
|
|
5140
5269
|
traceBatches = [];
|
|
5141
5270
|
}
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5271
|
+
// Finalize policy/materialization status before publishing the
|
|
5272
|
+
// high-priority manifest. The manifest must lead its evidence
|
|
5273
|
+
// on the wire so a large trace queue cannot starve completion.
|
|
5274
|
+
emitRequestCaptureManifest(traceBatches.length);
|
|
5145
5275
|
try {
|
|
5146
5276
|
for (let i = 0; i < traceBatches.length; i++) {
|
|
5147
5277
|
const batch = traceBatches[i];
|
|
@@ -5162,7 +5292,7 @@ function reproMiddleware(cfg) {
|
|
|
5162
5292
|
}
|
|
5163
5293
|
}
|
|
5164
5294
|
catch {
|
|
5165
|
-
|
|
5295
|
+
recordRequestCaptureFailure(captureScope, 'trace.enqueue', 'trace.batches', 'trace_enqueue_failed');
|
|
5166
5296
|
}
|
|
5167
5297
|
};
|
|
5168
5298
|
}
|
|
@@ -5729,6 +5859,11 @@ function emitDbQuery(cfg, sid, aid, payload) {
|
|
|
5729
5859
|
const spanContext = payload?.spanContext ?? captureSpanContextFromTracer();
|
|
5730
5860
|
if (!shouldCaptureDbSpan(spanContext))
|
|
5731
5861
|
return;
|
|
5862
|
+
if (sid && ctx.captureScope) {
|
|
5863
|
+
// Count the observed database operation before asynchronous privacy
|
|
5864
|
+
// materialization. A later failure must remain visible to completeness.
|
|
5865
|
+
ctx.captureScope.dbChangeCount += 1;
|
|
5866
|
+
}
|
|
5732
5867
|
const runCtx = {
|
|
5733
5868
|
sid: ctx.sid,
|
|
5734
5869
|
aid: ctx.aid,
|
|
@@ -5740,7 +5875,9 @@ function emitDbQuery(cfg, sid, aid, payload) {
|
|
|
5740
5875
|
};
|
|
5741
5876
|
scheduleSdkBackgroundWork(async () => {
|
|
5742
5877
|
await als.run(runCtx, async () => {
|
|
5743
|
-
await emitDbQueryAsync(cfg, sid, aid, payload).catch(() =>
|
|
5878
|
+
await emitDbQueryAsync(cfg, sid, aid, payload).catch(() => {
|
|
5879
|
+
recordRequestCaptureFailure(runCtx.captureScope, 'db.capture', 'db.change', 'db_capture_failed');
|
|
5880
|
+
});
|
|
5744
5881
|
});
|
|
5745
5882
|
}, { priority: 'high' });
|
|
5746
5883
|
}
|
|
@@ -5856,8 +5993,8 @@ async function emitDbQueryAsync(cfg, sid, aid, payload) {
|
|
|
5856
5993
|
t: payload.t,
|
|
5857
5994
|
}]
|
|
5858
5995
|
});
|
|
5859
|
-
if (enqueued
|
|
5860
|
-
ctx.captureScope.
|
|
5996
|
+
if (!enqueued) {
|
|
5997
|
+
recordRequestCaptureFailure(ctx.captureScope, 'db.enqueue', 'db.change', 'db_enqueue_failed');
|
|
5861
5998
|
}
|
|
5862
5999
|
}
|
|
5863
6000
|
function buildMinimalUpdate(before, after) {
|
|
@@ -6264,8 +6401,8 @@ function cloneKafkaTelemetryValue(value) {
|
|
|
6264
6401
|
return value;
|
|
6265
6402
|
}
|
|
6266
6403
|
}
|
|
6267
|
-
async function materializeKafkaRequestBody(cfg, maskReq, body) {
|
|
6268
|
-
return materializeInlinePrivacyValueAsync('request.body', sanitizeInlinePrivacyValue(body), cfg, maskReq, null, normalizeMaskingConfig(cfg.masking), getRuntimePrivacyState(cfg).policy ?? null);
|
|
6404
|
+
async function materializeKafkaRequestBody(cfg, maskReq, body, captureScope) {
|
|
6405
|
+
return materializeInlinePrivacyValueAsync('request.body', sanitizeInlinePrivacyValue(body), cfg, maskReq, null, normalizeMaskingConfig(cfg.masking), getRuntimePrivacyState(cfg).policy ?? null, undefined, captureScope);
|
|
6269
6406
|
}
|
|
6270
6407
|
function summarizeKafkaError(error) {
|
|
6271
6408
|
const message = typeof error?.message === 'string'
|
|
@@ -6336,6 +6473,7 @@ function recordKafkaTraceEvent(raw, sink, cfg, maskReq) {
|
|
|
6336
6473
|
fn: raw.fn,
|
|
6337
6474
|
wrapperClass: inferWrapperClassFromFn(raw.fn),
|
|
6338
6475
|
file: raw.file ?? null,
|
|
6476
|
+
sourceFile: sourceFileForLibrary,
|
|
6339
6477
|
line: typeof raw.line === 'number' ? raw.line : null,
|
|
6340
6478
|
depth: typeof raw.depth === 'number' ? raw.depth : undefined,
|
|
6341
6479
|
library: inferLibraryNameFromFile(sourceFileForLibrary ?? raw.file),
|
|
@@ -6441,6 +6579,7 @@ function buildPendingKafkaTraceEvent(raw) {
|
|
|
6441
6579
|
fn: raw.fn,
|
|
6442
6580
|
wrapperClass: inferWrapperClassFromFn(raw.fn),
|
|
6443
6581
|
file: raw.file ?? null,
|
|
6582
|
+
sourceFile: sourceFileForLibrary,
|
|
6444
6583
|
line: typeof raw.line === 'number' ? raw.line : null,
|
|
6445
6584
|
depth: typeof raw.depth === 'number' ? raw.depth : undefined,
|
|
6446
6585
|
library: inferLibraryNameFromFile(sourceFileForLibrary ?? raw.file),
|
|
@@ -6536,23 +6675,27 @@ function scheduleKafkaTraceFlush(cfg, kafkaCtx, actionId, requestRid, rawTraceEv
|
|
|
6536
6675
|
if (evt)
|
|
6537
6676
|
pendingEvents.push(evt);
|
|
6538
6677
|
}
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6678
|
+
let entries = [];
|
|
6679
|
+
try {
|
|
6680
|
+
if (pendingEvents.length) {
|
|
6681
|
+
const masking = normalizeMaskingConfig(cfg.masking);
|
|
6682
|
+
const preparedEvents = preparePendingTraceEventsForFlush(pendingEvents);
|
|
6683
|
+
const materializedEvents = await materializePendingTraceEventsAsync(preparedEvents, {
|
|
6684
|
+
cfg,
|
|
6685
|
+
maskReq,
|
|
6686
|
+
masking,
|
|
6687
|
+
resolvePrivacy: () => getRuntimePrivacyState(cfg).policy ?? null,
|
|
6688
|
+
captureScope,
|
|
6689
|
+
});
|
|
6690
|
+
entries = buildKafkaTraceEntries(actionId, requestRid, materializedEvents);
|
|
6691
|
+
}
|
|
6692
|
+
}
|
|
6693
|
+
catch {
|
|
6694
|
+
recordRequestCaptureFailure(captureScope, 'trace.capture', 'trace.batches', 'trace_capture_failed');
|
|
6695
|
+
}
|
|
6550
6696
|
if (captureScope) {
|
|
6551
6697
|
captureScope.traceBatchCount = entries.length;
|
|
6552
6698
|
}
|
|
6553
|
-
if (entries.length) {
|
|
6554
|
-
post(cfg, sid, { entries });
|
|
6555
|
-
}
|
|
6556
6699
|
if (captureScope) {
|
|
6557
6700
|
post(cfg, sid, {
|
|
6558
6701
|
entries: [{
|
|
@@ -6561,7 +6704,10 @@ function scheduleKafkaTraceFlush(cfg, kafkaCtx, actionId, requestRid, rawTraceEv
|
|
|
6561
6704
|
requestCaptureManifest: buildRequestCaptureManifestPayload(captureScope, entries.length),
|
|
6562
6705
|
t: alignedNow(),
|
|
6563
6706
|
}],
|
|
6564
|
-
});
|
|
6707
|
+
}, { priority: 'high' });
|
|
6708
|
+
}
|
|
6709
|
+
if (entries.length) {
|
|
6710
|
+
post(cfg, sid, { entries });
|
|
6565
6711
|
}
|
|
6566
6712
|
});
|
|
6567
6713
|
}, { priority: 'high' });
|
|
@@ -6579,7 +6725,7 @@ function patchKafkaProducerInstance(producer, cfg) {
|
|
|
6579
6725
|
const aid = ctx.aid ?? fallback.aid ?? null;
|
|
6580
6726
|
const span = captureSpanContextFromTracer();
|
|
6581
6727
|
const publishRid = nextRequestId(alignedNow());
|
|
6582
|
-
const captureScope = createRequestCaptureScope(publishRid, 'kafka');
|
|
6728
|
+
const captureScope = createRequestCaptureScope(publishRid, 'kafka', cfg);
|
|
6583
6729
|
emitRequestCaptureStart(cfg, sid, aid, captureScope);
|
|
6584
6730
|
const payloadObj = payload && typeof payload === 'object' ? payload : {};
|
|
6585
6731
|
const topic = sanitizeKafkaTopic(payloadObj.topic);
|
|
@@ -6638,7 +6784,7 @@ function patchKafkaProducerInstance(producer, cfg) {
|
|
|
6638
6784
|
traceId: span?.traceId ?? null,
|
|
6639
6785
|
spanId: span?.spanId ?? null,
|
|
6640
6786
|
parentSpanId: span?.parentSpanId ?? null,
|
|
6641
|
-
});
|
|
6787
|
+
}, captureScope);
|
|
6642
6788
|
const requestPayload = {
|
|
6643
6789
|
rid: publishRid,
|
|
6644
6790
|
method: 'KAFKA_PUBLISH',
|
|
@@ -6667,7 +6813,6 @@ function patchKafkaProducerInstance(producer, cfg) {
|
|
|
6667
6813
|
},
|
|
6668
6814
|
],
|
|
6669
6815
|
});
|
|
6670
|
-
captureScope.backendRequestCount += 1;
|
|
6671
6816
|
post(cfg, sid, {
|
|
6672
6817
|
entries: [{
|
|
6673
6818
|
actionId: aid ?? null,
|
|
@@ -6688,7 +6833,7 @@ function patchKafkaProducerInstance(producer, cfg) {
|
|
|
6688
6833
|
const aid = ctx.aid ?? fallback.aid ?? null;
|
|
6689
6834
|
const span = captureSpanContextFromTracer();
|
|
6690
6835
|
const publishRid = nextRequestId(alignedNow());
|
|
6691
|
-
const captureScope = createRequestCaptureScope(publishRid, 'kafka');
|
|
6836
|
+
const captureScope = createRequestCaptureScope(publishRid, 'kafka', cfg);
|
|
6692
6837
|
emitRequestCaptureStart(cfg, sid, aid, captureScope);
|
|
6693
6838
|
const payloadObj = payload && typeof payload === 'object' ? payload : {};
|
|
6694
6839
|
const topicMessages = Array.isArray(payloadObj.topicMessages)
|
|
@@ -6778,7 +6923,7 @@ function patchKafkaProducerInstance(producer, cfg) {
|
|
|
6778
6923
|
traceId: span?.traceId ?? null,
|
|
6779
6924
|
spanId: span?.spanId ?? null,
|
|
6780
6925
|
parentSpanId: span?.parentSpanId ?? null,
|
|
6781
|
-
});
|
|
6926
|
+
}, captureScope);
|
|
6782
6927
|
const requestPayload = {
|
|
6783
6928
|
rid: publishRid,
|
|
6784
6929
|
method: 'KAFKA_PUBLISH_BATCH',
|
|
@@ -6807,7 +6952,6 @@ function patchKafkaProducerInstance(producer, cfg) {
|
|
|
6807
6952
|
},
|
|
6808
6953
|
],
|
|
6809
6954
|
});
|
|
6810
|
-
captureScope.backendRequestCount += 1;
|
|
6811
6955
|
post(cfg, sid, {
|
|
6812
6956
|
entries: [{
|
|
6813
6957
|
actionId: aid ?? null,
|
|
@@ -6830,7 +6974,7 @@ function wrapKafkaEachMessageHandler(eachMessage, cfg, consumer) {
|
|
|
6830
6974
|
const aid = runtime.aid;
|
|
6831
6975
|
const consumeRid = nextRequestId(`${topic}-${message?.offset ?? alignedNow()}`);
|
|
6832
6976
|
const traceId = consumeRid;
|
|
6833
|
-
const captureScope = createRequestCaptureScope(consumeRid, 'kafka');
|
|
6977
|
+
const captureScope = createRequestCaptureScope(consumeRid, 'kafka', cfg);
|
|
6834
6978
|
emitRequestCaptureStart(cfg, sid, aid, captureScope);
|
|
6835
6979
|
const rawTraceEvents = [];
|
|
6836
6980
|
const maskReq = {
|
|
@@ -6908,7 +7052,7 @@ function wrapKafkaEachMessageHandler(eachMessage, cfg, consumer) {
|
|
|
6908
7052
|
valueEncoding: messagePayload.valueEncoding,
|
|
6909
7053
|
valueBytes: messagePayload.valueBytes,
|
|
6910
7054
|
message: messagePayload,
|
|
6911
|
-
});
|
|
7055
|
+
}, captureScope);
|
|
6912
7056
|
const requestPayload = {
|
|
6913
7057
|
rid: consumeRid,
|
|
6914
7058
|
method: 'KAFKA_CONSUME',
|
|
@@ -6929,7 +7073,6 @@ function wrapKafkaEachMessageHandler(eachMessage, cfg, consumer) {
|
|
|
6929
7073
|
t: alignedNow(),
|
|
6930
7074
|
}],
|
|
6931
7075
|
});
|
|
6932
|
-
captureScope.backendRequestCount += 1;
|
|
6933
7076
|
scheduleKafkaTraceFlush(cfg, kafkaCtx, aid, consumeRid, rawTraceEvents, maskReq, captureScope);
|
|
6934
7077
|
}
|
|
6935
7078
|
};
|
|
@@ -6945,7 +7088,7 @@ function wrapKafkaEachBatchHandler(eachBatch, cfg, consumer) {
|
|
|
6945
7088
|
const aid = runtime.aid;
|
|
6946
7089
|
const consumeRid = nextRequestId(`${topic}-batch-${alignedNow()}`);
|
|
6947
7090
|
const traceId = consumeRid;
|
|
6948
|
-
const captureScope = createRequestCaptureScope(consumeRid, 'kafka');
|
|
7091
|
+
const captureScope = createRequestCaptureScope(consumeRid, 'kafka', cfg);
|
|
6949
7092
|
emitRequestCaptureStart(cfg, sid, aid, captureScope);
|
|
6950
7093
|
const rawTraceEvents = [];
|
|
6951
7094
|
const maskReq = {
|
|
@@ -7021,7 +7164,7 @@ function wrapKafkaEachBatchHandler(eachBatch, cfg, consumer) {
|
|
|
7021
7164
|
parentSpanId: runtime.parentSpanId,
|
|
7022
7165
|
firstMessageKey: firstMessagePayload?.key ?? null,
|
|
7023
7166
|
messages: messages.map((message) => buildKafkaMessagePayload(message)),
|
|
7024
|
-
});
|
|
7167
|
+
}, captureScope);
|
|
7025
7168
|
const requestPayload = {
|
|
7026
7169
|
rid: consumeRid,
|
|
7027
7170
|
method: 'KAFKA_CONSUME_BATCH',
|
|
@@ -7042,7 +7185,6 @@ function wrapKafkaEachBatchHandler(eachBatch, cfg, consumer) {
|
|
|
7042
7185
|
t: alignedNow(),
|
|
7043
7186
|
}],
|
|
7044
7187
|
});
|
|
7045
|
-
captureScope.backendRequestCount += 1;
|
|
7046
7188
|
scheduleKafkaTraceFlush(cfg, kafkaCtx, aid, consumeRid, rawTraceEvents, maskReq, captureScope);
|
|
7047
7189
|
}
|
|
7048
7190
|
};
|
|
@@ -7422,24 +7564,24 @@ function scheduleAmqpTraceFlush(cfg, amqpCtx, actionId, requestRid, rawTraceEven
|
|
|
7422
7564
|
pendingEvents.push(evt);
|
|
7423
7565
|
}
|
|
7424
7566
|
let entries = [];
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
post(cfg, sid, { entries });
|
|
7567
|
+
try {
|
|
7568
|
+
if (pendingEvents.length) {
|
|
7569
|
+
const masking = normalizeMaskingConfig(cfg.masking);
|
|
7570
|
+
const preparedEvents = preparePendingTraceEventsForFlush(pendingEvents);
|
|
7571
|
+
const materializedEvents = await materializePendingTraceEventsAsync(preparedEvents, {
|
|
7572
|
+
cfg,
|
|
7573
|
+
maskReq,
|
|
7574
|
+
masking,
|
|
7575
|
+
resolvePrivacy: () => getRuntimePrivacyState(cfg).policy ?? null,
|
|
7576
|
+
captureScope,
|
|
7577
|
+
});
|
|
7578
|
+
entries = buildAmqpTraceEntries(actionId, requestRid, materializedEvents);
|
|
7438
7579
|
}
|
|
7439
7580
|
}
|
|
7440
|
-
|
|
7441
|
-
captureScope.
|
|
7581
|
+
catch {
|
|
7582
|
+
recordRequestCaptureFailure(captureScope, 'trace.capture', 'trace.batches', 'trace_capture_failed');
|
|
7442
7583
|
}
|
|
7584
|
+
captureScope.traceBatchCount = entries.length;
|
|
7443
7585
|
post(cfg, sid, {
|
|
7444
7586
|
entries: [{
|
|
7445
7587
|
actionId: actionId ?? null,
|
|
@@ -7447,7 +7589,10 @@ function scheduleAmqpTraceFlush(cfg, amqpCtx, actionId, requestRid, rawTraceEven
|
|
|
7447
7589
|
requestCaptureManifest: buildRequestCaptureManifestPayload(captureScope, entries.length),
|
|
7448
7590
|
t: alignedNow(),
|
|
7449
7591
|
}],
|
|
7450
|
-
});
|
|
7592
|
+
}, { priority: 'high' });
|
|
7593
|
+
if (entries.length) {
|
|
7594
|
+
post(cfg, sid, { entries });
|
|
7595
|
+
}
|
|
7451
7596
|
});
|
|
7452
7597
|
}, { priority: 'high' });
|
|
7453
7598
|
}
|
|
@@ -7493,7 +7638,7 @@ function scheduleAmqpPublishCapture(params) {
|
|
|
7493
7638
|
parentSpanId: params.span?.parentSpanId ?? null,
|
|
7494
7639
|
};
|
|
7495
7640
|
scheduleSdkBackgroundWork(async () => {
|
|
7496
|
-
const bodyMaterialization = await materializeKafkaRequestBody(params.cfg, maskReq, body);
|
|
7641
|
+
const bodyMaterialization = await materializeKafkaRequestBody(params.cfg, maskReq, body, params.captureScope);
|
|
7497
7642
|
const requestPayload = {
|
|
7498
7643
|
rid: params.publishRid,
|
|
7499
7644
|
method: params.method,
|
|
@@ -7523,7 +7668,6 @@ function scheduleAmqpPublishCapture(params) {
|
|
|
7523
7668
|
t: alignedNow(),
|
|
7524
7669
|
}],
|
|
7525
7670
|
});
|
|
7526
|
-
params.captureScope.backendRequestCount += 1;
|
|
7527
7671
|
post(params.cfg, params.sid, {
|
|
7528
7672
|
entries: [{
|
|
7529
7673
|
actionId: params.aid ?? null,
|
|
@@ -7574,7 +7718,7 @@ function patchAmqplibPublishMethod(channel, cfg, methodName) {
|
|
|
7574
7718
|
: `amqp://queue/${queue}`;
|
|
7575
7719
|
const key = `${method} ${methodName === 'publish' ? `${exchange || 'default'}/${routingKey}` : queue}`;
|
|
7576
7720
|
const content = methodName === 'publish' ? args[2] : args[1];
|
|
7577
|
-
const captureScope = createRequestCaptureScope(publishRid, 'amqp');
|
|
7721
|
+
const captureScope = createRequestCaptureScope(publishRid, 'amqp', cfg);
|
|
7578
7722
|
emitRequestCaptureStart(cfg, sid, aid, captureScope);
|
|
7579
7723
|
const t0 = Date.now();
|
|
7580
7724
|
let finished = false;
|
|
@@ -7661,7 +7805,7 @@ function wrapAmqplibConsumeHandler(onMessage, cfg, queue) {
|
|
|
7661
7805
|
const deliveryTag = message?.fields?.deliveryTag ?? alignedNow();
|
|
7662
7806
|
const consumeRid = nextRequestId(`${queueName}-${deliveryTag}`);
|
|
7663
7807
|
const traceId = consumeRid;
|
|
7664
|
-
const captureScope = createRequestCaptureScope(consumeRid, 'amqp');
|
|
7808
|
+
const captureScope = createRequestCaptureScope(consumeRid, 'amqp', cfg);
|
|
7665
7809
|
emitRequestCaptureStart(cfg, sid, aid, captureScope);
|
|
7666
7810
|
const rawTraceEvents = [];
|
|
7667
7811
|
const maskReq = {
|
|
@@ -7751,7 +7895,7 @@ function wrapAmqplibConsumeHandler(onMessage, cfg, queue) {
|
|
|
7751
7895
|
properties: buildAmqpMessagePropertiesPayload(properties),
|
|
7752
7896
|
};
|
|
7753
7897
|
scheduleSdkBackgroundWork(async () => {
|
|
7754
|
-
const bodyMaterialization = await materializeKafkaRequestBody(cfg, maskReq, body);
|
|
7898
|
+
const bodyMaterialization = await materializeKafkaRequestBody(cfg, maskReq, body, captureScope);
|
|
7755
7899
|
const requestPayload = {
|
|
7756
7900
|
rid: consumeRid,
|
|
7757
7901
|
method: 'AMQP_CONSUME',
|
|
@@ -7772,7 +7916,6 @@ function wrapAmqplibConsumeHandler(onMessage, cfg, queue) {
|
|
|
7772
7916
|
t: alignedNow(),
|
|
7773
7917
|
}],
|
|
7774
7918
|
});
|
|
7775
|
-
captureScope.backendRequestCount += 1;
|
|
7776
7919
|
scheduleAmqpTraceFlush(cfg, amqpCtx, aid, consumeRid, rawTraceEvents, maskReq, captureScope);
|
|
7777
7920
|
}, { priority: 'high' });
|
|
7778
7921
|
};
|