@reproapp/node-sdk 0.0.11 → 0.0.12
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 -1
- package/dist/index.js +186 -6
- package/package.json +1 -1
- package/src/index.ts +226 -15
- package/test/kafka-runtime-privacy-policy.test.js +55 -22
package/dist/index.d.ts
CHANGED
|
@@ -67,9 +67,12 @@ type TraceEventRecord = {
|
|
|
67
67
|
spanId?: string | number | null;
|
|
68
68
|
parentSpanId?: string | number | null;
|
|
69
69
|
args?: any;
|
|
70
|
+
argsValueCapture?: TraceValueCaptureRef;
|
|
70
71
|
returnValue?: any;
|
|
72
|
+
returnValueCapture?: TraceValueCaptureRef;
|
|
71
73
|
threw?: boolean;
|
|
72
74
|
error?: any;
|
|
75
|
+
errorValueCapture?: TraceValueCaptureRef;
|
|
73
76
|
unawaited?: boolean;
|
|
74
77
|
};
|
|
75
78
|
type PendingTraceEventRecord = TraceEventRecord & {
|
|
@@ -82,9 +85,14 @@ type PendingTraceEventRecord = TraceEventRecord & {
|
|
|
82
85
|
__reproSourceFile?: string | null;
|
|
83
86
|
__reproTraceValueEntries?: TraceValueBatchEntry[];
|
|
84
87
|
};
|
|
88
|
+
type TraceValueCaptureRef = {
|
|
89
|
+
status: 'stored' | 'truncated-for-storage' | 'skipped-non-meaningful';
|
|
90
|
+
valueId?: string;
|
|
91
|
+
projectedKind?: string;
|
|
92
|
+
};
|
|
85
93
|
type TraceValueBatchEntry = {
|
|
86
94
|
id: string;
|
|
87
|
-
target: 'db.pk' | 'db.before' | 'db.after' | 'db.query' | 'db.resultMeta' | 'db.error' | 'request.headers' | 'request.body' | 'request.params' | 'request.query' | 'response.body';
|
|
95
|
+
target: 'db.pk' | 'db.before' | 'db.after' | 'db.query' | 'db.resultMeta' | 'db.error' | 'request.headers' | 'request.body' | 'request.params' | 'request.query' | 'response.body' | 'trace.args' | 'trace.returnValue' | 'trace.error';
|
|
88
96
|
value: any;
|
|
89
97
|
truncatedForStorage?: boolean;
|
|
90
98
|
projectedKind?: string;
|
|
@@ -285,6 +293,7 @@ type InlinePrivacyMaterializationResult = {
|
|
|
285
293
|
};
|
|
286
294
|
};
|
|
287
295
|
declare function materializeInlinePrivacyValueAsync(target: RuntimePrivacySurface, value: any, cfg: ReproMiddlewareConfig, req: MaskRequestContext, trace: TraceEventForFilter | null, masking: NormalizedMaskingConfig | null, privacy: NormalizedRuntimePrivacyPolicy | null, db?: RuntimePrivacyDbContext | null): Promise<InlinePrivacyMaterializationResult>;
|
|
296
|
+
declare function getEventTraceValueEntries(event: TraceEventRecord | PendingTraceEventRecord): TraceValueBatchEntry[] | undefined;
|
|
288
297
|
declare function estimateTraceBatchSerializedBytes(batch: TraceEventRecord[], requestRid: string, actionId: string | null | undefined, batchIndex: number): number;
|
|
289
298
|
declare function chunkTraceEventsForTransport(events: TraceEventRecord[], requestRid: string, actionId: string | null | undefined): TraceEventRecord[][];
|
|
290
299
|
export type ReproMiddlewareConfig = IngestClientConfig & {
|
|
@@ -362,5 +371,6 @@ export declare const __reproTestHooks: {
|
|
|
362
371
|
estimateTraceBatchSerializedBytesForTest: typeof estimateTraceBatchSerializedBytes;
|
|
363
372
|
sanitizeTraceValueForPrivacyForTest: typeof sanitizeTraceValueForPrivacy;
|
|
364
373
|
sanitizeMaterializedTraceValueForTest: typeof sanitizeMaterializedTraceValue;
|
|
374
|
+
getEventTraceValueEntriesForTest: typeof getEventTraceValueEntries;
|
|
365
375
|
};
|
|
366
376
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -2129,6 +2129,56 @@ function sanitizeInlinePrivacyValue(value) {
|
|
|
2129
2129
|
function sanitizeMaterializedTraceValue(value) {
|
|
2130
2130
|
return sanitizeTraceValue(value, 0, new WeakMap(), { preserveLongStrings: true, disableTruncation: true });
|
|
2131
2131
|
}
|
|
2132
|
+
function compactMaterializedTracePreview(value, depth = 0) {
|
|
2133
|
+
if (value === undefined || value === null)
|
|
2134
|
+
return value;
|
|
2135
|
+
if (depth >= TRACE_VALUE_MAX_DEPTH) {
|
|
2136
|
+
return makeOmittedValue(`depth>${TRACE_VALUE_MAX_DEPTH}`);
|
|
2137
|
+
}
|
|
2138
|
+
const type = typeof value;
|
|
2139
|
+
if (type === 'string') {
|
|
2140
|
+
if (value.length <= TRACE_VALUE_MAX_STRING)
|
|
2141
|
+
return value;
|
|
2142
|
+
return value.slice(0, TRACE_VALUE_MAX_STRING);
|
|
2143
|
+
}
|
|
2144
|
+
if (type === 'number' || type === 'boolean')
|
|
2145
|
+
return value;
|
|
2146
|
+
if (type === 'bigint')
|
|
2147
|
+
return value.toString();
|
|
2148
|
+
if (type === 'symbol')
|
|
2149
|
+
return value.toString();
|
|
2150
|
+
if (type === 'function')
|
|
2151
|
+
return `[Function${value.name ? ` ${value.name}` : ''}]`;
|
|
2152
|
+
if (type !== 'object')
|
|
2153
|
+
return String(value);
|
|
2154
|
+
if (Array.isArray(value)) {
|
|
2155
|
+
return value
|
|
2156
|
+
.slice(0, TRACE_VALUE_MAX_ITEMS)
|
|
2157
|
+
.map((item) => compactMaterializedTracePreview(item, depth + 1));
|
|
2158
|
+
}
|
|
2159
|
+
const out = {};
|
|
2160
|
+
const keys = Object.keys(value).slice(0, TRACE_VALUE_MAX_KEYS);
|
|
2161
|
+
for (const key of keys) {
|
|
2162
|
+
try {
|
|
2163
|
+
out[key] = compactMaterializedTracePreview(value[key], depth + 1);
|
|
2164
|
+
}
|
|
2165
|
+
catch (err) {
|
|
2166
|
+
out[key] = `[Cannot serialize: ${err?.message || 'unknown error'}]`;
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
return out;
|
|
2170
|
+
}
|
|
2171
|
+
function limitMaterializedTraceInlineValue(value) {
|
|
2172
|
+
const inlineValue = sanitizeMaterializedTraceValue(value);
|
|
2173
|
+
if (!traceInlineValueExceedsLimit(inlineValue)) {
|
|
2174
|
+
return inlineValue;
|
|
2175
|
+
}
|
|
2176
|
+
const compactPreview = compactMaterializedTracePreview(inlineValue);
|
|
2177
|
+
if (!traceInlineValueExceedsLimit(compactPreview)) {
|
|
2178
|
+
return compactPreview;
|
|
2179
|
+
}
|
|
2180
|
+
return makeOmittedValue('inline-size-limit');
|
|
2181
|
+
}
|
|
2132
2182
|
function sanitizeTraceArgsForPrivacy(values) {
|
|
2133
2183
|
if (!Array.isArray(values))
|
|
2134
2184
|
return [sanitizeTraceValueForPrivacy(values)];
|
|
@@ -2142,6 +2192,14 @@ function normalizeRawTraceArgs(values) {
|
|
|
2142
2192
|
function hasMeaningfulRawTraceError(error) {
|
|
2143
2193
|
return error !== undefined && error !== null;
|
|
2144
2194
|
}
|
|
2195
|
+
function attachTraceValueEntry(event, entry) {
|
|
2196
|
+
const current = event[TRACE_FULL_VALUE_ENTRY_SYMBOL];
|
|
2197
|
+
if (Array.isArray(current)) {
|
|
2198
|
+
current.push(entry);
|
|
2199
|
+
return;
|
|
2200
|
+
}
|
|
2201
|
+
event[TRACE_FULL_VALUE_ENTRY_SYMBOL] = [entry];
|
|
2202
|
+
}
|
|
2145
2203
|
async function materializePendingTraceEvents(events, params) {
|
|
2146
2204
|
for (const evt of events) {
|
|
2147
2205
|
const pending = evt.__reproPending;
|
|
@@ -2151,14 +2209,71 @@ async function materializePendingTraceEvents(events, params) {
|
|
|
2151
2209
|
const candidate = pending.candidate ?? traceEventCandidateFromRecord(evt);
|
|
2152
2210
|
const omitJsonBuiltinValues = shouldOmitJsonBuiltinTraceValues(candidate);
|
|
2153
2211
|
const activePrivacy = params.resolvePrivacy();
|
|
2212
|
+
const captureContext = {
|
|
2213
|
+
runtimeConfig: params.cfg,
|
|
2214
|
+
captureHeaders: params.cfg.captureHeaders,
|
|
2215
|
+
maskReq: params.maskReq,
|
|
2216
|
+
trace: candidate,
|
|
2217
|
+
masking: params.masking,
|
|
2218
|
+
privacy: activePrivacy,
|
|
2219
|
+
};
|
|
2220
|
+
const traceValueMetadata = {
|
|
2221
|
+
fn: evt.fn,
|
|
2222
|
+
file: evt.file,
|
|
2223
|
+
line: evt.line ?? null,
|
|
2224
|
+
spanId: evt.spanId ?? null,
|
|
2225
|
+
parentSpanId: evt.parentSpanId ?? null,
|
|
2226
|
+
};
|
|
2154
2227
|
if (!omitJsonBuiltinValues && pending.argsRaw !== undefined) {
|
|
2155
|
-
|
|
2228
|
+
const argsMaterialized = await materializeTracePrivacyValueAsync('trace.args', sanitizeTraceArgsForPrivacy(pending.argsRaw), params.cfg, params.maskReq, candidate, params.masking, activePrivacy);
|
|
2229
|
+
evt.args = limitMaterializedTraceInlineValue(argsMaterialized);
|
|
2230
|
+
const argsValueCapture = await maybeCaptureTraceValueAsync({
|
|
2231
|
+
target: 'trace.args',
|
|
2232
|
+
rawValue: pending.argsRaw,
|
|
2233
|
+
previewValue: evt.args,
|
|
2234
|
+
capture: captureContext,
|
|
2235
|
+
metadata: traceValueMetadata,
|
|
2236
|
+
});
|
|
2237
|
+
if (argsValueCapture?.entry) {
|
|
2238
|
+
attachTraceValueEntry(evt, argsValueCapture.entry);
|
|
2239
|
+
}
|
|
2240
|
+
if (argsValueCapture?.captureRef) {
|
|
2241
|
+
evt.argsValueCapture = argsValueCapture.captureRef;
|
|
2242
|
+
}
|
|
2156
2243
|
}
|
|
2157
2244
|
if (!omitJsonBuiltinValues && pending.returnValueRaw !== undefined) {
|
|
2158
|
-
|
|
2245
|
+
const returnValueMaterialized = await materializeTracePrivacyValueAsync('trace.returnValue', sanitizeTraceValueForPrivacy(pending.returnValueRaw), params.cfg, params.maskReq, candidate, params.masking, activePrivacy);
|
|
2246
|
+
evt.returnValue = limitMaterializedTraceInlineValue(returnValueMaterialized);
|
|
2247
|
+
const returnValueCapture = await maybeCaptureTraceValueAsync({
|
|
2248
|
+
target: 'trace.returnValue',
|
|
2249
|
+
rawValue: pending.returnValueRaw,
|
|
2250
|
+
previewValue: evt.returnValue,
|
|
2251
|
+
capture: captureContext,
|
|
2252
|
+
metadata: traceValueMetadata,
|
|
2253
|
+
});
|
|
2254
|
+
if (returnValueCapture?.entry) {
|
|
2255
|
+
attachTraceValueEntry(evt, returnValueCapture.entry);
|
|
2256
|
+
}
|
|
2257
|
+
if (returnValueCapture?.captureRef) {
|
|
2258
|
+
evt.returnValueCapture = returnValueCapture.captureRef;
|
|
2259
|
+
}
|
|
2159
2260
|
}
|
|
2160
2261
|
if (pending.errorRaw !== undefined) {
|
|
2161
|
-
|
|
2262
|
+
const errorMaterialized = await materializeTracePrivacyValueAsync('trace.error', sanitizeTraceValueForPrivacy(pending.errorRaw), params.cfg, params.maskReq, candidate, params.masking, activePrivacy);
|
|
2263
|
+
evt.error = limitMaterializedTraceInlineValue(errorMaterialized);
|
|
2264
|
+
const errorValueCapture = await maybeCaptureTraceValueAsync({
|
|
2265
|
+
target: 'trace.error',
|
|
2266
|
+
rawValue: pending.errorRaw,
|
|
2267
|
+
previewValue: evt.error,
|
|
2268
|
+
capture: captureContext,
|
|
2269
|
+
metadata: traceValueMetadata,
|
|
2270
|
+
});
|
|
2271
|
+
if (errorValueCapture?.entry) {
|
|
2272
|
+
attachTraceValueEntry(evt, errorValueCapture.entry);
|
|
2273
|
+
}
|
|
2274
|
+
if (errorValueCapture?.captureRef) {
|
|
2275
|
+
evt.errorValueCapture = errorValueCapture.captureRef;
|
|
2276
|
+
}
|
|
2162
2277
|
}
|
|
2163
2278
|
}
|
|
2164
2279
|
return events;
|
|
@@ -3710,6 +3825,12 @@ async function maybeCaptureRequestValueAsync(params, sink) {
|
|
|
3710
3825
|
}
|
|
3711
3826
|
return result.captureRef;
|
|
3712
3827
|
}
|
|
3828
|
+
function maybeCaptureTraceValue(params) {
|
|
3829
|
+
return createCapturedValueEntry(params);
|
|
3830
|
+
}
|
|
3831
|
+
async function maybeCaptureTraceValueAsync(params) {
|
|
3832
|
+
return await createCapturedValueEntryAsync(params);
|
|
3833
|
+
}
|
|
3713
3834
|
function maybeCaptureDbValue(params, sink) {
|
|
3714
3835
|
const result = createCapturedValueEntry(params);
|
|
3715
3836
|
if (!result)
|
|
@@ -5288,14 +5409,71 @@ function recordKafkaTraceEvent(raw, sink, cfg, maskReq) {
|
|
|
5288
5409
|
};
|
|
5289
5410
|
const privacy = getRuntimePrivacyState(cfg).policy ?? null;
|
|
5290
5411
|
const masking = normalizeMaskingConfig(cfg.masking);
|
|
5412
|
+
const captureContext = {
|
|
5413
|
+
runtimeConfig: cfg,
|
|
5414
|
+
captureHeaders: cfg.captureHeaders,
|
|
5415
|
+
maskReq,
|
|
5416
|
+
trace: candidate,
|
|
5417
|
+
masking,
|
|
5418
|
+
privacy,
|
|
5419
|
+
};
|
|
5420
|
+
const traceValueMetadata = {
|
|
5421
|
+
fn: evt.fn,
|
|
5422
|
+
file: evt.file,
|
|
5423
|
+
line: evt.line ?? null,
|
|
5424
|
+
spanId: evt.spanId ?? null,
|
|
5425
|
+
parentSpanId: evt.parentSpanId ?? null,
|
|
5426
|
+
};
|
|
5291
5427
|
if (!omitJsonBuiltinValues && raw.args !== undefined) {
|
|
5292
|
-
|
|
5428
|
+
const argsMaterialized = materializeTracePrivacyValue('trace.args', sanitizeTraceArgsForPrivacy(raw.args), cfg, maskReq, candidate, masking, privacy);
|
|
5429
|
+
evt.args = limitMaterializedTraceInlineValue(argsMaterialized);
|
|
5430
|
+
const argsValueCapture = maybeCaptureTraceValue({
|
|
5431
|
+
target: 'trace.args',
|
|
5432
|
+
rawValue: normalizeRawTraceArgs(raw.args),
|
|
5433
|
+
previewValue: evt.args,
|
|
5434
|
+
capture: captureContext,
|
|
5435
|
+
metadata: traceValueMetadata,
|
|
5436
|
+
});
|
|
5437
|
+
if (argsValueCapture?.entry) {
|
|
5438
|
+
attachTraceValueEntry(evt, argsValueCapture.entry);
|
|
5439
|
+
}
|
|
5440
|
+
if (argsValueCapture?.captureRef) {
|
|
5441
|
+
evt.argsValueCapture = argsValueCapture.captureRef;
|
|
5442
|
+
}
|
|
5293
5443
|
}
|
|
5294
5444
|
if (!omitJsonBuiltinValues && raw.returnValue !== undefined) {
|
|
5295
|
-
|
|
5445
|
+
const returnValueMaterialized = materializeTracePrivacyValue('trace.returnValue', sanitizeTraceValueForPrivacy(raw.returnValue), cfg, maskReq, candidate, masking, privacy);
|
|
5446
|
+
evt.returnValue = limitMaterializedTraceInlineValue(returnValueMaterialized);
|
|
5447
|
+
const returnValueCapture = maybeCaptureTraceValue({
|
|
5448
|
+
target: 'trace.returnValue',
|
|
5449
|
+
rawValue: raw.returnValue,
|
|
5450
|
+
previewValue: evt.returnValue,
|
|
5451
|
+
capture: captureContext,
|
|
5452
|
+
metadata: traceValueMetadata,
|
|
5453
|
+
});
|
|
5454
|
+
if (returnValueCapture?.entry) {
|
|
5455
|
+
attachTraceValueEntry(evt, returnValueCapture.entry);
|
|
5456
|
+
}
|
|
5457
|
+
if (returnValueCapture?.captureRef) {
|
|
5458
|
+
evt.returnValueCapture = returnValueCapture.captureRef;
|
|
5459
|
+
}
|
|
5296
5460
|
}
|
|
5297
5461
|
if (hasMeaningfulRawTraceError(raw.error)) {
|
|
5298
|
-
|
|
5462
|
+
const errorMaterialized = materializeTracePrivacyValue('trace.error', sanitizeTraceValueForPrivacy(raw.error), cfg, maskReq, candidate, masking, privacy);
|
|
5463
|
+
evt.error = limitMaterializedTraceInlineValue(errorMaterialized);
|
|
5464
|
+
const errorValueCapture = maybeCaptureTraceValue({
|
|
5465
|
+
target: 'trace.error',
|
|
5466
|
+
rawValue: raw.error,
|
|
5467
|
+
previewValue: evt.error,
|
|
5468
|
+
capture: captureContext,
|
|
5469
|
+
metadata: traceValueMetadata,
|
|
5470
|
+
});
|
|
5471
|
+
if (errorValueCapture?.entry) {
|
|
5472
|
+
attachTraceValueEntry(evt, errorValueCapture.entry);
|
|
5473
|
+
}
|
|
5474
|
+
if (errorValueCapture?.captureRef) {
|
|
5475
|
+
evt.errorValueCapture = errorValueCapture.captureRef;
|
|
5476
|
+
}
|
|
5299
5477
|
}
|
|
5300
5478
|
if (raw.threw !== undefined)
|
|
5301
5479
|
evt.threw = raw.threw === true;
|
|
@@ -5388,6 +5566,7 @@ function buildKafkaTraceEntries(actionId, requestRid, events) {
|
|
|
5388
5566
|
return batches.map((batch, index) => ({
|
|
5389
5567
|
actionId: actionId ?? null,
|
|
5390
5568
|
trace: batch,
|
|
5569
|
+
traceValues: collectBatchTraceValueEntries(batch, index),
|
|
5391
5570
|
traceBatch: {
|
|
5392
5571
|
rid: requestRid,
|
|
5393
5572
|
index,
|
|
@@ -6727,4 +6906,5 @@ exports.__reproTestHooks = {
|
|
|
6727
6906
|
estimateTraceBatchSerializedBytesForTest: estimateTraceBatchSerializedBytes,
|
|
6728
6907
|
sanitizeTraceValueForPrivacyForTest: sanitizeTraceValueForPrivacy,
|
|
6729
6908
|
sanitizeMaterializedTraceValueForTest: sanitizeMaterializedTraceValue,
|
|
6909
|
+
getEventTraceValueEntriesForTest: getEventTraceValueEntries,
|
|
6730
6910
|
};
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -351,9 +351,12 @@ type TraceEventRecord = {
|
|
|
351
351
|
spanId?: string | number | null;
|
|
352
352
|
parentSpanId?: string | number | null;
|
|
353
353
|
args?: any;
|
|
354
|
+
argsValueCapture?: TraceValueCaptureRef;
|
|
354
355
|
returnValue?: any;
|
|
356
|
+
returnValueCapture?: TraceValueCaptureRef;
|
|
355
357
|
threw?: boolean;
|
|
356
358
|
error?: any;
|
|
359
|
+
errorValueCapture?: TraceValueCaptureRef;
|
|
357
360
|
unawaited?: boolean;
|
|
358
361
|
};
|
|
359
362
|
|
|
@@ -387,7 +390,10 @@ type TraceValueBatchEntry = {
|
|
|
387
390
|
| 'request.body'
|
|
388
391
|
| 'request.params'
|
|
389
392
|
| 'request.query'
|
|
390
|
-
| 'response.body'
|
|
393
|
+
| 'response.body'
|
|
394
|
+
| 'trace.args'
|
|
395
|
+
| 'trace.returnValue'
|
|
396
|
+
| 'trace.error';
|
|
391
397
|
value: any;
|
|
392
398
|
truncatedForStorage?: boolean;
|
|
393
399
|
projectedKind?: string;
|
|
@@ -2533,6 +2539,53 @@ function sanitizeMaterializedTraceValue(value: any): any {
|
|
|
2533
2539
|
return sanitizeTraceValue(value, 0, new WeakMap(), { preserveLongStrings: true, disableTruncation: true });
|
|
2534
2540
|
}
|
|
2535
2541
|
|
|
2542
|
+
function compactMaterializedTracePreview(value: any, depth = 0): any {
|
|
2543
|
+
if (value === undefined || value === null) return value;
|
|
2544
|
+
if (depth >= TRACE_VALUE_MAX_DEPTH) {
|
|
2545
|
+
return makeOmittedValue(`depth>${TRACE_VALUE_MAX_DEPTH}`);
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
const type = typeof value;
|
|
2549
|
+
if (type === 'string') {
|
|
2550
|
+
if (value.length <= TRACE_VALUE_MAX_STRING) return value;
|
|
2551
|
+
return value.slice(0, TRACE_VALUE_MAX_STRING);
|
|
2552
|
+
}
|
|
2553
|
+
if (type === 'number' || type === 'boolean') return value;
|
|
2554
|
+
if (type === 'bigint') return value.toString();
|
|
2555
|
+
if (type === 'symbol') return value.toString();
|
|
2556
|
+
if (type === 'function') return `[Function${value.name ? ` ${value.name}` : ''}]`;
|
|
2557
|
+
if (type !== 'object') return String(value);
|
|
2558
|
+
|
|
2559
|
+
if (Array.isArray(value)) {
|
|
2560
|
+
return value
|
|
2561
|
+
.slice(0, TRACE_VALUE_MAX_ITEMS)
|
|
2562
|
+
.map((item) => compactMaterializedTracePreview(item, depth + 1));
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2565
|
+
const out: Record<string, any> = {};
|
|
2566
|
+
const keys = Object.keys(value).slice(0, TRACE_VALUE_MAX_KEYS);
|
|
2567
|
+
for (const key of keys) {
|
|
2568
|
+
try {
|
|
2569
|
+
out[key] = compactMaterializedTracePreview((value as Record<string, any>)[key], depth + 1);
|
|
2570
|
+
} catch (err) {
|
|
2571
|
+
out[key] = `[Cannot serialize: ${(err as Error)?.message || 'unknown error'}]`;
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
return out;
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
function limitMaterializedTraceInlineValue(value: any): any {
|
|
2578
|
+
const inlineValue = sanitizeMaterializedTraceValue(value);
|
|
2579
|
+
if (!traceInlineValueExceedsLimit(inlineValue)) {
|
|
2580
|
+
return inlineValue;
|
|
2581
|
+
}
|
|
2582
|
+
const compactPreview = compactMaterializedTracePreview(inlineValue);
|
|
2583
|
+
if (!traceInlineValueExceedsLimit(compactPreview)) {
|
|
2584
|
+
return compactPreview;
|
|
2585
|
+
}
|
|
2586
|
+
return makeOmittedValue('inline-size-limit');
|
|
2587
|
+
}
|
|
2588
|
+
|
|
2536
2589
|
function sanitizeTraceArgsForPrivacy(values: any): any {
|
|
2537
2590
|
if (!Array.isArray(values)) return [sanitizeTraceValueForPrivacy(values)];
|
|
2538
2591
|
return values.map(v => sanitizeTraceValueForPrivacy(v));
|
|
@@ -2547,6 +2600,18 @@ function hasMeaningfulRawTraceError(error: any): boolean {
|
|
|
2547
2600
|
return error !== undefined && error !== null;
|
|
2548
2601
|
}
|
|
2549
2602
|
|
|
2603
|
+
function attachTraceValueEntry(
|
|
2604
|
+
event: TraceEventRecord | PendingTraceEventRecord,
|
|
2605
|
+
entry: TraceValueBatchEntry,
|
|
2606
|
+
): void {
|
|
2607
|
+
const current = (event as any)[TRACE_FULL_VALUE_ENTRY_SYMBOL] as TraceValueBatchEntry[] | undefined;
|
|
2608
|
+
if (Array.isArray(current)) {
|
|
2609
|
+
current.push(entry);
|
|
2610
|
+
return;
|
|
2611
|
+
}
|
|
2612
|
+
(event as any)[TRACE_FULL_VALUE_ENTRY_SYMBOL] = [entry];
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2550
2615
|
async function materializePendingTraceEvents(
|
|
2551
2616
|
events: PendingTraceEventRecord[],
|
|
2552
2617
|
params: {
|
|
@@ -2564,9 +2629,24 @@ async function materializePendingTraceEvents(
|
|
|
2564
2629
|
const candidate = pending.candidate ?? traceEventCandidateFromRecord(evt);
|
|
2565
2630
|
const omitJsonBuiltinValues = shouldOmitJsonBuiltinTraceValues(candidate);
|
|
2566
2631
|
const activePrivacy = params.resolvePrivacy();
|
|
2632
|
+
const captureContext: FullValueCaptureContext = {
|
|
2633
|
+
runtimeConfig: params.cfg,
|
|
2634
|
+
captureHeaders: params.cfg.captureHeaders,
|
|
2635
|
+
maskReq: params.maskReq,
|
|
2636
|
+
trace: candidate,
|
|
2637
|
+
masking: params.masking,
|
|
2638
|
+
privacy: activePrivacy,
|
|
2639
|
+
};
|
|
2640
|
+
const traceValueMetadata = {
|
|
2641
|
+
fn: evt.fn,
|
|
2642
|
+
file: evt.file,
|
|
2643
|
+
line: evt.line ?? null,
|
|
2644
|
+
spanId: evt.spanId ?? null,
|
|
2645
|
+
parentSpanId: evt.parentSpanId ?? null,
|
|
2646
|
+
};
|
|
2567
2647
|
|
|
2568
2648
|
if (!omitJsonBuiltinValues && pending.argsRaw !== undefined) {
|
|
2569
|
-
|
|
2649
|
+
const argsMaterialized = await materializeTracePrivacyValueAsync(
|
|
2570
2650
|
'trace.args',
|
|
2571
2651
|
sanitizeTraceArgsForPrivacy(pending.argsRaw),
|
|
2572
2652
|
params.cfg,
|
|
@@ -2574,10 +2654,24 @@ async function materializePendingTraceEvents(
|
|
|
2574
2654
|
candidate,
|
|
2575
2655
|
params.masking,
|
|
2576
2656
|
activePrivacy,
|
|
2577
|
-
)
|
|
2657
|
+
);
|
|
2658
|
+
evt.args = limitMaterializedTraceInlineValue(argsMaterialized);
|
|
2659
|
+
const argsValueCapture = await maybeCaptureTraceValueAsync({
|
|
2660
|
+
target: 'trace.args',
|
|
2661
|
+
rawValue: pending.argsRaw,
|
|
2662
|
+
previewValue: evt.args,
|
|
2663
|
+
capture: captureContext,
|
|
2664
|
+
metadata: traceValueMetadata,
|
|
2665
|
+
});
|
|
2666
|
+
if (argsValueCapture?.entry) {
|
|
2667
|
+
attachTraceValueEntry(evt, argsValueCapture.entry);
|
|
2668
|
+
}
|
|
2669
|
+
if (argsValueCapture?.captureRef) {
|
|
2670
|
+
evt.argsValueCapture = argsValueCapture.captureRef;
|
|
2671
|
+
}
|
|
2578
2672
|
}
|
|
2579
2673
|
if (!omitJsonBuiltinValues && pending.returnValueRaw !== undefined) {
|
|
2580
|
-
|
|
2674
|
+
const returnValueMaterialized = await materializeTracePrivacyValueAsync(
|
|
2581
2675
|
'trace.returnValue',
|
|
2582
2676
|
sanitizeTraceValueForPrivacy(pending.returnValueRaw),
|
|
2583
2677
|
params.cfg,
|
|
@@ -2585,10 +2679,24 @@ async function materializePendingTraceEvents(
|
|
|
2585
2679
|
candidate,
|
|
2586
2680
|
params.masking,
|
|
2587
2681
|
activePrivacy,
|
|
2588
|
-
)
|
|
2682
|
+
);
|
|
2683
|
+
evt.returnValue = limitMaterializedTraceInlineValue(returnValueMaterialized);
|
|
2684
|
+
const returnValueCapture = await maybeCaptureTraceValueAsync({
|
|
2685
|
+
target: 'trace.returnValue',
|
|
2686
|
+
rawValue: pending.returnValueRaw,
|
|
2687
|
+
previewValue: evt.returnValue,
|
|
2688
|
+
capture: captureContext,
|
|
2689
|
+
metadata: traceValueMetadata,
|
|
2690
|
+
});
|
|
2691
|
+
if (returnValueCapture?.entry) {
|
|
2692
|
+
attachTraceValueEntry(evt, returnValueCapture.entry);
|
|
2693
|
+
}
|
|
2694
|
+
if (returnValueCapture?.captureRef) {
|
|
2695
|
+
evt.returnValueCapture = returnValueCapture.captureRef;
|
|
2696
|
+
}
|
|
2589
2697
|
}
|
|
2590
2698
|
if (pending.errorRaw !== undefined) {
|
|
2591
|
-
|
|
2699
|
+
const errorMaterialized = await materializeTracePrivacyValueAsync(
|
|
2592
2700
|
'trace.error',
|
|
2593
2701
|
sanitizeTraceValueForPrivacy(pending.errorRaw),
|
|
2594
2702
|
params.cfg,
|
|
@@ -2596,7 +2704,21 @@ async function materializePendingTraceEvents(
|
|
|
2596
2704
|
candidate,
|
|
2597
2705
|
params.masking,
|
|
2598
2706
|
activePrivacy,
|
|
2599
|
-
)
|
|
2707
|
+
);
|
|
2708
|
+
evt.error = limitMaterializedTraceInlineValue(errorMaterialized);
|
|
2709
|
+
const errorValueCapture = await maybeCaptureTraceValueAsync({
|
|
2710
|
+
target: 'trace.error',
|
|
2711
|
+
rawValue: pending.errorRaw,
|
|
2712
|
+
previewValue: evt.error,
|
|
2713
|
+
capture: captureContext,
|
|
2714
|
+
metadata: traceValueMetadata,
|
|
2715
|
+
});
|
|
2716
|
+
if (errorValueCapture?.entry) {
|
|
2717
|
+
attachTraceValueEntry(evt, errorValueCapture.entry);
|
|
2718
|
+
}
|
|
2719
|
+
if (errorValueCapture?.captureRef) {
|
|
2720
|
+
evt.errorValueCapture = errorValueCapture.captureRef;
|
|
2721
|
+
}
|
|
2600
2722
|
}
|
|
2601
2723
|
}
|
|
2602
2724
|
return events;
|
|
@@ -4325,7 +4447,10 @@ function createCapturedValueEntry(
|
|
|
4325
4447
|
| 'request.body'
|
|
4326
4448
|
| 'request.params'
|
|
4327
4449
|
| 'request.query'
|
|
4328
|
-
| 'response.body'
|
|
4450
|
+
| 'response.body'
|
|
4451
|
+
| 'trace.args'
|
|
4452
|
+
| 'trace.returnValue'
|
|
4453
|
+
| 'trace.error';
|
|
4329
4454
|
rawValue: any;
|
|
4330
4455
|
previewValue: any;
|
|
4331
4456
|
capture: FullValueCaptureContext;
|
|
@@ -4404,7 +4529,10 @@ async function createCapturedValueEntryAsync(
|
|
|
4404
4529
|
| 'request.body'
|
|
4405
4530
|
| 'request.params'
|
|
4406
4531
|
| 'request.query'
|
|
4407
|
-
| 'response.body'
|
|
4532
|
+
| 'response.body'
|
|
4533
|
+
| 'trace.args'
|
|
4534
|
+
| 'trace.returnValue'
|
|
4535
|
+
| 'trace.error';
|
|
4408
4536
|
rawValue: any;
|
|
4409
4537
|
previewValue: any;
|
|
4410
4538
|
capture: FullValueCaptureContext;
|
|
@@ -4504,6 +4632,30 @@ async function maybeCaptureRequestValueAsync(
|
|
|
4504
4632
|
return result.captureRef;
|
|
4505
4633
|
}
|
|
4506
4634
|
|
|
4635
|
+
function maybeCaptureTraceValue(
|
|
4636
|
+
params: {
|
|
4637
|
+
target: 'trace.args' | 'trace.returnValue' | 'trace.error';
|
|
4638
|
+
rawValue: any;
|
|
4639
|
+
previewValue: any;
|
|
4640
|
+
capture: FullValueCaptureContext;
|
|
4641
|
+
metadata?: Partial<TraceValueBatchEntry>;
|
|
4642
|
+
},
|
|
4643
|
+
): { captureRef: TraceValueCaptureRef; entry?: TraceValueBatchEntry } | undefined {
|
|
4644
|
+
return createCapturedValueEntry(params);
|
|
4645
|
+
}
|
|
4646
|
+
|
|
4647
|
+
async function maybeCaptureTraceValueAsync(
|
|
4648
|
+
params: {
|
|
4649
|
+
target: 'trace.args' | 'trace.returnValue' | 'trace.error';
|
|
4650
|
+
rawValue: any;
|
|
4651
|
+
previewValue: any;
|
|
4652
|
+
capture: FullValueCaptureContext;
|
|
4653
|
+
metadata?: Partial<TraceValueBatchEntry>;
|
|
4654
|
+
},
|
|
4655
|
+
): Promise<{ captureRef: TraceValueCaptureRef; entry?: TraceValueBatchEntry } | undefined> {
|
|
4656
|
+
return await createCapturedValueEntryAsync(params);
|
|
4657
|
+
}
|
|
4658
|
+
|
|
4507
4659
|
function maybeCaptureDbValue(
|
|
4508
4660
|
params: {
|
|
4509
4661
|
target: 'db.pk' | 'db.before' | 'db.after' | 'db.query' | 'db.resultMeta' | 'db.error';
|
|
@@ -6222,8 +6374,23 @@ function recordKafkaTraceEvent(
|
|
|
6222
6374
|
|
|
6223
6375
|
const privacy = getRuntimePrivacyState(cfg).policy ?? null;
|
|
6224
6376
|
const masking = normalizeMaskingConfig(cfg.masking);
|
|
6377
|
+
const captureContext: FullValueCaptureContext = {
|
|
6378
|
+
runtimeConfig: cfg,
|
|
6379
|
+
captureHeaders: cfg.captureHeaders,
|
|
6380
|
+
maskReq,
|
|
6381
|
+
trace: candidate,
|
|
6382
|
+
masking,
|
|
6383
|
+
privacy,
|
|
6384
|
+
};
|
|
6385
|
+
const traceValueMetadata = {
|
|
6386
|
+
fn: evt.fn,
|
|
6387
|
+
file: evt.file,
|
|
6388
|
+
line: evt.line ?? null,
|
|
6389
|
+
spanId: evt.spanId ?? null,
|
|
6390
|
+
parentSpanId: evt.parentSpanId ?? null,
|
|
6391
|
+
};
|
|
6225
6392
|
if (!omitJsonBuiltinValues && raw.args !== undefined) {
|
|
6226
|
-
|
|
6393
|
+
const argsMaterialized = materializeTracePrivacyValue(
|
|
6227
6394
|
'trace.args',
|
|
6228
6395
|
sanitizeTraceArgsForPrivacy(raw.args),
|
|
6229
6396
|
cfg,
|
|
@@ -6231,10 +6398,24 @@ function recordKafkaTraceEvent(
|
|
|
6231
6398
|
candidate,
|
|
6232
6399
|
masking,
|
|
6233
6400
|
privacy,
|
|
6234
|
-
)
|
|
6401
|
+
);
|
|
6402
|
+
evt.args = limitMaterializedTraceInlineValue(argsMaterialized);
|
|
6403
|
+
const argsValueCapture = maybeCaptureTraceValue({
|
|
6404
|
+
target: 'trace.args',
|
|
6405
|
+
rawValue: normalizeRawTraceArgs(raw.args),
|
|
6406
|
+
previewValue: evt.args,
|
|
6407
|
+
capture: captureContext,
|
|
6408
|
+
metadata: traceValueMetadata,
|
|
6409
|
+
});
|
|
6410
|
+
if (argsValueCapture?.entry) {
|
|
6411
|
+
attachTraceValueEntry(evt, argsValueCapture.entry);
|
|
6412
|
+
}
|
|
6413
|
+
if (argsValueCapture?.captureRef) {
|
|
6414
|
+
evt.argsValueCapture = argsValueCapture.captureRef;
|
|
6415
|
+
}
|
|
6235
6416
|
}
|
|
6236
6417
|
if (!omitJsonBuiltinValues && raw.returnValue !== undefined) {
|
|
6237
|
-
|
|
6418
|
+
const returnValueMaterialized = materializeTracePrivacyValue(
|
|
6238
6419
|
'trace.returnValue',
|
|
6239
6420
|
sanitizeTraceValueForPrivacy(raw.returnValue),
|
|
6240
6421
|
cfg,
|
|
@@ -6242,10 +6423,24 @@ function recordKafkaTraceEvent(
|
|
|
6242
6423
|
candidate,
|
|
6243
6424
|
masking,
|
|
6244
6425
|
privacy,
|
|
6245
|
-
)
|
|
6426
|
+
);
|
|
6427
|
+
evt.returnValue = limitMaterializedTraceInlineValue(returnValueMaterialized);
|
|
6428
|
+
const returnValueCapture = maybeCaptureTraceValue({
|
|
6429
|
+
target: 'trace.returnValue',
|
|
6430
|
+
rawValue: raw.returnValue,
|
|
6431
|
+
previewValue: evt.returnValue,
|
|
6432
|
+
capture: captureContext,
|
|
6433
|
+
metadata: traceValueMetadata,
|
|
6434
|
+
});
|
|
6435
|
+
if (returnValueCapture?.entry) {
|
|
6436
|
+
attachTraceValueEntry(evt, returnValueCapture.entry);
|
|
6437
|
+
}
|
|
6438
|
+
if (returnValueCapture?.captureRef) {
|
|
6439
|
+
evt.returnValueCapture = returnValueCapture.captureRef;
|
|
6440
|
+
}
|
|
6246
6441
|
}
|
|
6247
6442
|
if (hasMeaningfulRawTraceError(raw.error)) {
|
|
6248
|
-
|
|
6443
|
+
const errorMaterialized = materializeTracePrivacyValue(
|
|
6249
6444
|
'trace.error',
|
|
6250
6445
|
sanitizeTraceValueForPrivacy(raw.error),
|
|
6251
6446
|
cfg,
|
|
@@ -6253,7 +6448,21 @@ function recordKafkaTraceEvent(
|
|
|
6253
6448
|
candidate,
|
|
6254
6449
|
masking,
|
|
6255
6450
|
privacy,
|
|
6256
|
-
)
|
|
6451
|
+
);
|
|
6452
|
+
evt.error = limitMaterializedTraceInlineValue(errorMaterialized);
|
|
6453
|
+
const errorValueCapture = maybeCaptureTraceValue({
|
|
6454
|
+
target: 'trace.error',
|
|
6455
|
+
rawValue: raw.error,
|
|
6456
|
+
previewValue: evt.error,
|
|
6457
|
+
capture: captureContext,
|
|
6458
|
+
metadata: traceValueMetadata,
|
|
6459
|
+
});
|
|
6460
|
+
if (errorValueCapture?.entry) {
|
|
6461
|
+
attachTraceValueEntry(evt, errorValueCapture.entry);
|
|
6462
|
+
}
|
|
6463
|
+
if (errorValueCapture?.captureRef) {
|
|
6464
|
+
evt.errorValueCapture = errorValueCapture.captureRef;
|
|
6465
|
+
}
|
|
6257
6466
|
}
|
|
6258
6467
|
if (raw.threw !== undefined) evt.threw = raw.threw === true;
|
|
6259
6468
|
if (raw.unawaited !== undefined) evt.unawaited = raw.unawaited === true;
|
|
@@ -6362,6 +6571,7 @@ function buildKafkaTraceEntries(
|
|
|
6362
6571
|
return batches.map((batch, index) => ({
|
|
6363
6572
|
actionId: actionId ?? null,
|
|
6364
6573
|
trace: batch,
|
|
6574
|
+
traceValues: collectBatchTraceValueEntries(batch, index),
|
|
6365
6575
|
traceBatch: {
|
|
6366
6576
|
rid: requestRid,
|
|
6367
6577
|
index,
|
|
@@ -7752,4 +7962,5 @@ export const __reproTestHooks = {
|
|
|
7752
7962
|
estimateTraceBatchSerializedBytesForTest: estimateTraceBatchSerializedBytes,
|
|
7753
7963
|
sanitizeTraceValueForPrivacyForTest: sanitizeTraceValueForPrivacy,
|
|
7754
7964
|
sanitizeMaterializedTraceValueForTest: sanitizeMaterializedTraceValue,
|
|
7965
|
+
getEventTraceValueEntriesForTest: getEventTraceValueEntries,
|
|
7755
7966
|
};
|
|
@@ -419,7 +419,19 @@ async function testKafkaProducerCapturesFullPublishedMessageValue() {
|
|
|
419
419
|
}
|
|
420
420
|
|
|
421
421
|
function assertNoLargeJsonPreviewArtifacts(value) {
|
|
422
|
-
const text = JSON.stringify(value)
|
|
422
|
+
const text = JSON.stringify(value, (key, currentValue) => {
|
|
423
|
+
if (
|
|
424
|
+
key === 'argsValueCapture' ||
|
|
425
|
+
key === 'returnValueCapture' ||
|
|
426
|
+
key === 'errorValueCapture' ||
|
|
427
|
+
key === 'argsMaterialization' ||
|
|
428
|
+
key === 'returnValueMaterialization' ||
|
|
429
|
+
key === 'errorMaterialization'
|
|
430
|
+
) {
|
|
431
|
+
return undefined;
|
|
432
|
+
}
|
|
433
|
+
return currentValue;
|
|
434
|
+
});
|
|
423
435
|
assert(!text.includes('__type":"json-string'), text);
|
|
424
436
|
assert(!text.includes('__truncatedKeys'), text);
|
|
425
437
|
assert(!text.includes('__truncatedItems'), text);
|
|
@@ -540,7 +552,7 @@ async function testJsonBuiltinTracePayloadsAreOmitted() {
|
|
|
540
552
|
assertNoLargeJsonPreviewArtifacts(consumedSink[0]);
|
|
541
553
|
}
|
|
542
554
|
|
|
543
|
-
async function
|
|
555
|
+
async function testLargeStringTraceValuesStayIngestibleAndCaptureFullValueOutOfBand() {
|
|
544
556
|
const hugeMarker = 'HUGE_INLINE_VALUE_MARKER';
|
|
545
557
|
const hugeJson = JSON.stringify({
|
|
546
558
|
eventId: 'evt-huge',
|
|
@@ -586,13 +598,18 @@ async function testLargeStringTraceValuesAreCapturedInlineWithoutTruncation() {
|
|
|
586
598
|
assert.strictEqual(sink[0].fn, 'parseGatewayPayload');
|
|
587
599
|
assert.strictEqual(typeof sink[0].args[0], 'string');
|
|
588
600
|
assert(sink[0].args[0].includes(hugeMarker), JSON.stringify(sink[0]));
|
|
589
|
-
assert(sink[0].args[0].
|
|
590
|
-
assert.strictEqual(sink[0].
|
|
591
|
-
|
|
592
|
-
|
|
601
|
+
assert(sink[0].args[0].length < 4096, JSON.stringify(sink[0]));
|
|
602
|
+
assert.strictEqual(sink[0].argsValueCapture?.status, 'stored', JSON.stringify(sink[0]));
|
|
603
|
+
const entries = __reproTestHooks.getEventTraceValueEntriesForTest(sink[0]);
|
|
604
|
+
assert(Array.isArray(entries) && entries.length === 1, JSON.stringify(entries));
|
|
605
|
+
assert.strictEqual(entries[0].target, 'trace.args');
|
|
606
|
+
assert.strictEqual(typeof entries[0].value?.[0], 'string');
|
|
607
|
+
assert(entries[0].value[0].includes(hugeMarker), JSON.stringify(entries[0]));
|
|
608
|
+
assert(entries[0].value[0].includes('x'.repeat(140 * 1024)), JSON.stringify(entries[0]));
|
|
609
|
+
assertNoLargeJsonPreviewArtifacts(sink[0].args);
|
|
593
610
|
}
|
|
594
611
|
|
|
595
|
-
async function
|
|
612
|
+
async function testLargeStructuredTraceValuesStayIngestibleAndCaptureFullValueOutOfBand() {
|
|
596
613
|
const hugeMarker = 'HUGE_STRUCTURED_TRACE_VALUE_MARKER';
|
|
597
614
|
const hugeEnvelope = {
|
|
598
615
|
eventId: 'evt-huge-structured',
|
|
@@ -641,19 +658,29 @@ async function testLargeStructuredTraceValuesAreCapturedInlineWithoutTruncation(
|
|
|
641
658
|
|
|
642
659
|
assert.strictEqual(sink.length, 1);
|
|
643
660
|
assert.strictEqual(sink[0].fn, 'recordConsumedEvent');
|
|
644
|
-
assert(sink[0].args, 'expected args to be stored inline');
|
|
645
|
-
assert.
|
|
661
|
+
assert(sink[0].args, 'expected args preview to be stored inline');
|
|
662
|
+
assert(JSON.stringify(sink[0].args).length < 9000, JSON.stringify(sink[0]).slice(0, 12000));
|
|
663
|
+
assert.strictEqual(
|
|
664
|
+
sink[0].args[0]?.providerResponse?.rawNarrative?.__kind,
|
|
665
|
+
'omitted',
|
|
666
|
+
JSON.stringify(sink[0]),
|
|
667
|
+
);
|
|
646
668
|
assert.strictEqual(typeof sink[0].args[2], 'string');
|
|
647
|
-
|
|
669
|
+
assert(sink[0].args[2].includes('providerResponse'), JSON.stringify(sink[0]));
|
|
670
|
+
assert.strictEqual(sink[0].argsValueCapture?.status, 'stored', JSON.stringify(sink[0]));
|
|
671
|
+
const entries = __reproTestHooks.getEventTraceValueEntriesForTest(sink[0]);
|
|
672
|
+
assert(Array.isArray(entries) && entries.length === 1, JSON.stringify(entries));
|
|
673
|
+
assert.strictEqual(entries[0].target, 'trace.args');
|
|
674
|
+
assert.strictEqual(entries[0].value?.[0]?.providerResponse?.rawNarrative, `${hugeMarker}:${'x'.repeat(40 * 1024)}`);
|
|
675
|
+
assert.strictEqual(typeof entries[0].value?.[2], 'string');
|
|
676
|
+
const parsedRawArg = JSON.parse(entries[0].value[2]);
|
|
648
677
|
assert.strictEqual(parsedRawArg.providerResponse.rawNarrative, `${hugeMarker}:${'x'.repeat(40 * 1024)}`);
|
|
649
678
|
assert.strictEqual(parsedRawArg.providerResponse.credentials.apiKey, '[dropped]');
|
|
650
679
|
assert.strictEqual(parsedRawArg.providerResponse.credentials.webhookSecret, '[dropped]');
|
|
651
|
-
|
|
652
|
-
assert.strictEqual(sink[0].argsValueCapture, undefined, JSON.stringify(sink[0]));
|
|
653
|
-
assertNoLargeJsonPreviewArtifacts(sink[0]);
|
|
680
|
+
assertNoLargeJsonPreviewArtifacts(sink[0].args);
|
|
654
681
|
}
|
|
655
682
|
|
|
656
|
-
async function
|
|
683
|
+
async function testLargeTraceReturnValueStaysIngestibleAndCapturesFullValueOutOfBand() {
|
|
657
684
|
const hugeMarker = 'HUGE_STRUCTURED_TRACE_RETURN_MARKER';
|
|
658
685
|
const hugeResponse = {
|
|
659
686
|
id: 'drill-1',
|
|
@@ -698,11 +725,17 @@ async function testLargeTraceReturnValueIsCapturedInlineWithoutTruncation() {
|
|
|
698
725
|
|
|
699
726
|
assert.strictEqual(sink.length, 1);
|
|
700
727
|
assert.strictEqual(sink[0].fn, 'toDrillResponse');
|
|
701
|
-
assert(sink[0].returnValue, 'expected return value to be stored inline');
|
|
702
|
-
assert.
|
|
703
|
-
assert.strictEqual(sink[0].
|
|
704
|
-
assert
|
|
705
|
-
|
|
728
|
+
assert(sink[0].returnValue, 'expected return value preview to be stored inline');
|
|
729
|
+
assert(JSON.stringify(sink[0].returnValue).length < 9000, JSON.stringify(sink[0]).slice(0, 12000));
|
|
730
|
+
assert.strictEqual(typeof sink[0].returnValue?.structuredSnapshot?.payload, 'string');
|
|
731
|
+
assert(sink[0].returnValue.structuredSnapshot.payload.includes(hugeMarker), JSON.stringify(sink[0]));
|
|
732
|
+
assert(sink[0].returnValue.structuredSnapshot.payload.length < 4096, JSON.stringify(sink[0]));
|
|
733
|
+
assert.strictEqual(sink[0].returnValueCapture?.status, 'stored', JSON.stringify(sink[0]));
|
|
734
|
+
const entries = __reproTestHooks.getEventTraceValueEntriesForTest(sink[0]);
|
|
735
|
+
assert(Array.isArray(entries) && entries.length === 1, JSON.stringify(entries));
|
|
736
|
+
assert.strictEqual(entries[0].target, 'trace.returnValue');
|
|
737
|
+
assert.strictEqual(entries[0].value?.structuredSnapshot?.payload, `${hugeMarker}:${'x'.repeat(40 * 1024)}`);
|
|
738
|
+
assertNoLargeJsonPreviewArtifacts(sink[0].returnValue);
|
|
706
739
|
}
|
|
707
740
|
|
|
708
741
|
async function main() {
|
|
@@ -712,9 +745,9 @@ async function main() {
|
|
|
712
745
|
await testKafkaTraceFlushIsNotBlockedForeverByActiveHttpRequest();
|
|
713
746
|
await testLargeHttpResponseBodyIsCapturedWithoutDroppingRequest();
|
|
714
747
|
await testJsonBuiltinTracePayloadsAreOmitted();
|
|
715
|
-
await
|
|
716
|
-
await
|
|
717
|
-
await
|
|
748
|
+
await testLargeStringTraceValuesStayIngestibleAndCaptureFullValueOutOfBand();
|
|
749
|
+
await testLargeStructuredTraceValuesStayIngestibleAndCaptureFullValueOutOfBand();
|
|
750
|
+
await testLargeTraceReturnValueStaysIngestibleAndCapturesFullValueOutOfBand();
|
|
718
751
|
console.log('kafka runtime privacy policy wiring OK');
|
|
719
752
|
}
|
|
720
753
|
|