@zintrust/trace 0.5.5 → 0.5.8

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.
Files changed (50) hide show
  1. package/dist/config.js +2 -0
  2. package/dist/dashboard/ui.js +4 -4
  3. package/dist/types.d.ts +1 -0
  4. package/dist/utils/requestFilter.d.ts +7 -2
  5. package/dist/utils/requestFilter.js +30 -4
  6. package/dist/watchers/AuthWatcher.js +4 -1
  7. package/dist/watchers/BatchWatcher.js +4 -1
  8. package/dist/watchers/CacheWatcher.js +4 -1
  9. package/dist/watchers/CommandWatcher.js +4 -1
  10. package/dist/watchers/DumpWatcher.js +4 -1
  11. package/dist/watchers/EventWatcher.js +4 -1
  12. package/dist/watchers/ExceptionWatcher.js +5 -2
  13. package/dist/watchers/GateWatcher.js +4 -1
  14. package/dist/watchers/HttpClientWatcher.js +4 -1
  15. package/dist/watchers/HttpWatcher.js +1 -1
  16. package/dist/watchers/JobWatcher.js +4 -1
  17. package/dist/watchers/LogWatcher.js +1 -1
  18. package/dist/watchers/MailWatcher.js +4 -1
  19. package/dist/watchers/MiddlewareWatcher.js +4 -1
  20. package/dist/watchers/ModelWatcher.js +4 -1
  21. package/dist/watchers/NotificationWatcher.js +4 -1
  22. package/dist/watchers/QueryWatcher.js +1 -1
  23. package/dist/watchers/RedisWatcher.js +4 -1
  24. package/dist/watchers/ScheduleWatcher.js +4 -1
  25. package/dist/watchers/ViewWatcher.js +4 -1
  26. package/package.json +2 -2
  27. package/src/config.ts +2 -0
  28. package/src/dashboard/ui.ts +4 -4
  29. package/src/types.ts +1 -0
  30. package/src/utils/requestFilter.ts +57 -11
  31. package/src/watchers/AuthWatcher.ts +4 -1
  32. package/src/watchers/BatchWatcher.ts +4 -1
  33. package/src/watchers/CacheWatcher.ts +4 -1
  34. package/src/watchers/CommandWatcher.ts +4 -1
  35. package/src/watchers/DumpWatcher.ts +4 -1
  36. package/src/watchers/EventWatcher.ts +4 -1
  37. package/src/watchers/ExceptionWatcher.ts +5 -2
  38. package/src/watchers/GateWatcher.ts +4 -1
  39. package/src/watchers/HttpClientWatcher.ts +4 -1
  40. package/src/watchers/HttpWatcher.ts +1 -1
  41. package/src/watchers/JobWatcher.ts +4 -1
  42. package/src/watchers/LogWatcher.ts +2 -1
  43. package/src/watchers/MailWatcher.ts +4 -1
  44. package/src/watchers/MiddlewareWatcher.ts +4 -1
  45. package/src/watchers/ModelWatcher.ts +4 -1
  46. package/src/watchers/NotificationWatcher.ts +4 -1
  47. package/src/watchers/QueryWatcher.ts +1 -1
  48. package/src/watchers/RedisWatcher.ts +4 -1
  49. package/src/watchers/ScheduleWatcher.ts +4 -1
  50. 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
+ ignorePaths: [],
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
+ ignorePaths: overrides.ignorePaths ?? DEFAULTS.ignorePaths,
258
260
  });
259
261
  },
260
262
  getRedactionFields,
@@ -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,.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
+ @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">',
package/dist/types.d.ts CHANGED
@@ -347,6 +347,7 @@ export interface ITraceConfig {
347
347
  observeConnection?: string;
348
348
  pruneAfterHours: number;
349
349
  ignoreRoutes: string[];
350
+ ignorePaths: string[];
350
351
  slowQueryThreshold: number;
351
352
  captureCachePayloads: boolean;
352
353
  captureQueryBindings: boolean;
@@ -1,4 +1,9 @@
1
+ type RequestIgnoreRules = {
2
+ ignoreRoutes?: string[];
3
+ ignorePaths?: string[];
4
+ };
1
5
  export declare const RequestFilter: Readonly<{
2
- matchesIgnoredPath: (path: string, ignoreRoutes: string[]) => boolean;
3
- shouldIgnoreCurrentRequest: (ignoreRoutes: string[]) => boolean;
6
+ matchesIgnoredPath: (path: string, ignoreRoutesOrRules: string[] | RequestIgnoreRules, ignorePaths?: string[]) => boolean;
7
+ shouldIgnoreCurrentRequest: (ignoreRoutesOrRules: string[] | RequestIgnoreRules, ignorePaths?: 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 matchesIgnoredPath = (path, ignoreRoutes) => {
9
+ const normalizeContainsPattern = (input) => {
10
+ const trimmed = input.trim();
11
+ const [pathOnly] = trimmed.split('?');
12
+ return pathOnly ?? '';
13
+ };
14
+ const resolveRules = (ignoreRoutesOrRules, ignorePaths) => {
15
+ if (Array.isArray(ignoreRoutesOrRules)) {
16
+ return {
17
+ ignoreRoutes: ignoreRoutesOrRules,
18
+ ignorePaths: ignorePaths ?? [],
19
+ };
20
+ }
21
+ return {
22
+ ignoreRoutes: ignoreRoutesOrRules.ignoreRoutes ?? [],
23
+ ignorePaths: ignoreRoutesOrRules.ignorePaths ?? [],
24
+ };
25
+ };
26
+ const matchesIgnoredPath = (path, ignoreRoutesOrRules, ignorePaths) => {
10
27
  const normalizedPath = normalizePath(path);
11
- return ignoreRoutes.some((route) => {
28
+ const rules = resolveRules(ignoreRoutesOrRules, ignorePaths);
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.ignorePaths.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 = (ignoreRoutes) => {
43
+ const shouldIgnoreCurrentRequest = (ignoreRoutesOrRules, ignorePaths) => {
18
44
  const currentPath = TraceContext.getRequestPath();
19
45
  if (typeof currentPath !== 'string' || currentPath === '')
20
46
  return false;
21
- return matchesIgnoredPath(currentPath, ignoreRoutes);
47
+ return matchesIgnoredPath(currentPath, ignoreRoutesOrRules, ignorePaths);
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 _ignorePaths = [];
10
11
  const emit = (event, userId) => {
11
12
  if (!_storage)
12
13
  return;
13
- if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
14
+ if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePaths))
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
+ _ignorePaths = config.ignorePaths;
44
46
  return () => {
45
47
  _storage = null;
46
48
  _ignoreRoutes = [];
49
+ _ignorePaths = [];
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 _ignorePaths = [];
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, _ignorePaths))
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
+ _ignorePaths = config.ignorePaths;
41
43
  return () => {
42
44
  _storage = null;
43
45
  _ignoreRoutes = [];
46
+ _ignorePaths = [];
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 _ignorePaths = [];
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, _ignorePaths))
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
+ _ignorePaths = config.ignorePaths;
53
55
  return () => {
54
56
  _storage = null;
55
57
  _config = null;
56
58
  _ignoreRoutes = [];
59
+ _ignorePaths = [];
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 _ignorePaths = [];
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, _ignorePaths))
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
+ _ignorePaths = config.ignorePaths;
44
46
  return () => {
45
47
  _storage = null;
46
48
  _ignoreRoutes = [];
49
+ _ignorePaths = [];
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 _ignorePaths = [];
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, _ignorePaths))
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
+ _ignorePaths = config.ignorePaths;
35
37
  return () => {
36
38
  _storage = null;
37
39
  _enabled = false;
38
40
  _ignoreRoutes = [];
41
+ _ignorePaths = [];
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 _ignorePaths = [];
7
8
  const emit = (name, listenerCount, payload) => {
8
9
  if (!_storage)
9
10
  return;
10
- if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
11
+ if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePaths))
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
+ _ignorePaths = config.ignorePaths;
37
39
  return () => {
38
40
  _storage = null;
39
41
  _ignoreRoutes = [];
42
+ _ignorePaths = [];
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 _ignorePaths = [];
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, _ignorePaths))
66
67
  return;
67
68
  }
68
- else if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes)) {
69
+ else if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePaths)) {
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
+ _ignorePaths = config.ignorePaths;
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
+ _ignorePaths = [];
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 _ignorePaths = [];
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, _ignorePaths))
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
+ _ignorePaths = config.ignorePaths;
40
42
  return () => {
41
43
  _storage = null;
42
44
  _ignoreRoutes = [];
45
+ _ignorePaths = [];
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 _ignorePaths = [];
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, _ignorePaths))
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
+ _ignorePaths = config.ignorePaths;
153
155
  return () => {
154
156
  _storage = null;
155
157
  _clientRequestWatcher = undefined;
156
158
  _redactBodyFields = [];
157
159
  _ignoreRoutes = [];
160
+ _ignorePaths = [];
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.ignoreRoutes);
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 _ignorePaths = [];
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, _ignorePaths))
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
+ _ignorePaths = config.ignorePaths;
102
104
  return () => {
103
105
  _storage = null;
104
106
  _ignoreRoutes = [];
107
+ _ignorePaths = [];
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.ignorePaths))
65
65
  return;
66
66
  if (shouldSkipTraceInfrastructureLog(message, context))
67
67
  return;
@@ -8,10 +8,11 @@ import { RequestFilter } from '../utils/requestFilter.js';
8
8
  let _storage = null;
9
9
  let _redactionFields = [];
10
10
  let _ignoreRoutes = [];
11
+ let _ignorePaths = [];
11
12
  const emit = (to, subject, template, text, html) => {
12
13
  if (!_storage)
13
14
  return;
14
- if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
15
+ if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePaths))
15
16
  return;
16
17
  const content = {
17
18
  to,
@@ -45,10 +46,12 @@ export const MailWatcher = Object.freeze({
45
46
  _storage = storage;
46
47
  _redactionFields = [...config.redaction.keys, ...config.redaction.body];
47
48
  _ignoreRoutes = config.ignoreRoutes;
49
+ _ignorePaths = config.ignorePaths;
48
50
  return () => {
49
51
  _storage = null;
50
52
  _redactionFields = [];
51
53
  _ignoreRoutes = [];
54
+ _ignorePaths = [];
52
55
  };
53
56
  },
54
57
  });
@@ -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 _ignorePaths = [];
6
7
  const emit = (name, event, duration) => {
7
8
  if (!_storage)
8
9
  return;
9
- if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
10
+ if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePaths))
10
11
  return;
11
12
  const content = {
12
13
  name,
@@ -33,6 +34,7 @@ export const MiddlewareWatcher = Object.freeze({
33
34
  return () => undefined;
34
35
  _storage = storage;
35
36
  _ignoreRoutes = config.ignoreRoutes;
37
+ _ignorePaths = config.ignorePaths;
36
38
  globalThis.__zintrust_trace_middleware_emit__ = emit;
37
39
  return () => {
38
40
  const globalState = globalThis;
@@ -41,6 +43,7 @@ export const MiddlewareWatcher = Object.freeze({
41
43
  }
42
44
  _storage = null;
43
45
  _ignoreRoutes = [];
46
+ _ignorePaths = [];
44
47
  };
45
48
  },
46
49
  });
@@ -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 _ignorePaths = [];
6
7
  const emit = (action, model, id, changes) => {
7
8
  if (!_storage)
8
9
  return;
9
- if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
10
+ if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePaths))
10
11
  return;
11
12
  const content = {
12
13
  action,
@@ -34,6 +35,7 @@ export const ModelWatcher = Object.freeze({
34
35
  return () => undefined;
35
36
  _storage = storage;
36
37
  _ignoreRoutes = config.ignoreRoutes;
38
+ _ignorePaths = config.ignorePaths;
37
39
  globalThis.__zintrust_trace_model_emit__ = emit;
38
40
  return () => {
39
41
  const globalState = globalThis;
@@ -42,6 +44,7 @@ export const ModelWatcher = Object.freeze({
42
44
  }
43
45
  _storage = null;
44
46
  _ignoreRoutes = [];
47
+ _ignorePaths = [];
45
48
  };
46
49
  },
47
50
  });
@@ -6,10 +6,11 @@ import { RequestFilter } from '../utils/requestFilter.js';
6
6
  let _storage = null;
7
7
  let _redactionFields = [];
8
8
  let _ignoreRoutes = [];
9
+ let _ignorePaths = [];
9
10
  const emit = (notification, channels, notifiable, message, payload) => {
10
11
  if (!_storage)
11
12
  return;
12
- if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
13
+ if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePaths))
13
14
  return;
14
15
  const content = {
15
16
  notification,
@@ -41,10 +42,12 @@ export const NotificationWatcher = Object.freeze({
41
42
  _storage = storage;
42
43
  _redactionFields = [...config.redaction.keys, ...config.redaction.body];
43
44
  _ignoreRoutes = config.ignoreRoutes;
45
+ _ignorePaths = config.ignorePaths;
44
46
  return () => {
45
47
  _storage = null;
46
48
  _redactionFields = [];
47
49
  _ignoreRoutes = [];
50
+ _ignorePaths = [];
48
51
  };
49
52
  },
50
53
  });
@@ -29,7 +29,7 @@ const isTraceStorageQuery = (sql) => {
29
29
  const emit = (query, params, duration, connection = 'default') => {
30
30
  if (_storage === null || _config === null)
31
31
  return;
32
- if (RequestFilter.shouldIgnoreCurrentRequest(_config.ignoreRoutes))
32
+ if (RequestFilter.shouldIgnoreCurrentRequest(_config.ignoreRoutes, _config.ignorePaths))
33
33
  return;
34
34
  if (isTraceStorageQuery(query))
35
35
  return;
@@ -4,11 +4,12 @@ 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 _ignorePaths = [];
7
8
  /** Emit a redis command trace. Key/value payload is intentionally omitted for security. */
8
9
  const emit = (command, duration) => {
9
10
  if (!_storage)
10
11
  return;
11
- if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
12
+ if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePaths))
12
13
  return;
13
14
  const content = { command, duration, hostname: TraceContext.getHostname() };
14
15
  _storage
@@ -30,9 +31,11 @@ export const RedisWatcher = Object.freeze({
30
31
  return () => undefined;
31
32
  _storage = storage;
32
33
  _ignoreRoutes = config.ignoreRoutes;
34
+ _ignorePaths = config.ignorePaths;
33
35
  return () => {
34
36
  _storage = null;
35
37
  _ignoreRoutes = [];
38
+ _ignorePaths = [];
36
39
  };
37
40
  },
38
41
  });
@@ -6,10 +6,11 @@ import { EntryType } from '../types.js';
6
6
  import { RequestFilter } from '../utils/requestFilter.js';
7
7
  let _storage = null;
8
8
  let _ignoreRoutes = [];
9
+ let _ignorePaths = [];
9
10
  const emit = (name, expression, status, duration, output) => {
10
11
  if (!_storage)
11
12
  return;
12
- if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes))
13
+ if (RequestFilter.shouldIgnoreCurrentRequest(_ignoreRoutes, _ignorePaths))
13
14
  return;
14
15
  const content = {
15
16
  name,
@@ -38,9 +39,11 @@ export const ScheduleWatcher = Object.freeze({
38
39
  return () => undefined;
39
40
  _storage = storage;
40
41
  _ignoreRoutes = config.ignoreRoutes;
42
+ _ignorePaths = config.ignorePaths;
41
43
  return () => {
42
44
  _storage = null;
43
45
  _ignoreRoutes = [];
46
+ _ignorePaths = [];
44
47
  };
45
48
  },
46
49
  });