logixia 1.12.6 → 1.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -4
- package/dist/{async-context-CwBNMm2E.mjs → async-context-BzJrbfQs.mjs} +8 -4
- package/dist/async-context-BzJrbfQs.mjs.map +1 -0
- package/dist/{async-context-CSHWoHMB.js → async-context-DyQQYq3I.js} +8 -4
- package/dist/async-context-DyQQYq3I.js.map +1 -0
- package/dist/{azure-monitor.transport-CG7ClkYj.d.ts → azure-monitor.transport-BDFO4F-i.d.ts} +2 -2
- package/dist/{azure-monitor.transport-CG7ClkYj.d.ts.map → azure-monitor.transport-BDFO4F-i.d.ts.map} +1 -1
- package/dist/{azure-monitor.transport-Cm74kXZS.d.mts → azure-monitor.transport-D5wQEH04.d.mts} +2 -2
- package/dist/{azure-monitor.transport-Cm74kXZS.d.mts.map → azure-monitor.transport-D5wQEH04.d.mts.map} +1 -1
- package/dist/azure.d.mts +2 -2
- package/dist/azure.d.ts +2 -2
- package/dist/cli/index.js +98 -52
- package/dist/cloudwatch.d.mts +2 -2
- package/dist/cloudwatch.d.ts +2 -2
- package/dist/cloudwatch.js +2 -1
- package/dist/cloudwatch.mjs +2 -1
- package/dist/{cloudwatch.transport-CGHY4buE.d.mts → cloudwatch.transport-B00st6Xv.d.ts} +9 -2
- package/dist/cloudwatch.transport-B00st6Xv.d.ts.map +1 -0
- package/dist/{cloudwatch.transport-pNBNWJLt.js → cloudwatch.transport-BO1ahxw-.js} +26 -19
- package/dist/cloudwatch.transport-BO1ahxw-.js.map +1 -0
- package/dist/{cloudwatch.transport-DK_8cKd3.d.ts → cloudwatch.transport-Blc7Gtxt.d.mts} +9 -2
- package/dist/cloudwatch.transport-Blc7Gtxt.d.mts.map +1 -0
- package/dist/{cloudwatch.transport-yBwm4OeO.mjs → cloudwatch.transport-DZ6ies7g.mjs} +26 -19
- package/dist/cloudwatch.transport-DZ6ies7g.mjs.map +1 -0
- package/dist/{coerce.utils-BN980Y9V.js → coerce.utils-B-LilukN.js} +1 -1
- package/dist/{coerce.utils-BN980Y9V.js.map → coerce.utils-B-LilukN.js.map} +1 -1
- package/dist/{coerce.utils-Dxv4_ikC.mjs → coerce.utils-Cu6IUTgX.mjs} +1 -1
- package/dist/{coerce.utils-Dxv4_ikC.mjs.map → coerce.utils-Cu6IUTgX.mjs.map} +1 -1
- package/dist/correlation.d.mts +31 -6
- package/dist/correlation.d.mts.map +1 -1
- package/dist/correlation.d.ts +31 -6
- package/dist/correlation.d.ts.map +1 -1
- package/dist/correlation.js +45 -20
- package/dist/correlation.js.map +1 -1
- package/dist/correlation.mjs +45 -20
- package/dist/correlation.mjs.map +1 -1
- package/dist/entry-fields-BJkuPnIg.mjs +30 -0
- package/dist/entry-fields-BJkuPnIg.mjs.map +1 -0
- package/dist/entry-fields-BvOLFlJ4.js +36 -0
- package/dist/entry-fields-BvOLFlJ4.js.map +1 -0
- package/dist/gcp.d.mts +2 -2
- package/dist/gcp.d.ts +2 -2
- package/dist/gcp.js +2 -1
- package/dist/gcp.mjs +2 -1
- package/dist/{gcp.transport-SHdtc1n0.js → gcp.transport-CHV8MGgz.js} +5 -5
- package/dist/gcp.transport-CHV8MGgz.js.map +1 -0
- package/dist/{gcp.transport-BJuNRFe_.mjs → gcp.transport-DBX5TPIy.mjs} +5 -5
- package/dist/gcp.transport-DBX5TPIy.mjs.map +1 -0
- package/dist/{gcp.transport-BOhkVKlI.d.ts → gcp.transport-m4fVw0b1.d.ts} +2 -2
- package/dist/gcp.transport-m4fVw0b1.d.ts.map +1 -0
- package/dist/{gcp.transport-Bi6CUqZR.d.mts → gcp.transport-zzNyIoih.d.mts} +2 -2
- package/dist/gcp.transport-zzNyIoih.d.mts.map +1 -0
- package/dist/{index-BPKwwERo.d.mts → index-BPwEisy4.d.mts} +2 -2
- package/dist/{index-BPKwwERo.d.mts.map → index-BPwEisy4.d.mts.map} +1 -1
- package/dist/{index-C1X-TE5I.d.ts → index-nZEeCr3X.d.ts} +2 -2
- package/dist/{index-C1X-TE5I.d.ts.map → index-nZEeCr3X.d.ts.map} +1 -1
- package/dist/index.d.mts +63 -98
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +63 -98
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +167 -443
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -377
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.d.mts +11 -4
- package/dist/middleware.d.mts.map +1 -1
- package/dist/middleware.d.ts +11 -4
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +148 -24
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +148 -24
- package/dist/middleware.mjs.map +1 -1
- package/dist/nest.d.mts +4 -4
- package/dist/nest.d.ts +4 -4
- package/dist/nest.js +20 -11
- package/dist/nest.mjs +7 -5
- package/dist/{logitron-logger.module-BsDZR5BH.js → nestjs-extras-DnJ6vrIC.js} +562 -444
- package/dist/nestjs-extras-DnJ6vrIC.js.map +1 -0
- package/dist/{logitron-logger.module-Bs3XYZgF.mjs → nestjs-extras-ImbuDhs1.mjs} +505 -349
- package/dist/nestjs-extras-ImbuDhs1.mjs.map +1 -0
- package/dist/{logitron-logger.module-zDKVd_o0.d.mts → nestjs-extras-OkC796py.d.mts} +113 -6
- package/dist/nestjs-extras-OkC796py.d.mts.map +1 -0
- package/dist/{logitron-logger.module-CxT1F6Cm.d.ts → nestjs-extras-mKrHE9S6.d.ts} +113 -6
- package/dist/nestjs-extras-mKrHE9S6.d.ts.map +1 -0
- package/dist/{search-njTI2hdo.js → search-B0MH1SJJ.js} +23 -10
- package/dist/search-B0MH1SJJ.js.map +1 -0
- package/dist/{search-DujhR94O.d.ts → search-BfBzDIT9.d.mts} +2 -3
- package/dist/search-BfBzDIT9.d.mts.map +1 -0
- package/dist/{search-CQOo-Iq6.d.mts → search-CHUZPl0h.d.ts} +2 -3
- package/dist/search-CHUZPl0h.d.ts.map +1 -0
- package/dist/{search-CFQRISUv.mjs → search-DjXSn6v5.mjs} +23 -10
- package/dist/search-DjXSn6v5.mjs.map +1 -0
- package/dist/search.d.mts +3 -3
- package/dist/search.d.ts +3 -3
- package/dist/search.js +2 -2
- package/dist/search.mjs +2 -2
- package/dist/testing.d.mts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/trace.utils-CvXgaiQT.mjs +278 -0
- package/dist/trace.utils-CvXgaiQT.mjs.map +1 -0
- package/dist/trace.utils-DpBOLDtq.js +358 -0
- package/dist/trace.utils-DpBOLDtq.js.map +1 -0
- package/dist/{transport.manager-D6KL3t9V.mjs → transport.manager-CpdVHEGP.mjs} +365 -86
- package/dist/transport.manager-CpdVHEGP.mjs.map +1 -0
- package/dist/{transport.manager-BivyUTtU.js → transport.manager-Crau3Rle.js} +370 -85
- package/dist/transport.manager-Crau3Rle.js.map +1 -0
- package/dist/{transport.types-B5vcyv2k.d.mts → transport.types-CtNr3D7S.d.mts} +19 -2
- package/dist/transport.types-CtNr3D7S.d.mts.map +1 -0
- package/dist/{transport.types-BuY84TwO.d.ts → transport.types-DqVLZTyf.d.ts} +19 -2
- package/dist/transport.types-DqVLZTyf.d.ts.map +1 -0
- package/dist/transports.d.mts +38 -13
- package/dist/transports.d.mts.map +1 -1
- package/dist/transports.d.ts +38 -13
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +6 -5
- package/dist/transports.mjs +6 -5
- package/dist/worker-entry.js +307 -55
- package/dist/worker.d.mts +2 -2
- package/dist/worker.d.ts +2 -2
- package/dist/worker.js +1 -1
- package/dist/worker.mjs +1 -1
- package/dist/{worker.transport-BP8Q28Z2.d.mts → worker.transport-Bgv9heDI.d.mts} +2 -2
- package/dist/{worker.transport-BP8Q28Z2.d.mts.map → worker.transport-Bgv9heDI.d.mts.map} +1 -1
- package/dist/{worker.transport-mKXgNK0L.d.ts → worker.transport-Bj-i0P9V.d.ts} +2 -2
- package/dist/{worker.transport-mKXgNK0L.d.ts.map → worker.transport-Bj-i0P9V.d.ts.map} +1 -1
- package/dist/{worker.transport-CfH6z37Z.js → worker.transport-JP8YHBuU.js} +1 -1
- package/dist/{worker.transport-CfH6z37Z.js.map → worker.transport-JP8YHBuU.js.map} +1 -1
- package/dist/{worker.transport-BhMyvqQ2.mjs → worker.transport-otwhJ_Et.mjs} +1 -1
- package/dist/{worker.transport-BhMyvqQ2.mjs.map → worker.transport-otwhJ_Et.mjs.map} +1 -1
- package/package.json +10 -6
- package/dist/.tsbuildinfo +0 -1
- package/dist/async-context-CSHWoHMB.js.map +0 -1
- package/dist/async-context-CwBNMm2E.mjs.map +0 -1
- package/dist/cloudwatch.transport-CGHY4buE.d.mts.map +0 -1
- package/dist/cloudwatch.transport-DK_8cKd3.d.ts.map +0 -1
- package/dist/cloudwatch.transport-pNBNWJLt.js.map +0 -1
- package/dist/cloudwatch.transport-yBwm4OeO.mjs.map +0 -1
- package/dist/gcp.transport-BJuNRFe_.mjs.map +0 -1
- package/dist/gcp.transport-BOhkVKlI.d.ts.map +0 -1
- package/dist/gcp.transport-Bi6CUqZR.d.mts.map +0 -1
- package/dist/gcp.transport-SHdtc1n0.js.map +0 -1
- package/dist/logitron-logger.module-Bs3XYZgF.mjs.map +0 -1
- package/dist/logitron-logger.module-BsDZR5BH.js.map +0 -1
- package/dist/logitron-logger.module-CxT1F6Cm.d.ts.map +0 -1
- package/dist/logitron-logger.module-zDKVd_o0.d.mts.map +0 -1
- package/dist/search-CFQRISUv.mjs.map +0 -1
- package/dist/search-CQOo-Iq6.d.mts.map +0 -1
- package/dist/search-DujhR94O.d.ts.map +0 -1
- package/dist/search-njTI2hdo.js.map +0 -1
- package/dist/transport.manager-BivyUTtU.js.map +0 -1
- package/dist/transport.manager-D6KL3t9V.mjs.map +0 -1
- package/dist/transport.types-B5vcyv2k.d.mts.map +0 -1
- package/dist/transport.types-BuY84TwO.d.ts.map +0 -1
- package/scripts/postinstall.js +0 -61
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
const require_chunk = require('./chunk-nOFOJqeH.js');
|
|
2
2
|
const require_internal_log = require('./internal-log-BUJYMZbE.js');
|
|
3
3
|
const require_safe_stringify = require('./safe-stringify-DWo3aZp_.js');
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
4
|
+
const require_trace_utils = require('./trace.utils-DpBOLDtq.js');
|
|
5
|
+
const require_async_context = require('./async-context-DyQQYq3I.js');
|
|
6
|
+
const require_coerce_utils = require('./coerce.utils-B-LilukN.js');
|
|
7
|
+
const require_transport_manager = require('./transport.manager-Crau3Rle.js');
|
|
7
8
|
let node_os = require("node:os");
|
|
8
9
|
node_os = require_chunk.__toESM(node_os);
|
|
9
|
-
let node_async_hooks = require("node:async_hooks");
|
|
10
|
-
node_async_hooks = require_chunk.__toESM(node_async_hooks);
|
|
11
10
|
let fast_json_stringify = require("fast-json-stringify");
|
|
12
11
|
fast_json_stringify = require_chunk.__toESM(fast_json_stringify);
|
|
13
|
-
let crypto = require("crypto");
|
|
14
|
-
crypto = require_chunk.__toESM(crypto);
|
|
15
12
|
let __nestjs_common = require("@nestjs/common");
|
|
16
13
|
__nestjs_common = require_chunk.__toESM(__nestjs_common);
|
|
17
14
|
let rxjs = require("rxjs");
|
|
@@ -392,16 +389,29 @@ function disableOtelBridge() {
|
|
|
392
389
|
//#endregion
|
|
393
390
|
//#region src/utils/redact.utils.ts
|
|
394
391
|
const DEFAULT_CENSOR = "[REDACTED]";
|
|
392
|
+
/** Maximum nesting depth walked; deeper values are replaced with a marker. */
|
|
393
|
+
const MAX_DEPTH = 32;
|
|
394
|
+
/** Maximum number of objects/arrays visited per redaction pass. */
|
|
395
|
+
const MAX_NODES = 1e4;
|
|
396
|
+
/**
|
|
397
|
+
* Strings longer than this are truncated before pattern scanning. The tail is
|
|
398
|
+
* dropped rather than emitted unscanned, so oversized input can never carry an
|
|
399
|
+
* unredacted secret past the patterns.
|
|
400
|
+
*/
|
|
401
|
+
const MAX_SCAN_LENGTH = 16384;
|
|
402
|
+
const MAX_DEPTH_MARKER = "[MaxDepth]";
|
|
403
|
+
const MAX_NODES_MARKER = "[MaxNodes]";
|
|
404
|
+
const REDACTION_FAILED = "[RedactionFailed]";
|
|
395
405
|
/**
|
|
396
406
|
* Conservative patterns: tokens and secrets that should NEVER appear in logs.
|
|
397
407
|
* Applied when `autoDetect: true` or `autoDetect: 'conservative'`.
|
|
398
408
|
*/
|
|
399
409
|
const PII_CONSERVATIVE_PATTERNS = [
|
|
400
|
-
/eyJ[A-Za-z0-9_-]
|
|
410
|
+
/eyJ[A-Za-z0-9_-]{1,1024}\.[A-Za-z0-9_-]{1,16384}\.[A-Za-z0-9_-]{0,1024}/g,
|
|
401
411
|
/Bearer\s+[A-Za-z0-9._~+/-]+=*/gi,
|
|
402
412
|
/\b(?:sk|pk|api|key|secret|token)-[A-Za-z0-9_-]{16,}/gi,
|
|
403
413
|
/\bAKIA[0-9A-Z]{16}\b/g,
|
|
404
|
-
|
|
414
|
+
/secret[_-]?(?:access[_-]?)?key["'\s:=]{1,6}[A-Za-z0-9/+]{40}(?![A-Za-z0-9/+])/gi
|
|
405
415
|
];
|
|
406
416
|
/**
|
|
407
417
|
* Conservative field-name paths auto-redacted by name regardless of value.
|
|
@@ -422,14 +432,24 @@ const PII_CONSERVATIVE_PATHS = [
|
|
|
422
432
|
"**.privateKey",
|
|
423
433
|
"**.private_key",
|
|
424
434
|
"**.clientSecret",
|
|
425
|
-
"**.client_secret"
|
|
435
|
+
"**.client_secret",
|
|
436
|
+
"**.cookie",
|
|
437
|
+
"**.set-cookie",
|
|
438
|
+
"**.x-api-key",
|
|
439
|
+
"**.session",
|
|
440
|
+
"**.proxy-authorization",
|
|
441
|
+
"**.x-auth-token",
|
|
442
|
+
"**.x-access-token",
|
|
443
|
+
"**.aws_secret_access_key",
|
|
444
|
+
"**.awsSecretAccessKey",
|
|
445
|
+
"**.secretAccessKey"
|
|
426
446
|
];
|
|
427
447
|
/**
|
|
428
448
|
* Aggressive patterns: also catch personal data that could identify a person.
|
|
429
449
|
* Applied when `autoDetect: 'aggressive'`.
|
|
430
450
|
*/
|
|
431
451
|
const PII_AGGRESSIVE_PATTERNS = [
|
|
432
|
-
/\b[A-Za-z0-9._%+-]
|
|
452
|
+
/\b[A-Za-z0-9._%+-]{1,64}@[A-Za-z0-9.-]{1,255}\.[A-Za-z]{2,24}\b/g,
|
|
433
453
|
/\b\d{3}-?\d{2}-?\d{4}\b/g,
|
|
434
454
|
/\b(?:\d[ -]?){13,19}\b/g,
|
|
435
455
|
/\b(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g,
|
|
@@ -526,32 +546,54 @@ function matchesPath(fullPath, pattern) {
|
|
|
526
546
|
}
|
|
527
547
|
return re.test(fullPath);
|
|
528
548
|
}
|
|
549
|
+
function isTokenChar(code) {
|
|
550
|
+
return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || code === 46 || code === 95 || code === 126 || code === 43 || code === 47 || code === 61 || code === 45;
|
|
551
|
+
}
|
|
529
552
|
function applyPatterns(value, patterns, censor) {
|
|
530
553
|
let redacted = value;
|
|
554
|
+
let suffix = "";
|
|
555
|
+
if (redacted.length > MAX_SCAN_LENGTH) {
|
|
556
|
+
let end = MAX_SCAN_LENGTH;
|
|
557
|
+
while (end > 0 && isTokenChar(redacted.charCodeAt(end - 1))) end--;
|
|
558
|
+
suffix = `…[truncated ${value.length - end} unscanned chars]`;
|
|
559
|
+
redacted = redacted.slice(0, end);
|
|
560
|
+
}
|
|
531
561
|
for (const pattern of patterns) redacted = redacted.replace(pattern, censor);
|
|
532
|
-
return redacted;
|
|
562
|
+
return redacted + suffix;
|
|
533
563
|
}
|
|
534
564
|
const CIRCULAR = "[Circular]";
|
|
535
565
|
function joinPath(parent, key) {
|
|
536
566
|
return parent ? `${parent}.${key}` : key;
|
|
537
567
|
}
|
|
538
|
-
function walkValue(value, state, fullPath, bare) {
|
|
568
|
+
function walkValue(value, state, fullPath, bare, depth) {
|
|
539
569
|
const { paths = [], excludePaths = [], patterns = [], censor = DEFAULT_CENSOR } = state.config;
|
|
540
570
|
if (paths.some((p) => matchesPath(fullPath, p) || matchesPath(bare, p))) return censor;
|
|
571
|
+
if (typeof value === "object" && value !== null) {
|
|
572
|
+
if (depth >= MAX_DEPTH) return MAX_DEPTH_MARKER;
|
|
573
|
+
if (++state.nodes > MAX_NODES) return MAX_NODES_MARKER;
|
|
574
|
+
}
|
|
541
575
|
if (typeof value === "string") {
|
|
542
576
|
if (patterns.length === 0) return value;
|
|
543
577
|
if (excludePaths.some((p) => matchesPath(fullPath, p) || matchesPath(bare, p))) return value;
|
|
544
578
|
return applyPatterns(value, patterns, censor);
|
|
545
579
|
}
|
|
546
|
-
if (Array.isArray(value)) return walkContainer(value, state, fullPath, bare, walkArray);
|
|
547
|
-
if (
|
|
580
|
+
if (Array.isArray(value)) return walkContainer(value, state, fullPath, bare, depth, walkArray);
|
|
581
|
+
if (value instanceof Error) return walkContainer(value, state, fullPath, bare, depth, walkError);
|
|
582
|
+
if (value instanceof URL) {
|
|
583
|
+
const url = new URL(value.href);
|
|
584
|
+
url.username = "";
|
|
585
|
+
url.password = "";
|
|
586
|
+
const redacted = walkValue(url.href, state, fullPath, bare, depth);
|
|
587
|
+
return redacted === value.href ? value : redacted;
|
|
588
|
+
}
|
|
589
|
+
if (isPlainObject(value)) return walkContainer(value, state, fullPath, bare, depth, typeof value.toJSON === "function" ? walkToJSON : walkRecord);
|
|
548
590
|
return value;
|
|
549
591
|
}
|
|
550
|
-
function walkContainer(value, state, fullPath, bare, walk) {
|
|
592
|
+
function walkContainer(value, state, fullPath, bare, depth, walk) {
|
|
551
593
|
if (state.ancestors.has(value)) return CIRCULAR;
|
|
552
594
|
state.ancestors.add(value);
|
|
553
595
|
try {
|
|
554
|
-
return walk(value, state, fullPath, bare);
|
|
596
|
+
return walk(value, state, fullPath, bare, depth + 1);
|
|
555
597
|
} finally {
|
|
556
598
|
state.ancestors.delete(value);
|
|
557
599
|
}
|
|
@@ -560,26 +602,51 @@ function walkContainer(value, state, fullPath, bare, walk) {
|
|
|
560
602
|
* Array elements are matched by their indexed path (`users.0.password`) and by
|
|
561
603
|
* the index-free path (`users.password`) that earlier versions used.
|
|
562
604
|
*/
|
|
563
|
-
function walkArray(arr, state, fullPath, bare) {
|
|
605
|
+
function walkArray(arr, state, fullPath, bare, depth) {
|
|
564
606
|
let result;
|
|
565
607
|
for (const [i, item] of arr.entries()) {
|
|
566
|
-
const next = walkValue(item, state, joinPath(fullPath, String(i)), bare);
|
|
608
|
+
const next = walkValue(item, state, joinPath(fullPath, String(i)), bare, depth);
|
|
567
609
|
if (next !== item && !result) result = arr.slice(0, i);
|
|
568
610
|
if (result) result.push(next);
|
|
569
611
|
}
|
|
570
612
|
return result ?? arr;
|
|
571
613
|
}
|
|
572
|
-
function walkRecord(obj, state, fullPath, bare) {
|
|
614
|
+
function walkRecord(obj, state, fullPath, bare, depth) {
|
|
573
615
|
let result;
|
|
574
616
|
const entries = Object.entries(obj);
|
|
575
617
|
for (const [index, [key, value]] of entries.entries()) {
|
|
576
618
|
const forbidden = key === "__proto__" || key === "constructor" || key === "prototype";
|
|
577
|
-
const next = forbidden ? void 0 : walkValue(value, state, joinPath(fullPath, key), joinPath(bare, key));
|
|
619
|
+
const next = forbidden ? void 0 : walkValue(value, state, joinPath(fullPath, key), joinPath(bare, key), depth);
|
|
578
620
|
if ((forbidden || next !== value) && !result) result = Object.fromEntries(entries.slice(0, index));
|
|
579
621
|
if (result && !forbidden) result[key] = next;
|
|
580
622
|
}
|
|
581
623
|
return result ?? obj;
|
|
582
624
|
}
|
|
625
|
+
/** Errors are serialized (own props + cause chain) and the result is walked. */
|
|
626
|
+
function walkError(err, state, fullPath, bare, depth) {
|
|
627
|
+
let serialized;
|
|
628
|
+
try {
|
|
629
|
+
serialized = serializeError(err);
|
|
630
|
+
} catch {
|
|
631
|
+
return {
|
|
632
|
+
name: err.name,
|
|
633
|
+
message: REDACTION_FAILED
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
const result = walkRecord(serialized, state, fullPath, bare, depth);
|
|
637
|
+
return result === serialized ? { ...serialized } : result;
|
|
638
|
+
}
|
|
639
|
+
/** Objects with `toJSON()` are redacted via the value they would serialize to. */
|
|
640
|
+
function walkToJSON(obj, state, fullPath, bare, depth) {
|
|
641
|
+
let json;
|
|
642
|
+
try {
|
|
643
|
+
json = obj.toJSON();
|
|
644
|
+
} catch {
|
|
645
|
+
return REDACTION_FAILED;
|
|
646
|
+
}
|
|
647
|
+
if (json === obj) return walkRecord(obj, state, fullPath, bare, depth);
|
|
648
|
+
return walkValue(json, state, fullPath, bare, depth);
|
|
649
|
+
}
|
|
583
650
|
/**
|
|
584
651
|
* Redact an object according to the given RedactConfig and return a new
|
|
585
652
|
* top-level object. Subtrees with nothing to redact are shared with the input,
|
|
@@ -588,8 +655,9 @@ function walkRecord(obj, state, fullPath, bare) {
|
|
|
588
655
|
function redactObject(obj, config, _currentPath = "") {
|
|
589
656
|
const result = walkRecord(obj, {
|
|
590
657
|
config,
|
|
591
|
-
ancestors: new Set([obj])
|
|
592
|
-
|
|
658
|
+
ancestors: new Set([obj]),
|
|
659
|
+
nodes: 0
|
|
660
|
+
}, _currentPath, _currentPath, 0);
|
|
593
661
|
return result === obj ? { ...obj } : result;
|
|
594
662
|
}
|
|
595
663
|
/**
|
|
@@ -600,12 +668,11 @@ function redactObject(obj, config, _currentPath = "") {
|
|
|
600
668
|
* stays allocation-free for the common no-redact case.
|
|
601
669
|
*/
|
|
602
670
|
function applyRedactionToString(value, config) {
|
|
603
|
-
|
|
671
|
+
const text = typeof value === "string" ? value : require_coerce_utils.safeToString(value);
|
|
672
|
+
if (!config) return text;
|
|
604
673
|
const resolved = resolveConfig(config);
|
|
605
|
-
if (!resolved.patterns || resolved.patterns.length === 0) return
|
|
606
|
-
|
|
607
|
-
for (const pattern of resolved.patterns) redacted = redacted.replace(pattern, resolved.censor ?? DEFAULT_CENSOR);
|
|
608
|
-
return redacted;
|
|
674
|
+
if (!resolved.patterns || resolved.patterns.length === 0) return text;
|
|
675
|
+
return applyPatterns(text, resolved.patterns, resolved.censor ?? DEFAULT_CENSOR);
|
|
609
676
|
}
|
|
610
677
|
/**
|
|
611
678
|
* Apply redaction to a log payload (top-level call convenience wrapper).
|
|
@@ -645,11 +712,21 @@ const ALWAYS_EMIT_LEVELS = new Set([
|
|
|
645
712
|
"warn",
|
|
646
713
|
"fatal"
|
|
647
714
|
]);
|
|
715
|
+
const MAX_CACHED_TRACE_ID_LENGTH = 256;
|
|
716
|
+
function isCacheableTraceId(id) {
|
|
717
|
+
if (typeof id !== "string" || id.length === 0 || id.length > MAX_CACHED_TRACE_ID_LENGTH) return false;
|
|
718
|
+
for (let i = 0; i < id.length; i++) {
|
|
719
|
+
const c = id.charCodeAt(i);
|
|
720
|
+
if (c < 32 || c >= 127 && c <= 159) return false;
|
|
721
|
+
}
|
|
722
|
+
return true;
|
|
723
|
+
}
|
|
648
724
|
var Sampler = class {
|
|
649
725
|
constructor(config, onStats) {
|
|
650
726
|
this.traceDecisions = /* @__PURE__ */ new Map();
|
|
651
727
|
this.maxTrackedTraces = 1e5;
|
|
652
728
|
this.traceTtlMs = 5 * 6e4;
|
|
729
|
+
this.traceMaxLifetimeMs = 60 * 6e4;
|
|
653
730
|
this._tokenBucket = 0;
|
|
654
731
|
this._lastRefillMs = Date.now();
|
|
655
732
|
this._adaptiveWindow = [];
|
|
@@ -769,13 +846,15 @@ var Sampler = class {
|
|
|
769
846
|
}
|
|
770
847
|
/**
|
|
771
848
|
* Return the cached decision for a trace, or make and cache a new one. Entries
|
|
772
|
-
* idle past the TTL are re-decided; the least
|
|
773
|
-
* once the cap is reached.
|
|
849
|
+
* idle past the TTL, or older than the hard lifetime, are re-decided; the least
|
|
850
|
+
* recently used entry is evicted once the cap is reached. IDs that are empty,
|
|
851
|
+
* too long or contain control characters are sampled independently and never cached.
|
|
774
852
|
*/
|
|
775
853
|
_decideForTrace(traceId, level) {
|
|
854
|
+
if (!isCacheableTraceId(traceId)) return this._sampleByRate(level);
|
|
776
855
|
const now = Date.now();
|
|
777
856
|
const known = this.traceDecisions.get(traceId);
|
|
778
|
-
if (known && now - known.seenAt <= this.traceTtlMs) {
|
|
857
|
+
if (known && now - known.seenAt <= this.traceTtlMs && now - known.firstAt <= this.traceMaxLifetimeMs) {
|
|
779
858
|
this.traceDecisions.delete(traceId);
|
|
780
859
|
known.seenAt = now;
|
|
781
860
|
this.traceDecisions.set(traceId, known);
|
|
@@ -785,6 +864,7 @@ var Sampler = class {
|
|
|
785
864
|
this.traceDecisions.delete(traceId);
|
|
786
865
|
this.traceDecisions.set(traceId, {
|
|
787
866
|
emit,
|
|
867
|
+
firstAt: now,
|
|
788
868
|
seenAt: now
|
|
789
869
|
});
|
|
790
870
|
if (this.traceDecisions.size > this.maxTrackedTraces) {
|
|
@@ -948,318 +1028,6 @@ function resetShutdownHandlers() {
|
|
|
948
1028
|
shutdownInProgress = false;
|
|
949
1029
|
}
|
|
950
1030
|
|
|
951
|
-
//#endregion
|
|
952
|
-
//#region node_modules/uuid/dist/esm-node/rng.js
|
|
953
|
-
const rnds8Pool = new Uint8Array(256);
|
|
954
|
-
let poolPtr = rnds8Pool.length;
|
|
955
|
-
function rng() {
|
|
956
|
-
if (poolPtr > rnds8Pool.length - 16) {
|
|
957
|
-
crypto.default.randomFillSync(rnds8Pool);
|
|
958
|
-
poolPtr = 0;
|
|
959
|
-
}
|
|
960
|
-
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
//#endregion
|
|
964
|
-
//#region node_modules/uuid/dist/esm-node/stringify.js
|
|
965
|
-
/**
|
|
966
|
-
* Convert array of 16 byte values to UUID string format of the form:
|
|
967
|
-
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
|
968
|
-
*/
|
|
969
|
-
const byteToHex = [];
|
|
970
|
-
for (let i = 0; i < 256; ++i) byteToHex.push((i + 256).toString(16).slice(1));
|
|
971
|
-
function unsafeStringify(arr, offset = 0) {
|
|
972
|
-
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
//#endregion
|
|
976
|
-
//#region node_modules/uuid/dist/esm-node/native.js
|
|
977
|
-
var native_default = { randomUUID: crypto.default.randomUUID };
|
|
978
|
-
|
|
979
|
-
//#endregion
|
|
980
|
-
//#region node_modules/uuid/dist/esm-node/v4.js
|
|
981
|
-
function v4(options, buf, offset) {
|
|
982
|
-
if (native_default.randomUUID && !buf && !options) return native_default.randomUUID();
|
|
983
|
-
options = options || {};
|
|
984
|
-
const rnds = options.random || (options.rng || rng)();
|
|
985
|
-
rnds[6] = rnds[6] & 15 | 64;
|
|
986
|
-
rnds[8] = rnds[8] & 63 | 128;
|
|
987
|
-
if (buf) {
|
|
988
|
-
offset = offset || 0;
|
|
989
|
-
for (let i = 0; i < 16; ++i) buf[offset + i] = rnds[i];
|
|
990
|
-
return buf;
|
|
991
|
-
}
|
|
992
|
-
return unsafeStringify(rnds);
|
|
993
|
-
}
|
|
994
|
-
var v4_default = v4;
|
|
995
|
-
|
|
996
|
-
//#endregion
|
|
997
|
-
//#region src/utils/trace.utils.ts
|
|
998
|
-
/** Default key used to store the trace ID in AsyncLocalStorage. */
|
|
999
|
-
const TRACE_CONTEXT_KEY = "traceId";
|
|
1000
|
-
/**
|
|
1001
|
-
* Singleton that owns the AsyncLocalStorage and the active contextKey.
|
|
1002
|
-
*
|
|
1003
|
-
* Why a class instead of bare module-level variables?
|
|
1004
|
-
* - The contextKey is user-configurable; encapsulating it here means there is
|
|
1005
|
-
* exactly one place that reads and writes it.
|
|
1006
|
-
* - All helpers (getCurrentTraceId, runWithTraceId, etc.) delegate to this
|
|
1007
|
-
* instance, so the key is always in sync without hidden global state.
|
|
1008
|
-
* - Easier to test: you can reset the singleton between test cases.
|
|
1009
|
-
*
|
|
1010
|
-
* Usage (advanced):
|
|
1011
|
-
* import { TraceContext } from 'logixia';
|
|
1012
|
-
* TraceContext.instance.contextKey // → 'traceId' (or custom)
|
|
1013
|
-
* TraceContext.instance.getCurrentTraceId() // same as standalone fn
|
|
1014
|
-
*/
|
|
1015
|
-
var TraceContext = class TraceContext {
|
|
1016
|
-
static #_ = this._instance = null;
|
|
1017
|
-
constructor() {
|
|
1018
|
-
this.storage = new node_async_hooks.AsyncLocalStorage();
|
|
1019
|
-
this._contextKey = TRACE_CONTEXT_KEY;
|
|
1020
|
-
}
|
|
1021
|
-
/** The process-wide singleton. */
|
|
1022
|
-
static get instance() {
|
|
1023
|
-
if (!TraceContext._instance) TraceContext._instance = new TraceContext();
|
|
1024
|
-
return TraceContext._instance;
|
|
1025
|
-
}
|
|
1026
|
-
/** @internal Reset the singleton (useful in tests). */
|
|
1027
|
-
static _reset() {
|
|
1028
|
-
TraceContext._instance = null;
|
|
1029
|
-
}
|
|
1030
|
-
/** The AsyncLocalStorage key that holds the trace ID value. */
|
|
1031
|
-
get contextKey() {
|
|
1032
|
-
return this._contextKey;
|
|
1033
|
-
}
|
|
1034
|
-
/** @internal Called by TraceMiddleware when it boots to register the user's key. */
|
|
1035
|
-
setContextKey(key) {
|
|
1036
|
-
this._contextKey = key;
|
|
1037
|
-
}
|
|
1038
|
-
/** UUID v4 generator (default). */
|
|
1039
|
-
generate() {
|
|
1040
|
-
return v4_default();
|
|
1041
|
-
}
|
|
1042
|
-
/** Read the trace ID from the current async context. */
|
|
1043
|
-
getCurrentTraceId() {
|
|
1044
|
-
var _this$storage$getStor;
|
|
1045
|
-
return (_this$storage$getStor = this.storage.getStore()) === null || _this$storage$getStor === void 0 ? void 0 : _this$storage$getStor[this._contextKey];
|
|
1046
|
-
}
|
|
1047
|
-
/**
|
|
1048
|
-
* Mutate the CURRENT async context in-place.
|
|
1049
|
-
*
|
|
1050
|
-
* ⚠️ DEPRECATED — unsafe for concurrent requests.
|
|
1051
|
-
*
|
|
1052
|
-
* Uses `AsyncLocalStorage.enterWith()`, which mutates the current async
|
|
1053
|
-
* execution context and every Promise chain spawned from it. In a server
|
|
1054
|
-
* processing overlapping requests this can cause a trace ID set for one
|
|
1055
|
-
* request to bleed into *other* in-flight requests that share the same
|
|
1056
|
-
* async parent (e.g. a module-level setup function or a cached handler).
|
|
1057
|
-
*
|
|
1058
|
-
* Use {@link run} instead — it scopes the context to a callback so there
|
|
1059
|
-
* is no risk of cross-request leakage.
|
|
1060
|
-
*
|
|
1061
|
-
* @deprecated Use `TraceContext.instance.run(traceId, fn)` — do not call
|
|
1062
|
-
* `setTraceId` from request-handling code.
|
|
1063
|
-
*/
|
|
1064
|
-
setTraceId(traceId, data) {
|
|
1065
|
-
const current = this.storage.getStore() ?? {};
|
|
1066
|
-
this.storage.enterWith({
|
|
1067
|
-
...current,
|
|
1068
|
-
[this._contextKey]: traceId,
|
|
1069
|
-
...data
|
|
1070
|
-
});
|
|
1071
|
-
}
|
|
1072
|
-
/** Run `fn` inside a new async context that carries `traceId`. */
|
|
1073
|
-
run(traceId, fn, data) {
|
|
1074
|
-
return this.storage.run({
|
|
1075
|
-
[this._contextKey]: traceId,
|
|
1076
|
-
...data
|
|
1077
|
-
}, fn);
|
|
1078
|
-
}
|
|
1079
|
-
};
|
|
1080
|
-
/**
|
|
1081
|
-
* The shared AsyncLocalStorage instance.
|
|
1082
|
-
* @deprecated Prefer `TraceContext.instance.storage` for new code.
|
|
1083
|
-
*/
|
|
1084
|
-
const traceStorage = TraceContext.instance.storage;
|
|
1085
|
-
/** Returns the key currently used to store the trace ID in AsyncLocalStorage. */
|
|
1086
|
-
function getTraceContextKey() {
|
|
1087
|
-
return TraceContext.instance.contextKey;
|
|
1088
|
-
}
|
|
1089
|
-
/** @internal Called by TraceMiddleware / traceMiddleware() when they boot. */
|
|
1090
|
-
function _setActiveContextKey(key) {
|
|
1091
|
-
TraceContext.instance.setContextKey(key);
|
|
1092
|
-
}
|
|
1093
|
-
/** Generate a UUID v4 trace ID. */
|
|
1094
|
-
function generateTraceId() {
|
|
1095
|
-
return TraceContext.instance.generate();
|
|
1096
|
-
}
|
|
1097
|
-
/**
|
|
1098
|
-
* Get the current trace ID from async context.
|
|
1099
|
-
* Returns `undefined` when called outside a traced request.
|
|
1100
|
-
*/
|
|
1101
|
-
function getCurrentTraceId() {
|
|
1102
|
-
return TraceContext.instance.getCurrentTraceId();
|
|
1103
|
-
}
|
|
1104
|
-
/**
|
|
1105
|
-
* Set trace ID in the CURRENT async context without starting a new one.
|
|
1106
|
-
*
|
|
1107
|
-
* ⚠️ DEPRECATED — unsafe for concurrent requests.
|
|
1108
|
-
*
|
|
1109
|
-
* Uses `AsyncLocalStorage.enterWith()`, which mutates the current async
|
|
1110
|
-
* execution context and every Promise chain spawned from it. Under load this
|
|
1111
|
-
* can cause a trace ID from one request to bleed into others sharing the same
|
|
1112
|
-
* async parent.
|
|
1113
|
-
*
|
|
1114
|
-
* Use {@link runWithTraceId} instead. Migration patterns:
|
|
1115
|
-
*
|
|
1116
|
-
* **Express / Fastify middleware — before:**
|
|
1117
|
-
* ```ts
|
|
1118
|
-
* app.use((req, _res, next) => {
|
|
1119
|
-
* setTraceId(req.headers['x-trace-id'] ?? generateTraceId());
|
|
1120
|
-
* next();
|
|
1121
|
-
* });
|
|
1122
|
-
* ```
|
|
1123
|
-
* **after:**
|
|
1124
|
-
* ```ts
|
|
1125
|
-
* app.use((req, _res, next) => {
|
|
1126
|
-
* runWithTraceId(req.headers['x-trace-id'] ?? generateTraceId(), () => next());
|
|
1127
|
-
* });
|
|
1128
|
-
* ```
|
|
1129
|
-
*
|
|
1130
|
-
* **Kafka / queue consumer — before:**
|
|
1131
|
-
* ```ts
|
|
1132
|
-
* async function handle(msg) {
|
|
1133
|
-
* setTraceId(msg.headers['x-trace-id']);
|
|
1134
|
-
* await processMessage(msg);
|
|
1135
|
-
* }
|
|
1136
|
-
* ```
|
|
1137
|
-
* **after:**
|
|
1138
|
-
* ```ts
|
|
1139
|
-
* async function handle(msg) {
|
|
1140
|
-
* await runWithTraceId(msg.headers['x-trace-id'], () => processMessage(msg));
|
|
1141
|
-
* }
|
|
1142
|
-
* ```
|
|
1143
|
-
*
|
|
1144
|
-
* **Background job — before:**
|
|
1145
|
-
* ```ts
|
|
1146
|
-
* setTraceId(generateTraceId(), { jobId: job.id });
|
|
1147
|
-
* await job.run();
|
|
1148
|
-
* ```
|
|
1149
|
-
* **after:**
|
|
1150
|
-
* ```ts
|
|
1151
|
-
* await runWithTraceId(generateTraceId(), () => job.run(), { jobId: job.id });
|
|
1152
|
-
* ```
|
|
1153
|
-
*
|
|
1154
|
-
* @deprecated Use `runWithTraceId(traceId, fn)` — do not call `setTraceId`
|
|
1155
|
-
* from request-handling code.
|
|
1156
|
-
*/
|
|
1157
|
-
function setTraceId(traceId, data) {
|
|
1158
|
-
TraceContext.instance.setTraceId(traceId, data);
|
|
1159
|
-
}
|
|
1160
|
-
/** Run `fn` inside a new async context carrying `traceId`. */
|
|
1161
|
-
function runWithTraceId(traceId, fn, data) {
|
|
1162
|
-
return TraceContext.instance.run(traceId, fn, data);
|
|
1163
|
-
}
|
|
1164
|
-
/**
|
|
1165
|
-
* Coerce an arbitrary value to a non-empty trace ID string, or `undefined`.
|
|
1166
|
-
* Rejects empty/whitespace-only strings, non-strings, and non-first array elements.
|
|
1167
|
-
*/
|
|
1168
|
-
function toValidTraceId(value) {
|
|
1169
|
-
const first = Array.isArray(value) ? value[0] : value;
|
|
1170
|
-
if (typeof first !== "string") return void 0;
|
|
1171
|
-
const trimmed = first.trim();
|
|
1172
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
1173
|
-
}
|
|
1174
|
-
/** W3C trace-context: `version-traceId(32hex)-spanId(16hex)-flags(2hex)`. */
|
|
1175
|
-
const W3C_TRACEPARENT_RE = /^[\da-f]{2}-([\da-f]{32})-[\da-f]{16}-[\da-f]{2}$/i;
|
|
1176
|
-
/**
|
|
1177
|
-
* Extract the 32-hex trace-id segment from a W3C `traceparent` header value.
|
|
1178
|
-
* Returns the parsed trace ID, or the original value unchanged when it is not a
|
|
1179
|
-
* well-formed traceparent (so non-W3C propagation still works).
|
|
1180
|
-
*/
|
|
1181
|
-
function parseTraceparent(value) {
|
|
1182
|
-
const m = W3C_TRACEPARENT_RE.exec(value);
|
|
1183
|
-
return m ? m[1] : value;
|
|
1184
|
-
}
|
|
1185
|
-
/** Extract trace ID from request using configuration (header → query → body → params). */
|
|
1186
|
-
function extractTraceId(request, config) {
|
|
1187
|
-
const req = request;
|
|
1188
|
-
if (config.header) {
|
|
1189
|
-
const headers = Array.isArray(config.header) ? config.header : [config.header];
|
|
1190
|
-
for (const header of headers) {
|
|
1191
|
-
var _req$headers;
|
|
1192
|
-
const lower = header.toLowerCase();
|
|
1193
|
-
const value = toValidTraceId((_req$headers = req.headers) === null || _req$headers === void 0 ? void 0 : _req$headers[lower]);
|
|
1194
|
-
if (value) return lower === "traceparent" ? parseTraceparent(value) : value;
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
if (config.query) {
|
|
1198
|
-
const queries = Array.isArray(config.query) ? config.query : [config.query];
|
|
1199
|
-
for (const query of queries) {
|
|
1200
|
-
var _req$query;
|
|
1201
|
-
const value = toValidTraceId((_req$query = req.query) === null || _req$query === void 0 ? void 0 : _req$query[query]);
|
|
1202
|
-
if (value) return value;
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
if (config.body) {
|
|
1206
|
-
const bodyFields = Array.isArray(config.body) ? config.body : [config.body];
|
|
1207
|
-
for (const field of bodyFields) {
|
|
1208
|
-
var _req$body;
|
|
1209
|
-
const value = toValidTraceId((_req$body = req.body) === null || _req$body === void 0 ? void 0 : _req$body[field]);
|
|
1210
|
-
if (value) return value;
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
if (config.params) {
|
|
1214
|
-
const paramFields = Array.isArray(config.params) ? config.params : [config.params];
|
|
1215
|
-
for (const param of paramFields) {
|
|
1216
|
-
var _req$params;
|
|
1217
|
-
const value = toValidTraceId((_req$params = req.params) === null || _req$params === void 0 ? void 0 : _req$params[param]);
|
|
1218
|
-
if (value) return value;
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
|
-
/**
|
|
1223
|
-
* Default headers checked for incoming trace ID propagation, in priority order:
|
|
1224
|
-
* traceparent (W3C/OTel) → x-trace-id → x-request-id → x-correlation-id → trace-id
|
|
1225
|
-
*/
|
|
1226
|
-
const DEFAULT_TRACE_HEADERS = [
|
|
1227
|
-
"traceparent",
|
|
1228
|
-
"x-trace-id",
|
|
1229
|
-
"x-request-id",
|
|
1230
|
-
"x-correlation-id",
|
|
1231
|
-
"trace-id"
|
|
1232
|
-
];
|
|
1233
|
-
/**
|
|
1234
|
-
* Create trace ID middleware for Express/NestJS
|
|
1235
|
-
*/
|
|
1236
|
-
function createTraceMiddleware(config) {
|
|
1237
|
-
const defaultExtractor = {
|
|
1238
|
-
header: DEFAULT_TRACE_HEADERS,
|
|
1239
|
-
query: ["traceId", "trace_id"]
|
|
1240
|
-
};
|
|
1241
|
-
const resolvedConfig = {
|
|
1242
|
-
...config,
|
|
1243
|
-
extractor: (config === null || config === void 0 ? void 0 : config.extractor) ? {
|
|
1244
|
-
...defaultExtractor,
|
|
1245
|
-
...config.extractor
|
|
1246
|
-
} : defaultExtractor
|
|
1247
|
-
};
|
|
1248
|
-
_setActiveContextKey(resolvedConfig.contextKey ?? TRACE_CONTEXT_KEY);
|
|
1249
|
-
return (req, res, next) => {
|
|
1250
|
-
let traceId;
|
|
1251
|
-
if (resolvedConfig.extractor) traceId = extractTraceId(req, resolvedConfig.extractor);
|
|
1252
|
-
if (!traceId) traceId = resolvedConfig.generator ? resolvedConfig.generator() : generateTraceId();
|
|
1253
|
-
req.traceId = traceId;
|
|
1254
|
-
const resObj = res;
|
|
1255
|
-
if (!resObj.headersSent) try {
|
|
1256
|
-
if (typeof resObj.setHeader === "function") resObj.setHeader("X-Trace-Id", traceId);
|
|
1257
|
-
else if (typeof resObj.header === "function") resObj.header("X-Trace-Id", traceId);
|
|
1258
|
-
} catch {}
|
|
1259
|
-
runWithTraceId(traceId, () => next());
|
|
1260
|
-
};
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
1031
|
//#endregion
|
|
1264
1032
|
//#region src/core/logitron-logger.ts
|
|
1265
1033
|
const _fastStringifyEntry = (0, fast_json_stringify.default)({
|
|
@@ -1348,7 +1116,7 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1348
1116
|
this.timers = /* @__PURE__ */ new Map();
|
|
1349
1117
|
this.contextData = {};
|
|
1350
1118
|
this.fieldState = /* @__PURE__ */ new Map();
|
|
1351
|
-
this.fallbackTraceId = TraceContext.instance.generate();
|
|
1119
|
+
this.fallbackTraceId = require_trace_utils.TraceContext.instance.generate();
|
|
1352
1120
|
this._levelValues = /* @__PURE__ */ new Map();
|
|
1353
1121
|
this._minLevelValue = 2;
|
|
1354
1122
|
this._warnedInvalidLevels = /* @__PURE__ */ new Set();
|
|
@@ -1799,7 +1567,7 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1799
1567
|
if (this.config.silent) return;
|
|
1800
1568
|
if (!this.shouldLog(level)) return;
|
|
1801
1569
|
if (this._sampler) {
|
|
1802
|
-
const traceId$1 = this.config.traceId ? TraceContext.instance.getCurrentTraceId() : void 0;
|
|
1570
|
+
const traceId$1 = this.config.traceId ? require_trace_utils.TraceContext.instance.getCurrentTraceId() : void 0;
|
|
1803
1571
|
if (!this._sampler.shouldEmit(level, traceId$1)) return;
|
|
1804
1572
|
}
|
|
1805
1573
|
const alsContext = require_async_context.LogixiaContext.get();
|
|
@@ -1822,9 +1590,21 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1822
1590
|
...mergedData
|
|
1823
1591
|
} : mergedData;
|
|
1824
1592
|
let payload;
|
|
1825
|
-
if (rawPayload !== void 0 && rawPayload !== null)
|
|
1826
|
-
|
|
1827
|
-
|
|
1593
|
+
if (rawPayload !== void 0 && rawPayload !== null) if (this._hasRedact) try {
|
|
1594
|
+
payload = applyRedaction(rawPayload, this.config.redact) ?? rawPayload;
|
|
1595
|
+
} catch (error) {
|
|
1596
|
+
require_internal_log.internalError("Redaction failed", error);
|
|
1597
|
+
payload = { redaction: REDACTION_FAILED };
|
|
1598
|
+
}
|
|
1599
|
+
else payload = rawPayload;
|
|
1600
|
+
const traceId = this.config.traceId ? require_trace_utils.TraceContext.instance.getCurrentTraceId() ?? this.fallbackTraceId : void 0;
|
|
1601
|
+
let safeMessage = message;
|
|
1602
|
+
if (this._hasRedact) try {
|
|
1603
|
+
safeMessage = applyRedactionToString(message, this.config.redact);
|
|
1604
|
+
} catch (error) {
|
|
1605
|
+
require_internal_log.internalError("Redaction failed", error);
|
|
1606
|
+
safeMessage = REDACTION_FAILED;
|
|
1607
|
+
}
|
|
1828
1608
|
const entry = {
|
|
1829
1609
|
timestamp: nowIso(),
|
|
1830
1610
|
level,
|
|
@@ -1895,9 +1675,9 @@ var LogixiaLogger = class LogixiaLogger {
|
|
|
1895
1675
|
if (((_this$config$format4 = this.config.format) === null || _this$config$format4 === void 0 ? void 0 : _this$config$format4.timestamp) !== false && this._fieldCache.get("timestamp") !== false) formatted += `${gray}[${entry.timestamp}]${reset} `;
|
|
1896
1676
|
if (this._fieldCache.get("level") !== false) formatted += this._formattedLevels.get(entry.level) ?? `[${entry.level.toUpperCase()}] `;
|
|
1897
1677
|
formatted += this._formattedAppName;
|
|
1898
|
-
if (entry.traceId && this._fieldCache.get("traceId") !== false) formatted += `${cyan}[${entry.traceId}]${reset} `;
|
|
1899
|
-
if (entry.context && this._fieldCache.get("context") !== false) formatted += `${yellow}[${entry.context}]${reset} `;
|
|
1900
|
-
if (this._fieldCache.get("message") !== false) formatted += entry.message;
|
|
1678
|
+
if (entry.traceId && this._fieldCache.get("traceId") !== false) formatted += `${cyan}[${require_transport_manager.stripControlChars(String(entry.traceId))}]${reset} `;
|
|
1679
|
+
if (entry.context && this._fieldCache.get("context") !== false) formatted += `${yellow}[${require_transport_manager.stripControlChars(String(entry.context))}]${reset} `;
|
|
1680
|
+
if (this._fieldCache.get("message") !== false) formatted += require_transport_manager.stripControlChars(require_coerce_utils.safeToString(entry.message));
|
|
1901
1681
|
if (entry.payload !== void 0 && this._fieldCache.get("payload") !== false) formatted += ` ${require_safe_stringify.stringifyForLog(entry.payload)}`;
|
|
1902
1682
|
return formatted;
|
|
1903
1683
|
}
|
|
@@ -2101,11 +1881,11 @@ let LogixiaLoggerService = _LogixiaLoggerService = class LogixiaLoggerService$1
|
|
|
2101
1881
|
return childService;
|
|
2102
1882
|
}
|
|
2103
1883
|
getCurrentTraceId() {
|
|
2104
|
-
return TraceContext.instance.getCurrentTraceId();
|
|
1884
|
+
return require_trace_utils.TraceContext.instance.getCurrentTraceId();
|
|
2105
1885
|
}
|
|
2106
1886
|
/** Returns the AsyncLocalStorage key currently used to store the trace ID. */
|
|
2107
1887
|
get traceContextKey() {
|
|
2108
|
-
return getTraceContextKey();
|
|
1888
|
+
return require_trace_utils.getTraceContextKey();
|
|
2109
1889
|
}
|
|
2110
1890
|
async close() {
|
|
2111
1891
|
return this.logger.close();
|
|
@@ -2156,7 +1936,7 @@ let KafkaTraceInterceptor = class KafkaTraceInterceptor$1 {
|
|
|
2156
1936
|
constructor(config, requireTraceId = false) {
|
|
2157
1937
|
this.config = config;
|
|
2158
1938
|
this.requireTraceId = requireTraceId;
|
|
2159
|
-
this.ctx = TraceContext.instance;
|
|
1939
|
+
this.ctx = require_trace_utils.TraceContext.instance;
|
|
2160
1940
|
this.config = {
|
|
2161
1941
|
enabled: true,
|
|
2162
1942
|
contextKey: "traceId",
|
|
@@ -2178,7 +1958,7 @@ let KafkaTraceInterceptor = class KafkaTraceInterceptor$1 {
|
|
|
2178
1958
|
const data = rpcContext.getData();
|
|
2179
1959
|
const rpcData = rpcContext.getContext();
|
|
2180
1960
|
let traceId;
|
|
2181
|
-
if (this.config.extractor) traceId = extractTraceId({
|
|
1961
|
+
if (this.config.extractor) traceId = require_trace_utils.extractTraceId({
|
|
2182
1962
|
body: data,
|
|
2183
1963
|
headers: (rpcData === null || rpcData === void 0 ? void 0 : rpcData.headers) ?? {},
|
|
2184
1964
|
query: {},
|
|
@@ -2258,9 +2038,9 @@ function writeTraceHeader(res, header, traceId) {
|
|
|
2258
2038
|
let TraceMiddleware = class TraceMiddleware$1 {
|
|
2259
2039
|
constructor(config) {
|
|
2260
2040
|
this.config = config;
|
|
2261
|
-
this.ctx = TraceContext.instance;
|
|
2041
|
+
this.ctx = require_trace_utils.TraceContext.instance;
|
|
2262
2042
|
const defaultExtractor = {
|
|
2263
|
-
header: DEFAULT_TRACE_HEADERS,
|
|
2043
|
+
header: require_trace_utils.DEFAULT_TRACE_HEADERS,
|
|
2264
2044
|
query: ["traceId", "trace_id"]
|
|
2265
2045
|
};
|
|
2266
2046
|
this.config = {
|
|
@@ -2279,7 +2059,7 @@ let TraceMiddleware = class TraceMiddleware$1 {
|
|
|
2279
2059
|
var _this$config, _req$socket, _req$connection;
|
|
2280
2060
|
if (!((_this$config = this.config) === null || _this$config === void 0 ? void 0 : _this$config.enabled)) return next();
|
|
2281
2061
|
let traceId;
|
|
2282
|
-
if (this.config.extractor) traceId = extractTraceId(req, this.config.extractor);
|
|
2062
|
+
if (this.config.extractor) traceId = require_trace_utils.extractTraceId(req, this.config.extractor);
|
|
2283
2063
|
if (!traceId && this.config.generator) {
|
|
2284
2064
|
const candidate = this.config.generator();
|
|
2285
2065
|
if (typeof candidate === "string" && candidate.trim().length > 0) traceId = candidate;
|
|
@@ -2308,7 +2088,7 @@ TraceMiddleware = __decorate([
|
|
|
2308
2088
|
let WebSocketTraceInterceptor = class WebSocketTraceInterceptor$1 {
|
|
2309
2089
|
constructor(config) {
|
|
2310
2090
|
this.config = config;
|
|
2311
|
-
this.ctx = TraceContext.instance;
|
|
2091
|
+
this.ctx = require_trace_utils.TraceContext.instance;
|
|
2312
2092
|
this.config = {
|
|
2313
2093
|
enabled: true,
|
|
2314
2094
|
contextKey: "traceId",
|
|
@@ -2333,7 +2113,7 @@ let WebSocketTraceInterceptor = class WebSocketTraceInterceptor$1 {
|
|
|
2333
2113
|
let traceId;
|
|
2334
2114
|
if (this.config.extractor) {
|
|
2335
2115
|
var _client$handshake, _client$handshake2;
|
|
2336
|
-
traceId = extractTraceId({
|
|
2116
|
+
traceId = require_trace_utils.extractTraceId({
|
|
2337
2117
|
body: data,
|
|
2338
2118
|
headers: (client === null || client === void 0 || (_client$handshake = client.handshake) === null || _client$handshake === void 0 ? void 0 : _client$handshake.headers) || {},
|
|
2339
2119
|
query: (client === null || client === void 0 || (_client$handshake2 = client.handshake) === null || _client$handshake2 === void 0 ? void 0 : _client$handshake2.query) || {},
|
|
@@ -2434,7 +2214,7 @@ let LogixiaLoggerModule = class LogixiaLoggerModule$1 {
|
|
|
2434
2214
|
else if (_LogixiaLoggerModule.loggerConfig.traceId === true) resolvedTraceConfig = {
|
|
2435
2215
|
enabled: true,
|
|
2436
2216
|
contextKey: "traceId",
|
|
2437
|
-
generator: () => TraceContext.instance.generate()
|
|
2217
|
+
generator: () => require_trace_utils.TraceContext.instance.generate()
|
|
2438
2218
|
};
|
|
2439
2219
|
const middleware = new TraceMiddleware(resolvedTraceConfig);
|
|
2440
2220
|
const middlewareConfig = (req, res, next) => middleware.use(req, res, next);
|
|
@@ -2623,6 +2403,380 @@ let LogixiaLoggerModule = class LogixiaLoggerModule$1 {
|
|
|
2623
2403
|
};
|
|
2624
2404
|
LogixiaLoggerModule = _LogixiaLoggerModule = __decorate([(0, __nestjs_common.Module)({})], LogixiaLoggerModule);
|
|
2625
2405
|
|
|
2406
|
+
//#endregion
|
|
2407
|
+
//#region src/exceptions/exception.ts
|
|
2408
|
+
var LogixiaException = class extends Error {
|
|
2409
|
+
constructor(options) {
|
|
2410
|
+
super(options.message, { cause: options.cause });
|
|
2411
|
+
this.name = "LogixiaException";
|
|
2412
|
+
this.errorCode = options.code;
|
|
2413
|
+
this.errorType = options.type;
|
|
2414
|
+
this.httpStatus = options.httpStatus;
|
|
2415
|
+
this.param = options.param;
|
|
2416
|
+
this.details = options.details;
|
|
2417
|
+
this.docUrl = options.docUrl;
|
|
2418
|
+
this.metadata = options.metadata;
|
|
2419
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
2420
|
+
}
|
|
2421
|
+
};
|
|
2422
|
+
/**
|
|
2423
|
+
* Returns `true` when `value` is a `LogixiaException` instance.
|
|
2424
|
+
*
|
|
2425
|
+
* Useful in exception filters or middleware that need to distinguish a
|
|
2426
|
+
* `LogixiaException` from a plain `Error` or a framework `HttpException`.
|
|
2427
|
+
*
|
|
2428
|
+
* @example
|
|
2429
|
+
* ```ts
|
|
2430
|
+
* if (isLogixiaException(err)) {
|
|
2431
|
+
* console.log(err.errorCode, err.httpStatus);
|
|
2432
|
+
* }
|
|
2433
|
+
* ```
|
|
2434
|
+
*/
|
|
2435
|
+
function isLogixiaException(value) {
|
|
2436
|
+
return value instanceof LogixiaException;
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
//#endregion
|
|
2440
|
+
//#region src/exceptions/builder.ts
|
|
2441
|
+
/**
|
|
2442
|
+
* Generates a trace ID via the shared {@link TraceContext} generator.
|
|
2443
|
+
*
|
|
2444
|
+
* Delegates to `TraceContext.instance.generate()` so any custom generator
|
|
2445
|
+
* configured on `TraceIdConfig.generator` is respected — avoids the silent
|
|
2446
|
+
* "builder has its own UUID source" divergence this module had previously.
|
|
2447
|
+
*
|
|
2448
|
+
* @example `'550e8400-e29b-41d4-a716-446655440000'`
|
|
2449
|
+
*/
|
|
2450
|
+
function generateTraceId() {
|
|
2451
|
+
return require_trace_utils.TraceContext.instance.generate();
|
|
2452
|
+
}
|
|
2453
|
+
/** @deprecated Use `generateTraceId` instead. */
|
|
2454
|
+
const generateRequestId = generateTraceId;
|
|
2455
|
+
/**
|
|
2456
|
+
* Maps an HTTP status code to a human-friendly error type string.
|
|
2457
|
+
* Used as a fallback when the exception is a generic `HttpException`.
|
|
2458
|
+
*/
|
|
2459
|
+
function httpStatusToType(status) {
|
|
2460
|
+
if (status === 400) return "api_error";
|
|
2461
|
+
if (status === 401) return "authentication_error";
|
|
2462
|
+
if (status === 402) return "payment_error";
|
|
2463
|
+
if (status === 403) return "authorization_error";
|
|
2464
|
+
if (status === 404) return "not_found_error";
|
|
2465
|
+
if (status === 408) return "timeout_error";
|
|
2466
|
+
if (status === 409) return "conflict_error";
|
|
2467
|
+
if (status === 422) return "validation_error";
|
|
2468
|
+
if (status === 429) return "rate_limit_error";
|
|
2469
|
+
if (status >= 500) return "server_error";
|
|
2470
|
+
if (status >= 400) return "api_error";
|
|
2471
|
+
return "server_error";
|
|
2472
|
+
}
|
|
2473
|
+
/**
|
|
2474
|
+
* Duck-type check for NestJS `HttpException`.
|
|
2475
|
+
* Avoids a hard import on `@nestjs/common` so the builder is usable outside NestJS.
|
|
2476
|
+
*/
|
|
2477
|
+
function isHttpException(value) {
|
|
2478
|
+
return typeof value === "object" && value !== null && typeof value["getStatus"] === "function" && typeof value["getResponse"] === "function";
|
|
2479
|
+
}
|
|
2480
|
+
/**
|
|
2481
|
+
* Builds the optional `debug` block from an error.
|
|
2482
|
+
* Returns `undefined` when there is nothing useful to include.
|
|
2483
|
+
*/
|
|
2484
|
+
function buildDebug(error, service, durationMs, expose) {
|
|
2485
|
+
if (expose.debug !== true) return void 0;
|
|
2486
|
+
const stack = error instanceof Error ? error.stack : void 0;
|
|
2487
|
+
const causeRaw = error instanceof Error ? error.cause : void 0;
|
|
2488
|
+
let cause;
|
|
2489
|
+
if (expose.cause !== true) cause = void 0;
|
|
2490
|
+
else if (causeRaw instanceof Error) cause = causeRaw.message;
|
|
2491
|
+
else if (causeRaw !== void 0 && causeRaw !== null) cause = String(causeRaw);
|
|
2492
|
+
if (!stack && !cause && !service && durationMs === void 0) return void 0;
|
|
2493
|
+
return {
|
|
2494
|
+
...stack !== void 0 ? { stack } : {},
|
|
2495
|
+
...cause !== void 0 ? { cause } : {},
|
|
2496
|
+
...service !== void 0 ? { service } : {},
|
|
2497
|
+
...durationMs !== void 0 ? { duration_ms: durationMs } : {}
|
|
2498
|
+
};
|
|
2499
|
+
}
|
|
2500
|
+
var ErrorResponseBuilder = class {
|
|
2501
|
+
/**
|
|
2502
|
+
* Build a `LogixiaErrorResponse` from any thrown value.
|
|
2503
|
+
*
|
|
2504
|
+
* @param params - See `BuildParams`.
|
|
2505
|
+
* @returns The unified error response and the HTTP status code to send.
|
|
2506
|
+
*
|
|
2507
|
+
* @remarks
|
|
2508
|
+
* `traceId` does not need to be supplied by the caller in most cases — the
|
|
2509
|
+
* builder reads `TraceContext.instance.getCurrentTraceId()` internally and
|
|
2510
|
+
* falls back to the explicit `traceId` argument only when AsyncLocalStorage
|
|
2511
|
+
* is empty. If neither source yields a value, `meta.trace_id` is omitted.
|
|
2512
|
+
*
|
|
2513
|
+
* @example In a NestJS exception filter
|
|
2514
|
+
* ```ts
|
|
2515
|
+
* const { response, httpStatus } = ErrorResponseBuilder.build<AppCode, AppType>({
|
|
2516
|
+
* exception,
|
|
2517
|
+
* // Omit traceId — it will be picked up from ALS automatically.
|
|
2518
|
+
* path: request.url,
|
|
2519
|
+
* service: process.env.SERVICE_NAME,
|
|
2520
|
+
* startTime: request.startTime,
|
|
2521
|
+
* });
|
|
2522
|
+
*
|
|
2523
|
+
* if (process.env.NODE_ENV === 'production') delete response.debug;
|
|
2524
|
+
* // Echo the resolved traceId back on whatever header your TraceIdConfig says —
|
|
2525
|
+
* // do NOT hardcode 'X-Trace-Id', use `resolveResponseHeader(config)` instead.
|
|
2526
|
+
* if (response.meta.trace_id) {
|
|
2527
|
+
* response.setHeader(resolveResponseHeader(config) ?? 'X-Trace-Id', response.meta.trace_id);
|
|
2528
|
+
* }
|
|
2529
|
+
* response.status(httpStatus).json(response);
|
|
2530
|
+
* ```
|
|
2531
|
+
*/
|
|
2532
|
+
static build(params) {
|
|
2533
|
+
const { exception, path, service, startTime, traceId: rawTraceId, exposeDebug, exposeCause } = params;
|
|
2534
|
+
const expose = {
|
|
2535
|
+
debug: exposeDebug,
|
|
2536
|
+
cause: exposeCause
|
|
2537
|
+
};
|
|
2538
|
+
const traceId = require_trace_utils.TraceContext.instance.getCurrentTraceId() ?? rawTraceId;
|
|
2539
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2540
|
+
const durationMs = startTime !== void 0 ? Date.now() - startTime : void 0;
|
|
2541
|
+
if (isLogixiaException(exception)) {
|
|
2542
|
+
const debug$1 = buildDebug(exception, service, durationMs, expose);
|
|
2543
|
+
const errorBlock = {
|
|
2544
|
+
type: exception.errorType,
|
|
2545
|
+
code: exception.errorCode,
|
|
2546
|
+
message: exception.message
|
|
2547
|
+
};
|
|
2548
|
+
if (exception.param !== void 0) errorBlock.param = exception.param;
|
|
2549
|
+
if (exception.details !== void 0 && exception.details.length > 0) errorBlock.details = exception.details;
|
|
2550
|
+
if (exception.docUrl !== void 0) errorBlock.doc_url = exception.docUrl;
|
|
2551
|
+
return {
|
|
2552
|
+
response: {
|
|
2553
|
+
success: false,
|
|
2554
|
+
error: errorBlock,
|
|
2555
|
+
meta: {
|
|
2556
|
+
...traceId !== void 0 ? { trace_id: traceId } : {},
|
|
2557
|
+
timestamp,
|
|
2558
|
+
path,
|
|
2559
|
+
status: exception.httpStatus
|
|
2560
|
+
},
|
|
2561
|
+
...debug$1 !== void 0 ? { debug: debug$1 } : {}
|
|
2562
|
+
},
|
|
2563
|
+
httpStatus: exception.httpStatus
|
|
2564
|
+
};
|
|
2565
|
+
}
|
|
2566
|
+
if (isHttpException(exception)) {
|
|
2567
|
+
const status = exception.getStatus();
|
|
2568
|
+
const exResponse = exception.getResponse();
|
|
2569
|
+
let message;
|
|
2570
|
+
if (typeof exResponse === "string") message = exResponse;
|
|
2571
|
+
else if (typeof exResponse === "object" && exResponse !== null && "message" in exResponse) {
|
|
2572
|
+
const raw = exResponse.message;
|
|
2573
|
+
message = Array.isArray(raw) ? raw.join(", ") : String(raw);
|
|
2574
|
+
} else message = exception.message;
|
|
2575
|
+
const type = httpStatusToType(status);
|
|
2576
|
+
const code = `HTTP_${status}`;
|
|
2577
|
+
const debug$1 = buildDebug(exception, service, durationMs, expose);
|
|
2578
|
+
return {
|
|
2579
|
+
response: {
|
|
2580
|
+
success: false,
|
|
2581
|
+
error: {
|
|
2582
|
+
type,
|
|
2583
|
+
code,
|
|
2584
|
+
message
|
|
2585
|
+
},
|
|
2586
|
+
meta: {
|
|
2587
|
+
...traceId !== void 0 ? { trace_id: traceId } : {},
|
|
2588
|
+
timestamp,
|
|
2589
|
+
path,
|
|
2590
|
+
status
|
|
2591
|
+
},
|
|
2592
|
+
...debug$1 !== void 0 ? { debug: debug$1 } : {}
|
|
2593
|
+
},
|
|
2594
|
+
httpStatus: status
|
|
2595
|
+
};
|
|
2596
|
+
}
|
|
2597
|
+
const debug = buildDebug(exception instanceof Error ? exception : new Error(String(exception)), service, durationMs, expose);
|
|
2598
|
+
return {
|
|
2599
|
+
response: {
|
|
2600
|
+
success: false,
|
|
2601
|
+
error: {
|
|
2602
|
+
type: "server_error",
|
|
2603
|
+
code: "INTERNAL_SERVER_ERROR",
|
|
2604
|
+
message: "An unexpected error occurred."
|
|
2605
|
+
},
|
|
2606
|
+
meta: {
|
|
2607
|
+
...traceId !== void 0 ? { trace_id: traceId } : {},
|
|
2608
|
+
timestamp,
|
|
2609
|
+
path,
|
|
2610
|
+
status: 500
|
|
2611
|
+
},
|
|
2612
|
+
...debug !== void 0 ? { debug } : {}
|
|
2613
|
+
},
|
|
2614
|
+
httpStatus: 500
|
|
2615
|
+
};
|
|
2616
|
+
}
|
|
2617
|
+
};
|
|
2618
|
+
|
|
2619
|
+
//#endregion
|
|
2620
|
+
//#region src/core/nestjs-extras.ts
|
|
2621
|
+
var _ref;
|
|
2622
|
+
/**
|
|
2623
|
+
* Inject the Logixia logger registered in the current NestJS DI container.
|
|
2624
|
+
*
|
|
2625
|
+
* Equivalent to `@Inject(LOGIXIA_LOGGER_TOKEN)` but without needing to import
|
|
2626
|
+
* the internal token constant yourself.
|
|
2627
|
+
*
|
|
2628
|
+
* @example
|
|
2629
|
+
* ```ts
|
|
2630
|
+
* constructor(@InjectLogger() private readonly logger: LogixiaLoggerService) {}
|
|
2631
|
+
* ```
|
|
2632
|
+
*/
|
|
2633
|
+
const InjectLogger = () => (0, __nestjs_common.Inject)(`${LOGIXIA_LOGGER_PREFIX}SERVICE`);
|
|
2634
|
+
/**
|
|
2635
|
+
* Method decorator that auto-logs entry, exit, duration, and errors.
|
|
2636
|
+
*
|
|
2637
|
+
* Preserves the original method's sync/async contract: a synchronous method
|
|
2638
|
+
* stays synchronous (returns its value directly, with logs emitted
|
|
2639
|
+
* fire-and-forget), and an async method is awaited so exit/error logs reflect
|
|
2640
|
+
* the resolved result. Attaches to the logger found on the class instance via a
|
|
2641
|
+
* `logger` property (the conventional NestJS name).
|
|
2642
|
+
*
|
|
2643
|
+
* @example
|
|
2644
|
+
* ```ts
|
|
2645
|
+
* @LogMethod({ level: 'info', logArgs: true })
|
|
2646
|
+
* async processPayment(orderId: string): Promise<void> { … }
|
|
2647
|
+
* ```
|
|
2648
|
+
*/
|
|
2649
|
+
function LogMethod(options = {}) {
|
|
2650
|
+
const { level = "debug", logArgs = true, logResult = false, logErrors = true } = options;
|
|
2651
|
+
return function(target, propertyKey, descriptor) {
|
|
2652
|
+
var _constructor;
|
|
2653
|
+
const originalMethod = descriptor.value;
|
|
2654
|
+
if (typeof originalMethod !== "function") return descriptor;
|
|
2655
|
+
const methodName = String(propertyKey);
|
|
2656
|
+
const className = ((_constructor = target.constructor) === null || _constructor === void 0 ? void 0 : _constructor.name) ?? "Unknown";
|
|
2657
|
+
const label = options.label ?? `${className}.${methodName}`;
|
|
2658
|
+
let _warnedNoLogger = false;
|
|
2659
|
+
const reportLogFailure = (phase, err) => {
|
|
2660
|
+
require_internal_log.internalError(`@LogMethod(${label}) ${phase} log failed: ${String(err)}`);
|
|
2661
|
+
};
|
|
2662
|
+
const emit = (logger, phase, message, data) => {
|
|
2663
|
+
const logFnRaw = logger[level];
|
|
2664
|
+
const p = (typeof logFnRaw === "function" ? logFnRaw : logger.debug).bind(logger)(message, data);
|
|
2665
|
+
if (p && typeof p.catch === "function") p.catch((e) => reportLogFailure(phase, e));
|
|
2666
|
+
};
|
|
2667
|
+
const emitError = (logger, error, start) => {
|
|
2668
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
2669
|
+
const errLog = logger.error(err, {
|
|
2670
|
+
method: label,
|
|
2671
|
+
durationMs: Date.now() - start
|
|
2672
|
+
});
|
|
2673
|
+
if (errLog && typeof errLog.catch === "function") errLog.catch((e) => reportLogFailure("error", e));
|
|
2674
|
+
};
|
|
2675
|
+
descriptor.value = function(...args) {
|
|
2676
|
+
const logger = this.logger ?? LogixiaLoggerModule._globalLogger ?? void 0;
|
|
2677
|
+
if (!logger && !_warnedNoLogger) {
|
|
2678
|
+
_warnedNoLogger = true;
|
|
2679
|
+
require_internal_log.internalWarn(`@LogMethod on ${label}: no logger available. Either inject LogixiaLoggerService as this.logger or ensure LogixiaLoggerModule is initialised.`);
|
|
2680
|
+
}
|
|
2681
|
+
const start = Date.now();
|
|
2682
|
+
const entry = { method: label };
|
|
2683
|
+
if (logArgs && args.length > 0) entry["args"] = args;
|
|
2684
|
+
if (logger) emit(logger, "entry", `→ ${label}`, entry);
|
|
2685
|
+
const buildExit = (result$1) => {
|
|
2686
|
+
const exit = {
|
|
2687
|
+
method: label,
|
|
2688
|
+
durationMs: Date.now() - start
|
|
2689
|
+
};
|
|
2690
|
+
if (logResult) exit["result"] = result$1;
|
|
2691
|
+
return exit;
|
|
2692
|
+
};
|
|
2693
|
+
let result;
|
|
2694
|
+
try {
|
|
2695
|
+
result = originalMethod.apply(this, args);
|
|
2696
|
+
} catch (error) {
|
|
2697
|
+
if (logger && logErrors) emitError(logger, error, start);
|
|
2698
|
+
throw error;
|
|
2699
|
+
}
|
|
2700
|
+
if (result && typeof result.then === "function") return result.then((resolved) => {
|
|
2701
|
+
if (logger) emit(logger, "exit", `← ${label}`, buildExit(resolved));
|
|
2702
|
+
return resolved;
|
|
2703
|
+
}, (error) => {
|
|
2704
|
+
if (logger && logErrors) emitError(logger, error, start);
|
|
2705
|
+
throw error;
|
|
2706
|
+
});
|
|
2707
|
+
if (logger) emit(logger, "exit", `← ${label}`, buildExit(result));
|
|
2708
|
+
return result;
|
|
2709
|
+
};
|
|
2710
|
+
return descriptor;
|
|
2711
|
+
};
|
|
2712
|
+
}
|
|
2713
|
+
/** Injection token for {@link LogixiaExceptionFilterOptions}. */
|
|
2714
|
+
const LOGIXIA_EXCEPTION_FILTER_OPTIONS = "LOGIXIA_EXCEPTION_FILTER_OPTIONS";
|
|
2715
|
+
let LogixiaExceptionFilter = class LogixiaExceptionFilter$1 {
|
|
2716
|
+
constructor(logger, loggerConfig, options) {
|
|
2717
|
+
this._options = options ?? {};
|
|
2718
|
+
this._logger = logger ?? LogixiaLoggerModule._globalLogger ?? void 0;
|
|
2719
|
+
this._traceConfig = typeof (loggerConfig === null || loggerConfig === void 0 ? void 0 : loggerConfig.traceId) === "object" ? loggerConfig.traceId : void 0;
|
|
2720
|
+
}
|
|
2721
|
+
catch(exception, host) {
|
|
2722
|
+
var _request$headers;
|
|
2723
|
+
const ctx = host.switchToHttp();
|
|
2724
|
+
const request = ctx.getRequest();
|
|
2725
|
+
const response = ctx.getResponse();
|
|
2726
|
+
const traceId = require_trace_utils.TraceContext.instance.getCurrentTraceId() ?? require_trace_utils.sanitizeIncomingId((_request$headers = request.headers) === null || _request$headers === void 0 ? void 0 : _request$headers["x-trace-id"]) ?? require_trace_utils.sanitizeIncomingId(request.id) ?? void 0;
|
|
2727
|
+
const { response: errorResponse, httpStatus } = ErrorResponseBuilder.build({
|
|
2728
|
+
exception,
|
|
2729
|
+
traceId,
|
|
2730
|
+
path: request.url ?? "/",
|
|
2731
|
+
startTime: request.startTime,
|
|
2732
|
+
exposeDebug: this._options.exposeDebug === true,
|
|
2733
|
+
exposeCause: this._options.exposeCause === true
|
|
2734
|
+
});
|
|
2735
|
+
if (this._logger) {
|
|
2736
|
+
const requestMeta = {
|
|
2737
|
+
method: request.method ?? "",
|
|
2738
|
+
url: request.url ?? "",
|
|
2739
|
+
status: httpStatus,
|
|
2740
|
+
...errorResponse.meta.trace_id !== void 0 ? { trace_id: errorResponse.meta.trace_id } : {}
|
|
2741
|
+
};
|
|
2742
|
+
const onLogFailure = (err) => {
|
|
2743
|
+
require_internal_log.internalError(`ExceptionFilter failed to write log entry: ${String(err)}`);
|
|
2744
|
+
};
|
|
2745
|
+
let logPromise;
|
|
2746
|
+
if (httpStatus >= 500) {
|
|
2747
|
+
const err = exception instanceof Error ? exception : new Error(String(exception));
|
|
2748
|
+
logPromise = this._logger.error(err, requestMeta);
|
|
2749
|
+
} else if (isLogixiaException(exception)) logPromise = this._logger.warn(`[${errorResponse.error.code}] ${errorResponse.error.message}`, requestMeta);
|
|
2750
|
+
else logPromise = this._logger.warn(`[${httpStatus}] ${errorResponse.error.message}`, requestMeta);
|
|
2751
|
+
if (logPromise && typeof logPromise.catch === "function") logPromise.catch(onLogFailure);
|
|
2752
|
+
}
|
|
2753
|
+
if (errorResponse.meta.trace_id) {
|
|
2754
|
+
const traceHeader = resolveResponseHeader(this._traceConfig);
|
|
2755
|
+
if (traceHeader) try {
|
|
2756
|
+
response.setHeader(traceHeader, errorResponse.meta.trace_id);
|
|
2757
|
+
} catch {}
|
|
2758
|
+
}
|
|
2759
|
+
if (httpStatus === 429) try {
|
|
2760
|
+
response.setHeader("Retry-After", "60");
|
|
2761
|
+
} catch {}
|
|
2762
|
+
response.status(httpStatus).json(errorResponse);
|
|
2763
|
+
}
|
|
2764
|
+
};
|
|
2765
|
+
LogixiaExceptionFilter = __decorate([
|
|
2766
|
+
(0, __nestjs_common.Catch)(),
|
|
2767
|
+
__decorateParam(0, (0, __nestjs_common.Optional)()),
|
|
2768
|
+
__decorateParam(0, (0, __nestjs_common.Inject)(`${LOGIXIA_LOGGER_PREFIX}SERVICE`)),
|
|
2769
|
+
__decorateParam(1, (0, __nestjs_common.Optional)()),
|
|
2770
|
+
__decorateParam(1, (0, __nestjs_common.Inject)(LOGIXIA_LOGGER_CONFIG)),
|
|
2771
|
+
__decorateParam(2, (0, __nestjs_common.Optional)()),
|
|
2772
|
+
__decorateParam(2, (0, __nestjs_common.Inject)(LOGIXIA_EXCEPTION_FILTER_OPTIONS)),
|
|
2773
|
+
__decorateMetadata("design:paramtypes", [
|
|
2774
|
+
Object,
|
|
2775
|
+
typeof (_ref = typeof Partial !== "undefined" && Partial) === "function" ? _ref : Object,
|
|
2776
|
+
Object
|
|
2777
|
+
])
|
|
2778
|
+
], LogixiaExceptionFilter);
|
|
2779
|
+
|
|
2626
2780
|
//#endregion
|
|
2627
2781
|
Object.defineProperty(exports, 'DEFAULT_LOG_COLORS', {
|
|
2628
2782
|
enumerable: true,
|
|
@@ -2636,10 +2790,16 @@ Object.defineProperty(exports, 'DEFAULT_LOG_LEVELS', {
|
|
|
2636
2790
|
return DEFAULT_LOG_LEVELS;
|
|
2637
2791
|
}
|
|
2638
2792
|
});
|
|
2639
|
-
Object.defineProperty(exports, '
|
|
2793
|
+
Object.defineProperty(exports, 'ErrorResponseBuilder', {
|
|
2794
|
+
enumerable: true,
|
|
2795
|
+
get: function () {
|
|
2796
|
+
return ErrorResponseBuilder;
|
|
2797
|
+
}
|
|
2798
|
+
});
|
|
2799
|
+
Object.defineProperty(exports, 'InjectLogger', {
|
|
2640
2800
|
enumerable: true,
|
|
2641
2801
|
get: function () {
|
|
2642
|
-
return
|
|
2802
|
+
return InjectLogger;
|
|
2643
2803
|
}
|
|
2644
2804
|
});
|
|
2645
2805
|
Object.defineProperty(exports, 'KafkaTraceInterceptor', {
|
|
@@ -2648,6 +2808,12 @@ Object.defineProperty(exports, 'KafkaTraceInterceptor', {
|
|
|
2648
2808
|
return KafkaTraceInterceptor;
|
|
2649
2809
|
}
|
|
2650
2810
|
});
|
|
2811
|
+
Object.defineProperty(exports, 'LOGIXIA_EXCEPTION_FILTER_OPTIONS', {
|
|
2812
|
+
enumerable: true,
|
|
2813
|
+
get: function () {
|
|
2814
|
+
return LOGIXIA_EXCEPTION_FILTER_OPTIONS;
|
|
2815
|
+
}
|
|
2816
|
+
});
|
|
2651
2817
|
Object.defineProperty(exports, 'LOGIXIA_LOGGER_CONFIG', {
|
|
2652
2818
|
enumerable: true,
|
|
2653
2819
|
get: function () {
|
|
@@ -2672,76 +2838,58 @@ Object.defineProperty(exports, 'LogLevel', {
|
|
|
2672
2838
|
return LogLevel;
|
|
2673
2839
|
}
|
|
2674
2840
|
});
|
|
2675
|
-
Object.defineProperty(exports, '
|
|
2676
|
-
enumerable: true,
|
|
2677
|
-
get: function () {
|
|
2678
|
-
return LogixiaLogger;
|
|
2679
|
-
}
|
|
2680
|
-
});
|
|
2681
|
-
Object.defineProperty(exports, 'LogixiaLoggerModule', {
|
|
2682
|
-
enumerable: true,
|
|
2683
|
-
get: function () {
|
|
2684
|
-
return LogixiaLoggerModule;
|
|
2685
|
-
}
|
|
2686
|
-
});
|
|
2687
|
-
Object.defineProperty(exports, 'LogixiaLoggerService', {
|
|
2688
|
-
enumerable: true,
|
|
2689
|
-
get: function () {
|
|
2690
|
-
return LogixiaLoggerService;
|
|
2691
|
-
}
|
|
2692
|
-
});
|
|
2693
|
-
Object.defineProperty(exports, 'PluginRegistry', {
|
|
2841
|
+
Object.defineProperty(exports, 'LogMethod', {
|
|
2694
2842
|
enumerable: true,
|
|
2695
2843
|
get: function () {
|
|
2696
|
-
return
|
|
2844
|
+
return LogMethod;
|
|
2697
2845
|
}
|
|
2698
2846
|
});
|
|
2699
|
-
Object.defineProperty(exports, '
|
|
2847
|
+
Object.defineProperty(exports, 'LogixiaException', {
|
|
2700
2848
|
enumerable: true,
|
|
2701
2849
|
get: function () {
|
|
2702
|
-
return
|
|
2850
|
+
return LogixiaException;
|
|
2703
2851
|
}
|
|
2704
2852
|
});
|
|
2705
|
-
Object.defineProperty(exports, '
|
|
2853
|
+
Object.defineProperty(exports, 'LogixiaExceptionFilter', {
|
|
2706
2854
|
enumerable: true,
|
|
2707
2855
|
get: function () {
|
|
2708
|
-
return
|
|
2856
|
+
return LogixiaExceptionFilter;
|
|
2709
2857
|
}
|
|
2710
2858
|
});
|
|
2711
|
-
Object.defineProperty(exports, '
|
|
2859
|
+
Object.defineProperty(exports, 'LogixiaLogger', {
|
|
2712
2860
|
enumerable: true,
|
|
2713
2861
|
get: function () {
|
|
2714
|
-
return
|
|
2862
|
+
return LogixiaLogger;
|
|
2715
2863
|
}
|
|
2716
2864
|
});
|
|
2717
|
-
Object.defineProperty(exports, '
|
|
2865
|
+
Object.defineProperty(exports, 'LogixiaLoggerModule', {
|
|
2718
2866
|
enumerable: true,
|
|
2719
2867
|
get: function () {
|
|
2720
|
-
return
|
|
2868
|
+
return LogixiaLoggerModule;
|
|
2721
2869
|
}
|
|
2722
2870
|
});
|
|
2723
|
-
Object.defineProperty(exports, '
|
|
2871
|
+
Object.defineProperty(exports, 'LogixiaLoggerService', {
|
|
2724
2872
|
enumerable: true,
|
|
2725
2873
|
get: function () {
|
|
2726
|
-
return
|
|
2874
|
+
return LogixiaLoggerService;
|
|
2727
2875
|
}
|
|
2728
2876
|
});
|
|
2729
|
-
Object.defineProperty(exports, '
|
|
2877
|
+
Object.defineProperty(exports, 'PluginRegistry', {
|
|
2730
2878
|
enumerable: true,
|
|
2731
2879
|
get: function () {
|
|
2732
|
-
return
|
|
2880
|
+
return PluginRegistry;
|
|
2733
2881
|
}
|
|
2734
2882
|
});
|
|
2735
|
-
Object.defineProperty(exports, '
|
|
2883
|
+
Object.defineProperty(exports, 'TraceMiddleware', {
|
|
2736
2884
|
enumerable: true,
|
|
2737
2885
|
get: function () {
|
|
2738
|
-
return
|
|
2886
|
+
return TraceMiddleware;
|
|
2739
2887
|
}
|
|
2740
2888
|
});
|
|
2741
|
-
Object.defineProperty(exports, '
|
|
2889
|
+
Object.defineProperty(exports, 'WebSocketTraceInterceptor', {
|
|
2742
2890
|
enumerable: true,
|
|
2743
2891
|
get: function () {
|
|
2744
|
-
return
|
|
2892
|
+
return WebSocketTraceInterceptor;
|
|
2745
2893
|
}
|
|
2746
2894
|
});
|
|
2747
2895
|
Object.defineProperty(exports, '_shutdownRegistrySize', {
|
|
@@ -2762,12 +2910,6 @@ Object.defineProperty(exports, 'createLogger', {
|
|
|
2762
2910
|
return createLogger;
|
|
2763
2911
|
}
|
|
2764
2912
|
});
|
|
2765
|
-
Object.defineProperty(exports, 'createTraceMiddleware', {
|
|
2766
|
-
enumerable: true,
|
|
2767
|
-
get: function () {
|
|
2768
|
-
return createTraceMiddleware;
|
|
2769
|
-
}
|
|
2770
|
-
});
|
|
2771
2913
|
Object.defineProperty(exports, 'deregisterFromShutdown', {
|
|
2772
2914
|
enumerable: true,
|
|
2773
2915
|
get: function () {
|
|
@@ -2780,40 +2922,34 @@ Object.defineProperty(exports, 'disableOtelBridge', {
|
|
|
2780
2922
|
return disableOtelBridge;
|
|
2781
2923
|
}
|
|
2782
2924
|
});
|
|
2783
|
-
Object.defineProperty(exports, 'extractTraceId', {
|
|
2784
|
-
enumerable: true,
|
|
2785
|
-
get: function () {
|
|
2786
|
-
return extractTraceId;
|
|
2787
|
-
}
|
|
2788
|
-
});
|
|
2789
2925
|
Object.defineProperty(exports, 'flushOnExit', {
|
|
2790
2926
|
enumerable: true,
|
|
2791
2927
|
get: function () {
|
|
2792
2928
|
return flushOnExit;
|
|
2793
2929
|
}
|
|
2794
2930
|
});
|
|
2795
|
-
Object.defineProperty(exports, '
|
|
2931
|
+
Object.defineProperty(exports, 'generateRequestId', {
|
|
2796
2932
|
enumerable: true,
|
|
2797
2933
|
get: function () {
|
|
2798
|
-
return
|
|
2934
|
+
return generateRequestId;
|
|
2799
2935
|
}
|
|
2800
2936
|
});
|
|
2801
|
-
Object.defineProperty(exports, '
|
|
2937
|
+
Object.defineProperty(exports, 'generateTraceId', {
|
|
2802
2938
|
enumerable: true,
|
|
2803
2939
|
get: function () {
|
|
2804
|
-
return
|
|
2940
|
+
return generateTraceId;
|
|
2805
2941
|
}
|
|
2806
2942
|
});
|
|
2807
|
-
Object.defineProperty(exports, '
|
|
2943
|
+
Object.defineProperty(exports, 'getActiveOtelContext', {
|
|
2808
2944
|
enumerable: true,
|
|
2809
2945
|
get: function () {
|
|
2810
|
-
return
|
|
2946
|
+
return getActiveOtelContext;
|
|
2811
2947
|
}
|
|
2812
2948
|
});
|
|
2813
|
-
Object.defineProperty(exports, '
|
|
2949
|
+
Object.defineProperty(exports, 'getOtelMetaFields', {
|
|
2814
2950
|
enumerable: true,
|
|
2815
2951
|
get: function () {
|
|
2816
|
-
return
|
|
2952
|
+
return getOtelMetaFields;
|
|
2817
2953
|
}
|
|
2818
2954
|
});
|
|
2819
2955
|
Object.defineProperty(exports, 'globalPluginRegistry', {
|
|
@@ -2834,6 +2970,12 @@ Object.defineProperty(exports, 'isError', {
|
|
|
2834
2970
|
return isError;
|
|
2835
2971
|
}
|
|
2836
2972
|
});
|
|
2973
|
+
Object.defineProperty(exports, 'isLogixiaException', {
|
|
2974
|
+
enumerable: true,
|
|
2975
|
+
get: function () {
|
|
2976
|
+
return isLogixiaException;
|
|
2977
|
+
}
|
|
2978
|
+
});
|
|
2837
2979
|
Object.defineProperty(exports, 'normalizeError', {
|
|
2838
2980
|
enumerable: true,
|
|
2839
2981
|
get: function () {
|
|
@@ -2858,40 +3000,16 @@ Object.defineProperty(exports, 'resetShutdownHandlers', {
|
|
|
2858
3000
|
return resetShutdownHandlers;
|
|
2859
3001
|
}
|
|
2860
3002
|
});
|
|
2861
|
-
Object.defineProperty(exports, 'resolveResponseHeader', {
|
|
2862
|
-
enumerable: true,
|
|
2863
|
-
get: function () {
|
|
2864
|
-
return resolveResponseHeader;
|
|
2865
|
-
}
|
|
2866
|
-
});
|
|
2867
|
-
Object.defineProperty(exports, 'runWithTraceId', {
|
|
2868
|
-
enumerable: true,
|
|
2869
|
-
get: function () {
|
|
2870
|
-
return runWithTraceId;
|
|
2871
|
-
}
|
|
2872
|
-
});
|
|
2873
3003
|
Object.defineProperty(exports, 'serializeError', {
|
|
2874
3004
|
enumerable: true,
|
|
2875
3005
|
get: function () {
|
|
2876
3006
|
return serializeError;
|
|
2877
3007
|
}
|
|
2878
3008
|
});
|
|
2879
|
-
Object.defineProperty(exports, 'setTraceId', {
|
|
2880
|
-
enumerable: true,
|
|
2881
|
-
get: function () {
|
|
2882
|
-
return setTraceId;
|
|
2883
|
-
}
|
|
2884
|
-
});
|
|
2885
|
-
Object.defineProperty(exports, 'traceStorage', {
|
|
2886
|
-
enumerable: true,
|
|
2887
|
-
get: function () {
|
|
2888
|
-
return traceStorage;
|
|
2889
|
-
}
|
|
2890
|
-
});
|
|
2891
3009
|
Object.defineProperty(exports, 'usePlugin', {
|
|
2892
3010
|
enumerable: true,
|
|
2893
3011
|
get: function () {
|
|
2894
3012
|
return usePlugin;
|
|
2895
3013
|
}
|
|
2896
3014
|
});
|
|
2897
|
-
//# sourceMappingURL=
|
|
3015
|
+
//# sourceMappingURL=nestjs-extras-DnJ6vrIC.js.map
|