@zintrust/trace 0.5.4 → 0.5.7
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/config.js +2 -0
- package/dist/dashboard/ui.js +4 -4
- package/dist/storage/TraceContentBudget.js +47 -85
- package/dist/types.d.ts +1 -0
- package/dist/utils/requestFilter.d.ts +7 -2
- package/dist/utils/requestFilter.js +30 -4
- package/dist/watchers/AuthWatcher.js +4 -1
- package/dist/watchers/BatchWatcher.js +4 -1
- package/dist/watchers/CacheWatcher.js +4 -1
- package/dist/watchers/CommandWatcher.js +4 -1
- package/dist/watchers/DumpWatcher.js +4 -1
- package/dist/watchers/EventWatcher.js +4 -1
- package/dist/watchers/ExceptionWatcher.js +5 -2
- package/dist/watchers/GateWatcher.js +4 -1
- package/dist/watchers/HttpClientWatcher.js +4 -1
- package/dist/watchers/HttpWatcher.js +1 -1
- package/dist/watchers/JobWatcher.js +4 -1
- package/dist/watchers/LogWatcher.js +1 -1
- package/dist/watchers/MailWatcher.js +4 -1
- package/dist/watchers/MiddlewareWatcher.js +4 -1
- package/dist/watchers/ModelWatcher.js +4 -1
- package/dist/watchers/NotificationWatcher.js +4 -1
- package/dist/watchers/QueryWatcher.js +1 -1
- package/dist/watchers/RedisWatcher.js +4 -1
- package/dist/watchers/ScheduleWatcher.js +4 -1
- package/dist/watchers/ViewWatcher.js +4 -1
- package/package.json +2 -2
- package/src/config.ts +2 -0
- package/src/dashboard/ui.ts +4 -4
- package/src/storage/TraceContentBudget.ts +57 -118
- package/src/types.ts +1 -0
- package/src/utils/requestFilter.ts +57 -11
- package/src/watchers/AuthWatcher.ts +4 -1
- package/src/watchers/BatchWatcher.ts +4 -1
- package/src/watchers/CacheWatcher.ts +4 -1
- package/src/watchers/CommandWatcher.ts +4 -1
- package/src/watchers/DumpWatcher.ts +4 -1
- package/src/watchers/EventWatcher.ts +4 -1
- package/src/watchers/ExceptionWatcher.ts +5 -2
- package/src/watchers/GateWatcher.ts +4 -1
- package/src/watchers/HttpClientWatcher.ts +4 -1
- package/src/watchers/HttpWatcher.ts +1 -1
- package/src/watchers/JobWatcher.ts +4 -1
- package/src/watchers/LogWatcher.ts +2 -1
- package/src/watchers/MailWatcher.ts +4 -1
- package/src/watchers/MiddlewareWatcher.ts +4 -1
- package/src/watchers/ModelWatcher.ts +4 -1
- package/src/watchers/NotificationWatcher.ts +4 -1
- package/src/watchers/QueryWatcher.ts +1 -1
- package/src/watchers/RedisWatcher.ts +4 -1
- package/src/watchers/ScheduleWatcher.ts +4 -1
- package/src/watchers/ViewWatcher.ts +4 -1
package/dist/config.js
CHANGED
|
@@ -169,6 +169,7 @@ const DEFAULTS = Object.freeze({
|
|
|
169
169
|
observeConnection: undefined,
|
|
170
170
|
pruneAfterHours: 24,
|
|
171
171
|
ignoreRoutes: ['/trace', '/health', '/ping'],
|
|
172
|
+
ignorePath: [],
|
|
172
173
|
slowQueryThreshold: 100,
|
|
173
174
|
captureCachePayloads: false,
|
|
174
175
|
captureQueryBindings: true,
|
|
@@ -255,6 +256,7 @@ export const TraceConfig = Object.freeze({
|
|
|
255
256
|
query: mergeStringLists(DEFAULTS.redaction.query, overrides.redaction?.query),
|
|
256
257
|
},
|
|
257
258
|
ignoreRoutes: overrides.ignoreRoutes ?? DEFAULTS.ignoreRoutes,
|
|
259
|
+
ignorePath: overrides.ignorePath ?? DEFAULTS.ignorePath,
|
|
258
260
|
});
|
|
259
261
|
},
|
|
260
262
|
getRedactionFields,
|
package/dist/dashboard/ui.js
CHANGED
|
@@ -70,13 +70,13 @@ const DASHBOARD_DOCUMENT = String.raw `<!DOCTYPE html>
|
|
|
70
70
|
.main{padding:28px;min-width:0}.shell{max-width:1320px;margin:0 auto;display:grid;gap:18px}
|
|
71
71
|
.panel{border-radius:var(--radius);border:1px solid var(--line);background:var(--surface);box-shadow:var(--shadow);backdrop-filter:blur(16px)}.stats-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:16px;margin-bottom:18px}.stat-card{padding:20px;position:relative;overflow:hidden}.stat-card::after{content:'';position:absolute;right:-18px;bottom:-26px;width:92px;height:92px;border-radius:28px;background:linear-gradient(135deg,rgba(56,189,248,.16),rgba(34,197,94,.08));transform:rotate(18deg)}.stat-label{font-size:.74rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:800;margin-bottom:12px}.stat-value{font-size:2.25rem;font-weight:800;line-height:1}.stat-meta{margin-top:10px;color:var(--muted);font-size:.9rem}.content-grid{display:grid;grid-template-columns:minmax(0,1.65fr) minmax(320px,.95fr);gap:18px}.side-stack{display:grid;gap:18px}
|
|
72
72
|
.section-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;padding:22px 24px 16px}.section-head h3{margin:0;font-size:1.04rem}.section-head p{margin:6px 0 0;color:var(--muted);font-size:.92rem}.toolbar{display:flex;flex-wrap:wrap;gap:10px;padding:0 24px 18px}.control,.toolbar input,.toolbar select{height:44px;border-radius:13px;border:1px solid var(--line);background:var(--surface-strong);color:var(--text);padding:0 14px;min-width:0}.toolbar input,.toolbar select{flex:1 1 180px}.toolbar input::placeholder{color:var(--muted)}.btn{height:44px;border:none;border-radius:13px;padding:0 16px;cursor:pointer;font-weight:800}.btn-primary{background:linear-gradient(135deg,var(--accent-strong),var(--accent));color:#fff}.btn-danger{background:rgba(239,68,68,.12);color:var(--danger);border:1px solid rgba(239,68,68,.18)}.btn-ghost{background:var(--surface-soft);color:var(--text);border:1px solid var(--line)}
|
|
73
|
-
.table-wrap{overflow:auto;padding:0 12px 12px}table{width:100%;border-collapse:separate;border-spacing:0;min-width:880px}th{padding:14px;color:var(--muted);font-size:.74rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;text-align:left;border-bottom:1px solid var(--line)}td{padding:15px 14px;border-bottom:1px solid var(--line);vertical-align:top}.row-button{cursor:pointer}.row-button:hover td{background:rgba(56,189,248,.05)}.summary{font-size:.93rem;font-weight:700;line-height:1.4;color:var(--text)}.summary-sub{margin-top:6px;color:var(--muted);font-size:.82rem;line-height:1.4}.mono{font-family:var(--mono)}.empty{padding:44px 24px;color:var(--muted);line-height:1.65;text-align:center}.pagination{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 24px 24px;color:var(--muted);flex-wrap:wrap}.pagination-controls{display:flex;gap:8px}.pagination button{height:40px;min-width:92px;padding:0 14px;border-radius:12px;border:1px solid var(--line);background:var(--surface-strong);color:var(--text);cursor:pointer}.pagination button:disabled{opacity:.45;cursor:not-allowed}
|
|
73
|
+
.table-wrap{overflow:auto;padding:0 12px 12px}.table-wrap table{width:100%;border-collapse:separate;border-spacing:0;min-width:880px}th{padding:14px;color:var(--muted);font-size:.74rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;text-align:left;border-bottom:1px solid var(--line)}td{padding:15px 14px;border-bottom:1px solid var(--line);vertical-align:top}.row-button{cursor:pointer}.row-button:hover td{background:rgba(56,189,248,.05)}.summary{font-size:.93rem;font-weight:700;line-height:1.4;color:var(--text)}.summary-sub{margin-top:6px;color:var(--muted);font-size:.82rem;line-height:1.4}.mono{font-family:var(--mono)}.empty{padding:44px 24px;color:var(--muted);line-height:1.65;text-align:center}.pagination{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 24px 24px;color:var(--muted);flex-wrap:wrap}.pagination-controls{display:flex;gap:8px}.pagination button{height:40px;min-width:92px;padding:0 14px;border-radius:12px;border:1px solid var(--line);background:var(--surface-strong);color:var(--text);cursor:pointer}.pagination button:disabled{opacity:.45;cursor:not-allowed}
|
|
74
74
|
.activity-list{list-style:none;margin:0;padding:0 24px 24px}.activity-item{padding:14px 0;border-top:1px solid var(--line)}.activity-item:first-child{border-top:none}.activity-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.activity-time{color:var(--muted);font-size:.85rem}.activity-summary{margin-top:8px;color:var(--text);line-height:1.48}.back-link{display:inline-flex;align-items:center;gap:8px;margin:0 0 14px;color:var(--accent);font-weight:800;cursor:pointer}.detail-card{padding:24px}.detail-meta{display:flex;flex-wrap:wrap;gap:10px;margin:14px 0 20px;color:var(--muted);font-size:.9rem;overflow-wrap:anywhere}.detail-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px}.detail-stack{display:grid;gap:16px;margin-top:18px}.detail-box{padding:16px;border-radius:16px;background:var(--surface-soft);border:1px solid var(--line)}.detail-box h4{margin:0 0 10px;font-size:.92rem}.detail-box dl{margin:0;display:grid;gap:8px}.detail-box dt{font-size:.76rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:800}.detail-box dd{margin:0;color:var(--text);line-height:1.45;overflow-wrap:anywhere}.trace-tabs{display:flex;gap:10px;flex-wrap:wrap;margin:20px 0 16px}.trace-tab{border:none;border-radius:12px;padding:10px 12px;background:transparent;color:var(--muted);cursor:pointer;box-shadow:inset 0 0 0 1px var(--line);font-weight:800}.trace-tab.active{background:rgba(56,189,248,.12);color:var(--text);box-shadow:inset 0 0 0 1px rgba(56,189,248,.28)}.trace-panel{display:grid;gap:14px}.trace-item{padding:18px;border-radius:16px;background:var(--surface-soft);border:1px solid var(--line)}.trace-item-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.trace-item-summary{margin-top:10px;display:grid;gap:10px}.trace-note{color:var(--muted);line-height:1.6}.trace-disclosure{padding:0;overflow:hidden}.trace-disclosure[open]{padding-bottom:18px}.trace-disclosure .trace-item-summary{margin-top:0}.trace-disclosure-body{display:grid;gap:12px;padding:0 18px}.trace-summary{list-style:none;cursor:pointer;padding:18px}.trace-summary::-webkit-details-marker{display:none}.trace-summary-main{display:grid;gap:10px;min-width:0;flex:1}.trace-summary-copy{display:grid;gap:6px;min-width:0}.trace-summary-copy .summary,.trace-summary-copy .summary-sub{display:block;overflow-wrap:anywhere}.trace-disclosure-body .summary-sub{overflow-wrap:anywhere}
|
|
75
75
|
.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}
|
|
76
76
|
.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}
|
|
77
77
|
.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}
|
|
78
78
|
.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.wrap{white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word}.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}.inline-collapse{margin:0;border-top:1px solid var(--line);background:var(--surface-strong)}.inline-collapse summary{cursor:pointer;list-style:none;padding:14px 16px;font-size:.82rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:800}.inline-collapse summary::-webkit-details-marker{display:none}.inline-collapse[open] summary{border-bottom:1px solid var(--line)}.inline-collapse .code-block{border-top:none}.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}
|
|
79
|
-
@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,.
|
|
79
|
+
@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:760px){.main{padding:16px}.shell{gap:14px}.stat-value{font-size:1.9rem}.section-head{flex-direction:column;align-items:stretch}.section-head .btn{width:100%}.toolbar{display:grid;grid-template-columns:1fr;padding-left:18px;padding-right:18px}.toolbar .btn,.toolbar input,.toolbar select{width:100%;flex:none}.pagination{padding-left:18px;padding-right:18px}.pagination,.pagination-controls{width:100%}.pagination-controls{justify-content:space-between}.pagination button{flex:1 1 0}.detail-meta{display:grid;gap:8px}.trace-tabs{flex-wrap:nowrap;overflow:auto;padding-bottom:4px}.trace-tab{white-space:nowrap}.code-toolbar{flex-wrap:wrap}.copy-button{width:100%}.html-preview{min-height:220px}.table-wrap{padding:0 14px 14px;overflow:visible}.table-wrap table{min-width:0;border-spacing:0}.table-wrap thead{display:none}.table-wrap tbody{display:grid;gap:12px}.table-wrap tr{display:block;border:1px solid var(--line);border-radius:16px;background:var(--surface-soft);overflow:hidden}.table-wrap td{display:grid;grid-template-columns:minmax(84px,108px) minmax(0,1fr);gap:10px;align-items:start;padding:12px 14px;border-bottom:1px solid var(--line)}.table-wrap td::before{content:attr(data-label);font-size:.72rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}.table-wrap td:last-child{border-bottom:none}.table-wrap td[data-label='Summary'],.table-wrap td[data-label='Tags']{grid-template-columns:1fr}.table-wrap td[data-label='Summary']::before,.table-wrap td[data-label='Tags']::before{margin-bottom:2px}.row-button:hover td{background:transparent}.row-button:hover{box-shadow:inset 0 0 0 1px rgba(56,189,248,.18)}}@media (max-width:640px){.stats-grid{grid-template-columns:1fr}.detail-card{padding:18px}.toolbar,.section-head,.activity-list,.monitoring-wrap{padding-left:18px;padding-right:18px}.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}}
|
|
80
80
|
</style>
|
|
81
81
|
</head>
|
|
82
82
|
<body>
|
|
@@ -839,7 +839,7 @@ const DASHBOARD_DOCUMENT = String.raw `<!DOCTYPE html>
|
|
|
839
839
|
const recentRows = recent.data || [];
|
|
840
840
|
const recentTable = recentRows.length === 0
|
|
841
841
|
? '<div class="empty">No trace entries recorded.</div>'
|
|
842
|
-
: '<div class="table-wrap"><table><thead><tr><th>Type</th><th>Summary</th><th>Tags</th><th>Duration</th><th>Happened</th></tr></thead><tbody>' + recentRows.map((entry) => '<tr class="row-button" data-action="show-detail" data-uuid="' + escapeHtml(entry.uuid) + '"><td><span class="' + typeClass(entry) + '">' + escapeHtml(entryTypeLabel(entry)) + '</span></td><td>' + entrySummaryHtml(entry) + '</td><td>' + tagsHtml(entry.tags) + '</td><td>' + durationHtml(entry) + '</td><td class="activity-time">' + escapeHtml(timeSince(entry.createdAt)) + '</td></tr>').join('') + '</tbody></table></div>';
|
|
842
|
+
: '<div class="table-wrap"><table><thead><tr><th>Type</th><th>Summary</th><th>Tags</th><th>Duration</th><th>Happened</th></tr></thead><tbody>' + recentRows.map((entry) => '<tr class="row-button" data-action="show-detail" data-uuid="' + escapeHtml(entry.uuid) + '"><td data-label="Type"><span class="' + typeClass(entry) + '">' + escapeHtml(entryTypeLabel(entry)) + '</span></td><td data-label="Summary">' + entrySummaryHtml(entry) + '</td><td data-label="Tags">' + tagsHtml(entry.tags) + '</td><td data-label="Duration">' + durationHtml(entry) + '</td><td data-label="Happened" class="activity-time">' + escapeHtml(timeSince(entry.createdAt)) + '</td></tr>').join('') + '</tbody></table></div>';
|
|
843
843
|
const activityList = recentRows.length === 0
|
|
844
844
|
? '<div class="empty">No recent activity.</div>'
|
|
845
845
|
: '<ul class="activity-list">' + recentRows.slice(0, 5).map((entry) => '<li class="activity-item"><div class="activity-head"><span class="' + typeClass(entry) + '">' + escapeHtml(entryTypeLabel(entry)) + '</span>' + durationHtml(entry) + '<span class="activity-time">' + escapeHtml(timeSince(entry.createdAt)) + '</span></div><div class="activity-summary">' + escapeHtml(entrySummaryText(entry)) + '</div></li>').join('') + '</ul>';
|
|
@@ -886,7 +886,7 @@ const DASHBOARD_DOCUMENT = String.raw `<!DOCTYPE html>
|
|
|
886
886
|
const total = Number(response.total || 0);
|
|
887
887
|
const perPage = Number(response.perPage || 50);
|
|
888
888
|
const totalPages = Math.max(1, Math.ceil(total / perPage));
|
|
889
|
-
const rows = data.map((entry) => '<tr class="row-button" data-action="show-detail" data-uuid="' + escapeHtml(entry.uuid) + '"><td><span class="' + typeClass(entry) + '">' + escapeHtml(entryTypeLabel(entry)) + '</span></td><td>' + entrySummaryHtml(entry) + '</td><td>' + tagsHtml(entry.tags) + '</td><td>' + durationHtml(entry) + '</td><td class="mono">' + batchSnippet(entry.batchId) + '</td><td class="activity-time">' + escapeHtml(timeSince(entry.createdAt)) + '</td></tr>').join('');
|
|
889
|
+
const rows = data.map((entry) => '<tr class="row-button" data-action="show-detail" data-uuid="' + escapeHtml(entry.uuid) + '"><td data-label="Type"><span class="' + typeClass(entry) + '">' + escapeHtml(entryTypeLabel(entry)) + '</span></td><td data-label="Summary">' + entrySummaryHtml(entry) + '</td><td data-label="Tags">' + tagsHtml(entry.tags) + '</td><td data-label="Duration">' + durationHtml(entry) + '</td><td data-label="Batch" class="mono">' + batchSnippet(entry.batchId) + '</td><td data-label="Happened" class="activity-time">' + escapeHtml(timeSince(entry.createdAt)) + '</td></tr>').join('');
|
|
890
890
|
|
|
891
891
|
main.innerHTML = [
|
|
892
892
|
'<section class="panel">',
|
|
@@ -22,58 +22,6 @@ const describeValueType = (value) => {
|
|
|
22
22
|
return 'null';
|
|
23
23
|
return typeof value;
|
|
24
24
|
};
|
|
25
|
-
const chooseLargerCandidate = (left, right) => {
|
|
26
|
-
if (left === null)
|
|
27
|
-
return right;
|
|
28
|
-
if (right === null)
|
|
29
|
-
return left;
|
|
30
|
-
return right.size > left.size ? right : left;
|
|
31
|
-
};
|
|
32
|
-
const fallbackCandidate = (value, path) => {
|
|
33
|
-
return path.length === 0 ? null : { path, size: serializedSize(value) };
|
|
34
|
-
};
|
|
35
|
-
const findLargestDroppablePathInArray = (value, path) => {
|
|
36
|
-
let best = null;
|
|
37
|
-
for (const [index, item] of value.entries()) {
|
|
38
|
-
best = chooseLargerCandidate(best, findLargestDroppablePath(item, [...path, index]));
|
|
39
|
-
}
|
|
40
|
-
return best ?? fallbackCandidate(value, path);
|
|
41
|
-
};
|
|
42
|
-
const findLargestDroppablePathInObject = (value, path) => {
|
|
43
|
-
let best = null;
|
|
44
|
-
for (const [key, entryValue] of Object.entries(value)) {
|
|
45
|
-
if (key === '__traceNotice')
|
|
46
|
-
continue;
|
|
47
|
-
best = chooseLargerCandidate(best, findLargestDroppablePath(entryValue, [...path, key]));
|
|
48
|
-
}
|
|
49
|
-
return best ?? fallbackCandidate(value, path);
|
|
50
|
-
};
|
|
51
|
-
const findLargestDroppablePath = (value, path = []) => {
|
|
52
|
-
if (Array.isArray(value))
|
|
53
|
-
return findLargestDroppablePathInArray(value, path);
|
|
54
|
-
if (typeof value === 'object' && value !== null) {
|
|
55
|
-
return findLargestDroppablePathInObject(value, path);
|
|
56
|
-
}
|
|
57
|
-
return fallbackCandidate(value, path);
|
|
58
|
-
};
|
|
59
|
-
const replaceAtPath = (value, path, replacement) => {
|
|
60
|
-
if (path.length === 0)
|
|
61
|
-
return replacement;
|
|
62
|
-
const [segment, ...rest] = path;
|
|
63
|
-
if (Array.isArray(value) && typeof segment === 'number') {
|
|
64
|
-
const next = value.slice();
|
|
65
|
-
next[segment] = replaceAtPath(next[segment], rest, replacement);
|
|
66
|
-
return next;
|
|
67
|
-
}
|
|
68
|
-
if (typeof value === 'object' && value !== null && typeof segment === 'string') {
|
|
69
|
-
const current = value;
|
|
70
|
-
return {
|
|
71
|
-
...current,
|
|
72
|
-
[segment]: replaceAtPath(current[segment], rest, replacement),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
return value;
|
|
76
|
-
};
|
|
77
25
|
const compactValue = (value, depth) => {
|
|
78
26
|
if (depth >= DEFAULT_MAX_DEPTH) {
|
|
79
27
|
return DROPPED_FIELD_MESSAGE;
|
|
@@ -106,17 +54,28 @@ const compactValue = (value, depth) => {
|
|
|
106
54
|
return Object.fromEntries(compactedEntries);
|
|
107
55
|
};
|
|
108
56
|
const compactStructuredValueToBudget = (value) => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
57
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
const compacted = {
|
|
61
|
+
...value,
|
|
62
|
+
__traceNotice: COMPACTED_CONTENT_MESSAGE,
|
|
63
|
+
};
|
|
64
|
+
const topLevelCandidates = Object.entries(compacted)
|
|
65
|
+
.filter(([key]) => key !== '__traceNotice')
|
|
66
|
+
.map(([key, entryValue]) => ({ key, size: serializedSize(entryValue) }))
|
|
67
|
+
.sort((left, right) => right.size - left.size);
|
|
68
|
+
let droppedCount = 0;
|
|
69
|
+
for (const candidate of topLevelCandidates) {
|
|
70
|
+
if (serializedSize(compacted) <= DEFAULT_MAX_ENTRY_BYTES) {
|
|
118
71
|
break;
|
|
119
|
-
|
|
72
|
+
}
|
|
73
|
+
compacted[candidate.key] = DROPPED_FIELD_MESSAGE;
|
|
74
|
+
droppedCount += 1;
|
|
75
|
+
}
|
|
76
|
+
if (droppedCount > 0) {
|
|
77
|
+
compacted['__traceNotice'] =
|
|
78
|
+
`${COMPACTED_CONTENT_MESSAGE} ${String(droppedCount)} top-level field(s) were dropped.`;
|
|
120
79
|
}
|
|
121
80
|
return compacted;
|
|
122
81
|
};
|
|
@@ -158,23 +117,24 @@ const closePort = (port) => {
|
|
|
158
117
|
port.close();
|
|
159
118
|
}
|
|
160
119
|
};
|
|
161
|
-
const scheduleTask = (task) => {
|
|
162
|
-
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
channel.port1.onmessage = null;
|
|
166
|
-
closePort(channel.port1);
|
|
167
|
-
closePort(channel.port2);
|
|
168
|
-
void task().catch(() => undefined);
|
|
120
|
+
const scheduleTask = async (task) => {
|
|
121
|
+
return await new Promise((resolve, reject) => {
|
|
122
|
+
const runTask = () => {
|
|
123
|
+
void task().then(resolve).catch(reject);
|
|
169
124
|
};
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
125
|
+
if (typeof MessageChannel === 'function') {
|
|
126
|
+
const channel = new MessageChannel();
|
|
127
|
+
channel.port1.onmessage = () => {
|
|
128
|
+
channel.port1.onmessage = null;
|
|
129
|
+
closePort(channel.port1);
|
|
130
|
+
closePort(channel.port2);
|
|
131
|
+
runTask();
|
|
132
|
+
};
|
|
133
|
+
channel.port2.postMessage(undefined);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
Promise.resolve().then(runTask).catch(reject);
|
|
137
|
+
});
|
|
178
138
|
};
|
|
179
139
|
const getReplacementContent = (content) => {
|
|
180
140
|
return {
|
|
@@ -283,7 +243,7 @@ const startInternalDispatchWorker = (storage, config, runtime) => {
|
|
|
283
243
|
if (startedWorkerKeys.has(key))
|
|
284
244
|
return;
|
|
285
245
|
startedWorkerKeys.add(key);
|
|
286
|
-
scheduleTask(async () => {
|
|
246
|
+
void scheduleTask(async () => {
|
|
287
247
|
const workersApi = runtime?.queueWorkerApi ?? (await getQueueWorkerApi());
|
|
288
248
|
if (workersApi === null) {
|
|
289
249
|
startedWorkerKeys.delete(key);
|
|
@@ -323,10 +283,12 @@ const startInternalDispatchWorker = (storage, config, runtime) => {
|
|
|
323
283
|
ensureWorkerTimer(key, setInterval(() => {
|
|
324
284
|
void runWorker();
|
|
325
285
|
}, intervalMs));
|
|
286
|
+
}).catch(() => {
|
|
287
|
+
startedWorkerKeys.delete(key);
|
|
326
288
|
});
|
|
327
289
|
};
|
|
328
|
-
const dispatchWrite = (storage, config, entry, runtime) => {
|
|
329
|
-
scheduleTask(async () => {
|
|
290
|
+
const dispatchWrite = async (storage, config, entry, runtime) => {
|
|
291
|
+
await scheduleTask(async () => {
|
|
330
292
|
if (hasQueueDispatch(config)) {
|
|
331
293
|
const enqueued = await enqueueTraceDispatch(config, { operation: 'write', entry }, runtime);
|
|
332
294
|
if (enqueued)
|
|
@@ -335,8 +297,8 @@ const dispatchWrite = (storage, config, entry, runtime) => {
|
|
|
335
297
|
await persistWriteFallback(storage, entry);
|
|
336
298
|
});
|
|
337
299
|
};
|
|
338
|
-
const dispatchUpdate = (storage, config, uuid, patch, runtime) => {
|
|
339
|
-
scheduleTask(async () => {
|
|
300
|
+
const dispatchUpdate = async (storage, config, uuid, patch, runtime) => {
|
|
301
|
+
await scheduleTask(async () => {
|
|
340
302
|
if (hasQueueDispatch(config)) {
|
|
341
303
|
const enqueued = await enqueueTraceDispatch(config, { operation: 'update', uuid, patch }, runtime);
|
|
342
304
|
if (enqueued)
|
|
@@ -351,10 +313,10 @@ export const TraceContentBudget = Object.freeze({
|
|
|
351
313
|
return Object.freeze({
|
|
352
314
|
...storage,
|
|
353
315
|
writeEntry: async (entry) => {
|
|
354
|
-
dispatchWrite(storage, config, entry, runtime);
|
|
316
|
+
await dispatchWrite(storage, config, entry, runtime);
|
|
355
317
|
},
|
|
356
318
|
updateEntry: async (uuid, patch) => {
|
|
357
|
-
dispatchUpdate(storage, config, uuid, patch, runtime);
|
|
319
|
+
await dispatchUpdate(storage, config, uuid, patch, runtime);
|
|
358
320
|
},
|
|
359
321
|
});
|
|
360
322
|
},
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
type RequestIgnoreRules = {
|
|
2
|
+
ignoreRoutes?: string[];
|
|
3
|
+
ignorePath?: string[];
|
|
4
|
+
};
|
|
1
5
|
export declare const RequestFilter: Readonly<{
|
|
2
|
-
matchesIgnoredPath: (path: string,
|
|
3
|
-
shouldIgnoreCurrentRequest: (
|
|
6
|
+
matchesIgnoredPath: (path: string, ignoreRoutesOrRules: string[] | RequestIgnoreRules, ignorePath?: string[]) => boolean;
|
|
7
|
+
shouldIgnoreCurrentRequest: (ignoreRoutesOrRules: string[] | RequestIgnoreRules, ignorePath?: string[]) => boolean;
|
|
4
8
|
}>;
|
|
9
|
+
export {};
|
|
@@ -6,19 +6,45 @@ const normalizePath = (input) => {
|
|
|
6
6
|
return '/';
|
|
7
7
|
return pathOnly.startsWith('/') ? pathOnly : `/${pathOnly}`;
|
|
8
8
|
};
|
|
9
|
-
const
|
|
9
|
+
const normalizeContainsPattern = (input) => {
|
|
10
|
+
const trimmed = input.trim();
|
|
11
|
+
const [pathOnly] = trimmed.split('?');
|
|
12
|
+
return pathOnly ?? '';
|
|
13
|
+
};
|
|
14
|
+
const resolveRules = (ignoreRoutesOrRules, ignorePath) => {
|
|
15
|
+
if (Array.isArray(ignoreRoutesOrRules)) {
|
|
16
|
+
return {
|
|
17
|
+
ignoreRoutes: ignoreRoutesOrRules,
|
|
18
|
+
ignorePath: ignorePath ?? [],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
ignoreRoutes: ignoreRoutesOrRules.ignoreRoutes ?? [],
|
|
23
|
+
ignorePath: ignoreRoutesOrRules.ignorePath ?? [],
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const matchesIgnoredPath = (path, ignoreRoutesOrRules, ignorePath) => {
|
|
10
27
|
const normalizedPath = normalizePath(path);
|
|
11
|
-
|
|
28
|
+
const rules = resolveRules(ignoreRoutesOrRules, ignorePath);
|
|
29
|
+
if (rules.ignoreRoutes.some((route) => {
|
|
12
30
|
const normalizedRoute = normalizePath(route);
|
|
13
31
|
return (normalizedPath === normalizedRoute ||
|
|
14
32
|
normalizedPath.startsWith(normalizedRoute.endsWith('/') ? normalizedRoute : `${normalizedRoute}/`));
|
|
33
|
+
})) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
return rules.ignorePath.some((route) => {
|
|
37
|
+
const containsPattern = normalizeContainsPattern(route);
|
|
38
|
+
if (containsPattern === '')
|
|
39
|
+
return false;
|
|
40
|
+
return normalizedPath.includes(containsPattern);
|
|
15
41
|
});
|
|
16
42
|
};
|
|
17
|
-
const shouldIgnoreCurrentRequest = (
|
|
43
|
+
const shouldIgnoreCurrentRequest = (ignoreRoutesOrRules, ignorePath) => {
|
|
18
44
|
const currentPath = TraceContext.getRequestPath();
|
|
19
45
|
if (typeof currentPath !== 'string' || currentPath === '')
|
|
20
46
|
return false;
|
|
21
|
-
return matchesIgnoredPath(currentPath,
|
|
47
|
+
return matchesIgnoredPath(currentPath, ignoreRoutesOrRules, ignorePath);
|
|
22
48
|
};
|
|
23
49
|
export const RequestFilter = Object.freeze({
|
|
24
50
|
matchesIgnoredPath,
|
|
@@ -7,10 +7,11 @@ import { EntryType } from '../types.js';
|
|
|
7
7
|
import { RequestFilter } from '../utils/requestFilter.js';
|
|
8
8
|
let _storage = null;
|
|
9
9
|
let _ignoreRoutes = [];
|
|
10
|
+
let _ignorePath = [];
|
|
10
11
|
const emit = (event, userId) => {
|
|
11
12
|
if (!_storage)
|
|
12
13
|
return;
|
|
13
|
-
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
|
|
14
|
+
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePath))
|
|
14
15
|
return;
|
|
15
16
|
const content = {
|
|
16
17
|
event,
|
|
@@ -41,9 +42,11 @@ export const AuthWatcher = Object.freeze({
|
|
|
41
42
|
return () => undefined;
|
|
42
43
|
_storage = storage;
|
|
43
44
|
_ignoreRoutes = config.ignoreRoutes;
|
|
45
|
+
_ignorePath = config.ignorePath;
|
|
44
46
|
return () => {
|
|
45
47
|
_storage = null;
|
|
46
48
|
_ignoreRoutes = [];
|
|
49
|
+
_ignorePath = [];
|
|
47
50
|
};
|
|
48
51
|
},
|
|
49
52
|
});
|
|
@@ -3,10 +3,11 @@ import { EntryType } from '../types.js';
|
|
|
3
3
|
import { RequestFilter } from '../utils/requestFilter.js';
|
|
4
4
|
let _storage = null;
|
|
5
5
|
let _ignoreRoutes = [];
|
|
6
|
+
let _ignorePath = [];
|
|
6
7
|
const emit = (name, total, processed, failed, status) => {
|
|
7
8
|
if (!_storage)
|
|
8
9
|
return;
|
|
9
|
-
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
|
|
10
|
+
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePath))
|
|
10
11
|
return;
|
|
11
12
|
const tags = [name];
|
|
12
13
|
if (failed > 0)
|
|
@@ -38,9 +39,11 @@ export const BatchWatcher = Object.freeze({
|
|
|
38
39
|
return () => undefined;
|
|
39
40
|
_storage = storage;
|
|
40
41
|
_ignoreRoutes = config.ignoreRoutes;
|
|
42
|
+
_ignorePath = config.ignorePath;
|
|
41
43
|
return () => {
|
|
42
44
|
_storage = null;
|
|
43
45
|
_ignoreRoutes = [];
|
|
46
|
+
_ignorePath = [];
|
|
44
47
|
};
|
|
45
48
|
},
|
|
46
49
|
});
|
|
@@ -11,10 +11,11 @@ let _storage = null;
|
|
|
11
11
|
let _config = null;
|
|
12
12
|
let _redactionFields = [];
|
|
13
13
|
let _ignoreRoutes = [];
|
|
14
|
+
let _ignorePath = [];
|
|
14
15
|
const emit = (operation, key, duration, hit, payload, store, ttl) => {
|
|
15
16
|
if (!_storage)
|
|
16
17
|
return;
|
|
17
|
-
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
|
|
18
|
+
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePath))
|
|
18
19
|
return;
|
|
19
20
|
const safeKey = redactString(key, _redactionFields);
|
|
20
21
|
const shouldLogPayload = _config?.captureCachePayloads === true;
|
|
@@ -50,10 +51,12 @@ export const CacheWatcher = Object.freeze({
|
|
|
50
51
|
_config = config;
|
|
51
52
|
_redactionFields = config.redaction.query;
|
|
52
53
|
_ignoreRoutes = config.ignoreRoutes;
|
|
54
|
+
_ignorePath = config.ignorePath;
|
|
53
55
|
return () => {
|
|
54
56
|
_storage = null;
|
|
55
57
|
_config = null;
|
|
56
58
|
_ignoreRoutes = [];
|
|
59
|
+
_ignorePath = [];
|
|
57
60
|
};
|
|
58
61
|
},
|
|
59
62
|
});
|
|
@@ -5,10 +5,11 @@ import { RequestFilter } from '../utils/requestFilter.js';
|
|
|
5
5
|
let _storage = null;
|
|
6
6
|
let _redactKeys = [];
|
|
7
7
|
let _ignoreRoutes = [];
|
|
8
|
+
let _ignorePath = [];
|
|
8
9
|
const emit = (name, args, exitCode, duration, output) => {
|
|
9
10
|
if (!_storage)
|
|
10
11
|
return;
|
|
11
|
-
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
|
|
12
|
+
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePath))
|
|
12
13
|
return;
|
|
13
14
|
const tags = [name];
|
|
14
15
|
if (exitCode !== 0)
|
|
@@ -41,9 +42,11 @@ export const CommandWatcher = Object.freeze({
|
|
|
41
42
|
_storage = storage;
|
|
42
43
|
_redactKeys = [...(config.redaction?.keys ?? []), ...(config.redaction?.body ?? [])];
|
|
43
44
|
_ignoreRoutes = config.ignoreRoutes;
|
|
45
|
+
_ignorePath = config.ignorePath;
|
|
44
46
|
return () => {
|
|
45
47
|
_storage = null;
|
|
46
48
|
_ignoreRoutes = [];
|
|
49
|
+
_ignorePath = [];
|
|
47
50
|
};
|
|
48
51
|
},
|
|
49
52
|
});
|
|
@@ -4,11 +4,12 @@ import { RequestFilter } from '../utils/requestFilter.js';
|
|
|
4
4
|
let _storage = null;
|
|
5
5
|
let _enabled = false;
|
|
6
6
|
let _ignoreRoutes = [];
|
|
7
|
+
let _ignorePath = [];
|
|
7
8
|
/** Explicitly opt-in (enabled only when config.watchers.dump === true, not just non-false). */
|
|
8
9
|
const emit = (value, file, line) => {
|
|
9
10
|
if (!_storage || !_enabled)
|
|
10
11
|
return;
|
|
11
|
-
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
|
|
12
|
+
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePath))
|
|
12
13
|
return;
|
|
13
14
|
const content = { value, file, line, hostname: TraceContext.getHostname() };
|
|
14
15
|
_storage
|
|
@@ -32,10 +33,12 @@ export const DumpWatcher = Object.freeze({
|
|
|
32
33
|
_storage = storage;
|
|
33
34
|
_enabled = true;
|
|
34
35
|
_ignoreRoutes = config.ignoreRoutes;
|
|
36
|
+
_ignorePath = config.ignorePath;
|
|
35
37
|
return () => {
|
|
36
38
|
_storage = null;
|
|
37
39
|
_enabled = false;
|
|
38
40
|
_ignoreRoutes = [];
|
|
41
|
+
_ignorePath = [];
|
|
39
42
|
};
|
|
40
43
|
},
|
|
41
44
|
});
|
|
@@ -4,10 +4,11 @@ import { AuthTag } from '../utils/authTag.js';
|
|
|
4
4
|
import { RequestFilter } from '../utils/requestFilter.js';
|
|
5
5
|
let _storage = null;
|
|
6
6
|
let _ignoreRoutes = [];
|
|
7
|
+
let _ignorePath = [];
|
|
7
8
|
const emit = (name, listenerCount, payload) => {
|
|
8
9
|
if (!_storage)
|
|
9
10
|
return;
|
|
10
|
-
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
|
|
11
|
+
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePath))
|
|
11
12
|
return;
|
|
12
13
|
const content = {
|
|
13
14
|
name,
|
|
@@ -34,9 +35,11 @@ export const EventWatcher = Object.freeze({
|
|
|
34
35
|
return () => undefined;
|
|
35
36
|
_storage = storage;
|
|
36
37
|
_ignoreRoutes = config.ignoreRoutes;
|
|
38
|
+
_ignorePath = config.ignorePath;
|
|
37
39
|
return () => {
|
|
38
40
|
_storage = null;
|
|
39
41
|
_ignoreRoutes = [];
|
|
42
|
+
_ignorePath = [];
|
|
40
43
|
};
|
|
41
44
|
},
|
|
42
45
|
});
|
|
@@ -37,6 +37,7 @@ const buildContent = (err, context) => {
|
|
|
37
37
|
let _storage = null;
|
|
38
38
|
let _listenerRefCount = 0;
|
|
39
39
|
let _ignoreRoutes = [];
|
|
40
|
+
let _ignorePath = [];
|
|
40
41
|
const handleUncaughtException = (error) => {
|
|
41
42
|
captureException(error);
|
|
42
43
|
};
|
|
@@ -62,10 +63,10 @@ const captureException = (err, context) => {
|
|
|
62
63
|
if (!(err instanceof Error))
|
|
63
64
|
return;
|
|
64
65
|
if (context?.path !== undefined) {
|
|
65
|
-
if (RequestFilter.matchesIgnoredPath(context.path, _ignoreRoutes))
|
|
66
|
+
if (RequestFilter.matchesIgnoredPath(context.path, _ignoreRoutes, _ignorePath))
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
68
|
-
else if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes)) {
|
|
69
|
+
else if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePath)) {
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
71
72
|
const content = buildContent(err, context);
|
|
@@ -92,6 +93,7 @@ export const ExceptionWatcher = Object.freeze({
|
|
|
92
93
|
return () => undefined;
|
|
93
94
|
_storage = storage;
|
|
94
95
|
_ignoreRoutes = config.ignoreRoutes;
|
|
96
|
+
_ignorePath = config.ignorePath;
|
|
95
97
|
if (_listenerRefCount === 0) {
|
|
96
98
|
registerProcessListeners();
|
|
97
99
|
}
|
|
@@ -103,6 +105,7 @@ export const ExceptionWatcher = Object.freeze({
|
|
|
103
105
|
}
|
|
104
106
|
_storage = null;
|
|
105
107
|
_ignoreRoutes = [];
|
|
108
|
+
_ignorePath = [];
|
|
106
109
|
};
|
|
107
110
|
},
|
|
108
111
|
});
|
|
@@ -3,10 +3,11 @@ import { EntryType } from '../types.js';
|
|
|
3
3
|
import { RequestFilter } from '../utils/requestFilter.js';
|
|
4
4
|
let _storage = null;
|
|
5
5
|
let _ignoreRoutes = [];
|
|
6
|
+
let _ignorePath = [];
|
|
6
7
|
const emit = (ability, result, userId, subject) => {
|
|
7
8
|
if (!_storage)
|
|
8
9
|
return;
|
|
9
|
-
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
|
|
10
|
+
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePath))
|
|
10
11
|
return;
|
|
11
12
|
const tags = [ability, result];
|
|
12
13
|
if (userId)
|
|
@@ -37,9 +38,11 @@ export const GateWatcher = Object.freeze({
|
|
|
37
38
|
return () => undefined;
|
|
38
39
|
_storage = storage;
|
|
39
40
|
_ignoreRoutes = config.ignoreRoutes;
|
|
41
|
+
_ignorePath = config.ignorePath;
|
|
40
42
|
return () => {
|
|
41
43
|
_storage = null;
|
|
42
44
|
_ignoreRoutes = [];
|
|
45
|
+
_ignorePath = [];
|
|
43
46
|
};
|
|
44
47
|
},
|
|
45
48
|
});
|
|
@@ -7,6 +7,7 @@ let _storage = null;
|
|
|
7
7
|
let _redactHeaderNames = [];
|
|
8
8
|
let _redactBodyFields = [];
|
|
9
9
|
let _ignoreRoutes = [];
|
|
10
|
+
let _ignorePath = [];
|
|
10
11
|
let _clientRequestWatcher;
|
|
11
12
|
const isObjectValue = (value) => {
|
|
12
13
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
@@ -102,7 +103,7 @@ const isWatcherEnabled = (value) => {
|
|
|
102
103
|
const emit = ({ source, method, url, requestHeaders, responseStatus, duration, requestBody, responseHeaders, responseBody, error, }) => {
|
|
103
104
|
if (!_storage)
|
|
104
105
|
return;
|
|
105
|
-
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
|
|
106
|
+
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePath))
|
|
106
107
|
return;
|
|
107
108
|
const normalizedSource = resolveSource(source);
|
|
108
109
|
const sourceRule = resolveSourceRule(normalizedSource);
|
|
@@ -150,11 +151,13 @@ export const HttpClientWatcher = Object.freeze({
|
|
|
150
151
|
_redactHeaderNames = [...(config.redaction?.keys ?? []), ...(config.redaction?.headers ?? [])];
|
|
151
152
|
_redactBodyFields = [...(config.redaction?.keys ?? []), ...(config.redaction?.body ?? [])];
|
|
152
153
|
_ignoreRoutes = config.ignoreRoutes;
|
|
154
|
+
_ignorePath = config.ignorePath;
|
|
153
155
|
return () => {
|
|
154
156
|
_storage = null;
|
|
155
157
|
_clientRequestWatcher = undefined;
|
|
156
158
|
_redactBodyFields = [];
|
|
157
159
|
_ignoreRoutes = [];
|
|
160
|
+
_ignorePath = [];
|
|
158
161
|
};
|
|
159
162
|
},
|
|
160
163
|
});
|
|
@@ -120,7 +120,7 @@ const buildEntry = (req, res, start, config, responseCapture) => {
|
|
|
120
120
|
};
|
|
121
121
|
};
|
|
122
122
|
const shouldIgnore = (req, config) => {
|
|
123
|
-
return RequestFilter.matchesIgnoredPath(req.getPath(), config
|
|
123
|
+
return RequestFilter.matchesIgnoredPath(req.getPath(), config);
|
|
124
124
|
};
|
|
125
125
|
const isWatcherEnabled = (config) => config.watchers.request !== false;
|
|
126
126
|
export const HttpWatcher = Object.freeze({
|
|
@@ -10,6 +10,7 @@ import { parseStackFrameLine } from '../utils/stackFrame.js';
|
|
|
10
10
|
// Module-level storage ref so emit helpers can be called from outside.
|
|
11
11
|
let _storage = null;
|
|
12
12
|
let _ignoreRoutes = [];
|
|
13
|
+
let _ignorePath = [];
|
|
13
14
|
const MAX_TRACKED_JOBS = 1000;
|
|
14
15
|
const pendingJobs = new Map();
|
|
15
16
|
const trackPendingJob = (name, job) => {
|
|
@@ -36,7 +37,7 @@ const takePendingJob = (name) => {
|
|
|
36
37
|
const emitDispatch = (name, queue, connection, data) => {
|
|
37
38
|
if (!_storage)
|
|
38
39
|
return;
|
|
39
|
-
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
|
|
40
|
+
if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePath))
|
|
40
41
|
return;
|
|
41
42
|
const uuid = crypto.randomUUID();
|
|
42
43
|
const content = {
|
|
@@ -99,9 +100,11 @@ export const JobWatcher = Object.freeze({
|
|
|
99
100
|
return () => undefined;
|
|
100
101
|
_storage = storage;
|
|
101
102
|
_ignoreRoutes = config.ignoreRoutes;
|
|
103
|
+
_ignorePath = config.ignorePath;
|
|
102
104
|
return () => {
|
|
103
105
|
_storage = null;
|
|
104
106
|
_ignoreRoutes = [];
|
|
107
|
+
_ignorePath = [];
|
|
105
108
|
pendingJobs.clear();
|
|
106
109
|
};
|
|
107
110
|
},
|
|
@@ -61,7 +61,7 @@ export const LogWatcher = Object.freeze({
|
|
|
61
61
|
const unsubscribe = loggerWithSink.addSink((level, message, context) => {
|
|
62
62
|
if ((LEVEL_PRIORITY[level] ?? 0) < minPriority)
|
|
63
63
|
return;
|
|
64
|
-
if (RequestFilter.shouldIgnoreCurrentRequest(config.ignoreRoutes))
|
|
64
|
+
if (RequestFilter.shouldIgnoreCurrentRequest(config.ignoreRoutes, config.ignorePath))
|
|
65
65
|
return;
|
|
66
66
|
if (shouldSkipTraceInfrastructureLog(message, context))
|
|
67
67
|
return;
|