@zintrust/trace 0.4.79 → 0.4.82
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/build-manifest.json +43 -43
- package/dist/config.js +2 -0
- package/dist/dashboard/ui.js +103 -8
- package/dist/register.js +16 -0
- package/dist/types.d.ts +29 -1
- package/dist/watchers/CacheWatcher.d.ts +1 -1
- package/dist/watchers/CacheWatcher.js +10 -2
- package/dist/watchers/HttpClientWatcher.d.ts +2 -2
- package/dist/watchers/HttpClientWatcher.js +17 -4
- package/dist/watchers/LogWatcher.js +9 -0
- package/dist/watchers/MailWatcher.d.ts +1 -1
- package/dist/watchers/MailWatcher.js +12 -3
- package/dist/watchers/NotificationWatcher.d.ts +1 -1
- package/dist/watchers/NotificationWatcher.js +9 -1
- package/dist/watchers/QueryWatcher.js +5 -1
- package/package.json +3 -3
- package/src/config.ts +2 -0
- package/src/dashboard/ui.ts +103 -8
- package/src/register.ts +16 -0
- package/src/types.ts +30 -1
- package/src/watchers/CacheWatcher.ts +13 -2
- package/src/watchers/HttpClientWatcher.ts +33 -11
- package/src/watchers/LogWatcher.ts +10 -0
- package/src/watchers/MailWatcher.ts +18 -3
- package/src/watchers/NotificationWatcher.ts +15 -1
- package/src/watchers/QueryWatcher.ts +5 -1
package/dist/build-manifest.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zintrust/trace",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"buildDate": "2026-04-
|
|
3
|
+
"version": "0.4.82",
|
|
4
|
+
"buildDate": "2026-04-08T15:23:56.210Z",
|
|
5
5
|
"buildEnvironment": {
|
|
6
6
|
"node": "v22.22.1",
|
|
7
7
|
"platform": "darwin",
|
|
8
8
|
"arch": "arm64"
|
|
9
9
|
},
|
|
10
10
|
"git": {
|
|
11
|
-
"commit": "
|
|
11
|
+
"commit": "54ac1e60",
|
|
12
12
|
"branch": "release"
|
|
13
13
|
},
|
|
14
14
|
"package": {
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
},
|
|
23
23
|
"files": {
|
|
24
24
|
"build-manifest.json": {
|
|
25
|
-
"size":
|
|
26
|
-
"sha256": "
|
|
25
|
+
"size": 14439,
|
|
26
|
+
"sha256": "b94e2cbd290c3992dabf8673fba6a501186ebe5386ee6bd2686a42f750881d00"
|
|
27
27
|
},
|
|
28
28
|
"cli-register.d.ts": {
|
|
29
29
|
"size": 255,
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"sha256": "b034cbef0c71fb868071363624ef7a9f8d7acc20f8be8c895dd5db5a75e81f37"
|
|
39
39
|
},
|
|
40
40
|
"config.js": {
|
|
41
|
-
"size":
|
|
42
|
-
"sha256": "
|
|
41
|
+
"size": 5927,
|
|
42
|
+
"sha256": "24f446c25ca4aae4ebc48ab54824c46e2042f1afbf41dd88b769fde4dced5886"
|
|
43
43
|
},
|
|
44
44
|
"context.d.ts": {
|
|
45
45
|
"size": 596,
|
|
@@ -70,16 +70,16 @@
|
|
|
70
70
|
"sha256": "4862b41e0477f01afa0dbb446d4553b65c22ed774cd1e2db3489059ced392f94"
|
|
71
71
|
},
|
|
72
72
|
"dashboard/ui.js": {
|
|
73
|
-
"size":
|
|
74
|
-
"sha256": "
|
|
73
|
+
"size": 70368,
|
|
74
|
+
"sha256": "b9f67e7977a36b459ac8d37312547b2638fcab7fc9b6c3d0c072d02510fca62f"
|
|
75
75
|
},
|
|
76
76
|
"index.d.ts": {
|
|
77
|
-
"size":
|
|
78
|
-
"sha256": "
|
|
77
|
+
"size": 2470,
|
|
78
|
+
"sha256": "99c28d43f79dbb2b372bf6a8b611841c131f59f5066702b499915b874e9fa2b8"
|
|
79
79
|
},
|
|
80
80
|
"index.js": {
|
|
81
|
-
"size":
|
|
82
|
-
"sha256": "
|
|
81
|
+
"size": 3255,
|
|
82
|
+
"sha256": "ab97f252e49aa760657c10b96ea3fc0857d626c128d70cbb423cf6b72d6a67fb"
|
|
83
83
|
},
|
|
84
84
|
"migrations/20260331000001_create_zin_trace_entries_table.d.ts": {
|
|
85
85
|
"size": 304,
|
|
@@ -134,8 +134,8 @@
|
|
|
134
134
|
"sha256": "71d366165dd36f1675aa253a76262b226fb6c62e5ab632746b8aea61c0c625fc"
|
|
135
135
|
},
|
|
136
136
|
"register.js": {
|
|
137
|
-
"size":
|
|
138
|
-
"sha256": "
|
|
137
|
+
"size": 11496,
|
|
138
|
+
"sha256": "46a85cc9e9fd14a48c66c0cdf348a84608ffc628e731c0d2cc129fc38d1fa9b6"
|
|
139
139
|
},
|
|
140
140
|
"storage/DebuggerStorage.d.ts": {
|
|
141
141
|
"size": 517,
|
|
@@ -186,8 +186,8 @@
|
|
|
186
186
|
"sha256": "d916e8e3abb1b1087f6b184851b0e6265e53380d7857b008e745d566aad15d44"
|
|
187
187
|
},
|
|
188
188
|
"types.d.ts": {
|
|
189
|
-
"size":
|
|
190
|
-
"sha256": "
|
|
189
|
+
"size": 8416,
|
|
190
|
+
"sha256": "03c17d7f3759890062d36089311d3c464ff833d90c1048dd8c35a07a33388862"
|
|
191
191
|
},
|
|
192
192
|
"types.js": {
|
|
193
193
|
"size": 696,
|
|
@@ -266,12 +266,12 @@
|
|
|
266
266
|
"sha256": "879a739de9ce2c3c5b57bdad73eae2ce3de94ccdc7e666ca52a50b45b0bc9bfd"
|
|
267
267
|
},
|
|
268
268
|
"watchers/CacheWatcher.d.ts": {
|
|
269
|
-
"size":
|
|
270
|
-
"sha256": "
|
|
269
|
+
"size": 314,
|
|
270
|
+
"sha256": "19b5f6fe4f0fc8f3df6762f4f46d36f198c7c7d7da8d3d23e5c8f124462e8cf7"
|
|
271
271
|
},
|
|
272
272
|
"watchers/CacheWatcher.js": {
|
|
273
|
-
"size":
|
|
274
|
-
"sha256": "
|
|
273
|
+
"size": 1956,
|
|
274
|
+
"sha256": "e1e1b79e85e7553d856ff0209d912e27d7b4fe665579de856c60e04bb7519aa1"
|
|
275
275
|
},
|
|
276
276
|
"watchers/CommandWatcher.d.ts": {
|
|
277
277
|
"size": 267,
|
|
@@ -298,12 +298,12 @@
|
|
|
298
298
|
"sha256": "ff32b44b48b6e313d15ba4370a845faf74ff8b03504a6336c19f183ff91a90dc"
|
|
299
299
|
},
|
|
300
300
|
"watchers/ExceptionWatcher.d.ts": {
|
|
301
|
-
"size":
|
|
302
|
-
"sha256": "
|
|
301
|
+
"size": 311,
|
|
302
|
+
"sha256": "0f58c50fd77704151399ca6cb6ec7890a9aef86afe28235951971f8cc9c1d600"
|
|
303
303
|
},
|
|
304
304
|
"watchers/ExceptionWatcher.js": {
|
|
305
|
-
"size":
|
|
306
|
-
"sha256": "
|
|
305
|
+
"size": 3691,
|
|
306
|
+
"sha256": "d2ddd55f14730b0404cea53c17a6cfd4bd65ff3c17c8b068cc284de109da36d1"
|
|
307
307
|
},
|
|
308
308
|
"watchers/GateWatcher.d.ts": {
|
|
309
309
|
"size": 262,
|
|
@@ -314,20 +314,20 @@
|
|
|
314
314
|
"sha256": "f318cdeec954ce0bba97be1dc11a6dff935b081e6b6a417c614be1934fa47f04"
|
|
315
315
|
},
|
|
316
316
|
"watchers/HttpClientWatcher.d.ts": {
|
|
317
|
-
"size":
|
|
318
|
-
"sha256": "
|
|
317
|
+
"size": 333,
|
|
318
|
+
"sha256": "08ab7e213c489ecc4fdd3166d7a121b9a5220ff9cbae9841d4787d9a804e11ce"
|
|
319
319
|
},
|
|
320
320
|
"watchers/HttpClientWatcher.js": {
|
|
321
|
-
"size":
|
|
322
|
-
"sha256": "
|
|
321
|
+
"size": 2414,
|
|
322
|
+
"sha256": "817c74e7a89bcd0c53c0344d713b422e0c9e51ec65e7b6c97f0c486116dda7a5"
|
|
323
323
|
},
|
|
324
324
|
"watchers/HttpWatcher.d.ts": {
|
|
325
325
|
"size": 96,
|
|
326
326
|
"sha256": "ce9a95a670f755193fd74ce721dbfa4b30f20c879a6566ebb35229b3b2435429"
|
|
327
327
|
},
|
|
328
328
|
"watchers/HttpWatcher.js": {
|
|
329
|
-
"size":
|
|
330
|
-
"sha256": "
|
|
329
|
+
"size": 5916,
|
|
330
|
+
"sha256": "9b3fed08fd11f8a2bfe1f667293af437b00f11dcc66bfb545b2f77925394e611"
|
|
331
331
|
},
|
|
332
332
|
"watchers/JobWatcher.d.ts": {
|
|
333
333
|
"size": 441,
|
|
@@ -342,16 +342,16 @@
|
|
|
342
342
|
"sha256": "f3ddc5f8b58c6c86ac6b464dd48e5a55e79ab2bf2e735feacffc7480e4ccc0c4"
|
|
343
343
|
},
|
|
344
344
|
"watchers/LogWatcher.js": {
|
|
345
|
-
"size":
|
|
346
|
-
"sha256": "
|
|
345
|
+
"size": 2026,
|
|
346
|
+
"sha256": "c5d2227cd76ce10162993ac31f474b2460cd41264c36f01b5130152f14a0ad21"
|
|
347
347
|
},
|
|
348
348
|
"watchers/MailWatcher.d.ts": {
|
|
349
|
-
"size":
|
|
350
|
-
"sha256": "
|
|
349
|
+
"size": 244,
|
|
350
|
+
"sha256": "5031b96ef8e64a6d376576e8cddf1c2560f22432a78f1d2be55f7cea6bff4547"
|
|
351
351
|
},
|
|
352
352
|
"watchers/MailWatcher.js": {
|
|
353
|
-
"size":
|
|
354
|
-
"sha256": "
|
|
353
|
+
"size": 1655,
|
|
354
|
+
"sha256": "0eb4f43c27a0c76cf290bb6507e71dc595bff3f8ab66c25249d9ac6027b351c5"
|
|
355
355
|
},
|
|
356
356
|
"watchers/MiddlewareWatcher.d.ts": {
|
|
357
357
|
"size": 259,
|
|
@@ -370,20 +370,20 @@
|
|
|
370
370
|
"sha256": "de3d1e379c7b1289167fe0b1dbf2aa5a54137b841df17c8d397ee656d9ce37fd"
|
|
371
371
|
},
|
|
372
372
|
"watchers/NotificationWatcher.d.ts": {
|
|
373
|
-
"size":
|
|
374
|
-
"sha256": "
|
|
373
|
+
"size": 274,
|
|
374
|
+
"sha256": "a1d918122c5db9a7f27fdf78c0c14a61f6e1213748ee6f9b06f976f33589dc33"
|
|
375
375
|
},
|
|
376
376
|
"watchers/NotificationWatcher.js": {
|
|
377
|
-
"size":
|
|
378
|
-
"sha256": "
|
|
377
|
+
"size": 1697,
|
|
378
|
+
"sha256": "b0ecc1df6a49dc8c5ffeb8dff0f1e3594ba016c4de3424dc8b5d7832e2f4cd11"
|
|
379
379
|
},
|
|
380
380
|
"watchers/QueryWatcher.d.ts": {
|
|
381
381
|
"size": 97,
|
|
382
382
|
"sha256": "6832a282b1658398264ede770d41c6aa86cb13625a3a87dac27fbaf7d2f7be6a"
|
|
383
383
|
},
|
|
384
384
|
"watchers/QueryWatcher.js": {
|
|
385
|
-
"size":
|
|
386
|
-
"sha256": "
|
|
385
|
+
"size": 2899,
|
|
386
|
+
"sha256": "a5bb991149846b67edf9658ce448172ec0b6f2f1bfb1cab25d9b2831a5e19a64"
|
|
387
387
|
},
|
|
388
388
|
"watchers/RedisWatcher.d.ts": {
|
|
389
389
|
"size": 294,
|
package/dist/config.js
CHANGED
package/dist/dashboard/ui.js
CHANGED
|
@@ -41,7 +41,7 @@ const encodeSvgDataUri = (svg) => {
|
|
|
41
41
|
const compactSvg = svg.replaceAll(/>\s+</g, '><').trim();
|
|
42
42
|
return `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(compactSvg)}`;
|
|
43
43
|
};
|
|
44
|
-
const DASHBOARD_DOCUMENT = `<!DOCTYPE html>
|
|
44
|
+
const DASHBOARD_DOCUMENT = String.raw `<!DOCTYPE html>
|
|
45
45
|
<html lang="en">
|
|
46
46
|
<head>
|
|
47
47
|
<meta charset="UTF-8">
|
|
@@ -74,7 +74,7 @@ const DASHBOARD_DOCUMENT = `<!DOCTYPE html>
|
|
|
74
74
|
.tag{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;background:rgba(56,189,248,.12);color:#bae6fd;font-size:.78rem;font-weight:800;margin:0 6px 6px 0;border:1px solid rgba(56,189,248,.18);text-decoration:none}button.tag{cursor:pointer}html[data-theme='light'] .tag{color:#075985}.tag.failed{background:rgba(239,68,68,.14);color:#fecaca;border-color:rgba(239,68,68,.2)}html[data-theme='light'] .tag.failed{color:#b91c1c}.tag.slow{background:rgba(245,158,11,.12);color:#fde68a;border-color:rgba(245,158,11,.18)}html[data-theme='light'] .tag.slow{color:#92400e}.type-pill{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:999px;font-size:.74rem;font-weight:900;text-transform:uppercase;letter-spacing:.08em;border:1px solid transparent}.pill-request{background:rgba(56,189,248,.14);color:#93c5fd}.pill-request.method-get{background:rgba(34,197,94,.16);color:#bbf7d0}.pill-request.method-post{background:rgba(59,130,246,.16);color:#bfdbfe}.pill-request.method-other{background:rgba(245,158,11,.16);color:#fde68a}.pill-query{background:rgba(34,197,94,.12);color:#86efac}.pill-exception{background:rgba(239,68,68,.14);color:#fecaca}.pill-log{background:rgba(168,85,247,.14);color:#ddd6fe}.pill-job,.pill-batch{background:rgba(245,158,11,.14);color:#fde68a}.pill-cache{background:rgba(20,184,166,.12);color:#99f6e4}.pill-schedule,.pill-command{background:rgba(14,165,233,.14);color:#bae6fd}.pill-mail,.pill-notification{background:rgba(236,72,153,.14);color:#fbcfe8}.pill-auth{background:rgba(148,163,184,.16);color:#e2e8f0}.pill-event,.pill-model{background:rgba(74,222,128,.14);color:#bbf7d0}.pill-redis{background:rgba(239,68,68,.12);color:#fecaca}.pill-gate{background:rgba(99,102,241,.14);color:#c7d2fe}.pill-middleware{background:rgba(45,212,191,.12);color:#ccfbf1}.pill-dump,.pill-view{background:rgba(148,163,184,.14);color:#e2e8f0}.pill-client-request{background:rgba(59,130,246,.14);color:#bfdbfe}html[data-theme='light'] .pill-request{color:#1d4ed8}html[data-theme='light'] .pill-request.method-get{color:#166534}html[data-theme='light'] .pill-request.method-post{color:#1d4ed8}html[data-theme='light'] .pill-request.method-other{color:#92400e}html[data-theme='light'] .pill-query{color:#166534}html[data-theme='light'] .pill-exception{color:#b91c1c}html[data-theme='light'] .pill-log{color:#6d28d9}html[data-theme='light'] .pill-job,html[data-theme='light'] .pill-batch{color:#92400e}html[data-theme='light'] .pill-cache{color:#115e59}html[data-theme='light'] .pill-schedule,html[data-theme='light'] .pill-command{color:#0c4a6e}html[data-theme='light'] .pill-mail,html[data-theme='light'] .pill-notification{color:#9d174d}html[data-theme='light'] .pill-auth,html[data-theme='light'] .pill-dump,html[data-theme='light'] .pill-view{color:#334155}html[data-theme='light'] .pill-event,html[data-theme='light'] .pill-model{color:#166534}html[data-theme='light'] .pill-redis{color:#991b1b}html[data-theme='light'] .pill-gate{color:#3730a3}html[data-theme='light'] .pill-middleware{color:#155e75}html[data-theme='light'] .pill-client-request{color:#1d4ed8}
|
|
75
75
|
.monitoring-wrap{padding:0 24px 24px}.tag-list{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:18px}.tag-item{display:inline-flex;align-items:center;gap:10px;padding:10px 14px;border-radius:999px;border:1px solid var(--line);background:var(--surface-strong)}.tag-remove{border:none;background:rgba(239,68,68,.14);color:var(--danger);border-radius:999px;width:24px;height:24px;cursor:pointer;font-size:1rem;line-height:1}.helper-text{color:var(--muted);line-height:1.6}
|
|
76
76
|
.duration-chip{display:inline-flex;align-items:center;padding:5px 9px;border-radius:999px;border:1px solid transparent;font-size:.8rem;font-weight:700;color:var(--text);white-space:nowrap}.duration-chip.vfast{background:rgba(34,197,94,.14);border-color:rgba(34,197,94,.28);color:#bbf7d0}.duration-chip.fast{background:rgba(56,189,248,.12);border-color:rgba(56,189,248,.24);color:#bae6fd}.duration-chip.slow{background:rgba(245,158,11,.12);border-color:rgba(245,158,11,.22);color:#fde68a}.duration-chip.vslow{background:rgba(239,68,68,.14);border-color:rgba(239,68,68,.24);color:#fecaca}html[data-theme='light'] .duration-chip.vfast{color:#166534}html[data-theme='light'] .duration-chip.fast{color:#1d4ed8}html[data-theme='light'] .duration-chip.slow{color:#92400e}html[data-theme='light'] .duration-chip.vslow{color:#b91c1c}
|
|
77
|
-
.code-card{border-radius:16px;border:1px solid var(--code-border);background:var(--surface-soft);overflow:hidden}.code-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 14px;border-bottom:1px solid var(--line)}.code-label{font-size:.76rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:800}.copy-button{display:inline-flex;align-items:center;justify-content:center;gap:8px;width:38px;height:38px;border-radius:12px;border:1px solid var(--line);background:var(--surface-strong);color:var(--text);cursor:pointer;transition:border-color .16s ease,color .16s ease}.copy-button:hover{border-color:rgba(56,189,248,.35);color:var(--accent)}.copy-button[data-copied='true']{color:var(--success);border-color:rgba(34,197,94,.28)}.copy-button svg{width:16px;height:16px;display:block}.code-block{margin:0;padding:18px 20px;background:var(--code-bg);color:#dbeafe;border:0;overflow:auto;white-space:pre;line-height:1.72;font-family:var(--mono);font-size:.92rem}.code-block code{font-family:inherit}.tok-key{color:#93c5fd}.tok-string{color:#86efac}.tok-number{color:#f9a8d4}.tok-boolean{color:#facc15}.tok-null{color:#fb7185}.tok-punctuation{color:#94a3b8}.tok-sql-keyword{color:#f472b6;font-weight:700}.tok-sql-identifier{color:#93c5fd}.tok-sql-string{color:#86efac}.tok-sql-number{color:#facc15}.tok-sql-comment{color:#64748b;font-style:italic}html[data-theme='light'] .code-block{color:#0f172a}html[data-theme='light'] .tok-key{color:#1d4ed8}html[data-theme='light'] .tok-string{color:#15803d}html[data-theme='light'] .tok-number{color:#c026d3}html[data-theme='light'] .tok-boolean{color:#b45309}html[data-theme='light'] .tok-null{color:#dc2626}html[data-theme='light'] .tok-punctuation{color:#64748b}html[data-theme='light'] .tok-sql-keyword{color:#db2777}html[data-theme='light'] .tok-sql-identifier{color:#2563eb}html[data-theme='light'] .tok-sql-string{color:#15803d}html[data-theme='light'] .tok-sql-number{color:#b45309}html[data-theme='light'] .tok-sql-comment{color:#6b7280}
|
|
77
|
+
.code-card{border-radius:16px;border:1px solid var(--code-border);background:var(--surface-soft);overflow:hidden}.code-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 14px;border-bottom:1px solid var(--line)}.code-label{font-size:.76rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:800}.copy-button{display:inline-flex;align-items:center;justify-content:center;gap:8px;width:38px;height:38px;border-radius:12px;border:1px solid var(--line);background:var(--surface-strong);color:var(--text);cursor:pointer;transition:border-color .16s ease,color .16s ease}.copy-button:hover{border-color:rgba(56,189,248,.35);color:var(--accent)}.copy-button[data-copied='true']{color:var(--success);border-color:rgba(34,197,94,.28)}.copy-button svg{width:16px;height:16px;display:block}.code-block{margin:0;padding:18px 20px;background:var(--code-bg);color:#dbeafe;border:0;overflow:auto;white-space:pre;line-height:1.72;font-family:var(--mono);font-size:.92rem}.code-block code{font-family:inherit}.html-preview-wrap{padding:14px;background:var(--surface-strong);border-top:1px solid var(--line)}.html-preview{display:block;width:100%;min-height:320px;border:1px solid var(--line);border-radius:14px;background:#fff}.tok-key{color:#93c5fd}.tok-string{color:#86efac}.tok-number{color:#f9a8d4}.tok-boolean{color:#facc15}.tok-null{color:#fb7185}.tok-punctuation{color:#94a3b8}.tok-sql-keyword{color:#f472b6;font-weight:700}.tok-sql-identifier{color:#93c5fd}.tok-sql-string{color:#86efac}.tok-sql-number{color:#facc15}.tok-sql-comment{color:#64748b;font-style:italic}html[data-theme='light'] .code-block{color:#0f172a}html[data-theme='light'] .tok-key{color:#1d4ed8}html[data-theme='light'] .tok-string{color:#15803d}html[data-theme='light'] .tok-number{color:#c026d3}html[data-theme='light'] .tok-boolean{color:#b45309}html[data-theme='light'] .tok-null{color:#dc2626}html[data-theme='light'] .tok-punctuation{color:#64748b}html[data-theme='light'] .tok-sql-keyword{color:#db2777}html[data-theme='light'] .tok-sql-identifier{color:#2563eb}html[data-theme='light'] .tok-sql-string{color:#15803d}html[data-theme='light'] .tok-sql-number{color:#b45309}html[data-theme='light'] .tok-sql-comment{color:#6b7280}
|
|
78
78
|
@media (max-width:1120px){.content-grid{grid-template-columns:1fr}}@media (max-width:920px){.layout{grid-template-columns:1fr}.sidebar{position:static;height:auto;border-right:none;border-bottom:1px solid var(--line);padding:20px 16px 18px}.brand-row{padding:0 0 16px}.sidebar-status{margin:0 0 16px}.sidebar-group{padding:0}.main{padding:20px}}@media (max-width:640px){.stats-grid{grid-template-columns:1fr}.detail-card{padding:18px}.toolbar,.section-head,.pagination,.activity-list,.monitoring-wrap{padding-left:18px;padding-right:18px}.table-wrap{padding:0 8px 10px}.brand-row{align-items:stretch;gap:14px;padding:0 0 14px}.brand{width:100%;align-items:flex-start}.brand-copy{min-width:0}.brand-copy h1{font-size:1.18rem;line-height:1.12}.brand-copy p{font-size:.82rem;overflow-wrap:anywhere}.icon-button{align-self:flex-end}.sidebar-status{padding:12px}.nav-button{padding:11px 12px}.nav-title{font-size:.95rem}.nav-meta{font-size:.72rem}}@media (max-width:480px){.brand-row{flex-direction:column}.icon-button{align-self:flex-start}.nav-button{align-items:flex-start;flex-direction:column}.nav-meta{font-size:.7rem}}
|
|
79
79
|
</style>
|
|
80
80
|
</head>
|
|
@@ -196,6 +196,8 @@ const DASHBOARD_DOCUMENT = `<!DOCTYPE html>
|
|
|
196
196
|
.replace(/"/g, '"')
|
|
197
197
|
.replace(/'/g, ''');
|
|
198
198
|
|
|
199
|
+
const looksLikeHtml = (value) => new RegExp('</?(?:html|body|div|table)\\b|<!doctype\\b', 'i').test(String(value || ''));
|
|
200
|
+
|
|
199
201
|
const api = async (path, opts) => {
|
|
200
202
|
const response = await fetch(API + path, opts);
|
|
201
203
|
if (!response.ok) {
|
|
@@ -335,6 +337,28 @@ const DASHBOARD_DOCUMENT = `<!DOCTYPE html>
|
|
|
335
337
|
].join('');
|
|
336
338
|
};
|
|
337
339
|
|
|
340
|
+
const renderTextCard = (label, value) => {
|
|
341
|
+
const source = String(value ?? '');
|
|
342
|
+
return renderCodeCard(label, source, escapeHtml(source), 'language-text');
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const renderHtmlPreview = (label, html) => {
|
|
346
|
+
const source = String(html ?? '');
|
|
347
|
+
const copyId = registerCopyPayload(source);
|
|
348
|
+
return [
|
|
349
|
+
'<section class="code-card">',
|
|
350
|
+
'<div class="code-toolbar">',
|
|
351
|
+
'<span class="code-label">' + escapeHtml(label) + '</span>',
|
|
352
|
+
'<button type="button" class="copy-button" data-action="copy-code" data-copy-id="' + escapeHtml(copyId) + '" title="Copy ' + escapeHtml(label) + '">',
|
|
353
|
+
COPY_ICON,
|
|
354
|
+
'</button>',
|
|
355
|
+
'</div>',
|
|
356
|
+
'<pre class="code-block language-html"><code>' + escapeHtml(source) + '</code></pre>',
|
|
357
|
+
'<div class="html-preview-wrap"><iframe class="html-preview" sandbox="allow-same-origin" srcdoc="' + escapeHtml(source) + '"></iframe></div>',
|
|
358
|
+
'</section>'
|
|
359
|
+
].join('');
|
|
360
|
+
};
|
|
361
|
+
|
|
338
362
|
const highlightJson = (value, label = 'JSON') => {
|
|
339
363
|
const source = prettyJson(value);
|
|
340
364
|
let output = '';
|
|
@@ -386,6 +410,14 @@ const DASHBOARD_DOCUMENT = `<!DOCTYPE html>
|
|
|
386
410
|
|
|
387
411
|
const detailJson = (value, label = 'JSON') => highlightJson(value ?? {}, label);
|
|
388
412
|
|
|
413
|
+
const renderPayload = (label, value) => {
|
|
414
|
+
if (value === undefined) return '<p class="trace-note">No ' + escapeHtml(label.toLowerCase()) + ' was captured.</p>';
|
|
415
|
+
if (typeof value === 'string') {
|
|
416
|
+
return looksLikeHtml(value) ? renderHtmlPreview(label, value) : renderTextCard(label, value);
|
|
417
|
+
}
|
|
418
|
+
return detailJson(value, label);
|
|
419
|
+
};
|
|
420
|
+
|
|
389
421
|
const entrySummaryText = (entry) => {
|
|
390
422
|
const content = entry && entry.content ? entry.content : {};
|
|
391
423
|
if (entry.type === 'request') return [content.responseStatus || '', content.method || '', content.uri || ''].filter(Boolean).join(' ');
|
|
@@ -393,20 +425,20 @@ const DASHBOARD_DOCUMENT = `<!DOCTYPE html>
|
|
|
393
425
|
if (entry.type === 'exception') return [content.class || '', content.message || ''].filter(Boolean).join(': ');
|
|
394
426
|
if (entry.type === 'log') return '[' + String(content.level || 'log') + '] ' + String(content.message || '').slice(0, 160);
|
|
395
427
|
if (entry.type === 'job') return [content.name || '', content.status || 'queued'].filter(Boolean).join(' · ');
|
|
396
|
-
if (entry.type === 'cache') return [content.operation || '', content.key || ''].filter(Boolean).join(' ');
|
|
428
|
+
if (entry.type === 'cache') return [content.operation || '', content.key || '', content.payloadLogged ? '' : '(payload off)'].filter(Boolean).join(' ');
|
|
397
429
|
if (entry.type === 'schedule') return [content.name || '', content.status || 'ran'].filter(Boolean).join(' · ');
|
|
398
430
|
if (entry.type === 'mail') return ['To ' + (content.to || 'unknown'), content.subject || 'No subject'].join(' · ');
|
|
399
431
|
if (entry.type === 'auth') return [content.event || 'auth', content.userId ? '#' + content.userId : ''].filter(Boolean).join(' ');
|
|
400
432
|
if (entry.type === 'event') return String(content.name || 'event');
|
|
401
433
|
if (entry.type === 'model') return [content.action || '', content.model || ''].filter(Boolean).join(' ');
|
|
402
|
-
if (entry.type === 'notification') return [content.notification || '', (content.channels || []).join(', ')].filter(Boolean).join(' -> ');
|
|
434
|
+
if (entry.type === 'notification') return [content.notification || '', content.message || (content.channels || []).join(', ')].filter(Boolean).join(' -> ');
|
|
403
435
|
if (entry.type === 'redis') return String(content.command || 'redis');
|
|
404
436
|
if (entry.type === 'gate') return [content.ability || '', content.result || ''].filter(Boolean).join(' · ');
|
|
405
437
|
if (entry.type === 'middleware') return [content.name || '', content.event || ''].filter(Boolean).join(' · ');
|
|
406
438
|
if (entry.type === 'command') return [content.name || '', content.exitCode !== undefined ? 'exit=' + content.exitCode : ''].filter(Boolean).join(' ');
|
|
407
439
|
if (entry.type === 'batch') return [content.name || '', 'processed ' + (content.processed || 0) + '/' + (content.total || 0)].join(' · ');
|
|
408
440
|
if (entry.type === 'view') return String(content.template || 'view');
|
|
409
|
-
if (entry.type === 'client_request') return [content.method || '', content.url || ''].filter(Boolean).join(' ');
|
|
441
|
+
if (entry.type === 'client_request') return [content.method || '', content.url || '', content.responseStatus ? '[' + content.responseStatus + ']' : content.error ? '[failed]' : ''].filter(Boolean).join(' ');
|
|
410
442
|
return JSON.stringify(content).slice(0, 160);
|
|
411
443
|
};
|
|
412
444
|
|
|
@@ -442,6 +474,7 @@ const DASHBOARD_DOCUMENT = `<!DOCTYPE html>
|
|
|
442
474
|
{ label: 'Connection', value: escapeHtml(content.connection || 'default') },
|
|
443
475
|
{ label: 'Duration', value: escapeHtml(formatDuration(getEntryDuration(entry))) },
|
|
444
476
|
{ label: 'Slow', value: escapeHtml(content.slow ? 'Yes' : 'No') },
|
|
477
|
+
{ label: 'Bindings', value: escapeHtml(content.bindingsIncluded === false ? 'Hidden' : 'Included') },
|
|
445
478
|
{ label: 'Hash', value: '<span class="mono">' + escapeHtml(content.hash || '') + '</span>' }
|
|
446
479
|
]),
|
|
447
480
|
renderMetricBox('Runtime', [
|
|
@@ -449,7 +482,8 @@ const DASHBOARD_DOCUMENT = `<!DOCTYPE html>
|
|
|
449
482
|
{ label: 'Batch', value: '<span class="mono">' + escapeHtml(entry.batchId || '-') + '</span>' }
|
|
450
483
|
]),
|
|
451
484
|
'</div>',
|
|
452
|
-
highlightSql(content.sql || '')
|
|
485
|
+
highlightSql(content.sql || ''),
|
|
486
|
+
content.bindingsIncluded === false ? '<p class="trace-note">SQL bindings were hidden for this entry.</p>' : (Array.isArray(content.bindings) ? detailJson(content.bindings, 'Bindings Json') : '')
|
|
453
487
|
].join('');
|
|
454
488
|
}
|
|
455
489
|
|
|
@@ -493,7 +527,34 @@ const DASHBOARD_DOCUMENT = `<!DOCTYPE html>
|
|
|
493
527
|
renderMetricBox('Request', [
|
|
494
528
|
{ label: 'Method', value: escapeHtml(content.method || '') },
|
|
495
529
|
{ label: 'URL', value: '<span class="mono">' + escapeHtml(content.url || '') + '</span>' },
|
|
496
|
-
{ label: 'Status', value: escapeHtml(content.responseStatus || '') },
|
|
530
|
+
{ label: 'Status', value: escapeHtml(content.responseStatus || (content.error ? 'Failed' : 'Pending')) },
|
|
531
|
+
{ label: 'Duration', value: escapeHtml(formatDuration(getEntryDuration(entry))) }
|
|
532
|
+
]),
|
|
533
|
+
renderMetricBox('Runtime', [
|
|
534
|
+
{ label: 'Hostname', value: escapeHtml(content.hostname || '') },
|
|
535
|
+
{ label: 'Batch', value: '<span class="mono">' + escapeHtml(entry.batchId || '-') + '</span>' },
|
|
536
|
+
{ label: 'Error', value: escapeHtml(content.error || '-') }
|
|
537
|
+
]),
|
|
538
|
+
'</div>',
|
|
539
|
+
'<div class="detail-stack">',
|
|
540
|
+
detailJson(content.requestHeaders || {}, 'Request Header Json'),
|
|
541
|
+
renderPayload('Request Body', content.requestBody),
|
|
542
|
+
detailJson(content.responseHeaders || {}, 'Response Header Json'),
|
|
543
|
+
renderPayload('Response Body', content.responseBody),
|
|
544
|
+
'</div>'
|
|
545
|
+
].join('');
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (entry.type === 'cache') {
|
|
549
|
+
return [
|
|
550
|
+
'<div class="detail-grid">',
|
|
551
|
+
renderMetricBox('Cache', [
|
|
552
|
+
{ label: 'Operation', value: escapeHtml(content.operation || '') },
|
|
553
|
+
{ label: 'Key', value: '<span class="mono">' + escapeHtml(content.key || '') + '</span>' },
|
|
554
|
+
{ label: 'Store', value: escapeHtml(content.store || 'default') },
|
|
555
|
+
{ label: 'Hit', value: escapeHtml(content.hit === undefined ? '-' : (content.hit ? 'Yes' : 'No')) },
|
|
556
|
+
{ label: 'Payload', value: escapeHtml(content.payloadLogged ? 'Captured' : 'Disabled') },
|
|
557
|
+
{ label: 'TTL', value: escapeHtml(content.ttl === undefined ? '-' : String(content.ttl)) },
|
|
497
558
|
{ label: 'Duration', value: escapeHtml(formatDuration(getEntryDuration(entry))) }
|
|
498
559
|
]),
|
|
499
560
|
renderMetricBox('Runtime', [
|
|
@@ -501,7 +562,41 @@ const DASHBOARD_DOCUMENT = `<!DOCTYPE html>
|
|
|
501
562
|
{ label: 'Batch', value: '<span class="mono">' + escapeHtml(entry.batchId || '-') + '</span>' }
|
|
502
563
|
]),
|
|
503
564
|
'</div>',
|
|
504
|
-
|
|
565
|
+
content.payloadLogged ? renderPayload('Cache Payload', content.payload) : '<p class="trace-note">Cache payload logging is disabled. Set TRACE_CACHE_PAYLOADS=true to include values.</p>'
|
|
566
|
+
].join('');
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
if (entry.type === 'mail') {
|
|
570
|
+
return [
|
|
571
|
+
'<div class="detail-grid">',
|
|
572
|
+
renderMetricBox('Mail', [
|
|
573
|
+
{ label: 'To', value: escapeHtml(content.to || '') },
|
|
574
|
+
{ label: 'Subject', value: escapeHtml(content.subject || '') },
|
|
575
|
+
{ label: 'Template', value: escapeHtml(content.template || '-') },
|
|
576
|
+
{ label: 'Hostname', value: escapeHtml(content.hostname || '') }
|
|
577
|
+
]),
|
|
578
|
+
'</div>',
|
|
579
|
+
'<div class="detail-stack">',
|
|
580
|
+
renderPayload('Mail Text', content.text),
|
|
581
|
+
renderPayload('Mail Html', content.html),
|
|
582
|
+
'</div>'
|
|
583
|
+
].join('');
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
if (entry.type === 'notification') {
|
|
587
|
+
return [
|
|
588
|
+
'<div class="detail-grid">',
|
|
589
|
+
renderMetricBox('Notification', [
|
|
590
|
+
{ label: 'Notification', value: escapeHtml(content.notification || '') },
|
|
591
|
+
{ label: 'Channels', value: escapeHtml((content.channels || []).join(', ') || '-') },
|
|
592
|
+
{ label: 'Recipient', value: escapeHtml(content.notifiable || '-') },
|
|
593
|
+
{ label: 'Hostname', value: escapeHtml(content.hostname || '') }
|
|
594
|
+
]),
|
|
595
|
+
'</div>',
|
|
596
|
+
'<div class="detail-stack">',
|
|
597
|
+
renderPayload('Message', content.message),
|
|
598
|
+
content.payload === undefined ? '<p class="trace-note">No additional notification payload was captured.</p>' : detailJson(content.payload, 'Notification Payload Json'),
|
|
599
|
+
'</div>'
|
|
505
600
|
].join('');
|
|
506
601
|
}
|
|
507
602
|
|
package/dist/register.js
CHANGED
|
@@ -90,6 +90,16 @@ const parseEnvList = (rawValue) => {
|
|
|
90
90
|
.map((entry) => entry.trim())
|
|
91
91
|
.filter((entry) => entry !== '');
|
|
92
92
|
};
|
|
93
|
+
const parseEnvBool = (rawValue) => {
|
|
94
|
+
const value = rawValue.trim().toLowerCase();
|
|
95
|
+
if (value === '')
|
|
96
|
+
return undefined;
|
|
97
|
+
if (['1', 'true', 'yes', 'on'].includes(value))
|
|
98
|
+
return true;
|
|
99
|
+
if (['0', 'false', 'no', 'off'].includes(value))
|
|
100
|
+
return false;
|
|
101
|
+
return undefined;
|
|
102
|
+
};
|
|
93
103
|
const resolveTraceStartupOverrides = (core) => {
|
|
94
104
|
const traceConfigFile = core.StartupConfigFile?.Trace;
|
|
95
105
|
if (typeof traceConfigFile !== 'string' || traceConfigFile.trim() === '')
|
|
@@ -139,6 +149,8 @@ if (!traceAlreadyInitialized && Env) {
|
|
|
139
149
|
const pruneAfterHoursRaw = Env.get('TRACE_PRUNE_HOURS', '').trim();
|
|
140
150
|
const slowQueryThresholdRaw = Env.get('TRACE_SLOW_QUERY_MS', '').trim();
|
|
141
151
|
const logMinLevelRaw = Env.get('TRACE_LOG_LEVEL', '').trim();
|
|
152
|
+
const captureCachePayloadsRaw = Env.get('TRACE_CACHE_PAYLOADS', '').trim();
|
|
153
|
+
const captureQueryBindingsRaw = Env.get('TRACE_QUERY_BINDINGS', '').trim();
|
|
142
154
|
const redactionKeys = parseEnvList(Env.get('TRACE_REDACT_KEYS', ''));
|
|
143
155
|
const redactionHeaders = parseEnvList(Env.get('TRACE_REDACT_HEADERS', ''));
|
|
144
156
|
const redactionBody = parseEnvList(Env.get('TRACE_REDACT_BODY', ''));
|
|
@@ -151,6 +163,8 @@ if (!traceAlreadyInitialized && Env) {
|
|
|
151
163
|
? startupOverrides?.slowQueryThreshold
|
|
152
164
|
: Number.parseInt(slowQueryThresholdRaw, 10);
|
|
153
165
|
const logMinLevel = (logMinLevelRaw === '' ? startupOverrides?.logMinLevel : logMinLevelRaw);
|
|
166
|
+
const captureCachePayloads = parseEnvBool(captureCachePayloadsRaw) ?? startupOverrides?.captureCachePayloads;
|
|
167
|
+
const captureQueryBindings = parseEnvBool(captureQueryBindingsRaw) ?? startupOverrides?.captureQueryBindings;
|
|
154
168
|
const redaction = buildTraceRedactionOverrides({
|
|
155
169
|
startupOverrides,
|
|
156
170
|
redactionBody,
|
|
@@ -168,6 +182,8 @@ if (!traceAlreadyInitialized && Env) {
|
|
|
168
182
|
...(typeof slowQueryThreshold === 'number' && Number.isFinite(slowQueryThreshold)
|
|
169
183
|
? { slowQueryThreshold }
|
|
170
184
|
: {}),
|
|
185
|
+
...(typeof captureCachePayloads === 'boolean' ? { captureCachePayloads } : {}),
|
|
186
|
+
...(typeof captureQueryBindings === 'boolean' ? { captureQueryBindings } : {}),
|
|
171
187
|
logMinLevel,
|
|
172
188
|
...(redaction === undefined ? {} : { redaction }),
|
|
173
189
|
});
|
package/dist/types.d.ts
CHANGED
|
@@ -43,6 +43,9 @@ export interface RequestContent {
|
|
|
43
43
|
export interface QueryContent {
|
|
44
44
|
connection: string;
|
|
45
45
|
sql: string;
|
|
46
|
+
statement?: string;
|
|
47
|
+
bindings?: unknown[];
|
|
48
|
+
bindingsIncluded?: boolean;
|
|
46
49
|
time: number;
|
|
47
50
|
duration: number;
|
|
48
51
|
slow: boolean;
|
|
@@ -91,6 +94,10 @@ export interface CacheContent {
|
|
|
91
94
|
operation: 'get' | 'set' | 'delete' | 'clear' | 'has';
|
|
92
95
|
key: string;
|
|
93
96
|
hit?: boolean;
|
|
97
|
+
store?: string;
|
|
98
|
+
payload?: unknown;
|
|
99
|
+
payloadLogged?: boolean;
|
|
100
|
+
ttl?: number;
|
|
94
101
|
duration: number;
|
|
95
102
|
hostname: string;
|
|
96
103
|
}
|
|
@@ -106,6 +113,8 @@ export interface MailContent {
|
|
|
106
113
|
to: string;
|
|
107
114
|
subject: string;
|
|
108
115
|
template?: string;
|
|
116
|
+
text?: string;
|
|
117
|
+
html?: string;
|
|
109
118
|
hostname: string;
|
|
110
119
|
}
|
|
111
120
|
export interface AuthContent {
|
|
@@ -130,6 +139,8 @@ export interface NotificationContent {
|
|
|
130
139
|
channels: string[];
|
|
131
140
|
notifiable?: string;
|
|
132
141
|
notification: string;
|
|
142
|
+
message?: string;
|
|
143
|
+
payload?: unknown;
|
|
133
144
|
hostname: string;
|
|
134
145
|
}
|
|
135
146
|
export interface RedisContent {
|
|
@@ -181,10 +192,25 @@ export interface ClientRequestContent {
|
|
|
181
192
|
method: string;
|
|
182
193
|
url: string;
|
|
183
194
|
requestHeaders: Record<string, string>;
|
|
184
|
-
|
|
195
|
+
requestBody?: unknown;
|
|
196
|
+
responseStatus?: number;
|
|
197
|
+
responseHeaders?: Record<string, string>;
|
|
198
|
+
responseBody?: unknown;
|
|
199
|
+
error?: string;
|
|
185
200
|
duration: number;
|
|
186
201
|
hostname: string;
|
|
187
202
|
}
|
|
203
|
+
export interface ClientRequestTraceInput {
|
|
204
|
+
method: string;
|
|
205
|
+
url: string;
|
|
206
|
+
requestHeaders: Record<string, string>;
|
|
207
|
+
responseStatus?: number;
|
|
208
|
+
duration: number;
|
|
209
|
+
requestBody?: unknown;
|
|
210
|
+
responseHeaders?: Record<string, string>;
|
|
211
|
+
responseBody?: unknown;
|
|
212
|
+
error?: string;
|
|
213
|
+
}
|
|
188
214
|
export interface ITraceEntry<T = unknown> {
|
|
189
215
|
uuid: string;
|
|
190
216
|
batchId: string;
|
|
@@ -280,6 +306,8 @@ export interface ITraceConfig {
|
|
|
280
306
|
pruneAfterHours: number;
|
|
281
307
|
ignoreRoutes: string[];
|
|
282
308
|
slowQueryThreshold: number;
|
|
309
|
+
captureCachePayloads: boolean;
|
|
310
|
+
captureQueryBindings: boolean;
|
|
283
311
|
logMinLevel: 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
|
284
312
|
watchers: WatcherToggles;
|
|
285
313
|
redaction: RedactionConfig;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CacheContent, ITraceWatcher } from '../types';
|
|
2
|
-
declare const emit: (operation: CacheContent["operation"], key: string, duration: number, hit?: boolean) => void;
|
|
2
|
+
declare const emit: (operation: CacheContent["operation"], key: string, duration: number, hit?: boolean, payload?: unknown, store?: string, ttl?: number) => void;
|
|
3
3
|
export declare const CacheWatcher: ITraceWatcher & {
|
|
4
4
|
emit: typeof emit;
|
|
5
5
|
};
|
|
@@ -5,21 +5,27 @@
|
|
|
5
5
|
import { TraceContext } from '../context.js';
|
|
6
6
|
import { EntryType } from '../types.js';
|
|
7
7
|
import { AuthTag } from '../utils/authTag.js';
|
|
8
|
-
import { redactString } from '../utils/redact.js';
|
|
8
|
+
import { redactString, redactUnknown } from '../utils/redact.js';
|
|
9
9
|
import { RequestFilter } from '../utils/requestFilter.js';
|
|
10
10
|
let _storage = null;
|
|
11
|
+
let _config = null;
|
|
11
12
|
let _redactionFields = [];
|
|
12
13
|
let _ignoreRoutes = [];
|
|
13
|
-
const emit = (operation, key, duration, hit) => {
|
|
14
|
+
const emit = (operation, key, duration, hit, payload, store, ttl) => {
|
|
14
15
|
if (!_storage)
|
|
15
16
|
return;
|
|
16
17
|
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
|
|
17
18
|
return;
|
|
18
19
|
const safeKey = redactString(key, _redactionFields);
|
|
20
|
+
const shouldLogPayload = _config?.captureCachePayloads === true;
|
|
19
21
|
const content = {
|
|
20
22
|
operation,
|
|
21
23
|
key: safeKey,
|
|
22
24
|
hit,
|
|
25
|
+
...(typeof store === 'string' && store !== '' ? { store } : {}),
|
|
26
|
+
...(typeof ttl === 'number' ? { ttl } : {}),
|
|
27
|
+
payloadLogged: shouldLogPayload,
|
|
28
|
+
...(shouldLogPayload ? { payload: redactUnknown(payload, _redactionFields) } : {}),
|
|
23
29
|
duration,
|
|
24
30
|
hostname: TraceContext.getHostname(),
|
|
25
31
|
};
|
|
@@ -41,10 +47,12 @@ export const CacheWatcher = Object.freeze({
|
|
|
41
47
|
if (config.watchers.cache === false)
|
|
42
48
|
return () => undefined;
|
|
43
49
|
_storage = storage;
|
|
50
|
+
_config = config;
|
|
44
51
|
_redactionFields = config.redaction.query;
|
|
45
52
|
_ignoreRoutes = config.ignoreRoutes;
|
|
46
53
|
return () => {
|
|
47
54
|
_storage = null;
|
|
55
|
+
_config = null;
|
|
48
56
|
_ignoreRoutes = [];
|
|
49
57
|
};
|
|
50
58
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ITraceWatcher } from '../types';
|
|
2
|
-
declare const emit: (method
|
|
1
|
+
import type { ClientRequestTraceInput, ITraceWatcher } from '../types';
|
|
2
|
+
declare const emit: ({ method, url, requestHeaders, responseStatus, duration, requestBody, responseHeaders, responseBody, error, }: ClientRequestTraceInput) => void;
|
|
3
3
|
export declare const HttpClientWatcher: ITraceWatcher & {
|
|
4
4
|
emit: typeof emit;
|
|
5
5
|
};
|
|
@@ -1,24 +1,35 @@
|
|
|
1
1
|
import { TraceContext } from '../context.js';
|
|
2
2
|
import { EntryType } from '../types.js';
|
|
3
3
|
import { AuthTag } from '../utils/authTag.js';
|
|
4
|
-
import { redactHeaders } from '../utils/redact.js';
|
|
4
|
+
import { redactHeaders, redactUnknown } from '../utils/redact.js';
|
|
5
5
|
import { RequestFilter } from '../utils/requestFilter.js';
|
|
6
6
|
let _storage = null;
|
|
7
7
|
let _redactHeaderNames = [];
|
|
8
|
+
let _redactBodyFields = [];
|
|
8
9
|
let _ignoreRoutes = [];
|
|
9
|
-
const emit = (method, url, requestHeaders, responseStatus, duration) => {
|
|
10
|
+
const emit = ({ method, url, requestHeaders, responseStatus, duration, requestBody, responseHeaders, responseBody, error, }) => {
|
|
10
11
|
if (!_storage)
|
|
11
12
|
return;
|
|
12
13
|
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
|
|
13
14
|
return;
|
|
14
15
|
const tags = AuthTag.append([method.toUpperCase()]);
|
|
15
|
-
if (responseStatus >= 400)
|
|
16
|
+
if ((responseStatus ?? 0) >= 400 || error)
|
|
16
17
|
tags.push('failed');
|
|
17
18
|
const content = {
|
|
18
19
|
method: method.toUpperCase(),
|
|
19
20
|
url,
|
|
20
21
|
requestHeaders: redactHeaders(requestHeaders, _redactHeaderNames),
|
|
21
|
-
|
|
22
|
+
...(requestBody === undefined
|
|
23
|
+
? {}
|
|
24
|
+
: { requestBody: redactUnknown(requestBody, _redactBodyFields) }),
|
|
25
|
+
...(responseStatus === undefined ? {} : { responseStatus }),
|
|
26
|
+
...(responseHeaders === undefined
|
|
27
|
+
? {}
|
|
28
|
+
: { responseHeaders: redactHeaders(responseHeaders, _redactHeaderNames) }),
|
|
29
|
+
...(responseBody === undefined
|
|
30
|
+
? {}
|
|
31
|
+
: { responseBody: redactUnknown(responseBody, _redactBodyFields) }),
|
|
32
|
+
...(typeof error === 'string' && error !== '' ? { error } : {}),
|
|
22
33
|
duration,
|
|
23
34
|
hostname: TraceContext.getHostname(),
|
|
24
35
|
};
|
|
@@ -41,9 +52,11 @@ export const HttpClientWatcher = Object.freeze({
|
|
|
41
52
|
return () => undefined;
|
|
42
53
|
_storage = storage;
|
|
43
54
|
_redactHeaderNames = [...(config.redaction?.keys ?? []), ...(config.redaction?.headers ?? [])];
|
|
55
|
+
_redactBodyFields = [...(config.redaction?.keys ?? []), ...(config.redaction?.body ?? [])];
|
|
44
56
|
_ignoreRoutes = config.ignoreRoutes;
|
|
45
57
|
return () => {
|
|
46
58
|
_storage = null;
|
|
59
|
+
_redactBodyFields = [];
|
|
47
60
|
_ignoreRoutes = [];
|
|
48
61
|
};
|
|
49
62
|
},
|