@zintrust/trace 0.4.76 → 0.4.79
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 +101 -15
- package/dist/build-manifest.json +78 -38
- package/dist/config.d.ts +1 -0
- package/dist/config.js +123 -4
- package/dist/dashboard/ui.js +88 -29
- package/dist/index.d.ts +7 -0
- package/dist/index.js +5 -0
- package/dist/migrations/20260331000001_create_zin_trace_entries_table.js +1 -1
- package/dist/migrations/20260407193000_widen_trace_created_at_for_sql.d.ts +10 -0
- package/dist/migrations/20260407193000_widen_trace_created_at_for_sql.js +34 -0
- package/dist/migrations/index.js +2 -1
- package/dist/register.js +107 -9
- package/dist/storage/TraceContentRedaction.d.ts +4 -0
- package/dist/storage/TraceContentRedaction.js +33 -0
- package/dist/storage/TraceEntryFiltering.d.ts +4 -0
- package/dist/storage/TraceEntryFiltering.js +13 -0
- package/dist/storage/TraceStorage.js +35 -5
- package/dist/storage/TraceWriteDiagnostics.d.ts +19 -0
- package/dist/storage/TraceWriteDiagnostics.js +98 -0
- package/dist/types.d.ts +38 -21
- package/dist/utils/entryFilter.d.ts +4 -0
- package/dist/utils/entryFilter.js +95 -0
- package/dist/utils/redact.d.ts +1 -0
- package/dist/utils/redact.js +43 -9
- package/dist/watchers/CommandWatcher.js +1 -1
- package/dist/watchers/ExceptionWatcher.d.ts +8 -1
- package/dist/watchers/ExceptionWatcher.js +12 -7
- package/dist/watchers/HttpClientWatcher.js +1 -1
- package/dist/watchers/HttpWatcher.js +112 -21
- package/package.json +2 -2
- package/src/config.ts +152 -5
- package/src/dashboard/routes.ts +6 -2
- package/src/dashboard/ui.ts +88 -29
- package/src/index.ts +10 -0
- package/src/register.ts +137 -10
- package/src/storage/TraceContentRedaction.ts +44 -0
- package/src/storage/TraceEntryFiltering.ts +14 -0
- package/src/storage/TraceStorage.ts +52 -5
- package/src/storage/TraceWriteDiagnostics.ts +174 -0
- package/src/types.ts +41 -21
- package/src/utils/entryFilter.ts +108 -0
- package/src/utils/redact.ts +57 -9
- package/src/watchers/CommandWatcher.ts +1 -1
- package/src/watchers/ExceptionWatcher.ts +21 -8
- package/src/watchers/HttpClientWatcher.ts +1 -1
- package/src/watchers/HttpWatcher.ts +142 -23
- package/src/watchers/LogWatcher.ts +26 -28
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Works with both `zin s` (Node.js) and `zin s --wg` (Cloudflare Workers).
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
|
|
12
|
+
npm install @zintrust/trace
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Run the provided migrations to create the three required tables (`zin_trace_entries`, `zin_trace_entries_tags`, `zin_trace_monitoring`):
|
|
@@ -63,7 +63,44 @@ Why this is the preferred path:
|
|
|
63
63
|
- The core runtime can then lazy-load the trace only after databases and the kernel are ready.
|
|
64
64
|
- The plugin activates trace runtime logic only; the dashboard route stays inactive until you register it yourself.
|
|
65
65
|
|
|
66
|
-
With the stock ZinTrust bootstrap, `TRACE_ENABLED=true` plus the plugin import above activates the watchers and storage integration. Dashboard UI/routes are a separate
|
|
66
|
+
With the stock ZinTrust bootstrap, `TRACE_ENABLED=true` plus the plugin import above activates the watchers and storage integration. Dashboard UI/routes are still a separate opt-in unless you also set `TRACE_AUTO_MOUNT=true`.
|
|
67
|
+
|
|
68
|
+
### Optional: configure filters in `config/trace.ts`
|
|
69
|
+
|
|
70
|
+
If you prefer project-owned trace configuration over env-only setup, put the filter rules directly in `config/trace.ts`.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
// config/trace.ts
|
|
74
|
+
import { Env } from '@config/env';
|
|
75
|
+
import type { TraceConfigOverrides } from '@zintrust/trace';
|
|
76
|
+
|
|
77
|
+
export default {
|
|
78
|
+
enabled: Env.getBool('TRACE_ENABLED', false),
|
|
79
|
+
connection: Env.get('TRACE_DB_CONNECTION', '') || undefined,
|
|
80
|
+
pruneAfterHours: Env.getInt('TRACE_PRUNE_HOURS', 24),
|
|
81
|
+
slowQueryThreshold: Env.getInt('TRACE_SLOW_QUERY_MS', 100),
|
|
82
|
+
logMinLevel: Env.get('TRACE_LOG_LEVEL', 'info') as TraceConfigOverrides['logMinLevel'],
|
|
83
|
+
watchers: {
|
|
84
|
+
request: {
|
|
85
|
+
get: { exclude: ['report'] },
|
|
86
|
+
post: { include: ['auth'] },
|
|
87
|
+
patch: { include: ['profile'] },
|
|
88
|
+
delete: { exclude: ['internal'] },
|
|
89
|
+
},
|
|
90
|
+
log: { exclude: ['healthcheck'] },
|
|
91
|
+
exception: { include: ['trace'] },
|
|
92
|
+
cache: { include: ['session:'] },
|
|
93
|
+
},
|
|
94
|
+
redaction: {
|
|
95
|
+
keys: ['password', 'token', 'secret'],
|
|
96
|
+
headers: ['authorization', 'cookie'],
|
|
97
|
+
body: ['password', 'token', 'secret'],
|
|
98
|
+
query: [],
|
|
99
|
+
},
|
|
100
|
+
} satisfies TraceConfigOverrides;
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
All include/exclude matching is contains-based, so a term like `report` matches `/reports/daily`, `monthly-report`, or any other trace content containing that fragment.
|
|
67
104
|
|
|
68
105
|
### 3. Mount the dashboard
|
|
69
106
|
|
|
@@ -98,6 +135,19 @@ registerTraceRoutes(router, TraceStorage.resolveStorage(db), {
|
|
|
98
135
|
|
|
99
136
|
If you need a manual late bootstrap instead of plugin-driven activation, you can still import `@zintrust/trace/register` yourself, but that is the advanced path rather than the default project setup.
|
|
100
137
|
|
|
138
|
+
### 4. Optional stock-bootstrap auto-mount
|
|
139
|
+
|
|
140
|
+
If you want core to expose the trace dashboard without editing your route file, opt in explicitly:
|
|
141
|
+
|
|
142
|
+
```env
|
|
143
|
+
TRACE_ENABLED=true
|
|
144
|
+
TRACE_AUTO_MOUNT=true
|
|
145
|
+
TRACE_BASE_PATH=/trace
|
|
146
|
+
TRACE_MIDDLEWARE=auth,admin
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
When `TRACE_AUTO_MOUNT=true`, ZinTrust calls `registerTraceDashboard(...)` during bootstrap using `TRACE_BASE_PATH` and the optional comma-separated `TRACE_MIDDLEWARE` list. Keep this off if you want route ownership to stay fully in application code.
|
|
150
|
+
|
|
101
151
|
## CLI commands
|
|
102
152
|
|
|
103
153
|
When the optional package is installed, ZinTrust auto-registers these commands:
|
|
@@ -111,6 +161,14 @@ zin trace:clear
|
|
|
111
161
|
|
|
112
162
|
`zin trace:status` reports the active connection, retention window, current entry counts, and the expected dashboard URL derived from your current env and route choices.
|
|
113
163
|
|
|
164
|
+
### Monitoring tags
|
|
165
|
+
|
|
166
|
+
The Monitoring page lets you save a short list of tags that you filter by often.
|
|
167
|
+
|
|
168
|
+
- Add tags like `auth`, `checkout`, `queue:emails`, or `nightly-sync` once, then click them later to jump straight to matching entries.
|
|
169
|
+
- Monitoring tags are just saved dashboard shortcuts. Removing a monitoring tag does not delete trace entries or strip tags from stored data.
|
|
170
|
+
- Use short, exact tag names. The dashboard filters entries by the exact tag value you click.
|
|
171
|
+
|
|
114
172
|
---
|
|
115
173
|
|
|
116
174
|
## Watchers
|
|
@@ -164,6 +222,16 @@ const config = TraceConfig.merge({
|
|
|
164
222
|
// disable specific watchers
|
|
165
223
|
redis: false,
|
|
166
224
|
view: false,
|
|
225
|
+
request: {
|
|
226
|
+
get: { exclude: ['report'] },
|
|
227
|
+
post: { include: ['auth'] },
|
|
228
|
+
},
|
|
229
|
+
log: {
|
|
230
|
+
exclude: ['healthcheck'],
|
|
231
|
+
},
|
|
232
|
+
exception: {
|
|
233
|
+
include: ['trace'],
|
|
234
|
+
},
|
|
167
235
|
},
|
|
168
236
|
redaction: {
|
|
169
237
|
body: ['password', 'secret', 'token'],
|
|
@@ -184,18 +252,36 @@ ExceptionWatcher.register({ storage, config, db });
|
|
|
184
252
|
|
|
185
253
|
`TraceConfig.merge(overrides?)` accepts the following options:
|
|
186
254
|
|
|
187
|
-
| Option | Type | Default | Description
|
|
188
|
-
| -------------------- | --------------------------------------------------- | ---------------------------------- |
|
|
189
|
-
| `enabled` | `boolean` | `false` | Master switch — no watchers activate when `false`
|
|
190
|
-
| `connection` | `string \| undefined` | `undefined` | Named DB connection for storing entries; uses `'default'` if omitted
|
|
191
|
-
| `pruneAfterHours` | `number` | `24` | Entries older than this are pruned
|
|
192
|
-
| `slowQueryThreshold` | `number` | `100` | Queries taking longer (ms) are flagged as slow
|
|
193
|
-
| `logMinLevel` | `'debug' \| 'info' \| 'warn' \| 'error' \| 'fatal'` | `'info'` | Minimum log severity captured
|
|
194
|
-
| `ignoreRoutes` | `string[]` | `['/trace', '/health', '/ping']` | Routes excluded from HTTP watcher
|
|
195
|
-
| `watchers` | `Record<string, boolean>`
|
|
196
|
-
| `redaction.
|
|
197
|
-
| `redaction.
|
|
198
|
-
| `redaction.
|
|
255
|
+
| Option | Type | Default | Description |
|
|
256
|
+
| -------------------- | --------------------------------------------------- | ---------------------------------- | ---------------------------------------------------------------------------- |
|
|
257
|
+
| `enabled` | `boolean` | `false` | Master switch — no watchers activate when `false` |
|
|
258
|
+
| `connection` | `string \| undefined` | `undefined` | Named DB connection for storing entries; uses `'default'` if omitted |
|
|
259
|
+
| `pruneAfterHours` | `number` | `24` | Entries older than this are pruned |
|
|
260
|
+
| `slowQueryThreshold` | `number` | `100` | Queries taking longer (ms) are flagged as slow |
|
|
261
|
+
| `logMinLevel` | `'debug' \| 'info' \| 'warn' \| 'error' \| 'fatal'` | `'info'` | Minimum log severity captured |
|
|
262
|
+
| `ignoreRoutes` | `string[]` | `['/trace', '/health', '/ping']` | Routes excluded from HTTP watcher |
|
|
263
|
+
| `watchers` | `Record<string, boolean \| { include?, exclude? }>` | `{}` | Per-watcher enable/disable flags plus contains-based include/exclude filters |
|
|
264
|
+
| `redaction.keys` | `string[]` | common auth/card/session keys | Extra sensitive keys redacted recursively before trace persistence |
|
|
265
|
+
| `redaction.headers` | `string[]` | `['authorization', 'cookie', ...]` | Request header names to redact |
|
|
266
|
+
| `redaction.body` | `string[]` | `['password', 'token', ...]` | Request body keys to redact |
|
|
267
|
+
| `redaction.query` | `string[]` | `[]` | Query-string keys to redact |
|
|
268
|
+
|
|
269
|
+
Request watcher filters can also be scoped per method. Matching is contains-based against the stored trace content, so values like `report`, `auth`, or `trace` match any request or entry whose content includes those fragments.
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
const config = TraceConfig.merge({
|
|
273
|
+
watchers: {
|
|
274
|
+
request: {
|
|
275
|
+
get: { exclude: ['report'] },
|
|
276
|
+
post: { include: ['auth'] },
|
|
277
|
+
patch: { include: ['profile'] },
|
|
278
|
+
},
|
|
279
|
+
log: { exclude: ['healthcheck'] },
|
|
280
|
+
exception: { include: ['trace'] },
|
|
281
|
+
cache: { include: ['session:'] },
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
```
|
|
199
285
|
|
|
200
286
|
---
|
|
201
287
|
|
|
@@ -275,7 +361,7 @@ import {
|
|
|
275
361
|
## Security considerations
|
|
276
362
|
|
|
277
363
|
- **Always** protect the dashboard with middleware (e.g. `middleware: ['admin']`). `@zintrust/trace/ui` exports `registerTraceDashboard(...)` and `registerTraceRoutes(...)`, and neither applies any authentication by default.
|
|
278
|
-
- Sensitive fields
|
|
364
|
+
- Sensitive fields are redacted using the `redaction` config before they are stored. Review and extend the default `redaction.keys`, `redaction.headers`, `redaction.body`, and `redaction.query` lists to match your application's data model.
|
|
279
365
|
- Use a **dedicated database connection** (`TRACE_DB_CONNECTION`) in production so trace writes cannot impact your primary DB connection pool.
|
|
280
366
|
- Keep `TRACE_ENABLED=false` (or unset) in production unless actively investigating an issue.
|
|
281
367
|
|
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.77",
|
|
4
|
+
"buildDate": "2026-04-08T09:26:55.306Z",
|
|
5
5
|
"buildEnvironment": {
|
|
6
|
-
"node": "
|
|
6
|
+
"node": "v22.22.1",
|
|
7
7
|
"platform": "darwin",
|
|
8
8
|
"arch": "arm64"
|
|
9
9
|
},
|
|
10
10
|
"git": {
|
|
11
|
-
"commit": "
|
|
11
|
+
"commit": "f37a0c05",
|
|
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": 14438,
|
|
26
|
+
"sha256": "967934d372f36722143e02cd66b98dae1904122d34754fa8267bf3133725e1b2"
|
|
27
27
|
},
|
|
28
28
|
"cli-register.d.ts": {
|
|
29
29
|
"size": 255,
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
"sha256": "c6de87d0a73df7ac66e18ecdc6f758b2652ec3abe9698e43620cf41135b33e4b"
|
|
35
35
|
},
|
|
36
36
|
"config.d.ts": {
|
|
37
|
-
"size":
|
|
38
|
-
"sha256": "
|
|
37
|
+
"size": 470,
|
|
38
|
+
"sha256": "b034cbef0c71fb868071363624ef7a9f8d7acc20f8be8c895dd5db5a75e81f37"
|
|
39
39
|
},
|
|
40
40
|
"config.js": {
|
|
41
|
-
"size":
|
|
42
|
-
"sha256": "
|
|
41
|
+
"size": 5862,
|
|
42
|
+
"sha256": "2692029ea79d7454f920fcdd6466cd6ee443a7029f36597a213585ed869f9af7"
|
|
43
43
|
},
|
|
44
44
|
"context.d.ts": {
|
|
45
45
|
"size": 596,
|
|
@@ -70,24 +70,24 @@
|
|
|
70
70
|
"sha256": "4862b41e0477f01afa0dbb446d4553b65c22ed774cd1e2db3489059ced392f94"
|
|
71
71
|
},
|
|
72
72
|
"dashboard/ui.js": {
|
|
73
|
-
"size":
|
|
74
|
-
"sha256": "
|
|
73
|
+
"size": 64493,
|
|
74
|
+
"sha256": "061c304bad22631db4ad795457c0eb5064f060f534d5050e2e14c6a1c01a2c1b"
|
|
75
75
|
},
|
|
76
76
|
"index.d.ts": {
|
|
77
|
-
"size":
|
|
78
|
-
"sha256": "
|
|
77
|
+
"size": 2370,
|
|
78
|
+
"sha256": "4cfee97f40d9dd12f5ea37996bee548a5964ee2cbe45c4e844bf5a119d9470d3"
|
|
79
79
|
},
|
|
80
80
|
"index.js": {
|
|
81
|
-
"size":
|
|
82
|
-
"sha256": "
|
|
81
|
+
"size": 3237,
|
|
82
|
+
"sha256": "d610de7775e31196a8acca02425c407e64bfdb69977290443664d36eaa022426"
|
|
83
83
|
},
|
|
84
84
|
"migrations/20260331000001_create_zin_trace_entries_table.d.ts": {
|
|
85
85
|
"size": 304,
|
|
86
86
|
"sha256": "7d99b4d7c02855d6e68ad87e39dffff5fec83a406bdf2414665c23ba3ce8711d"
|
|
87
87
|
},
|
|
88
88
|
"migrations/20260331000001_create_zin_trace_entries_table.js": {
|
|
89
|
-
"size":
|
|
90
|
-
"sha256": "
|
|
89
|
+
"size": 955,
|
|
90
|
+
"sha256": "6aa54f3a6a95a78714e9b14d7f6adb4e94e9420e4e17ac467b43fef12bbc2583"
|
|
91
91
|
},
|
|
92
92
|
"migrations/20260331000002_create_zin_trace_entries_tags_table.d.ts": {
|
|
93
93
|
"size": 304,
|
|
@@ -105,13 +105,21 @@
|
|
|
105
105
|
"size": 522,
|
|
106
106
|
"sha256": "dd80ea1fdfe6ea7f57330b2dff530d97ee8054081436f41bbf234b814cb1df19"
|
|
107
107
|
},
|
|
108
|
+
"migrations/20260407193000_widen_trace_created_at_for_sql.d.ts": {
|
|
109
|
+
"size": 335,
|
|
110
|
+
"sha256": "6e9c826a08a983927d9e801b2740f58d0cf6fbf7bff02ee5c1fd01227f73b741"
|
|
111
|
+
},
|
|
112
|
+
"migrations/20260407193000_widen_trace_created_at_for_sql.js": {
|
|
113
|
+
"size": 1185,
|
|
114
|
+
"sha256": "1de9d8e4a91ffeaed4a0bc5cf942e428cd76bdb6b65bc67fa76ef62f3c99e94d"
|
|
115
|
+
},
|
|
108
116
|
"migrations/index.d.ts": {
|
|
109
117
|
"size": 280,
|
|
110
118
|
"sha256": "0ba7bc9421754ff489f6947463c13e7e9c80558eb6611a818f3baab3b518a502"
|
|
111
119
|
},
|
|
112
120
|
"migrations/index.js": {
|
|
113
|
-
"size":
|
|
114
|
-
"sha256": "
|
|
121
|
+
"size": 500,
|
|
122
|
+
"sha256": "6118c5f4e01ecd73208425253caa3a17e4304ff6f9f00ac7afc18785684e9e85"
|
|
115
123
|
},
|
|
116
124
|
"plugin.d.ts": {
|
|
117
125
|
"size": 16,
|
|
@@ -126,8 +134,8 @@
|
|
|
126
134
|
"sha256": "71d366165dd36f1675aa253a76262b226fb6c62e5ab632746b8aea61c0c625fc"
|
|
127
135
|
},
|
|
128
136
|
"register.js": {
|
|
129
|
-
"size":
|
|
130
|
-
"sha256": "
|
|
137
|
+
"size": 10601,
|
|
138
|
+
"sha256": "4e25cf1a5206578c0c1ad77febc258215d97d0468facc51d01a9259c0634757d"
|
|
131
139
|
},
|
|
132
140
|
"storage/DebuggerStorage.d.ts": {
|
|
133
141
|
"size": 517,
|
|
@@ -137,13 +145,37 @@
|
|
|
137
145
|
"size": 7442,
|
|
138
146
|
"sha256": "5ecce0fcfcf695df587a7b90a7a5c7efd2e64ad13c9f2d104b392f89f34f0dc4"
|
|
139
147
|
},
|
|
148
|
+
"storage/TraceContentRedaction.d.ts": {
|
|
149
|
+
"size": 207,
|
|
150
|
+
"sha256": "2fd7b317c5ee87d8ecaa6467a75959499673ef374fec3ecfaa7911c4f3d5c83c"
|
|
151
|
+
},
|
|
152
|
+
"storage/TraceContentRedaction.js": {
|
|
153
|
+
"size": 1083,
|
|
154
|
+
"sha256": "127aa026f155c47361d3b44021138157cb2743f5e02e044ce6df66cc693cc3cb"
|
|
155
|
+
},
|
|
156
|
+
"storage/TraceEntryFiltering.d.ts": {
|
|
157
|
+
"size": 196,
|
|
158
|
+
"sha256": "a1158cedb4e4e749658127086e138e47886422366a697619d6ea9bd3338066e6"
|
|
159
|
+
},
|
|
160
|
+
"storage/TraceEntryFiltering.js": {
|
|
161
|
+
"size": 422,
|
|
162
|
+
"sha256": "f9174cf9d4d09785c7c71930ded64b12e12a6e5765c8d1462cd3ecb9669f6b58"
|
|
163
|
+
},
|
|
140
164
|
"storage/TraceStorage.d.ts": {
|
|
141
165
|
"size": 517,
|
|
142
166
|
"sha256": "c9c215aaa414f7b0c1fec6c82b054fc52bdf97af58f96f35c7f96672fb859c31"
|
|
143
167
|
},
|
|
144
168
|
"storage/TraceStorage.js": {
|
|
145
|
-
"size":
|
|
146
|
-
"sha256": "
|
|
169
|
+
"size": 9089,
|
|
170
|
+
"sha256": "e4e05dc45411f0b7f0deacd9567d2b83325566cb69b885ebec848bcfcc43b338"
|
|
171
|
+
},
|
|
172
|
+
"storage/TraceWriteDiagnostics.d.ts": {
|
|
173
|
+
"size": 581,
|
|
174
|
+
"sha256": "5f49df97a830ad895653fa4a18b3a1b31ca4a5066d6f8150ee02dca013e16397"
|
|
175
|
+
},
|
|
176
|
+
"storage/TraceWriteDiagnostics.js": {
|
|
177
|
+
"size": 4162,
|
|
178
|
+
"sha256": "06ba6979f5053956f7a5f9ec8dc301864f36276a2c74b0bf63cf733ad7c5eac2"
|
|
147
179
|
},
|
|
148
180
|
"storage/index.d.ts": {
|
|
149
181
|
"size": 100,
|
|
@@ -154,8 +186,8 @@
|
|
|
154
186
|
"sha256": "d916e8e3abb1b1087f6b184851b0e6265e53380d7857b008e745d566aad15d44"
|
|
155
187
|
},
|
|
156
188
|
"types.d.ts": {
|
|
157
|
-
"size":
|
|
158
|
-
"sha256": "
|
|
189
|
+
"size": 7687,
|
|
190
|
+
"sha256": "c1c5f5140d157d66355c65c774f055af2dccc470c9ee9fe403bbb96fbf4447d0"
|
|
159
191
|
},
|
|
160
192
|
"types.js": {
|
|
161
193
|
"size": 696,
|
|
@@ -177,6 +209,14 @@
|
|
|
177
209
|
"size": 534,
|
|
178
210
|
"sha256": "0c506812967c17548162ce0f28d96089b023865883ee8cfd0824a94084580afb"
|
|
179
211
|
},
|
|
212
|
+
"utils/entryFilter.d.ts": {
|
|
213
|
+
"size": 183,
|
|
214
|
+
"sha256": "a7809e98f76b4e326262c26b0e43e278b1c50ac0b35fee145e3e6006357dc700"
|
|
215
|
+
},
|
|
216
|
+
"utils/entryFilter.js": {
|
|
217
|
+
"size": 3279,
|
|
218
|
+
"sha256": "0ce8c5955411194447a16bd79c2f0a33ba60f63b2bd010ac33772718f02f0124"
|
|
219
|
+
},
|
|
180
220
|
"utils/familyHash.d.ts": {
|
|
181
221
|
"size": 60,
|
|
182
222
|
"sha256": "c94f85390c52470df6946a39576c720ea92c89797ae62fff913191c45580248f"
|
|
@@ -186,12 +226,12 @@
|
|
|
186
226
|
"sha256": "f60526423e69fa5c461b0f5d8dac90b1f0c18149609cd1109226f1c8d985f223"
|
|
187
227
|
},
|
|
188
228
|
"utils/redact.d.ts": {
|
|
189
|
-
"size":
|
|
190
|
-
"sha256": "
|
|
229
|
+
"size": 449,
|
|
230
|
+
"sha256": "b72d01ebac46a984d314905b14de5b05c3f9c27141e460c5305dd16e347f5a13"
|
|
191
231
|
},
|
|
192
232
|
"utils/redact.js": {
|
|
193
|
-
"size":
|
|
194
|
-
"sha256": "
|
|
233
|
+
"size": 2646,
|
|
234
|
+
"sha256": "4e82eaa3bb48f9d621b70f69519b0615d992068eb9f836beaf6df6c2382c2cff"
|
|
195
235
|
},
|
|
196
236
|
"utils/requestFilter.d.ts": {
|
|
197
237
|
"size": 195,
|
|
@@ -238,8 +278,8 @@
|
|
|
238
278
|
"sha256": "f1b3a3253e7265c7b56a74ba674cd23426ea5227a33abb1bde0d941e2a02e894"
|
|
239
279
|
},
|
|
240
280
|
"watchers/CommandWatcher.js": {
|
|
241
|
-
"size":
|
|
242
|
-
"sha256": "
|
|
281
|
+
"size": 1442,
|
|
282
|
+
"sha256": "5e4ae33bf9088b60c3999580b9d4662162a319cc51fb80ee07da7571f6d98863"
|
|
243
283
|
},
|
|
244
284
|
"watchers/DumpWatcher.d.ts": {
|
|
245
285
|
"size": 308,
|
|
@@ -278,16 +318,16 @@
|
|
|
278
318
|
"sha256": "1b48661bff79b2f72464c978ad7e6dcf011197ca4a3014e64e99b70437b3e5a1"
|
|
279
319
|
},
|
|
280
320
|
"watchers/HttpClientWatcher.js": {
|
|
281
|
-
"size":
|
|
282
|
-
"sha256": "
|
|
321
|
+
"size": 1627,
|
|
322
|
+
"sha256": "65e910145f4d24f06643a847a1d75bc60034a629a5da61097ba9324d1d1c7ddd"
|
|
283
323
|
},
|
|
284
324
|
"watchers/HttpWatcher.d.ts": {
|
|
285
325
|
"size": 96,
|
|
286
326
|
"sha256": "ce9a95a670f755193fd74ce721dbfa4b30f20c879a6566ebb35229b3b2435429"
|
|
287
327
|
},
|
|
288
328
|
"watchers/HttpWatcher.js": {
|
|
289
|
-
"size":
|
|
290
|
-
"sha256": "
|
|
329
|
+
"size": 5557,
|
|
330
|
+
"sha256": "9f86966178485e2aab46ce03785c7c512feb641dbf5d0dda22d51f3f259d374e"
|
|
291
331
|
},
|
|
292
332
|
"watchers/JobWatcher.d.ts": {
|
|
293
333
|
"size": 441,
|
|
@@ -302,8 +342,8 @@
|
|
|
302
342
|
"sha256": "f3ddc5f8b58c6c86ac6b464dd48e5a55e79ab2bf2e735feacffc7480e4ccc0c4"
|
|
303
343
|
},
|
|
304
344
|
"watchers/LogWatcher.js": {
|
|
305
|
-
"size":
|
|
306
|
-
"sha256": "
|
|
345
|
+
"size": 1768,
|
|
346
|
+
"sha256": "a7e769d504d5528068e9349f28d703606d21404d3976f7cdb131cee417420ff6"
|
|
307
347
|
},
|
|
308
348
|
"watchers/MailWatcher.d.ts": {
|
|
309
349
|
"size": 214,
|
package/dist/config.d.ts
CHANGED
|
@@ -5,5 +5,6 @@ import type { ITraceConfig, TraceConfigOverrides } from './types';
|
|
|
5
5
|
export declare const TraceConfig: Readonly<{
|
|
6
6
|
defaults(): ITraceConfig;
|
|
7
7
|
merge(overrides?: TraceConfigOverrides): ITraceConfig;
|
|
8
|
+
getRedactionFields: (config: ITraceConfig, key: keyof ITraceConfig["redaction"]) => string[];
|
|
8
9
|
isWatcherEnabled: (config: ITraceConfig, key: keyof ITraceConfig["watchers"]) => boolean;
|
|
9
10
|
}>;
|
package/dist/config.js
CHANGED
|
@@ -1,3 +1,78 @@
|
|
|
1
|
+
const mergeStringLists = (base, override) => {
|
|
2
|
+
const merged = new Set();
|
|
3
|
+
for (const value of [...base, ...(override ?? [])]) {
|
|
4
|
+
if (typeof value !== 'string')
|
|
5
|
+
continue;
|
|
6
|
+
const normalized = value.trim();
|
|
7
|
+
if (normalized !== '')
|
|
8
|
+
merged.add(normalized);
|
|
9
|
+
}
|
|
10
|
+
return [...merged];
|
|
11
|
+
};
|
|
12
|
+
const isObjectValue = (value) => {
|
|
13
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
14
|
+
};
|
|
15
|
+
const mergeFilterRule = (base, override) => {
|
|
16
|
+
const include = mergeStringLists(base?.include ?? [], override?.include);
|
|
17
|
+
const exclude = mergeStringLists(base?.exclude ?? [], override?.exclude);
|
|
18
|
+
if (include.length === 0 && exclude.length === 0)
|
|
19
|
+
return undefined;
|
|
20
|
+
return Object.freeze({
|
|
21
|
+
...(include.length > 0 ? { include } : {}),
|
|
22
|
+
...(exclude.length > 0 ? { exclude } : {}),
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
const mergeWatcherToggle = (base, override) => {
|
|
26
|
+
if (override === undefined)
|
|
27
|
+
return base;
|
|
28
|
+
if (override === false || override === true)
|
|
29
|
+
return override;
|
|
30
|
+
const baseRule = isObjectValue(base) ? base : undefined;
|
|
31
|
+
return mergeFilterRule(baseRule, override);
|
|
32
|
+
};
|
|
33
|
+
const REQUEST_METHOD_KEYS = ['all', 'get', 'post', 'put', 'patch', 'delete'];
|
|
34
|
+
const mergeRequestWatcherToggle = (base, override) => {
|
|
35
|
+
if (override === undefined)
|
|
36
|
+
return base;
|
|
37
|
+
if (override === false || override === true)
|
|
38
|
+
return override;
|
|
39
|
+
const baseConfig = isObjectValue(base) ? base : undefined;
|
|
40
|
+
const merged = mergeFilterRule(baseConfig, override) ?? {};
|
|
41
|
+
for (const key of REQUEST_METHOD_KEYS) {
|
|
42
|
+
const rule = mergeFilterRule(baseConfig?.[key], override[key]);
|
|
43
|
+
if (rule !== undefined)
|
|
44
|
+
merged[key] = rule;
|
|
45
|
+
}
|
|
46
|
+
return merged;
|
|
47
|
+
};
|
|
48
|
+
const mergeWatchers = (base, override) => {
|
|
49
|
+
if (override === undefined)
|
|
50
|
+
return { ...base };
|
|
51
|
+
return {
|
|
52
|
+
...base,
|
|
53
|
+
...override,
|
|
54
|
+
request: mergeRequestWatcherToggle(base.request, override.request),
|
|
55
|
+
query: mergeWatcherToggle(base.query, override.query),
|
|
56
|
+
exception: mergeWatcherToggle(base.exception, override.exception),
|
|
57
|
+
log: mergeWatcherToggle(base.log, override.log),
|
|
58
|
+
job: mergeWatcherToggle(base.job, override.job),
|
|
59
|
+
cache: mergeWatcherToggle(base.cache, override.cache),
|
|
60
|
+
schedule: mergeWatcherToggle(base.schedule, override.schedule),
|
|
61
|
+
mail: mergeWatcherToggle(base.mail, override.mail),
|
|
62
|
+
auth: mergeWatcherToggle(base.auth, override.auth),
|
|
63
|
+
event: mergeWatcherToggle(base.event, override.event),
|
|
64
|
+
model: mergeWatcherToggle(base.model, override.model),
|
|
65
|
+
notification: mergeWatcherToggle(base.notification, override.notification),
|
|
66
|
+
redis: mergeWatcherToggle(base.redis, override.redis),
|
|
67
|
+
gate: mergeWatcherToggle(base.gate, override.gate),
|
|
68
|
+
middleware: mergeWatcherToggle(base.middleware, override.middleware),
|
|
69
|
+
command: mergeWatcherToggle(base.command, override.command),
|
|
70
|
+
batch: mergeWatcherToggle(base.batch, override.batch),
|
|
71
|
+
dump: mergeWatcherToggle(base.dump, override.dump),
|
|
72
|
+
view: mergeWatcherToggle(base.view, override.view),
|
|
73
|
+
clientRequest: mergeWatcherToggle(base.clientRequest, override.clientRequest),
|
|
74
|
+
};
|
|
75
|
+
};
|
|
1
76
|
const DEFAULTS = Object.freeze({
|
|
2
77
|
enabled: false,
|
|
3
78
|
connection: undefined,
|
|
@@ -7,6 +82,37 @@ const DEFAULTS = Object.freeze({
|
|
|
7
82
|
logMinLevel: 'info',
|
|
8
83
|
watchers: {},
|
|
9
84
|
redaction: {
|
|
85
|
+
keys: [
|
|
86
|
+
'password',
|
|
87
|
+
'pass',
|
|
88
|
+
'passwd',
|
|
89
|
+
'token',
|
|
90
|
+
'accessToken',
|
|
91
|
+
'access_token',
|
|
92
|
+
'refreshToken',
|
|
93
|
+
'refresh_token',
|
|
94
|
+
'secret',
|
|
95
|
+
'secretKey',
|
|
96
|
+
'secret_key',
|
|
97
|
+
'apiKey',
|
|
98
|
+
'api_key',
|
|
99
|
+
'auth',
|
|
100
|
+
'authToken',
|
|
101
|
+
'auth_token',
|
|
102
|
+
'authorization',
|
|
103
|
+
'cookie',
|
|
104
|
+
'session',
|
|
105
|
+
'sessionId',
|
|
106
|
+
'session_id',
|
|
107
|
+
'card',
|
|
108
|
+
'cardNumber',
|
|
109
|
+
'card_number',
|
|
110
|
+
'cardToken',
|
|
111
|
+
'card_token',
|
|
112
|
+
'cvv',
|
|
113
|
+
'cvc',
|
|
114
|
+
'pan',
|
|
115
|
+
],
|
|
10
116
|
headers: ['authorization', 'cookie', 'x-api-key', 'x-auth-token'],
|
|
11
117
|
body: ['password', 'token', 'secret', 'apiKey', 'api_key', 'jwt', 'bearer'],
|
|
12
118
|
query: [],
|
|
@@ -14,7 +120,17 @@ const DEFAULTS = Object.freeze({
|
|
|
14
120
|
});
|
|
15
121
|
const isWatcherEnabled = (config, key) => {
|
|
16
122
|
const override = config.watchers[key];
|
|
17
|
-
|
|
123
|
+
if (override === false)
|
|
124
|
+
return false;
|
|
125
|
+
if (isObjectValue(override) && override.enabled === false)
|
|
126
|
+
return false;
|
|
127
|
+
return true; // undefined = enabled by default; explicit false = disabled
|
|
128
|
+
};
|
|
129
|
+
const getRedactionFields = (config, key) => {
|
|
130
|
+
if (key === 'keys') {
|
|
131
|
+
return mergeStringLists([], config.redaction.keys);
|
|
132
|
+
}
|
|
133
|
+
return mergeStringLists(config.redaction.keys, config.redaction[key]);
|
|
18
134
|
};
|
|
19
135
|
export const TraceConfig = Object.freeze({
|
|
20
136
|
defaults() {
|
|
@@ -26,13 +142,16 @@ export const TraceConfig = Object.freeze({
|
|
|
26
142
|
return Object.freeze({
|
|
27
143
|
...DEFAULTS,
|
|
28
144
|
...overrides,
|
|
29
|
-
watchers:
|
|
145
|
+
watchers: mergeWatchers(DEFAULTS.watchers, overrides.watchers),
|
|
30
146
|
redaction: {
|
|
31
|
-
|
|
32
|
-
|
|
147
|
+
keys: mergeStringLists(DEFAULTS.redaction.keys, overrides.redaction?.keys),
|
|
148
|
+
headers: mergeStringLists(DEFAULTS.redaction.headers, overrides.redaction?.headers),
|
|
149
|
+
body: mergeStringLists(DEFAULTS.redaction.body, overrides.redaction?.body),
|
|
150
|
+
query: mergeStringLists(DEFAULTS.redaction.query, overrides.redaction?.query),
|
|
33
151
|
},
|
|
34
152
|
ignoreRoutes: overrides.ignoreRoutes ?? DEFAULTS.ignoreRoutes,
|
|
35
153
|
});
|
|
36
154
|
},
|
|
155
|
+
getRedactionFields,
|
|
37
156
|
isWatcherEnabled,
|
|
38
157
|
});
|