@sfdxy/anypoint-connect 0.14.0 → 0.16.2

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 (278) hide show
  1. package/README.md +39 -16
  2. package/dist/analysis/LogAnalyzer.d.ts +10 -4
  3. package/dist/analysis/LogAnalyzer.d.ts.map +1 -1
  4. package/dist/analysis/LogAnalyzer.js +29 -18
  5. package/dist/analysis/LogAnalyzer.js.map +1 -1
  6. package/dist/analysis/error-context.d.ts +2 -0
  7. package/dist/analysis/error-context.d.ts.map +1 -1
  8. package/dist/analysis/error-context.js +2 -1
  9. package/dist/analysis/error-context.js.map +1 -1
  10. package/dist/analysis/error-grouper.js +1 -1
  11. package/dist/analysis/error-grouper.js.map +1 -1
  12. package/dist/analysis/filter.d.ts +54 -0
  13. package/dist/analysis/filter.d.ts.map +1 -0
  14. package/dist/analysis/filter.js +100 -0
  15. package/dist/analysis/filter.js.map +1 -0
  16. package/dist/analysis/{utils.d.ts → normalize.d.ts} +1 -1
  17. package/dist/analysis/normalize.d.ts.map +1 -0
  18. package/dist/analysis/{utils.js → normalize.js} +2 -2
  19. package/dist/analysis/normalize.js.map +1 -0
  20. package/dist/analysis/parser.d.ts.map +1 -1
  21. package/dist/analysis/parser.js +45 -17
  22. package/dist/analysis/parser.js.map +1 -1
  23. package/dist/analysis/pattern-detector.js +1 -1
  24. package/dist/analysis/pattern-detector.js.map +1 -1
  25. package/dist/analysis/stats.d.ts +25 -0
  26. package/dist/analysis/stats.d.ts.map +1 -1
  27. package/dist/analysis/stats.js +35 -1
  28. package/dist/analysis/stats.js.map +1 -1
  29. package/dist/analysis/summary.d.ts +51 -0
  30. package/dist/analysis/summary.d.ts.map +1 -0
  31. package/dist/analysis/summary.js +47 -0
  32. package/dist/analysis/summary.js.map +1 -0
  33. package/dist/analysis/types.d.ts +14 -0
  34. package/dist/analysis/types.d.ts.map +1 -1
  35. package/dist/api/ApiManagerApi.d.ts +53 -0
  36. package/dist/api/ApiManagerApi.d.ts.map +1 -1
  37. package/dist/api/ApiManagerApi.js +53 -2
  38. package/dist/api/ApiManagerApi.js.map +1 -1
  39. package/dist/api/CloudHub2Api.d.ts +24 -4
  40. package/dist/api/CloudHub2Api.d.ts.map +1 -1
  41. package/dist/api/CloudHub2Api.js +10 -22
  42. package/dist/api/CloudHub2Api.js.map +1 -1
  43. package/dist/api/DesignCenterApi.d.ts +0 -20
  44. package/dist/api/DesignCenterApi.d.ts.map +1 -1
  45. package/dist/api/DesignCenterApi.js +0 -22
  46. package/dist/api/DesignCenterApi.js.map +1 -1
  47. package/dist/api/ExchangeApi.d.ts +15 -0
  48. package/dist/api/ExchangeApi.d.ts.map +1 -1
  49. package/dist/api/ExchangeApi.js +51 -0
  50. package/dist/api/ExchangeApi.js.map +1 -1
  51. package/dist/api/LogsApi.d.ts +50 -18
  52. package/dist/api/LogsApi.d.ts.map +1 -1
  53. package/dist/api/LogsApi.js +69 -98
  54. package/dist/api/LogsApi.js.map +1 -1
  55. package/dist/api/MonitoringApi.d.ts +137 -93
  56. package/dist/api/MonitoringApi.d.ts.map +1 -1
  57. package/dist/api/MonitoringApi.js +471 -204
  58. package/dist/api/MonitoringApi.js.map +1 -1
  59. package/dist/api/RuntimesApi.d.ts +56 -0
  60. package/dist/api/RuntimesApi.d.ts.map +1 -0
  61. package/dist/api/RuntimesApi.js +58 -0
  62. package/dist/api/RuntimesApi.js.map +1 -0
  63. package/dist/auth/FileStore.js +1 -1
  64. package/dist/auth/FileStore.js.map +1 -1
  65. package/dist/cli.js +4 -2
  66. package/dist/cli.js.map +1 -1
  67. package/dist/client/AnypointClient.d.ts +3 -1
  68. package/dist/client/AnypointClient.d.ts.map +1 -1
  69. package/dist/client/AnypointClient.js +5 -2
  70. package/dist/client/AnypointClient.js.map +1 -1
  71. package/dist/client/smoke-test.d.ts +111 -0
  72. package/dist/client/smoke-test.d.ts.map +1 -0
  73. package/dist/client/smoke-test.js +275 -0
  74. package/dist/client/smoke-test.js.map +1 -0
  75. package/dist/commands/api.d.ts +1 -1
  76. package/dist/commands/api.d.ts.map +1 -1
  77. package/dist/commands/api.js +175 -30
  78. package/dist/commands/api.js.map +1 -1
  79. package/dist/commands/app-change-cli.d.ts +52 -0
  80. package/dist/commands/app-change-cli.d.ts.map +1 -0
  81. package/dist/commands/app-change-cli.js +149 -0
  82. package/dist/commands/app-change-cli.js.map +1 -0
  83. package/dist/commands/apps.d.ts +1 -1
  84. package/dist/commands/apps.d.ts.map +1 -1
  85. package/dist/commands/apps.js +199 -18
  86. package/dist/commands/apps.js.map +1 -1
  87. package/dist/commands/auth.js +1 -1
  88. package/dist/commands/auth.js.map +1 -1
  89. package/dist/commands/compare.d.ts +8 -0
  90. package/dist/commands/compare.d.ts.map +1 -0
  91. package/dist/commands/compare.js +104 -0
  92. package/dist/commands/compare.js.map +1 -0
  93. package/dist/commands/config.js +1 -1
  94. package/dist/commands/config.js.map +1 -1
  95. package/dist/commands/deploy.d.ts +6 -1
  96. package/dist/commands/deploy.d.ts.map +1 -1
  97. package/dist/commands/deploy.js +89 -91
  98. package/dist/commands/deploy.js.map +1 -1
  99. package/dist/commands/design-center.d.ts +1 -1
  100. package/dist/commands/design-center.d.ts.map +1 -1
  101. package/dist/commands/design-center.js +36 -25
  102. package/dist/commands/design-center.js.map +1 -1
  103. package/dist/commands/index.d.ts +1 -0
  104. package/dist/commands/index.d.ts.map +1 -1
  105. package/dist/commands/index.js +1 -0
  106. package/dist/commands/index.js.map +1 -1
  107. package/dist/commands/logs.d.ts +3 -2
  108. package/dist/commands/logs.d.ts.map +1 -1
  109. package/dist/commands/logs.js +142 -17
  110. package/dist/commands/logs.js.map +1 -1
  111. package/dist/commands/monitor.d.ts +5 -6
  112. package/dist/commands/monitor.d.ts.map +1 -1
  113. package/dist/commands/monitor.js +210 -230
  114. package/dist/commands/monitor.js.map +1 -1
  115. package/dist/commands/runtimes.d.ts +7 -0
  116. package/dist/commands/runtimes.d.ts.map +1 -0
  117. package/dist/commands/runtimes.js +66 -0
  118. package/dist/commands/runtimes.js.map +1 -0
  119. package/dist/commands/shared.d.ts +2 -0
  120. package/dist/commands/shared.d.ts.map +1 -1
  121. package/dist/commands/shared.js +16 -1
  122. package/dist/commands/shared.js.map +1 -1
  123. package/dist/{utils/config.d.ts → config/profiles.d.ts} +9 -1
  124. package/dist/config/profiles.d.ts.map +1 -0
  125. package/dist/{utils/config.js → config/profiles.js} +1 -1
  126. package/dist/config/profiles.js.map +1 -0
  127. package/dist/index.d.ts +12 -3
  128. package/dist/index.d.ts.map +1 -1
  129. package/dist/index.js +12 -2
  130. package/dist/index.js.map +1 -1
  131. package/dist/mcp/prompts.js +7 -7
  132. package/dist/mcp/prompts.js.map +1 -1
  133. package/dist/mcp/server.d.ts +14 -0
  134. package/dist/mcp/server.d.ts.map +1 -0
  135. package/dist/mcp/server.js +61 -0
  136. package/dist/mcp/server.js.map +1 -0
  137. package/dist/mcp/tools/analysis.d.ts.map +1 -1
  138. package/dist/mcp/tools/analysis.js +74 -46
  139. package/dist/mcp/tools/analysis.js.map +1 -1
  140. package/dist/mcp/tools/anypoint-mq.d.ts.map +1 -1
  141. package/dist/mcp/tools/anypoint-mq.js +25 -54
  142. package/dist/mcp/tools/anypoint-mq.js.map +1 -1
  143. package/dist/mcp/tools/api-manager.d.ts +2 -1
  144. package/dist/mcp/tools/api-manager.d.ts.map +1 -1
  145. package/dist/mcp/tools/api-manager.js +154 -89
  146. package/dist/mcp/tools/api-manager.js.map +1 -1
  147. package/dist/mcp/tools/app-inputs.d.ts +92 -0
  148. package/dist/mcp/tools/app-inputs.d.ts.map +1 -0
  149. package/dist/mcp/tools/app-inputs.js +142 -0
  150. package/dist/mcp/tools/app-inputs.js.map +1 -0
  151. package/dist/mcp/tools/apps-deploy.d.ts +13 -0
  152. package/dist/mcp/tools/apps-deploy.d.ts.map +1 -0
  153. package/dist/mcp/tools/apps-deploy.js +358 -0
  154. package/dist/mcp/tools/apps-deploy.js.map +1 -0
  155. package/dist/mcp/tools/apps-lifecycle.d.ts +11 -0
  156. package/dist/mcp/tools/apps-lifecycle.d.ts.map +1 -0
  157. package/dist/mcp/tools/apps-lifecycle.js +244 -0
  158. package/dist/mcp/tools/apps-lifecycle.js.map +1 -0
  159. package/dist/mcp/tools/apps-read.d.ts +9 -0
  160. package/dist/mcp/tools/apps-read.d.ts.map +1 -0
  161. package/dist/mcp/tools/apps-read.js +414 -0
  162. package/dist/mcp/tools/apps-read.js.map +1 -0
  163. package/dist/mcp/tools/artifacts.d.ts +8 -0
  164. package/dist/mcp/tools/artifacts.d.ts.map +1 -0
  165. package/dist/mcp/tools/artifacts.js +81 -0
  166. package/dist/mcp/tools/artifacts.js.map +1 -0
  167. package/dist/mcp/tools/audit.d.ts.map +1 -1
  168. package/dist/mcp/tools/audit.js +9 -17
  169. package/dist/mcp/tools/audit.js.map +1 -1
  170. package/dist/mcp/tools/design-center.d.ts +2 -3
  171. package/dist/mcp/tools/design-center.d.ts.map +1 -1
  172. package/dist/mcp/tools/design-center.js +41 -185
  173. package/dist/mcp/tools/design-center.js.map +1 -1
  174. package/dist/mcp/tools/exchange.d.ts +1 -2
  175. package/dist/mcp/tools/exchange.d.ts.map +1 -1
  176. package/dist/mcp/tools/exchange.js +51 -312
  177. package/dist/mcp/tools/exchange.js.map +1 -1
  178. package/dist/mcp/tools/governance.d.ts +8 -0
  179. package/dist/mcp/tools/governance.d.ts.map +1 -0
  180. package/dist/mcp/tools/governance.js +59 -0
  181. package/dist/mcp/tools/governance.js.map +1 -0
  182. package/dist/mcp/tools/identity.d.ts.map +1 -1
  183. package/dist/mcp/tools/identity.js +15 -36
  184. package/dist/mcp/tools/identity.js.map +1 -1
  185. package/dist/mcp/tools/index.d.ts +5 -1
  186. package/dist/mcp/tools/index.d.ts.map +1 -1
  187. package/dist/mcp/tools/index.js +5 -1
  188. package/dist/mcp/tools/index.js.map +1 -1
  189. package/dist/mcp/tools/logs.d.ts +48 -2
  190. package/dist/mcp/tools/logs.d.ts.map +1 -1
  191. package/dist/mcp/tools/logs.js +204 -54
  192. package/dist/mcp/tools/logs.js.map +1 -1
  193. package/dist/mcp/tools/monitoring.d.ts +1 -2
  194. package/dist/mcp/tools/monitoring.d.ts.map +1 -1
  195. package/dist/mcp/tools/monitoring.js +78 -285
  196. package/dist/mcp/tools/monitoring.js.map +1 -1
  197. package/dist/mcp/tools/object-store.d.ts +1 -1
  198. package/dist/mcp/tools/object-store.d.ts.map +1 -1
  199. package/dist/mcp/tools/object-store.js +19 -59
  200. package/dist/mcp/tools/object-store.js.map +1 -1
  201. package/dist/mcp/tools/profile.d.ts.map +1 -1
  202. package/dist/mcp/tools/profile.js +15 -35
  203. package/dist/mcp/tools/profile.js.map +1 -1
  204. package/dist/mcp/tools/shared.d.ts +43 -0
  205. package/dist/mcp/tools/shared.d.ts.map +1 -1
  206. package/dist/mcp/tools/shared.js +54 -0
  207. package/dist/mcp/tools/shared.js.map +1 -1
  208. package/dist/mcp.d.ts +3 -11
  209. package/dist/mcp.d.ts.map +1 -1
  210. package/dist/mcp.js +4 -56
  211. package/dist/mcp.js.map +1 -1
  212. package/dist/safety/deployment.d.ts +47 -2
  213. package/dist/safety/deployment.d.ts.map +1 -1
  214. package/dist/safety/deployment.js +139 -6
  215. package/dist/safety/deployment.js.map +1 -1
  216. package/dist/safety/guards.d.ts +2 -2
  217. package/dist/safety/guards.d.ts.map +1 -1
  218. package/dist/safety/guards.js +4 -4
  219. package/dist/safety/guards.js.map +1 -1
  220. package/dist/safety/paths.d.ts +29 -0
  221. package/dist/safety/paths.d.ts.map +1 -0
  222. package/dist/safety/paths.js +76 -0
  223. package/dist/safety/paths.js.map +1 -0
  224. package/dist/safety/runtime.d.ts +24 -0
  225. package/dist/safety/runtime.d.ts.map +1 -0
  226. package/dist/safety/runtime.js +59 -0
  227. package/dist/safety/runtime.js.map +1 -0
  228. package/dist/safety/secret-sources.d.ts +51 -0
  229. package/dist/safety/secret-sources.d.ts.map +1 -0
  230. package/dist/safety/secret-sources.js +124 -0
  231. package/dist/safety/secret-sources.js.map +1 -0
  232. package/dist/safety/secrets.d.ts +32 -0
  233. package/dist/safety/secrets.d.ts.map +1 -0
  234. package/dist/safety/secrets.js +91 -0
  235. package/dist/safety/secrets.js.map +1 -0
  236. package/dist/utils/errors.d.ts +14 -1
  237. package/dist/utils/errors.d.ts.map +1 -1
  238. package/dist/utils/errors.js +31 -3
  239. package/dist/utils/errors.js.map +1 -1
  240. package/dist/workflows/app-change.d.ts +124 -0
  241. package/dist/workflows/app-change.d.ts.map +1 -0
  242. package/dist/workflows/app-change.js +305 -0
  243. package/dist/workflows/app-change.js.map +1 -0
  244. package/dist/workflows/app-state.d.ts +60 -0
  245. package/dist/workflows/app-state.d.ts.map +1 -0
  246. package/dist/workflows/app-state.js +95 -0
  247. package/dist/workflows/app-state.js.map +1 -0
  248. package/dist/workflows/artifact-compare.d.ts +134 -0
  249. package/dist/workflows/artifact-compare.d.ts.map +1 -0
  250. package/dist/workflows/artifact-compare.js +419 -0
  251. package/dist/workflows/artifact-compare.js.map +1 -0
  252. package/dist/workflows/asset-naming.d.ts +72 -0
  253. package/dist/workflows/asset-naming.d.ts.map +1 -0
  254. package/dist/workflows/asset-naming.js +116 -0
  255. package/dist/workflows/asset-naming.js.map +1 -0
  256. package/dist/{api/DesignCenterWorkflow.d.ts → workflows/design-center.d.ts} +4 -4
  257. package/dist/workflows/design-center.d.ts.map +1 -0
  258. package/dist/{api/DesignCenterWorkflow.js → workflows/design-center.js} +1 -1
  259. package/dist/workflows/design-center.js.map +1 -0
  260. package/dist/workflows/jar-deployment.d.ts +156 -0
  261. package/dist/workflows/jar-deployment.d.ts.map +1 -0
  262. package/dist/workflows/jar-deployment.js +178 -0
  263. package/dist/workflows/jar-deployment.js.map +1 -0
  264. package/package.json +12 -4
  265. package/dist/analysis/utils.d.ts.map +0 -1
  266. package/dist/analysis/utils.js.map +0 -1
  267. package/dist/api/DesignCenterWorkflow.d.ts.map +0 -1
  268. package/dist/api/DesignCenterWorkflow.js.map +0 -1
  269. package/dist/api/index.d.ts +0 -13
  270. package/dist/api/index.d.ts.map +0 -1
  271. package/dist/api/index.js +0 -13
  272. package/dist/api/index.js.map +0 -1
  273. package/dist/mcp/tools/applications.d.ts +0 -4
  274. package/dist/mcp/tools/applications.d.ts.map +0 -1
  275. package/dist/mcp/tools/applications.js +0 -815
  276. package/dist/mcp/tools/applications.js.map +0 -1
  277. package/dist/utils/config.d.ts.map +0 -1
  278. package/dist/utils/config.js.map +0 -1
package/README.md CHANGED
@@ -63,16 +63,29 @@ release does not support the `client_credentials` grant, and its encrypted token
63
63
 
64
64
  | Area | Examples |
65
65
  | --- | --- |
66
- | Applications | Status, deployment spec, resources, settings, deploy, redeploy, rollback, restart, scale, stop, start, delete |
67
- | Logs | Tail, download, error clustering with context, recurring patterns, statistical health |
68
- | Monitoring | Request metrics, percentiles, time series, per-replica metrics, JVM memory and GC, freeform AMQL |
69
- | Exchange | Search, asset details, spec download, JAR publication, environment comparison |
70
- | API Manager | Instances, policies, SLA tiers, alerts |
71
- | Design Center | Projects, branches, conflict-safe file synchronization, governed publication |
66
+ | Applications | Status with a start-up-aware phase, deployment spec, resources, cross-environment comparison, publish and deploy a JAR, one-call `update_app` (version, runtime, settings and update strategy, in place or stop-then-start), runtime catalogs with retired-runtime refusal, asset naming conventions, rollback, restart, scale, stop, start, delete, and a check of what runs against a repo or JAR |
67
+ | Settings | Add, change, remove and move properties; secret values read from project files or environment variables; secret-looking plain values masked and flagged |
68
+ | Logs | Tail, search over message, logger and stack trace, download with filters, summaries and file output, error clustering with context, recurring patterns, log health statistics |
69
+ | Monitoring | Traffic, failures, and p50–p99 latency per app, worker, or route; heap, old-generation pressure, GC, CPU, and RAM per worker; time series from 1-minute to 1-day buckets; freeform AMQL |
70
+ | Exchange | Search, asset details, spec download, application JAR publication |
71
+ | API Manager and Governance | Instances, policies, SLA tiers, alerts, contracts, client applications with masked credentials, smoke tests with the client's credentials, governance rulesets and conformance |
72
+ | Design Center | Projects, branches, file reads, preview-then-apply file sync, verified Exchange publication |
72
73
  | Platform services | Environments, entitlements, audit log, Anypoint MQ, Object Store v2 |
73
74
 
75
+ New in 0.16, each with a recipe:
76
+
77
+ - `update_app` with `mode: "stopStart"`: [deploy a listener-driven app without overlap](https://avinava.github.io/anypoint-connect/recipes/#deploy-a-listener-driven-app-without-overlap)
78
+ - `list_runtime_versions`: [move an app off a retired runtime](https://avinava.github.io/anypoint-connect/recipes/#move-an-app-off-a-retired-runtime)
79
+ - `securePropertiesFrom`: [add or rotate one secret](https://avinava.github.io/anypoint-connect/recipes/#add-or-rotate-one-secret)
80
+ - `moveToSecure`: [move a plain-text secret to secure](https://avinava.github.io/anypoint-connect/recipes/#move-a-plain-text-secret-to-secure)
81
+ - `compare_deployed_artifact`: [check that a repository matches what runs](https://avinava.github.io/anypoint-connect/recipes/#check-that-a-repository-matches-what-runs)
82
+ - `smoke_test_api`: [smoke test an API with its client credentials](https://avinava.github.io/anypoint-connect/recipes/#smoke-test-an-api-with-its-client-credentials)
83
+ - `download_logs` summary and `outputFile`: [keep log downloads small](https://avinava.github.io/anypoint-connect/recipes/#keep-log-downloads-small)
84
+
74
85
  Copyable task flows are in [Common recipes](https://avinava.github.io/anypoint-connect/recipes/); every CLI
75
- command is in the [CLI reference](https://avinava.github.io/anypoint-connect/cli-reference/).
86
+ command is in the [CLI reference](https://avinava.github.io/anypoint-connect/cli-reference/), every MCP tool
87
+ in the [tool catalog](https://avinava.github.io/anypoint-connect/tools/), and how to read runtime metrics in
88
+ [Monitoring](https://avinava.github.io/anypoint-connect/monitoring/).
76
89
 
77
90
  ## MCP server
78
91
 
@@ -84,7 +97,7 @@ OAuth tokens; it sends tool calls to the local server that owns the session.
84
97
  "mcpServers": {
85
98
  "anypoint-connect": {
86
99
  "command": "npx",
87
- "args": ["-y", "@sfdxy/anypoint-connect@0.14.0", "mcp"]
100
+ "args": ["-y", "@sfdxy/anypoint-connect@0.16.2", "mcp"]
88
101
  }
89
102
  }
90
103
  }
@@ -99,33 +112,43 @@ Example requests use synthetic names:
99
112
  ```text
100
113
  What applications are visible in Sandbox? Read only.
101
114
  Analyze errors for sample-orders-api in Sandbox over the last two hours.
115
+ Is the old generation of sample-orders-api in Production close to its limit?
102
116
  Preview a deployment of target/sample-orders-api-1.3.0-mule-application.jar to Sandbox; do not apply it.
103
117
  ```
104
118
 
105
119
  ## Safety
106
120
 
107
- Mutating MCP tools are previews until `confirm: true` is supplied. Artifact updates preserve runtime,
108
- target, replicas, and settings. Deletion requires the deployment ID returned by the preview, and
109
- production operations require an additional acknowledgement.
121
+ Every MCP write tool returns a preview first and changes nothing until it is called again with
122
+ `confirm: true`; in production it also needs `confirmProduction: true`. `anc deploy --dry-run` and
123
+ `anc apps update --dry-run` print the same plan.
124
+ Publishing binds the JAR's SHA-256. A change to an existing app is one update that carries only what you
125
+ asked to change, with the runtime checked against the target first. Secret values come from project files
126
+ or environment variables, never the conversation. Deletion requires the deployment ID returned by the
127
+ preview, and Design Center writes require a single-use preview token.
110
128
 
111
129
  ```jsonc
112
130
  // Preview only
113
- update_app_artifact({
114
- "appName": "sample-orders-api",
131
+ update_app({
132
+ "appName": "orders-sapi",
115
133
  "environment": "Sandbox",
116
- "version": "1.3.0"
134
+ "version": "1.3.0",
135
+ "mode": "stopStart"
117
136
  })
118
137
 
119
138
  // Apply the reviewed change
120
- update_app_artifact({
121
- "appName": "sample-orders-api",
139
+ update_app({
140
+ "appName": "orders-sapi",
122
141
  "environment": "Sandbox",
123
142
  "version": "1.3.0",
143
+ "mode": "stopStart",
124
144
  "confirm": true
125
145
  })
126
146
  ```
127
147
 
128
148
  The complete contract is in the [safety model](https://avinava.github.io/anypoint-connect/safety/).
149
+ Upgrading from 0.15? The
150
+ [migration tables](https://github.com/Avinava/anypoint-connect/blob/main/CHANGELOG.md#migration-from-015x)
151
+ list every changed tool, command and library call.
129
152
 
130
153
  ## Library
131
154
 
@@ -9,18 +9,24 @@
9
9
  * - error-context.ts — Error context window builder
10
10
  * - error-grouper.ts — Clusters similar errors
11
11
  * - pattern-detector.ts — Identifies recurring message templates
12
- * - stats.ts — Level distribution, error rate, spike detection
12
+ * - stats.ts — Level distribution, error rate, spike detection, histogram
13
+ * - filter.ts - Time, level, logger and text filters shared by every log surface
13
14
  */
14
15
  export type { EnrichedLogEntry, ErrorWithContext, ErrorGroup, LogPattern, ErrorSpike, LogStats, AnalysisOptions, AnalysisResult, } from './types.js';
15
16
  export { parseRawLogs } from './parser.js';
16
17
  export { buildErrorContexts } from './error-context.js';
17
18
  export { groupErrors } from './error-grouper.js';
18
19
  export { detectPatterns } from './pattern-detector.js';
19
- export { calculateStats } from './stats.js';
20
- export { templatize, isNoise, LEVEL_PRIORITY } from './utils.js';
20
+ export { calculateStats, histogram, topCounts, BUCKETS, type Bucket, type HistogramBucket } from './stats.js';
21
+ export { templatize, isNoise, LEVEL_PRIORITY } from './normalize.js';
22
+ export { buildFilter, filterEntries, searchEntries, entryText, clampLimit, MAX_LOG_LINES, type LogFilter, type LogSearchOptions, type LogSearchResult, } from './filter.js';
23
+ export { summarizeEntries, formatEntry, formatEntries, MAX_HISTOGRAM_ROWS, type LogSummary, type SummaryOptions, } from './summary.js';
21
24
  import type { AnalysisOptions, AnalysisResult } from './types.js';
22
25
  /**
23
- * Full analysis pipeline: parse → enrich → context → group → pattern → stats.
26
+ * Full analysis pipeline: parse → filter → context → group → pattern → stats.
27
+ * The time window applies to everything. Level, logger and search select the entries
28
+ * that are counted and analyzed as errors; error context still comes from every entry
29
+ * in the window, so a filtered error keeps the lines that led up to it.
24
30
  */
25
31
  export declare function analyzeLogs(rawText: string, options?: AnalysisOptions): AnalysisResult;
26
32
  //# sourceMappingURL=LogAnalyzer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LogAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analysis/LogAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,YAAY,EACR,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,eAAe,EACf,cAAc,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjE,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAQlE;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CAsC1F"}
1
+ {"version":3,"file":"LogAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analysis/LogAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,YAAY,EACR,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,eAAe,EACf,cAAc,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAC9G,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EACH,WAAW,EACX,aAAa,EACb,aAAa,EACb,SAAS,EACT,UAAU,EACV,aAAa,EACb,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACvB,MAAM,aAAa,CAAC;AAErB,OAAO,EACH,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,KAAK,UAAU,EACf,KAAK,cAAc,GACtB,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AASlE;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CA2C1F"}
@@ -9,42 +9,53 @@
9
9
  * - error-context.ts — Error context window builder
10
10
  * - error-grouper.ts — Clusters similar errors
11
11
  * - pattern-detector.ts — Identifies recurring message templates
12
- * - stats.ts — Level distribution, error rate, spike detection
12
+ * - stats.ts — Level distribution, error rate, spike detection, histogram
13
+ * - filter.ts - Time, level, logger and text filters shared by every log surface
13
14
  */
14
15
  // Re-export individual modules for direct use
15
16
  export { parseRawLogs } from './parser.js';
16
17
  export { buildErrorContexts } from './error-context.js';
17
18
  export { groupErrors } from './error-grouper.js';
18
19
  export { detectPatterns } from './pattern-detector.js';
19
- export { calculateStats } from './stats.js';
20
- export { templatize, isNoise, LEVEL_PRIORITY } from './utils.js';
21
- import { LEVEL_PRIORITY } from './utils.js';
20
+ export { calculateStats, histogram, topCounts, BUCKETS } from './stats.js';
21
+ export { templatize, isNoise, LEVEL_PRIORITY } from './normalize.js';
22
+ export { buildFilter, filterEntries, searchEntries, entryText, clampLimit, MAX_LOG_LINES, } from './filter.js';
23
+ export { summarizeEntries, formatEntry, formatEntries, MAX_HISTOGRAM_ROWS, } from './summary.js';
22
24
  import { parseRawLogs } from './parser.js';
23
25
  import { buildErrorContexts } from './error-context.js';
24
26
  import { groupErrors } from './error-grouper.js';
25
27
  import { detectPatterns } from './pattern-detector.js';
26
28
  import { calculateStats } from './stats.js';
29
+ import { buildFilter, levelPriority } from './filter.js';
30
+ import { LEVEL_PRIORITY } from './normalize.js';
27
31
  /**
28
- * Full analysis pipeline: parse → enrich → context → group → pattern → stats.
32
+ * Full analysis pipeline: parse → filter → context → group → pattern → stats.
33
+ * The time window applies to everything. Level, logger and search select the entries
34
+ * that are counted and analyzed as errors; error context still comes from every entry
35
+ * in the window, so a filtered error keeps the lines that led up to it.
29
36
  */
30
37
  export function analyzeLogs(rawText, options = {}) {
31
38
  const totalLines = rawText.split('\n').length;
32
39
  // 1. Parse and join multi-line entries
33
- let entries = parseRawLogs(rawText);
34
- // 2. Filter by time if requested
35
- if (options.hoursBack) {
36
- const cutoff = Date.now() - options.hoursBack * 60 * 60 * 1000;
37
- entries = entries.filter((e) => e.timestamp >= cutoff);
38
- }
39
- // 3. Filter by level if requested
40
- if (options.level) {
41
- const minLevel = LEVEL_PRIORITY[options.level.toUpperCase()] ?? 0;
42
- entries = entries.filter((e) => (LEVEL_PRIORITY[e.priority] ?? 0) >= minLevel);
43
- }
44
- // 4. Build error contexts
45
- const errorContexts = buildErrorContexts(entries, {
40
+ const parsed = parseRawLogs(rawText);
41
+ // 2. Time window
42
+ const startTime = options.startTime ?? (options.hoursBack ? Date.now() - options.hoursBack * 60 * 60 * 1000 : undefined);
43
+ const inWindow = buildFilter({ startTime, endTime: options.endTime });
44
+ const windowed = parsed.filter(inWindow);
45
+ // 3. Level, logger and search
46
+ const selected = buildFilter({
47
+ level: options.level,
48
+ logger: options.logger,
49
+ search: options.search,
50
+ regex: options.regex,
51
+ });
52
+ const entries = windowed.filter(selected);
53
+ // 4. Build error contexts over the whole window
54
+ const minErrorLevel = levelPriority(options.errorLevel ?? 'ERROR');
55
+ const errorContexts = buildErrorContexts(windowed, {
46
56
  beforeCount: options.contextBefore,
47
57
  afterCount: options.contextAfter,
58
+ isError: (e) => (LEVEL_PRIORITY[e.priority] ?? 0) >= minErrorLevel && selected(e),
48
59
  });
49
60
  // 5. Group errors
50
61
  const errorGroups = groupErrors(errorContexts, {
@@ -1 +1 @@
1
- {"version":3,"file":"LogAnalyzer.js","sourceRoot":"","sources":["../../src/analysis/LogAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAcH,8CAA8C;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,UAA2B,EAAE;IACtE,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IAE9C,uCAAuC;IACvC,IAAI,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAEpC,iCAAiC;IACjC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QAC/D,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC;IAC3D,CAAC;IAED,kCAAkC;IAClC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC;QAClE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC;IACnF,CAAC;IAED,0BAA0B;IAC1B,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,EAAE;QAC9C,WAAW,EAAE,OAAO,CAAC,aAAa;QAClC,UAAU,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;IAEH,kBAAkB;IAClB,MAAM,WAAW,GAAG,WAAW,CAAC,aAAa,EAAE;QAC3C,SAAS,EAAE,OAAO,CAAC,cAAc;KACpC,CAAC,CAAC;IAEH,qBAAqB;IACrB,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,EAAE;QACrC,IAAI,EAAE,OAAO,CAAC,WAAW;KAC5B,CAAC,CAAC;IAEH,qBAAqB;IACrB,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAEzE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACpE,CAAC"}
1
+ {"version":3,"file":"LogAnalyzer.js","sourceRoot":"","sources":["../../src/analysis/LogAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,8 @@ export interface ErrorContextOptions {
11
11
  afterCount?: number;
12
12
  /** Time window in ms for fallback mode (default: 30000) */
13
13
  timeWindowMs?: number;
14
+ /** Which entries count as errors (default: ERROR and FATAL) */
15
+ isError?: (entry: EnrichedLogEntry) => boolean;
14
16
  }
15
17
  /**
16
18
  * Build error context for all ERROR entries.
@@ -1 +1 @@
1
- {"version":3,"file":"error-context.d.ts","sourceRoot":"","sources":["../../src/analysis/error-context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErE,MAAM,WAAW,mBAAmB;IAChC,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,OAAO,GAAE,mBAAwB,GAAG,gBAAgB,EAAE,CAiDrH"}
1
+ {"version":3,"file":"error-context.d.ts","sourceRoot":"","sources":["../../src/analysis/error-context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErE,MAAM,WAAW,mBAAmB;IAChC,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC;CAClD;AAID;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,OAAO,GAAE,mBAAwB,GAAG,gBAAgB,EAAE,CAiDrH"}
@@ -3,6 +3,7 @@
3
3
  * Builds before/after context windows for ERROR entries.
4
4
  * Uses correlation-based context when available, time-window fallback otherwise.
5
5
  */
6
+ const isErrorLevel = (entry) => entry.priority === 'ERROR' || entry.priority === 'FATAL';
6
7
  /**
7
8
  * Build error context for all ERROR entries.
8
9
  */
@@ -10,7 +11,7 @@ export function buildErrorContexts(entries, options = {}) {
10
11
  const beforeCount = options.beforeCount ?? 15;
11
12
  const afterCount = options.afterCount ?? 10;
12
13
  const timeWindowMs = options.timeWindowMs ?? 30000;
13
- const errorEntries = entries.filter((e) => e.priority === 'ERROR');
14
+ const errorEntries = entries.filter(options.isError ?? isErrorLevel);
14
15
  const contexts = [];
15
16
  // Build correlation index for fast lookup
16
17
  const correlationIndex = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"error-context.js","sourceRoot":"","sources":["../../src/analysis/error-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"error-context.js","sourceRoot":"","sources":["../../src/analysis/error-context.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  * Log Analysis — Error Grouper
3
3
  * Clusters similar errors by (errorType + message template).
4
4
  */
5
- import { templatize } from './utils.js';
5
+ import { templatize } from './normalize.js';
6
6
  /**
7
7
  * Group similar errors by error type and message pattern.
8
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"error-grouper.js","sourceRoot":"","sources":["../../src/analysis/error-grouper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AASxC;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,QAA4B,EAAE,UAA+B,EAAE;IACvF,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;IAE1C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgE,CAAC;IAEvF,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC;QACnD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,GAAG,SAAS,KAAK,QAAQ,EAAE,CAAC;QAExC,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,KAAK,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;YAC3C,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC3B,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACrB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;SAC/B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;SAC3D,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAEzB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC/B,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;QAEvE,OAAO;YACH,SAAS;YACT,QAAQ;YACR,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;YAC5B,SAAS,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YAChD,QAAQ,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YACnE,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;YAC5C,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;SAClC,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"error-grouper.js","sourceRoot":"","sources":["../../src/analysis/error-grouper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAS5C;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,QAA4B,EAAE,UAA+B,EAAE;IACvF,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;IAE1C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgE,CAAC;IAEvF,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC;QACnD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,GAAG,SAAS,KAAK,QAAQ,EAAE,CAAC;QAExC,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,KAAK,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;YAC3C,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC3B,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACrB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;SAC/B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;SAC3D,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAEzB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC/B,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;QAEvE,OAAO;YACH,SAAS;YACT,QAAQ;YACR,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;YAC5B,SAAS,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YAChD,QAAQ,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YACnE,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;YAC5C,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;SAClC,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Log Analysis - Filter
3
+ * One filter for every log surface: time window, minimum level, logger and text search.
4
+ * Search covers the whole entry (logger, thread, message, stack trace and JSON payload),
5
+ * so text on continuation lines is found on the entry it belongs to.
6
+ */
7
+ import type { EnrichedLogEntry } from './types.js';
8
+ /** Hard cap on the lines a single search returns. */
9
+ export declare const MAX_LOG_LINES = 1000;
10
+ export interface LogFilter {
11
+ /** Inclusive start, epoch milliseconds */
12
+ startTime?: number;
13
+ /** Inclusive end, epoch milliseconds */
14
+ endTime?: number;
15
+ /** Minimum level: TRACE, DEBUG, INFO, WARN, ERROR or FATAL */
16
+ level?: string;
17
+ /** Case-insensitive substring of the logger name */
18
+ logger?: string;
19
+ /** Text to find anywhere in the entry */
20
+ search?: string;
21
+ /** Treat `search` as a case-insensitive regular expression */
22
+ regex?: boolean;
23
+ }
24
+ export interface LogSearchOptions extends LogFilter {
25
+ /** Most entries to return, newest first (default 100, capped at MAX_LOG_LINES) */
26
+ limit?: number;
27
+ }
28
+ export interface LogSearchResult {
29
+ /** Matches before `limit` was applied */
30
+ total: number;
31
+ /** Entries in this response */
32
+ returned: number;
33
+ truncated: boolean;
34
+ /** Newest first */
35
+ entries: EnrichedLogEntry[];
36
+ }
37
+ /** Validate a level name, returning its numeric priority. */
38
+ export declare function levelPriority(level: string): number;
39
+ /** Build the text matcher for a search term, or null when there is none. */
40
+ export declare function buildMatcher(search?: string, regex?: boolean): ((text: string) => boolean) | null;
41
+ /** The searchable text of an entry, in log line order. */
42
+ export declare function entryText(entry: EnrichedLogEntry): string;
43
+ /** Build a predicate for a filter. Validates the level and regex up front. */
44
+ export declare function buildFilter(filter: LogFilter): (entry: EnrichedLogEntry) => boolean;
45
+ /** Keep the entries that pass a filter, in their original order. */
46
+ export declare function filterEntries(entries: EnrichedLogEntry[], filter: LogFilter): EnrichedLogEntry[];
47
+ /** Clamp a requested line count to 1..MAX_LOG_LINES. */
48
+ export declare function clampLimit(limit: number | undefined, fallback?: number): number;
49
+ /**
50
+ * Filter entries and return the newest `limit` matches.
51
+ * `total` counts every match, so callers can tell when the result was cut.
52
+ */
53
+ export declare function searchEntries(entries: EnrichedLogEntry[], options?: LogSearchOptions): LogSearchResult;
54
+ //# sourceMappingURL=filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/analysis/filter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,qDAAqD;AACrD,eAAO,MAAM,aAAa,OAAO,CAAC;AAKlC,MAAM,WAAW,SAAS;IACtB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IAC/C,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC5B,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,mBAAmB;IACnB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC/B;AAED,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,IAAI,CAgBjG;AAED,0DAA0D;AAC1D,wBAAgB,SAAS,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAazD;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAcnF;AAED,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,MAAM,EAAE,SAAS,GAAG,gBAAgB,EAAE,CAGhG;AAED,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,SAAM,GAAG,MAAM,CAG5E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,OAAO,GAAE,gBAAqB,GAAG,eAAe,CAO1G"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Log Analysis - Filter
3
+ * One filter for every log surface: time window, minimum level, logger and text search.
4
+ * Search covers the whole entry (logger, thread, message, stack trace and JSON payload),
5
+ * so text on continuation lines is found on the entry it belongs to.
6
+ */
7
+ import { LEVEL_PRIORITY } from './normalize.js';
8
+ /** Hard cap on the lines a single search returns. */
9
+ export const MAX_LOG_LINES = 1000;
10
+ /** Longest regex pattern accepted for search. */
11
+ const MAX_PATTERN_LENGTH = 500;
12
+ /** Validate a level name, returning its numeric priority. */
13
+ export function levelPriority(level) {
14
+ const name = level.toUpperCase();
15
+ const priority = LEVEL_PRIORITY[name === 'WARNING' ? 'WARN' : name];
16
+ if (priority === undefined) {
17
+ throw new Error(`Unknown log level "${level}". Use one of ${Object.keys(LEVEL_PRIORITY).join(', ')}`);
18
+ }
19
+ return priority;
20
+ }
21
+ /** Build the text matcher for a search term, or null when there is none. */
22
+ export function buildMatcher(search, regex) {
23
+ if (!search)
24
+ return null;
25
+ if (regex) {
26
+ if (search.length > MAX_PATTERN_LENGTH) {
27
+ throw new Error(`Search regex is longer than ${MAX_PATTERN_LENGTH} characters`);
28
+ }
29
+ let pattern;
30
+ try {
31
+ pattern = new RegExp(search, 'i');
32
+ }
33
+ catch (error) {
34
+ throw new Error(`Invalid search regex: ${error.message}`);
35
+ }
36
+ return (text) => pattern.test(text);
37
+ }
38
+ const needle = search.toLowerCase();
39
+ return (text) => text.toLowerCase().includes(needle);
40
+ }
41
+ /** The searchable text of an entry, in log line order. */
42
+ export function entryText(entry) {
43
+ const header = [
44
+ entry.loggerName,
45
+ entry.eventId ? `event:${entry.eventId}` : undefined,
46
+ entry.threadName !== undefined ? `${entry.threadName} -` : undefined,
47
+ entry.message,
48
+ ]
49
+ .filter((part) => part !== undefined && part !== '')
50
+ .join(' ');
51
+ const parts = [header];
52
+ if (entry.stackTrace)
53
+ parts.push(entry.stackTrace);
54
+ if (entry.jsonPayload)
55
+ parts.push(JSON.stringify(entry.jsonPayload));
56
+ return parts.join('\n');
57
+ }
58
+ /** Build a predicate for a filter. Validates the level and regex up front. */
59
+ export function buildFilter(filter) {
60
+ const minLevel = filter.level ? levelPriority(filter.level) : undefined;
61
+ const logger = filter.logger?.toLowerCase();
62
+ const matches = buildMatcher(filter.search, filter.regex);
63
+ return (entry) => {
64
+ if (filter.startTime !== undefined && entry.timestamp < filter.startTime)
65
+ return false;
66
+ if (filter.endTime !== undefined && entry.timestamp > filter.endTime)
67
+ return false;
68
+ if (minLevel !== undefined && (LEVEL_PRIORITY[entry.priority] ?? 0) < minLevel)
69
+ return false;
70
+ if (logger && !(entry.loggerName ?? '').toLowerCase().includes(logger))
71
+ return false;
72
+ // The message alone first, so a regex anchored with ^ or $ means the message.
73
+ if (matches && !matches(entry.message ?? '') && !matches(entryText(entry)))
74
+ return false;
75
+ return true;
76
+ };
77
+ }
78
+ /** Keep the entries that pass a filter, in their original order. */
79
+ export function filterEntries(entries, filter) {
80
+ const keep = buildFilter(filter);
81
+ return entries.filter(keep);
82
+ }
83
+ /** Clamp a requested line count to 1..MAX_LOG_LINES. */
84
+ export function clampLimit(limit, fallback = 100) {
85
+ const value = limit === undefined || !Number.isFinite(limit) ? fallback : Math.floor(limit);
86
+ return Math.min(Math.max(value, 1), MAX_LOG_LINES);
87
+ }
88
+ /**
89
+ * Filter entries and return the newest `limit` matches.
90
+ * `total` counts every match, so callers can tell when the result was cut.
91
+ */
92
+ export function searchEntries(entries, options = {}) {
93
+ const limit = clampLimit(options.limit);
94
+ const matched = filterEntries(entries, options);
95
+ // Reverse, then a stable sort: entries that share a timestamp stay newest first.
96
+ const newestFirst = [...matched].reverse().sort((a, b) => b.timestamp - a.timestamp);
97
+ const page = newestFirst.slice(0, limit);
98
+ return { total: matched.length, returned: page.length, truncated: matched.length > page.length, entries: page };
99
+ }
100
+ //# sourceMappingURL=filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.js","sourceRoot":"","sources":["../../src/analysis/filter.ts"],"names":[],"mappings":"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"}
@@ -13,4 +13,4 @@ export declare function templatize(message: string): string;
13
13
  * Check if an entry is HTTP listener noise.
14
14
  */
15
15
  export declare function isNoise(entry: EnrichedLogEntry): boolean;
16
- //# sourceMappingURL=utils.d.ts.map
16
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/analysis/normalize.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAgBnD,+CAA+C;AAC/C,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOjD,CAAC;AAEF;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUlD;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CASxD"}
@@ -5,7 +5,7 @@
5
5
  /** Variable-like tokens to replace with <*> in pattern detection */
6
6
  const VARIABLE_PATTERNS = [
7
7
  /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi, // UUIDs
8
- /\b[a-zA-Z0-9]{15,18}\b/g, // Salesforce IDs
8
+ /\b[a-zA-Z0-9]{15,18}\b/g, // Opaque 15-18 character record IDs
9
9
  /\b\d{4}-\d{2}-\d{2}T[\d:.]+Z?\b/g, // ISO timestamps
10
10
  /\b\d+\.\d+\.\d+\.\d+\b/g, // IP addresses
11
11
  /\b\d{5,}\b/g, // Long numbers (5+ digits)
@@ -52,4 +52,4 @@ export function isNoise(entry) {
52
52
  }
53
53
  return false;
54
54
  }
55
- //# sourceMappingURL=utils.js.map
55
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/analysis/normalize.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,oEAAoE;AACpE,MAAM,iBAAiB,GAAG;IACtB,oEAAoE,EAAE,QAAQ;IAC9E,yBAAyB,EAAE,oCAAoC;IAC/D,kCAAkC,EAAE,iBAAiB;IACrD,yBAAyB,EAAE,eAAe;IAC1C,aAAa,EAAE,2BAA2B;IAC1C,qBAAqB,EAAE,gBAAgB;IACvC,qBAAqB,EAAE,wCAAwC;CAClE,CAAC;AAEF,kCAAkC;AAClC,MAAM,qBAAqB,GAAG,iCAAiC,CAAC;AAEhE,+CAA+C;AAC/C,MAAM,CAAC,MAAM,cAAc,GAA2B;IAClD,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;CACX,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe;IACtC,IAAI,MAAM,GAAG,OAAO,CAAC;IACrB,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;QACtC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACtB,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;IAC9C,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,KAAuB;IAC3C,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;QAC5C,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;YAAE,OAAO,IAAI,CAAC;IACtF,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAC9C,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;IAC/D,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/analysis/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AASnD;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAoFhE"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/analysis/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAuCnD;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAkFhE"}
@@ -3,16 +3,34 @@
3
3
  * Parses raw CloudHub log text into enriched entries, joining multi-line blocks.
4
4
  * Handles: JSON Logger blocks, stack traces, HTTP dumps, continuation lines.
5
5
  */
6
+ /** ISO timestamp, level and replica: the prefix every new entry starts with. */
7
+ const HEADER_PREFIX = String.raw `^(\d{4}-\d{2}-\d{2}T[\d:.]+(?:Z|[+-]\d{2}:?\d{2}))\s+(TRACE|DEBUG|INFO|WARN|ERROR|FATAL)\s+\[([^\]]*)\]`;
6
8
  /**
7
- * Enhanced log line regex that captures:
8
- * - timestamp, level, instanceId, loggerName, eventId, thread, message
9
+ * Full Mule line: timestamp, level, instanceId, loggerName, optional eventId, thread, message.
10
+ * The first " - " separates the thread from the message.
9
11
  */
10
- const LOG_LINE_REGEX = /^(\d{4}-\d{2}-\d{2}T[\d:.]+Z)\s+(TRACE|DEBUG|INFO|WARN|ERROR|FATAL)\s+\[([^\]]*)\]\s+(\S+)\s+(?:event:(\S+)\s+)?(.+?)(?:\s+-\s+(.*))?$/;
12
+ const LOG_LINE_REGEX = new RegExp(HEADER_PREFIX + String.raw `\s+(\S+)\s+(?:event:(\S+)\s+)?(.+?)\s+-(?:\s(.*))?$`);
13
+ /** Any other line with the header prefix: the rest of the line is the message. */
14
+ const LOOSE_LINE_REGEX = new RegExp(HEADER_PREFIX + String.raw `\s*(.*)$`);
15
+ /** Parse the first line of an entry, or return null for a continuation line. */
16
+ function parseHeader(line) {
17
+ const full = line.match(LOG_LINE_REGEX);
18
+ if (full) {
19
+ const [, timestamp, level, instanceId, loggerName, eventId, threadName, message] = full;
20
+ return { timestamp, level, instanceId, loggerName, eventId, threadName, message: message ?? '' };
21
+ }
22
+ const loose = line.match(LOOSE_LINE_REGEX);
23
+ if (loose) {
24
+ const [, timestamp, level, instanceId, message] = loose;
25
+ return { timestamp, level, instanceId, message };
26
+ }
27
+ return null;
28
+ }
11
29
  /**
12
30
  * Parse raw log text into enriched entries, joining multi-line blocks.
13
31
  */
14
32
  export function parseRawLogs(rawText) {
15
- const lines = rawText.split('\n');
33
+ const lines = rawText.split(/\r?\n/);
16
34
  const entries = [];
17
35
  let current = null;
18
36
  let jsonBuffer = null;
@@ -20,8 +38,8 @@ export function parseRawLogs(rawText) {
20
38
  for (const line of lines) {
21
39
  if (!line.trim())
22
40
  continue;
23
- const match = line.match(LOG_LINE_REGEX);
24
- if (match) {
41
+ const header = parseHeader(line);
42
+ if (header) {
25
43
  // Flush any pending entry
26
44
  if (current) {
27
45
  if (jsonBuffer) {
@@ -31,15 +49,14 @@ export function parseRawLogs(rawText) {
31
49
  }
32
50
  entries.push(current);
33
51
  }
34
- const [, timestamp, level, instanceId, loggerName, eventId, threadOrMessage, messageAfterDash] = match;
35
52
  current = {
36
- timestamp: new Date(timestamp).getTime(),
37
- priority: level,
38
- instanceId,
39
- loggerName,
40
- eventId,
41
- threadName: messageAfterDash !== undefined ? threadOrMessage : undefined,
42
- message: messageAfterDash !== undefined ? messageAfterDash : threadOrMessage,
53
+ timestamp: new Date(header.timestamp.replace(/([+-]\d{2})(\d{2})$/, '$1:$2')).getTime(),
54
+ priority: header.level,
55
+ instanceId: header.instanceId,
56
+ loggerName: header.loggerName,
57
+ eventId: header.eventId,
58
+ threadName: header.threadName,
59
+ message: header.message,
43
60
  };
44
61
  // Check if this is a JSON Logger entry starting with "{"
45
62
  if (current.message !== undefined) {
@@ -96,6 +113,17 @@ export function parseRawLogs(rawText) {
96
113
  }
97
114
  return entries;
98
115
  }
116
+ /** Logger payloads name the stack trace field differently (stackTrace, stacktrace, stack_trace, …). */
117
+ const STACK_TRACE_KEY = /^stack_?trace/i;
118
+ function findStackTrace(payload) {
119
+ if (!payload || typeof payload !== 'object')
120
+ return undefined;
121
+ for (const [key, value] of Object.entries(payload)) {
122
+ if (STACK_TRACE_KEY.test(key) && typeof value === 'string' && value.trim())
123
+ return value;
124
+ }
125
+ return undefined;
126
+ }
99
127
  /**
100
128
  * Parse accumulated JSON lines and enrich the log entry with structured fields.
101
129
  */
@@ -112,9 +140,9 @@ function finalizeJsonEntry(entry, jsonLines) {
112
140
  if (parsed.message && (!entry.message || entry.message.trim() === '')) {
113
141
  entry.message = parsed.message;
114
142
  }
115
- if (parsed.Stacktrace__c || parsed.content?.Stacktrace__c) {
116
- entry.stackTrace = parsed.Stacktrace__c || parsed.content?.Stacktrace__c;
117
- }
143
+ const stackTrace = findStackTrace(parsed) ?? findStackTrace(parsed.content);
144
+ if (stackTrace)
145
+ entry.stackTrace = stackTrace;
118
146
  }
119
147
  catch {
120
148
  entry.message = (entry.message || '') + '\n' + jsonText;