@wizeworks/lens-cloud 0.3.0-alpha.1 → 0.3.0-alpha.3

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 (423) hide show
  1. package/README.md +58 -5
  2. package/dist/alerts/evaluate.d.ts.map +1 -1
  3. package/dist/alerts/evaluate.js +20 -6
  4. package/dist/alerts/evaluate.js.map +1 -1
  5. package/dist/alerts/notify.d.ts +13 -2
  6. package/dist/alerts/notify.d.ts.map +1 -1
  7. package/dist/alerts/notify.js +22 -16
  8. package/dist/alerts/notify.js.map +1 -1
  9. package/dist/app.d.ts +16 -2
  10. package/dist/app.d.ts.map +1 -1
  11. package/dist/auth/auth.d.ts +51 -0
  12. package/dist/auth/auth.d.ts.map +1 -0
  13. package/dist/auth/auth.js +63 -0
  14. package/dist/auth/auth.js.map +1 -0
  15. package/dist/auth/bridge.d.ts +7 -0
  16. package/dist/auth/bridge.d.ts.map +1 -0
  17. package/dist/auth/bridge.js +39 -0
  18. package/dist/auth/bridge.js.map +1 -0
  19. package/dist/auth/crypto.d.ts +0 -5
  20. package/dist/auth/crypto.d.ts.map +1 -1
  21. package/dist/auth/crypto.js +3 -20
  22. package/dist/auth/crypto.js.map +1 -1
  23. package/dist/auth/delete-user.d.ts +16 -0
  24. package/dist/auth/delete-user.d.ts.map +1 -0
  25. package/dist/auth/delete-user.js +21 -0
  26. package/dist/auth/delete-user.js.map +1 -0
  27. package/dist/auth/deps.d.ts +27 -0
  28. package/dist/auth/deps.d.ts.map +1 -0
  29. package/dist/auth/deps.js +3 -0
  30. package/dist/auth/deps.js.map +1 -0
  31. package/dist/auth/email-token.d.ts +8 -0
  32. package/dist/auth/email-token.d.ts.map +1 -0
  33. package/dist/auth/email-token.js +15 -0
  34. package/dist/auth/email-token.js.map +1 -0
  35. package/dist/auth/hooks.d.ts +4 -0
  36. package/dist/auth/hooks.d.ts.map +1 -0
  37. package/dist/auth/hooks.js +143 -0
  38. package/dist/auth/hooks.js.map +1 -0
  39. package/dist/auth/join-scope.d.ts +7 -0
  40. package/dist/auth/join-scope.d.ts.map +1 -0
  41. package/dist/auth/join-scope.js +17 -0
  42. package/dist/auth/join-scope.js.map +1 -0
  43. package/dist/auth/options.d.ts +17 -0
  44. package/dist/auth/options.d.ts.map +1 -0
  45. package/dist/auth/options.js +98 -0
  46. package/dist/auth/options.js.map +1 -0
  47. package/dist/auth/password.d.ts +10 -0
  48. package/dist/auth/password.d.ts.map +1 -0
  49. package/dist/auth/password.js +22 -0
  50. package/dist/auth/password.js.map +1 -0
  51. package/dist/auth/plugins.d.ts +4 -0
  52. package/dist/auth/plugins.d.ts.map +1 -0
  53. package/dist/auth/plugins.js +45 -0
  54. package/dist/auth/plugins.js.map +1 -0
  55. package/dist/auth/principal.d.ts +8 -3
  56. package/dist/auth/principal.d.ts.map +1 -1
  57. package/dist/auth/principal.js +13 -8
  58. package/dist/auth/principal.js.map +1 -1
  59. package/dist/auth/roles.d.ts +43 -3
  60. package/dist/auth/roles.d.ts.map +1 -1
  61. package/dist/auth/roles.js +15 -6
  62. package/dist/auth/roles.js.map +1 -1
  63. package/dist/auth/schema-names.d.ts +130 -0
  64. package/dist/auth/schema-names.d.ts.map +1 -0
  65. package/dist/auth/schema-names.js +53 -0
  66. package/dist/auth/schema-names.js.map +1 -0
  67. package/dist/auth/secret.d.ts +12 -0
  68. package/dist/auth/secret.d.ts.map +1 -0
  69. package/dist/auth/secret.js +32 -0
  70. package/dist/auth/secret.js.map +1 -0
  71. package/dist/auth/security-notices.d.ts +34 -0
  72. package/dist/auth/security-notices.d.ts.map +1 -0
  73. package/dist/auth/security-notices.js +81 -0
  74. package/dist/auth/security-notices.js.map +1 -0
  75. package/dist/auth/signup.d.ts +23 -0
  76. package/dist/auth/signup.d.ts.map +1 -0
  77. package/dist/auth/signup.js +61 -0
  78. package/dist/auth/signup.js.map +1 -0
  79. package/dist/auth/sso.d.ts +21 -0
  80. package/dist/auth/sso.d.ts.map +1 -0
  81. package/dist/auth/sso.js +35 -0
  82. package/dist/auth/sso.js.map +1 -0
  83. package/dist/auth/wire.d.ts +16 -0
  84. package/dist/auth/wire.d.ts.map +1 -0
  85. package/dist/auth/wire.js +47 -0
  86. package/dist/auth/wire.js.map +1 -0
  87. package/dist/changes.d.ts +15 -0
  88. package/dist/changes.d.ts.map +1 -0
  89. package/dist/changes.js +45 -0
  90. package/dist/changes.js.map +1 -0
  91. package/dist/cli-args.d.ts +1 -1
  92. package/dist/cli-args.d.ts.map +1 -1
  93. package/dist/cli-args.js +66 -14
  94. package/dist/cli-args.js.map +1 -1
  95. package/dist/cli.js +22 -2
  96. package/dist/cli.js.map +1 -1
  97. package/dist/config.d.ts +30 -4
  98. package/dist/config.d.ts.map +1 -1
  99. package/dist/config.js +37 -0
  100. package/dist/config.js.map +1 -1
  101. package/dist/copy-cli.d.ts +3 -0
  102. package/dist/copy-cli.d.ts.map +1 -0
  103. package/dist/copy-cli.js +24 -0
  104. package/dist/copy-cli.js.map +1 -0
  105. package/dist/db/db.d.ts +7 -2
  106. package/dist/db/db.d.ts.map +1 -1
  107. package/dist/db/db.js +28 -10
  108. package/dist/db/db.js.map +1 -1
  109. package/dist/db/migrate.d.ts +2 -2
  110. package/dist/db/migrate.d.ts.map +1 -1
  111. package/dist/db/migrate.js +15 -5
  112. package/dist/db/migrate.js.map +1 -1
  113. package/dist/db/schema-auth.d.ts +2 -0
  114. package/dist/db/schema-auth.d.ts.map +1 -0
  115. package/dist/db/schema-auth.js +93 -0
  116. package/dist/db/schema-auth.js.map +1 -0
  117. package/dist/db/schema-mail.d.ts +2 -0
  118. package/dist/db/schema-mail.d.ts.map +1 -0
  119. package/dist/db/schema-mail.js +8 -0
  120. package/dist/db/schema-mail.js.map +1 -0
  121. package/dist/db/schema-notify.d.ts +2 -0
  122. package/dist/db/schema-notify.d.ts.map +1 -0
  123. package/dist/db/schema-notify.js +26 -0
  124. package/dist/db/schema-notify.js.map +1 -0
  125. package/dist/db/schema-search.d.ts +2 -0
  126. package/dist/db/schema-search.d.ts.map +1 -0
  127. package/dist/db/schema-search.js +16 -0
  128. package/dist/db/schema-search.js.map +1 -0
  129. package/dist/db/schema-sso.d.ts +2 -0
  130. package/dist/db/schema-sso.d.ts.map +1 -0
  131. package/dist/db/schema-sso.js +17 -0
  132. package/dist/db/schema-sso.js.map +1 -0
  133. package/dist/db/schema.d.ts.map +1 -1
  134. package/dist/db/schema.js +10 -0
  135. package/dist/db/schema.js.map +1 -1
  136. package/dist/db/trigram.d.ts +4 -0
  137. package/dist/db/trigram.d.ts.map +1 -0
  138. package/dist/db/trigram.js +34 -0
  139. package/dist/db/trigram.js.map +1 -0
  140. package/dist/http/http.d.ts +2 -0
  141. package/dist/http/http.d.ts.map +1 -1
  142. package/dist/http/http.js +7 -3
  143. package/dist/http/http.js.map +1 -1
  144. package/dist/jobs.d.ts +1 -1
  145. package/dist/jobs.d.ts.map +1 -1
  146. package/dist/jobs.js +23 -11
  147. package/dist/jobs.js.map +1 -1
  148. package/dist/mail/blocks.d.ts +14 -0
  149. package/dist/mail/blocks.d.ts.map +1 -0
  150. package/dist/mail/blocks.js +35 -0
  151. package/dist/mail/blocks.js.map +1 -0
  152. package/dist/mail/content.d.ts +68 -0
  153. package/dist/mail/content.d.ts.map +1 -0
  154. package/dist/mail/content.js +6 -0
  155. package/dist/mail/content.js.map +1 -0
  156. package/dist/mail/emails-digest.d.ts +10 -0
  157. package/dist/mail/emails-digest.d.ts.map +1 -0
  158. package/dist/mail/emails-digest.js +55 -0
  159. package/dist/mail/emails-digest.js.map +1 -0
  160. package/dist/mail/emails-health.d.ts +6 -0
  161. package/dist/mail/emails-health.d.ts.map +1 -0
  162. package/dist/mail/emails-health.js +36 -0
  163. package/dist/mail/emails-health.js.map +1 -0
  164. package/dist/mail/emails-security.d.ts +14 -0
  165. package/dist/mail/emails-security.d.ts.map +1 -0
  166. package/dist/mail/emails-security.js +27 -0
  167. package/dist/mail/emails-security.js.map +1 -0
  168. package/dist/mail/emails-team.d.ts +11 -0
  169. package/dist/mail/emails-team.d.ts.map +1 -0
  170. package/dist/mail/emails-team.js +45 -0
  171. package/dist/mail/emails-team.js.map +1 -0
  172. package/dist/mail/emails.d.ts +9 -0
  173. package/dist/mail/emails.d.ts.map +1 -0
  174. package/dist/mail/emails.js +49 -0
  175. package/dist/mail/emails.js.map +1 -0
  176. package/dist/mail/layout.d.ts +6 -0
  177. package/dist/mail/layout.d.ts.map +1 -0
  178. package/dist/mail/layout.js +10 -0
  179. package/dist/mail/layout.js.map +1 -0
  180. package/dist/mail/mailer.d.ts +25 -0
  181. package/dist/mail/mailer.d.ts.map +1 -0
  182. package/dist/mail/mailer.js +50 -0
  183. package/dist/mail/mailer.js.map +1 -0
  184. package/dist/mail/preview.d.ts +6 -0
  185. package/dist/mail/preview.d.ts.map +1 -0
  186. package/dist/mail/preview.js +26 -0
  187. package/dist/mail/preview.js.map +1 -0
  188. package/dist/mail/resend.d.ts +13 -0
  189. package/dist/mail/resend.d.ts.map +1 -0
  190. package/dist/mail/resend.js +34 -0
  191. package/dist/mail/resend.js.map +1 -0
  192. package/dist/mail/samples.d.ts +3 -0
  193. package/dist/mail/samples.d.ts.map +1 -0
  194. package/dist/mail/samples.js +63 -0
  195. package/dist/mail/samples.js.map +1 -0
  196. package/dist/mail/stop-route.d.ts +4 -0
  197. package/dist/mail/stop-route.d.ts.map +1 -0
  198. package/dist/mail/stop-route.js +41 -0
  199. package/dist/mail/stop-route.js.map +1 -0
  200. package/dist/mail/svix.d.ts +8 -0
  201. package/dist/mail/svix.d.ts.map +1 -0
  202. package/dist/mail/svix.js +17 -0
  203. package/dist/mail/svix.js.map +1 -0
  204. package/dist/mail/templates.d.ts +12 -0
  205. package/dist/mail/templates.d.ts.map +1 -0
  206. package/dist/mail/templates.js +18 -0
  207. package/dist/mail/templates.js.map +1 -0
  208. package/dist/mail/text.d.ts +4 -0
  209. package/dist/mail/text.d.ts.map +1 -0
  210. package/dist/mail/text.js +17 -0
  211. package/dist/mail/text.js.map +1 -0
  212. package/dist/mail/theme.d.ts +32 -0
  213. package/dist/mail/theme.d.ts.map +1 -0
  214. package/dist/mail/theme.js +27 -0
  215. package/dist/mail/theme.js.map +1 -0
  216. package/dist/mail/unsubscribe.d.ts +14 -0
  217. package/dist/mail/unsubscribe.d.ts.map +1 -0
  218. package/dist/mail/unsubscribe.js +39 -0
  219. package/dist/mail/unsubscribe.js.map +1 -0
  220. package/dist/mail/webhook.d.ts +5 -0
  221. package/dist/mail/webhook.d.ts.map +1 -0
  222. package/dist/mail/webhook.js +41 -0
  223. package/dist/mail/webhook.js.map +1 -0
  224. package/dist/notify/digest-data.d.ts +32 -0
  225. package/dist/notify/digest-data.d.ts.map +1 -0
  226. package/dist/notify/digest-data.js +31 -0
  227. package/dist/notify/digest-data.js.map +1 -0
  228. package/dist/notify/digest.d.ts +17 -0
  229. package/dist/notify/digest.d.ts.map +1 -0
  230. package/dist/notify/digest.js +76 -0
  231. package/dist/notify/digest.js.map +1 -0
  232. package/dist/notify/health.d.ts +6 -0
  233. package/dist/notify/health.d.ts.map +1 -0
  234. package/dist/notify/health.js +42 -0
  235. package/dist/notify/health.js.map +1 -0
  236. package/dist/notify/team-describe.d.ts +22 -0
  237. package/dist/notify/team-describe.d.ts.map +1 -0
  238. package/dist/notify/team-describe.js +67 -0
  239. package/dist/notify/team-describe.js.map +1 -0
  240. package/dist/notify/team.d.ts +6 -0
  241. package/dist/notify/team.d.ts.map +1 -0
  242. package/dist/notify/team.js +56 -0
  243. package/dist/notify/team.js.map +1 -0
  244. package/dist/repo/alerts.d.ts +6 -2
  245. package/dist/repo/alerts.d.ts.map +1 -1
  246. package/dist/repo/alerts.js.map +1 -1
  247. package/dist/repo/auth-prune.d.ts +4 -0
  248. package/dist/repo/auth-prune.d.ts.map +1 -0
  249. package/dist/repo/auth-prune.js +8 -0
  250. package/dist/repo/auth-prune.js.map +1 -0
  251. package/dist/repo/mail-prefs.d.ts +35 -0
  252. package/dist/repo/mail-prefs.d.ts.map +1 -0
  253. package/dist/repo/mail-prefs.js +34 -0
  254. package/dist/repo/mail-prefs.js.map +1 -0
  255. package/dist/repo/orgs.d.ts +15 -25
  256. package/dist/repo/orgs.d.ts.map +1 -1
  257. package/dist/repo/orgs.js +18 -60
  258. package/dist/repo/orgs.js.map +1 -1
  259. package/dist/repo/services.d.ts +6 -0
  260. package/dist/repo/services.d.ts.map +1 -0
  261. package/dist/repo/services.js +16 -0
  262. package/dist/repo/services.js.map +1 -0
  263. package/dist/repo/suppressions.d.ts +8 -0
  264. package/dist/repo/suppressions.d.ts.map +1 -0
  265. package/dist/repo/suppressions.js +16 -0
  266. package/dist/repo/suppressions.js.map +1 -0
  267. package/dist/repo/trace-join.d.ts +9 -0
  268. package/dist/repo/trace-join.d.ts.map +1 -0
  269. package/dist/repo/trace-join.js +35 -0
  270. package/dist/repo/trace-join.js.map +1 -0
  271. package/dist/repo/trace-read.d.ts +6 -13
  272. package/dist/repo/trace-read.d.ts.map +1 -1
  273. package/dist/repo/trace-read.js +8 -3
  274. package/dist/repo/trace-read.js.map +1 -1
  275. package/dist/repo/trace-write.d.ts +5 -1
  276. package/dist/repo/trace-write.d.ts.map +1 -1
  277. package/dist/repo/trace-write.js +11 -2
  278. package/dist/repo/trace-write.js.map +1 -1
  279. package/dist/repo/users.d.ts +5 -16
  280. package/dist/repo/users.d.ts.map +1 -1
  281. package/dist/repo/users.js +2 -60
  282. package/dist/repo/users.js.map +1 -1
  283. package/dist/routes/alerts.d.ts.map +1 -1
  284. package/dist/routes/alerts.js +23 -6
  285. package/dist/routes/alerts.js.map +1 -1
  286. package/dist/routes/changes.d.ts +4 -0
  287. package/dist/routes/changes.d.ts.map +1 -0
  288. package/dist/routes/changes.js +19 -0
  289. package/dist/routes/changes.js.map +1 -0
  290. package/dist/routes/data.d.ts.map +1 -1
  291. package/dist/routes/data.js +24 -9
  292. package/dist/routes/data.js.map +1 -1
  293. package/dist/routes/index.d.ts.map +1 -1
  294. package/dist/routes/index.js +8 -2
  295. package/dist/routes/index.js.map +1 -1
  296. package/dist/routes/ingest.d.ts.map +1 -1
  297. package/dist/routes/ingest.js +7 -2
  298. package/dist/routes/ingest.js.map +1 -1
  299. package/dist/routes/mcp.d.ts.map +1 -1
  300. package/dist/routes/mcp.js +42 -25
  301. package/dist/routes/mcp.js.map +1 -1
  302. package/dist/routes/me.d.ts +4 -0
  303. package/dist/routes/me.d.ts.map +1 -0
  304. package/dist/routes/me.js +37 -0
  305. package/dist/routes/me.js.map +1 -0
  306. package/dist/routes/metrics.d.ts +2 -2
  307. package/dist/routes/metrics.d.ts.map +1 -1
  308. package/dist/routes/metrics.js +2 -3
  309. package/dist/routes/metrics.js.map +1 -1
  310. package/dist/routes/models.d.ts +2 -0
  311. package/dist/routes/models.d.ts.map +1 -1
  312. package/dist/routes/models.js +10 -5
  313. package/dist/routes/models.js.map +1 -1
  314. package/dist/routes/notify.d.ts +4 -0
  315. package/dist/routes/notify.d.ts.map +1 -0
  316. package/dist/routes/notify.js +55 -0
  317. package/dist/routes/notify.js.map +1 -0
  318. package/dist/routes/orgs.d.ts.map +1 -1
  319. package/dist/routes/orgs.js +34 -53
  320. package/dist/routes/orgs.js.map +1 -1
  321. package/dist/routes/projects.d.ts.map +1 -1
  322. package/dist/routes/projects.js +5 -3
  323. package/dist/routes/projects.js.map +1 -1
  324. package/dist/routes/search.d.ts +4 -0
  325. package/dist/routes/search.d.ts.map +1 -0
  326. package/dist/routes/search.js +33 -0
  327. package/dist/routes/search.js.map +1 -0
  328. package/dist/routes/shares.d.ts.map +1 -1
  329. package/dist/routes/shares.js +8 -5
  330. package/dist/routes/shares.js.map +1 -1
  331. package/dist/server.d.ts +2 -0
  332. package/dist/server.d.ts.map +1 -1
  333. package/dist/server.js +59 -16
  334. package/dist/server.js.map +1 -1
  335. package/dist/settle.d.ts +7 -6
  336. package/dist/settle.d.ts.map +1 -1
  337. package/dist/settle.js +30 -13
  338. package/dist/settle.js.map +1 -1
  339. package/dist/telemetry/cached.d.ts +11 -0
  340. package/dist/telemetry/cached.d.ts.map +1 -0
  341. package/dist/telemetry/cached.js +30 -0
  342. package/dist/telemetry/cached.js.map +1 -0
  343. package/dist/telemetry/ch/admin.d.ts +10 -0
  344. package/dist/telemetry/ch/admin.d.ts.map +1 -0
  345. package/dist/telemetry/ch/admin.js +65 -0
  346. package/dist/telemetry/ch/admin.js.map +1 -0
  347. package/dist/telemetry/ch/http.d.ts +19 -0
  348. package/dist/telemetry/ch/http.d.ts.map +1 -0
  349. package/dist/telemetry/ch/http.js +91 -0
  350. package/dist/telemetry/ch/http.js.map +1 -0
  351. package/dist/telemetry/ch/metrics.d.ts +10 -0
  352. package/dist/telemetry/ch/metrics.d.ts.map +1 -0
  353. package/dist/telemetry/ch/metrics.js +61 -0
  354. package/dist/telemetry/ch/metrics.js.map +1 -0
  355. package/dist/telemetry/ch/queries.d.ts +19 -0
  356. package/dist/telemetry/ch/queries.d.ts.map +1 -0
  357. package/dist/telemetry/ch/queries.js +30 -0
  358. package/dist/telemetry/ch/queries.js.map +1 -0
  359. package/dist/telemetry/ch/queue.d.ts +34 -0
  360. package/dist/telemetry/ch/queue.d.ts.map +1 -0
  361. package/dist/telemetry/ch/queue.js +79 -0
  362. package/dist/telemetry/ch/queue.js.map +1 -0
  363. package/dist/telemetry/ch/read.d.ts +12 -0
  364. package/dist/telemetry/ch/read.d.ts.map +1 -0
  365. package/dist/telemetry/ch/read.js +72 -0
  366. package/dist/telemetry/ch/read.js.map +1 -0
  367. package/dist/telemetry/ch/schema-facts.d.ts +6 -0
  368. package/dist/telemetry/ch/schema-facts.d.ts.map +1 -0
  369. package/dist/telemetry/ch/schema-facts.js +49 -0
  370. package/dist/telemetry/ch/schema-facts.js.map +1 -0
  371. package/dist/telemetry/ch/schema-raw.d.ts +8 -0
  372. package/dist/telemetry/ch/schema-raw.d.ts.map +1 -0
  373. package/dist/telemetry/ch/schema-raw.js +35 -0
  374. package/dist/telemetry/ch/schema-raw.js.map +1 -0
  375. package/dist/telemetry/ch/schema-rollups.d.ts +2 -0
  376. package/dist/telemetry/ch/schema-rollups.d.ts.map +1 -0
  377. package/dist/telemetry/ch/schema-rollups.js +61 -0
  378. package/dist/telemetry/ch/schema-rollups.js.map +1 -0
  379. package/dist/telemetry/ch/schema.d.ts +12 -0
  380. package/dist/telemetry/ch/schema.d.ts.map +1 -0
  381. package/dist/telemetry/ch/schema.js +25 -0
  382. package/dist/telemetry/ch/schema.js.map +1 -0
  383. package/dist/telemetry/ch/settle-rows.d.ts +13 -0
  384. package/dist/telemetry/ch/settle-rows.d.ts.map +1 -0
  385. package/dist/telemetry/ch/settle-rows.js +67 -0
  386. package/dist/telemetry/ch/settle-rows.js.map +1 -0
  387. package/dist/telemetry/ch/settle.d.ts +7 -0
  388. package/dist/telemetry/ch/settle.d.ts.map +1 -0
  389. package/dist/telemetry/ch/settle.js +96 -0
  390. package/dist/telemetry/ch/settle.js.map +1 -0
  391. package/dist/telemetry/ch/store.d.ts +16 -0
  392. package/dist/telemetry/ch/store.d.ts.map +1 -0
  393. package/dist/telemetry/ch/store.js +65 -0
  394. package/dist/telemetry/ch/store.js.map +1 -0
  395. package/dist/telemetry/ch/util.d.ts +20 -0
  396. package/dist/telemetry/ch/util.d.ts.map +1 -0
  397. package/dist/telemetry/ch/util.js +45 -0
  398. package/dist/telemetry/ch/util.js.map +1 -0
  399. package/dist/telemetry/ch/write.d.ts +11 -0
  400. package/dist/telemetry/ch/write.d.ts.map +1 -0
  401. package/dist/telemetry/ch/write.js +59 -0
  402. package/dist/telemetry/ch/write.js.map +1 -0
  403. package/dist/telemetry/copy.d.ts +9 -0
  404. package/dist/telemetry/copy.d.ts.map +1 -0
  405. package/dist/telemetry/copy.js +60 -0
  406. package/dist/telemetry/copy.js.map +1 -0
  407. package/dist/telemetry/index.d.ts +11 -0
  408. package/dist/telemetry/index.d.ts.map +1 -0
  409. package/dist/telemetry/index.js +21 -0
  410. package/dist/telemetry/index.js.map +1 -0
  411. package/dist/telemetry/pg-store.d.ts +5 -0
  412. package/dist/telemetry/pg-store.d.ts.map +1 -0
  413. package/dist/telemetry/pg-store.js +78 -0
  414. package/dist/telemetry/pg-store.js.map +1 -0
  415. package/dist/telemetry/store.d.ts +74 -0
  416. package/dist/telemetry/store.d.ts.map +1 -0
  417. package/dist/telemetry/store.js +2 -0
  418. package/dist/telemetry/store.js.map +1 -0
  419. package/package.json +20 -6
  420. package/dist/routes/auth.d.ts +0 -4
  421. package/dist/routes/auth.d.ts.map +0 -1
  422. package/dist/routes/auth.js +0 -106
  423. package/dist/routes/auth.js.map +0 -1
@@ -0,0 +1,25 @@
1
+ // ClickHouse schema setup: the database, then every table and view. Statements are idempotent, so each start runs them all.
2
+ import { chClient } from "./http.js";
3
+ import { FACT_ALTERS, FACT_DDL } from "./schema-facts.js";
4
+ import { RAW_TABLES } from "./schema-raw.js";
5
+ import { ROLLUP_DDL } from "./schema-rollups.js";
6
+ const TABLES = [...RAW_TABLES, ...FACT_DDL, ...ROLLUP_DDL].map((s) => /^CREATE TABLE IF NOT EXISTS (\w+)/.exec(s)?.[1]).filter((t) => !!t);
7
+ /** New parts write no column statistics (see http.ts); old parts lose theirs as they merge. */
8
+ const NO_STATISTICS = TABLES.map((t) => `ALTER TABLE ${t} MODIFY SETTING auto_statistics_types = ''`);
9
+ /** Tables only settling writes, always with a token: a retried insert lands once (see settle-rows.ts, Label). */
10
+ const DEDUPLICATED = TABLES.filter((t) => /^(fact_|rollup_|hist_)|^settle_state$/.test(t)).map((t) => `ALTER TABLE ${t} MODIFY SETTING non_replicated_deduplication_window = 1000`);
11
+ /** Every statement, in order. A change to a shipped table needs an ALTER added here, never an edit to its CREATE. */
12
+ export const CH_SCHEMA = [...RAW_TABLES, ...FACT_DDL, ...FACT_ALTERS, ...ROLLUP_DDL, ...NO_STATISTICS, ...DEDUPLICATED];
13
+ /** Tables whose rows belong to one project, for clearing it. Views are left out. */
14
+ export const PROJECT_TABLES = TABLES.filter((t) => t !== "trace_updates");
15
+ /** Every statement without its TTL clauses: for tests on a fixed clock, whose rows would expire on insert. */
16
+ export const withoutTtl = (sql) => sql.replace(/\sTTL\s[\s\S]*?DELETE/g, "");
17
+ /** Create the database (through the default one) and every table and view. `ttl: false` keeps every row (tests only). */
18
+ export async function migrateClickHouse(url, client, o = {}) {
19
+ const u = new URL(url);
20
+ u.pathname = "/default";
21
+ await chClient({ url: u.toString() }).command(`CREATE DATABASE IF NOT EXISTS \`${client.database.replace(/`/g, "")}\``);
22
+ for (const sql of CH_SCHEMA)
23
+ await client.command(o.ttl === false ? withoutTtl(sql) : sql);
24
+ }
25
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/telemetry/ch/schema.ts"],"names":[],"mappings":"AAAA,4HAA4H;AAC5H,OAAO,EAAiB,QAAQ,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,QAAQ,EAAE,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mCAAmC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAExJ,+FAA+F;AAC/F,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,4CAA4C,CAAC,CAAC;AAEtG,iHAAiH;AACjH,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uCAAuC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,4DAA4D,CAAC,CAAC;AAEpL,qHAAqH;AACrH,MAAM,CAAC,MAAM,SAAS,GAAsB,CAAC,GAAG,UAAU,EAAE,GAAG,QAAQ,EAAE,GAAG,WAAW,EAAE,GAAG,UAAU,EAAE,GAAG,aAAa,EAAE,GAAG,YAAY,CAAC,CAAC;AAE3I,oFAAoF;AACpF,MAAM,CAAC,MAAM,cAAc,GAAsB,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC;AAE7F,8GAA8G;AAC9G,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;AAE7F,yHAAyH;AACzH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,MAAgB,EAAE,CAAC,GAAsB,EAAE;IAC9F,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,QAAQ,GAAG,UAAU,CAAC;IACxB,MAAM,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,mCAAmC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IACxH,KAAK,MAAM,GAAG,IAAI,SAAS;QAAE,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAC7F,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type FactTable, type SettleDelta } from "@wizeworks/lens-core";
2
+ import type { ChClient } from "./http.js";
3
+ type Row = Record<string, unknown>;
4
+ /** Fact rows as objects, with their version and expiry. `expire` maps a trace id to its row expiry base. */
5
+ export declare function factObjects(rows: Record<FactTable, unknown[][]>, ver: number, expireOf: (r: Row) => number): Record<FactTable, Row[]>;
6
+ /** Rows the re-settled traces had before and no longer have, as tombstones. Only traces settled before can have any. */
7
+ export declare function tombstones(ch: ChClient, project: string, traceIds: readonly string[], fresh: Record<FactTable, Row[]>, ver: number): Promise<Record<FactTable, Row[]>>;
8
+ /** Settings that make one batch's insert into a table safe to send again: ClickHouse keeps the first copy of a token. */
9
+ export type Label = (table: string) => Record<string, string>;
10
+ /** Write a merged settle delta into every tier. `retentionMs` is per project. */
11
+ export declare function writeDeltas(ch: ChClient, delta: SettleDelta, retentionMs: (project: string) => number, label: Label): Promise<void>;
12
+ export {};
13
+ //# sourceMappingURL=settle-rows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settle-rows.d.ts","sourceRoot":"","sources":["../../../src/telemetry/ch/settle-rows.ts"],"names":[],"mappings":"AACA,OAAO,EAA6B,KAAK,SAAS,EAAgC,KAAK,WAAW,EAAS,MAAM,sBAAsB,CAAC;AAExI,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAG1C,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAMnC,4GAA4G;AAC5G,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAUrI;AAED,wHAAwH;AACxH,wBAAsB,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,CAa5K;AAoBD,yHAAyH;AACzH,MAAM,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9D,iFAAiF;AACjF,wBAAsB,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAczI"}
@@ -0,0 +1,67 @@
1
+ // What one settle batch writes to ClickHouse: fact rows, tombstones for rows a trace no longer has, and rollup deltas.
2
+ import { FACT_COLUMNS, FACT_TABLES, IDS_MAX, NONE_HIGH, NONE_LOW, TIERS } from "@wizeworks/lens-core";
3
+ import { FACT_KEYS } from "./schema-facts.js";
4
+ import { rowOf } from "./util.js";
5
+ const COUNTERS = ["c0", "c1", "c2", "c3", "c4", "c5"];
6
+ const keyCols = (t) => FACT_KEYS[`${t}_t`];
7
+ const keyOf = (t, r) => [r.trace_id, ...keyCols(t).map((c) => r[c])].map((v) => JSON.stringify(v ?? null)).join("|");
8
+ /** Fact rows as objects, with their version and expiry. `expire` maps a trace id to its row expiry base. */
9
+ export function factObjects(rows, ver, expireOf) {
10
+ const out = {};
11
+ for (const t of FACT_TABLES) {
12
+ const cols = ["project_id", ...FACT_COLUMNS[t]];
13
+ out[t] = rows[t].map((values) => {
14
+ const r = rowOf(cols, values);
15
+ return { ...r, ver, is_deleted: 0, expire_ms: expireOf(r) };
16
+ });
17
+ }
18
+ return out;
19
+ }
20
+ /** Rows the re-settled traces had before and no longer have, as tombstones. Only traces settled before can have any. */
21
+ export async function tombstones(ch, project, traceIds, fresh, ver) {
22
+ const out = {};
23
+ for (const t of FACT_TABLES) {
24
+ out[t] = [];
25
+ if (!traceIds.length)
26
+ continue;
27
+ const cols = ["trace_id", ...keyCols(t)];
28
+ const sql = `SELECT ${cols.join(", ")} FROM ${t}_t FINAL WHERE project_id = {p1:String} AND has({p2:Array(String)}, trace_id)`;
29
+ const keep = new Set(fresh[t].map((r) => keyOf(t, r)));
30
+ for (const old of await ch.query(sql, [project, traceIds])) {
31
+ if (!keep.has(keyOf(t, old)))
32
+ out[t].push({ project_id: project, ...old, ver, is_deleted: 1, expire_ms: NONE_HIGH });
33
+ }
34
+ }
35
+ return out;
36
+ }
37
+ const ROLLUP_INPUT = [
38
+ "project_id String, env String, kind String, key String, bucket_ms Float64, n Float64, err Float64, sum_v Float64",
39
+ ...COUNTERS.map((c) => `${c} Float64`),
40
+ "first_ms Float64, last_ms Float64, top_rank Float64, top Nullable(String), ids String, expire_ms Float64",
41
+ ].join(", ");
42
+ /** Deltas add into the merge tables; a batch's deltas for one bucket and key become one row. */
43
+ function rollupInsert(table) {
44
+ const sums = ["n", "err", "sum_v", ...COUNTERS].map((c) => `sum(${c})`).join(", ");
45
+ const ids = `groupArraySortedArrayState(${IDS_MAX})(arrayMap(x -> (-last_ms, x), arrayFilter(x -> x != '', splitByChar(' ', ids))))`;
46
+ return `${table}_t SELECT project_id, env, kind, key, bucket_ms, ${sums}, min(first_ms), max(last_ms), max(top_rank), argMaxState(top, top_rank), ${ids}, max(expire_ms)
47
+ FROM input('${ROLLUP_INPUT}') GROUP BY project_id, env, kind, key, bucket_ms`;
48
+ }
49
+ const HIST_INPUT = "project_id String, env String, kind String, key String, bucket_ms Float64, bin Int32, cnt Float64, expire_ms Float64";
50
+ const histInsert = (table) => `${table}_t SELECT project_id, env, kind, key, bucket_ms, bin, sum(cnt), max(expire_ms) FROM input('${HIST_INPUT}') GROUP BY project_id, env, kind, key, bucket_ms, bin`;
51
+ /** Write a merged settle delta into every tier. `retentionMs` is per project. */
52
+ export async function writeDeltas(ch, delta, retentionMs, label) {
53
+ const writes = [];
54
+ for (const tier of TIERS) {
55
+ const rollups = delta.rollup.filter((r) => r.tier === tier.name).map((r) => ({
56
+ project_id: r.project, env: r.env, kind: r.kind, key: r.key, bucket_ms: r.bucket, n: r.n, err: r.err, sum_v: r.sum,
57
+ ...Object.fromEntries(COUNTERS.map((c, i) => [c, r.c[i] ?? 0])), first_ms: r.firstMs ?? NONE_HIGH, last_ms: r.lastMs ?? NONE_LOW,
58
+ top_rank: r.topRank ?? NONE_LOW, top: r.topRank === null ? null : JSON.stringify(r.top ?? null), ids: r.ids, expire_ms: r.bucket + retentionMs(r.project),
59
+ }));
60
+ const hists = delta.hist.filter((h) => h.tier === tier.name).map((h) => ({
61
+ project_id: h.project, env: h.env, kind: h.kind, key: h.key, bucket_ms: h.bucket, bin: h.bin, cnt: h.cnt, expire_ms: h.bucket + retentionMs(h.project),
62
+ }));
63
+ writes.push(ch.insert(rollupInsert(tier.table), rollups, label(tier.table)), ch.insert(histInsert(tier.hist), hists, label(tier.hist)));
64
+ }
65
+ await Promise.all(writes);
66
+ }
67
+ //# sourceMappingURL=settle-rows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settle-rows.js","sourceRoot":"","sources":["../../../src/telemetry/ch/settle-rows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { SettleOptions } from "../store.js";
2
+ import type { ChClient } from "./http.js";
3
+ import type { SettleQueue } from "./queue.js";
4
+ import { type RetentionCache } from "./util.js";
5
+ /** Settle due traces until none are left or the budget is spent. Batches overlap (`DEPTH` at once): one reads and computes while others wait on their writes. */
6
+ export declare function settleClickHouse(ch: ChClient, queue: SettleQueue, retention: RetentionCache, now: number, o?: SettleOptions): Promise<number>;
7
+ //# sourceMappingURL=settle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settle.d.ts","sourceRoot":"","sources":["../../../src/telemetry/ch/settle.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAS,WAAW,EAAE,MAAM,YAAY,CAAC;AAGrD,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AA6EpE,iKAAiK;AACjK,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBvJ"}
@@ -0,0 +1,96 @@
1
+ // Settling on ClickHouse: the same facts and deltas as Postgres, written as inserts. One process settles, so no lock is needed.
2
+ import { compact, factRows, FACT_TABLES, mergeDeltas, settleDelta, storedOf, traceFacts, withoutTop } from "@wizeworks/lens-core";
3
+ import { loadTraces } from "./read.js";
4
+ import { factObjects, tombstones, writeDeltas } from "./settle-rows.js";
5
+ import { byProject, nextVer } from "./util.js";
6
+ const BATCH = 2_000;
7
+ const BUDGET_MS = 2_000;
8
+ const DEPTH = 3;
9
+ const hasData = (t) => !!t && t.spanCount + t.logs.length > 0;
10
+ /** Stored contributions of some traces, by trace id. */
11
+ async function storedContribs(ch, project, ids) {
12
+ const rows = await ch.query("SELECT trace_id, contrib FROM settle_state FINAL WHERE project_id = {p1:String} AND has({p2:Array(String)}, trace_id)", [project, ids]);
13
+ return new Map(rows.map((r) => [r.trace_id, r.contrib]));
14
+ }
15
+ /** Facts, deltas, and new settle states for one project's dirty traces. */
16
+ async function projectWork(ch, project, items, now, retentionMs, ver) {
17
+ const ids = items.map((d) => d.traceId);
18
+ const [traces, stored] = await Promise.all([loadTraces(ch, [project], ids), storedContribs(ch, project, ids)]);
19
+ const raw = Object.fromEntries(FACT_TABLES.map((t) => [t, []]));
20
+ const work = { facts: {}, deltas: [], states: [], resettled: [] };
21
+ items.forEach((d, i) => {
22
+ const trace = traces[i];
23
+ const scope = { project, env: d.env };
24
+ const facts = hasData(trace) ? traceFacts(trace) : null;
25
+ const next = facts ? compact(facts, scope) : null;
26
+ const old = stored.get(d.traceId);
27
+ if (old !== undefined)
28
+ work.resettled.push(d.traceId);
29
+ work.deltas.push(settleDelta(storedOf(old || null), next, now, retentionMs));
30
+ if (facts)
31
+ for (const [t, rows] of Object.entries(factRows(facts, scope, trace)))
32
+ raw[t].push(...rows);
33
+ const start = trace?.startMs ?? now;
34
+ work.states.push({ project_id: project, trace_id: d.traceId, settled_ms: d.updatedMs, contrib: next ? JSON.stringify(withoutTop(next)) : "", ver, expire_ms: start + retentionMs });
35
+ });
36
+ const timeOf = (r) => Number(r.start_ms ?? r.time_ms ?? now);
37
+ work.facts = factObjects(raw, ver, (r) => timeOf(r) + retentionMs);
38
+ return work;
39
+ }
40
+ /** Write one project's work: facts (with tombstones) and rollups at once, then the settle states, so a failed write settles again. */
41
+ async function writeWork(ch, project, w, ver, retentionMs, label) {
42
+ const dead = await tombstones(ch, project, w.resettled, w.facts, ver);
43
+ const facts = FACT_TABLES.map((t) => ch.insert(`${t}_t`, [...dead[t], ...w.facts[t]], label(t)));
44
+ await Promise.all([...facts, writeDeltas(ch, mergeDeltas(w.deltas), () => retentionMs, label)]);
45
+ await ch.insert("settle_state", w.states, label("settle_state"));
46
+ }
47
+ /** Settle one batch of taken traces. A failure releases the ones not written yet. */
48
+ async function settleItems(ch, queue, retention, now, due, o) {
49
+ let left = [...due];
50
+ try {
51
+ const days = await retention.daysOf(due.map((d) => d.project));
52
+ for (const [project, items] of byProject(due)) {
53
+ const retentionMs = days.get(project) * 86_400_000;
54
+ const ver = nextVer(now);
55
+ const label = (table) => ({ insert_deduplication_token: `${ver}:${project}:${table}` });
56
+ await writeWork(ch, project, await projectWork(ch, project, items, now, retentionMs, ver), ver, retentionMs, label);
57
+ for (const d of items)
58
+ queue.settled(d, d.updatedMs);
59
+ left = left.filter((d) => d.project !== project);
60
+ o.onSettled?.(project);
61
+ }
62
+ return due.length;
63
+ }
64
+ finally {
65
+ queue.release(left);
66
+ }
67
+ }
68
+ /** Settle due traces until none are left or the budget is spent. Batches overlap (`DEPTH` at once): one reads and computes while others wait on their writes. */
69
+ export async function settleClickHouse(ch, queue, retention, now, o = {}) {
70
+ const start = Date.now();
71
+ const batch = o.batch ?? BATCH;
72
+ const running = [];
73
+ const started = [];
74
+ let total = 0;
75
+ try {
76
+ for (;;) {
77
+ const due = queue.take(now, batch);
78
+ if (due.length) {
79
+ const run = settleItems(ch, queue, retention, now, due, o);
80
+ // Handled now, awaited in turn: a batch that fails while another is awaited must not end the process.
81
+ run.catch(() => undefined);
82
+ running.push(run);
83
+ started.push(run);
84
+ }
85
+ const last = !due.length || due.length < batch || Date.now() - start >= (o.budgetMs ?? BUDGET_MS);
86
+ while (running.length && (last || running.length >= DEPTH))
87
+ total += await running.shift();
88
+ if (last)
89
+ return total;
90
+ }
91
+ }
92
+ finally {
93
+ await Promise.allSettled(started);
94
+ }
95
+ }
96
+ //# sourceMappingURL=settle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settle.js","sourceRoot":"","sources":["../../../src/telemetry/ch/settle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type SqlRunner } from "@wizeworks/lens-core";
2
+ import type { RetentionOf, TelemetryStore } from "../store.js";
3
+ import { type ChClient } from "./http.js";
4
+ export interface ChStoreOptions {
5
+ url: string;
6
+ retentionOf: RetentionOf;
7
+ defaultRetentionDays: number;
8
+ /** The clock for recovery on start. */
9
+ now: () => number;
10
+ /** False leaves the TTLs out (tests on a fixed clock). Default true. */
11
+ ttl?: boolean;
12
+ }
13
+ export declare const chRunner: (ch: ChClient) => SqlRunner;
14
+ /** Create the schema, rebuild the settle queue, and return the store. */
15
+ export declare function openClickHouse(o: ChStoreOptions): Promise<TelemetryStore>;
16
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/telemetry/ch/store.ts"],"names":[],"mappings":"AACA,OAAO,EAAoH,KAAK,SAAS,EAAc,MAAM,sBAAsB,CAAC;AACpL,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,WAAW,CAAC;AAUpD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,WAAW,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uCAAuC;IACvC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,wEAAwE;IACxE,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,eAAO,MAAM,QAAQ,OAAQ,QAAQ,KAAG,SAAuF,CAAC;AAWhI,yEAAyE;AACzE,wBAAsB,cAAc,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAO/E"}
@@ -0,0 +1,65 @@
1
+ // Scale mode: telemetry in ClickHouse. Reads go through views with the Postgres names, so the shared SQL answers pages and searches.
2
+ import { alignNow, CH_DIALECT, metricAlertSteps, metricPageSteps, runMetricAsync, searchSql, sqlExecutor, suggestSql } from "@wizeworks/lens-core";
3
+ import { checkFactsVersionCh, clearProjectCh, syncProjects } from "./admin.js";
4
+ import { chClient } from "./http.js";
5
+ import { MetricWriter } from "./metrics.js";
6
+ import { activeHours, counts, lastTraceMs, slowestEndpoints, traceEnvs } from "./queries.js";
7
+ import { SettleQueue } from "./queue.js";
8
+ import { findTraceIds, getTrace, joinedTrace, loadTraces } from "./read.js";
9
+ import { migrateClickHouse } from "./schema.js";
10
+ import { settleClickHouse } from "./settle.js";
11
+ import { RetentionCache } from "./util.js";
12
+ import { writeRaw } from "./write.js";
13
+ export const chRunner = (ch) => ({ all: (sql, params) => ch.query(sql, params) });
14
+ /** ClickHouse may still be starting (a deploy starts both at once): wait up to two minutes. */
15
+ async function waitReady(ch) {
16
+ for (let i = 0; i < 60; i++) {
17
+ if (await ch.ping())
18
+ return;
19
+ await new Promise((r) => setTimeout(r, 2_000));
20
+ }
21
+ throw new Error("ClickHouse did not answer /ping for two minutes. Check --clickhouse and that the server runs.");
22
+ }
23
+ /** Create the schema, rebuild the settle queue, and return the store. */
24
+ export async function openClickHouse(o) {
25
+ const ch = chClient({ url: o.url });
26
+ await waitReady(ch);
27
+ await migrateClickHouse(o.url, ch, { ttl: o.ttl });
28
+ const queue = new SettleQueue();
29
+ await queue.recover(ch, o.now());
30
+ return chTelemetry(ch, queue, new RetentionCache(o.retentionOf, o.defaultRetentionDays), o.retentionOf);
31
+ }
32
+ function chTelemetry(ch, queue, retention, retentionOf) {
33
+ const src = (projectId) => ({ d: CH_DIALECT, run: chRunner(ch), scope: { project: projectId } });
34
+ const metrics = new MetricWriter(ch);
35
+ const runMetric = (s) => ch.query(s.sql, s.args);
36
+ return {
37
+ kind: "clickhouse",
38
+ async write(projectId, w, now) {
39
+ const retentionMs = await retention.msOf(projectId);
40
+ await writeRaw(ch, queue, projectId, w, now, retentionMs);
41
+ await metrics.write(projectId, w.sender.environment ?? "", w.metrics ?? [], now, retentionMs);
42
+ },
43
+ traces: async (t) => loadTraces(ch, [t.projectId], await findTraceIds(ch, t, Date.now())),
44
+ trace: (projectId, traceId) => getTrace(ch, [projectId], traceId),
45
+ joinedTrace: (primaryId, scope, traceId) => joinedTrace(ch, primaryId, scope, traceId),
46
+ counts: (projectId) => counts(ch, projectId),
47
+ traceEnvs: (projectId) => traceEnvs(ch, projectId),
48
+ activeHours: (projectId, from, to) => activeHours(ch, projectId, from, to),
49
+ lastTraceMs: () => lastTraceMs(ch, Date.now()),
50
+ executor: (projectId, retentionMs, env) => sqlExecutor({ ...src(projectId), scope: { project: projectId, env }, retentionMs, loadTrace: (id) => getTrace(ch, [projectId], id).then((t) => t ?? null) }),
51
+ settling: async (projectId, env) => queue.count(projectId, env) || null,
52
+ search: (projectId, q) => searchSql(src(projectId), q),
53
+ suggest: (projectId, r) => suggestSql(src(projectId), r),
54
+ slowestEndpoints: (projectId, w, minCount, limit) => slowestEndpoints(ch, projectId, w, minCount, limit),
55
+ metricData: (m, range, params, now) => runMetricAsync(metricPageSteps("ch", { project: m.projectId, env: m.env }, range, alignNow(now), params), runMetric),
56
+ metricAlertData: (m, name, w, now) => runMetricAsync(metricAlertSteps("ch", { project: m.projectId, env: m.env, service: m.service }, name, w, now), runMetric),
57
+ settle: (now, o) => settleClickHouse(ch, queue, retention, now, o),
58
+ prune: (now) => syncProjects(ch, queue, retentionOf, now),
59
+ pruneRollups: async () => undefined,
60
+ checkFactsVersion: () => checkFactsVersionCh(ch, queue),
61
+ clearProject: (projectId) => clearProjectCh(ch, queue, projectId),
62
+ close: async () => undefined,
63
+ };
64
+ }
65
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/telemetry/ch/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { RetentionOf } from "../store.js";
2
+ declare const DAY_MS = 86400000;
3
+ /** A row version that only grows: ms times 1000, plus a counter within the same ms. */
4
+ export declare function nextVer(now: number): number;
5
+ /** Retention days per project, from Postgres, cached for a minute. */
6
+ export declare class RetentionCache {
7
+ private readonly lookup;
8
+ private readonly defaultDays;
9
+ private readonly cache;
10
+ constructor(lookup: RetentionOf, defaultDays: number);
11
+ daysOf(projectIds: readonly string[]): Promise<Map<string, number>>;
12
+ msOf(projectId: string): Promise<number>;
13
+ }
14
+ /** A row object from a column list and values in the same order. */
15
+ export declare function rowOf(cols: readonly string[], values: readonly unknown[]): Record<string, unknown>;
16
+ export declare const byProject: <T extends {
17
+ project: string;
18
+ }>(items: readonly T[]) => Map<string, T[]>;
19
+ export { DAY_MS };
20
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/telemetry/ch/util.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,QAAA,MAAM,MAAM,WAAa,CAAC;AAK1B,uFAAuF;AACvF,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG3C;AAED,sEAAsE;AACtE,qBAAa,cAAc;IAIvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAJ9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqD;IAE3E,YACmB,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,MAAM,EAClC;IAEE,MAAM,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAQxE;IAEK,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7C;CACF;AAED,oEAAoE;AACpE,wBAAgB,KAAK,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAIlG;AAED,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,SAAS,SAAS,CAAC,EAAE,KAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAI7F,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,45 @@
1
+ const DAY_MS = 86_400_000;
2
+ const RETENTION_CACHE_MS = 60_000;
3
+ let lastVer = 0;
4
+ /** A row version that only grows: ms times 1000, plus a counter within the same ms. */
5
+ export function nextVer(now) {
6
+ lastVer = Math.max(lastVer + 1, Math.floor(now) * 1000);
7
+ return lastVer;
8
+ }
9
+ /** Retention days per project, from Postgres, cached for a minute. */
10
+ export class RetentionCache {
11
+ lookup;
12
+ defaultDays;
13
+ cache = new Map();
14
+ constructor(lookup, defaultDays) {
15
+ this.lookup = lookup;
16
+ this.defaultDays = defaultDays;
17
+ }
18
+ async daysOf(projectIds) {
19
+ const now = Date.now();
20
+ const missing = [...new Set(projectIds)].filter((id) => !this.cache.has(id) || now - this.cache.get(id).atMs > RETENTION_CACHE_MS);
21
+ if (missing.length) {
22
+ const found = await this.lookup(missing);
23
+ for (const id of missing)
24
+ this.cache.set(id, { days: found.get(id) ?? this.defaultDays, atMs: now });
25
+ }
26
+ return new Map(projectIds.map((id) => [id, this.cache.get(id).days]));
27
+ }
28
+ async msOf(projectId) {
29
+ return (await this.daysOf([projectId])).get(projectId) * DAY_MS;
30
+ }
31
+ }
32
+ /** A row object from a column list and values in the same order. */
33
+ export function rowOf(cols, values) {
34
+ const out = {};
35
+ cols.forEach((c, i) => (out[c] = values[i] ?? null));
36
+ return out;
37
+ }
38
+ export const byProject = (items) => {
39
+ const out = new Map();
40
+ for (const it of items)
41
+ out.set(it.project, [...(out.get(it.project) ?? []), it]);
42
+ return out;
43
+ };
44
+ export { DAY_MS };
45
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/telemetry/ch/util.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,IAAI,OAAO,GAAG,CAAC,CAAC;AAEhB,uFAAuF;AACvF,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACxD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,sEAAsE;AACtE,MAAM,OAAO,cAAc;IAIN,MAAM;IACN,WAAW;IAJb,KAAK,GAAG,IAAI,GAAG,EAA0C,CAAC;IAE3E,YACmB,MAAmB,EACnB,WAAmB;sBADnB,MAAM;2BACN,WAAW;IAC3B,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,UAA6B;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,IAAI,GAAG,kBAAkB,CAAC,CAAC;QACpI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACzC,KAAK,MAAM,EAAE,IAAI,OAAO;gBAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QACvG,CAAC;QACD,OAAO,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAE,GAAG,MAAM,CAAC;IACnE,CAAC;CACF;AAED,oEAAoE;AACpE,MAAM,UAAU,KAAK,CAAC,IAAuB,EAAE,MAA0B;IACvE,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IACrD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,CAAgC,KAAmB,EAAoB,EAAE;IAChG,MAAM,GAAG,GAAG,IAAI,GAAG,EAAe,CAAC;IACnC,KAAK,MAAM,EAAE,IAAI,KAAK;QAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAClF,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { HubWrite } from "@wizeworks/lens-hub/kit";
2
+ import type { ChClient } from "./http.js";
3
+ import type { SettleQueue } from "./queue.js";
4
+ /** Small batches from many add-ons: ClickHouse buffers them into one part, and answers once they are written. */
5
+ export declare const ASYNC: {
6
+ async_insert: string;
7
+ wait_for_async_insert: string;
8
+ };
9
+ /** Save one batch's raw telemetry and queue its traces for settling. Metric rollups are written by the caller. */
10
+ export declare function writeRaw(ch: ChClient, queue: SettleQueue, projectId: string, w: HubWrite, now: number, retentionMs: number): Promise<void>;
11
+ //# sourceMappingURL=write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/telemetry/ch/write.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,iHAAiH;AACjH,eAAO,MAAM,KAAK;IAAK,YAAY;IAAO,qBAAqB;CAAO,CAAC;AA0CvE,kHAAkH;AAClH,wBAAsB,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAahJ"}
@@ -0,0 +1,59 @@
1
+ // Ingest into ClickHouse: raw spans, logs, trace bounds, the update log, and metric points. Server-side async inserts batch the small writes.
2
+ import { createHash } from "node:crypto";
3
+ import { ATTR_BROWSER_SESSION, logKey, seriesKeyOf } from "@wizeworks/lens-core";
4
+ import { nextVer } from "./util.js";
5
+ /** Small batches from many add-ons: ClickHouse buffers them into one part, and answers once they are written. */
6
+ export const ASYNC = { async_insert: "1", wait_for_async_insert: "1" };
7
+ const sha1 = (text) => createHash("sha1").update(text).digest("hex");
8
+ const sessionOf = (s) => {
9
+ const v = s.attributes[ATTR_BROWSER_SESSION];
10
+ return typeof v === "string" && v ? v : null;
11
+ };
12
+ /** One bounds row per trace in the batch: its earliest start and latest end here. */
13
+ function headRows(w, projectId, now, expire) {
14
+ const bounds = new Map();
15
+ const touch = (id, start, end) => {
16
+ const b = bounds.get(id);
17
+ bounds.set(id, b ? [Math.min(b[0], start), Math.max(b[1], end)] : [start, end]);
18
+ };
19
+ for (const s of w.spans)
20
+ touch(s.traceId, s.startMs, s.startMs + s.durationMs);
21
+ for (const { traceId, log } of w.logs)
22
+ touch(traceId, log.timeMs, log.timeMs);
23
+ const env = w.sender.environment ?? "";
24
+ return [...bounds].map(([trace_id, [start, end]]) => ({ project_id: projectId, trace_id, start_ms: start, end_ms: end, updated_ms: now, env, expire_ms: expire(start) }));
25
+ }
26
+ function spanRows(w, projectId, ver, expire) {
27
+ return w.spans.map((s) => ({
28
+ project_id: projectId, trace_id: s.traceId, span_id: s.spanId, service: s.service, start_ms: s.startMs, duration_ms: s.durationMs,
29
+ session: sessionOf(s), json: JSON.stringify(s), ver, expire_ms: expire(s.startMs),
30
+ }));
31
+ }
32
+ function logRows(w, projectId, ver, expire) {
33
+ return w.logs.map(({ traceId, log }) => ({
34
+ project_id: projectId, trace_id: traceId, key: sha1(logKey(log)), time_ms: log.timeMs, json: JSON.stringify(log), ver, expire_ms: expire(log.timeMs),
35
+ }));
36
+ }
37
+ function pointRows(w, projectId, expire) {
38
+ const env = w.sender.environment ?? "";
39
+ return (w.metrics ?? []).map((p) => ({
40
+ project_id: projectId, time_ms: p.timeMs, env, service: p.service, name: p.name, series_key: sha1(seriesKeyOf(p)), json: JSON.stringify(p), expire_ms: expire(p.timeMs),
41
+ }));
42
+ }
43
+ /** Save one batch's raw telemetry and queue its traces for settling. Metric rollups are written by the caller. */
44
+ export async function writeRaw(ch, queue, projectId, w, now, retentionMs) {
45
+ const expire = (ms) => ms + retentionMs;
46
+ const ver = nextVer(now);
47
+ const heads = headRows(w, projectId, now, expire);
48
+ await Promise.all([
49
+ ch.insert("spans_raw", spanRows(w, projectId, ver, expire), ASYNC),
50
+ ch.insert("logs_raw", logRows(w, projectId, ver, expire), ASYNC),
51
+ ch.insert("metric_points_raw", pointRows(w, projectId, expire), ASYNC),
52
+ ]);
53
+ // Bounds and the update log go last, so a settle never sees a trace before its parts.
54
+ const updates = heads.map((h) => ({ project_id: h.project_id, trace_id: h.trace_id, updated_ms: now, env: h.env }));
55
+ await Promise.all([ch.insert("trace_heads", heads, ASYNC), ch.insert("trace_updates", updates, ASYNC)]);
56
+ for (const h of heads)
57
+ queue.touch(projectId, h.trace_id, h.env, now);
58
+ }
59
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../../src/telemetry/ch/write.ts"],"names":[],"mappings":"AAAA,8IAA8I;AAC9I,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,WAAW,EAAa,MAAM,sBAAsB,CAAC;AAI5F,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,iHAAiH;AACjH,MAAM,CAAC,MAAM,KAAK,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,qBAAqB,EAAE,GAAG,EAAE,CAAC;AAEvE,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAE7E,MAAM,SAAS,GAAG,CAAC,CAAO,EAAE,EAAE;IAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAC7C,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC,CAAC;AAEF,qFAAqF;AACrF,SAAS,QAAQ,CAAC,CAAW,EAAE,SAAiB,EAAE,GAAW,EAAE,MAA8B;IAC3F,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IACnD,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,KAAa,EAAE,GAAW,EAAE,EAAE;QACvD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAClF,CAAC,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK;QAAE,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;IAC/E,KAAK,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI;QAAE,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;IACvC,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5K,CAAC;AAED,SAAS,QAAQ,CAAC,CAAW,EAAE,SAAiB,EAAE,GAAW,EAAE,MAA8B;IAC3F,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,UAAU;QACjI,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;KAClF,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,OAAO,CAAC,CAAW,EAAE,SAAiB,EAAE,GAAW,EAAE,MAA8B;IAC1F,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;QACvC,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;KACrJ,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,SAAS,CAAC,CAAW,EAAE,SAAiB,EAAE,MAA8B;IAC/E,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;IACvC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;KACxK,CAAC,CAAC,CAAC;AACN,CAAC;AAED,kHAAkH;AAClH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,EAAY,EAAE,KAAkB,EAAE,SAAiB,EAAE,CAAW,EAAE,GAAW,EAAE,WAAmB;IAC/H,MAAM,MAAM,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,EAAE,GAAG,WAAW,CAAC;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC;QAClE,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC;QAChE,EAAE,CAAC,MAAM,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC;KACvE,CAAC,CAAC;IACH,sFAAsF;IACtF,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpH,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,eAAe,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACxG,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACxE,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Db } from "../db/db.js";
2
+ import type { TelemetryStore } from "./store.js";
3
+ export interface CopyResult {
4
+ traces: number;
5
+ points: number;
6
+ }
7
+ /** Copy everything (the target settles it later); projects the target has are skipped, else rollups count twice; `force` copies them too, after the switch. */
8
+ export declare function copyTelemetry(db: Db, to: TelemetryStore, now: number, log?: (line: string) => void, force?: boolean): Promise<CopyResult>;
9
+ //# sourceMappingURL=copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../../src/telemetry/copy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAoDD,+JAA+J;AAC/J,wBAAsB,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAe,EAAE,KAAK,UAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAcvJ"}
@@ -0,0 +1,60 @@
1
+ const PAGE = 500;
2
+ /** One page of a project's traces, newest first, after the (start, id) cursor. */
3
+ async function tracePage(db, projectId, after) {
4
+ const cursor = after ? "AND (start_ms < $2 OR (start_ms = $2 AND trace_id > $3))" : "";
5
+ return db.query(`SELECT trace_id, start_ms, env FROM traces WHERE project_id = $1 ${cursor} ORDER BY start_ms DESC, trace_id LIMIT ${PAGE}`, after ? [projectId, after[0], after[1]] : [projectId]);
6
+ }
7
+ async function partsOf(db, projectId, ids) {
8
+ const spans = await db.query("SELECT trace_id, json FROM spans WHERE project_id = $1 AND trace_id = ANY($2)", [projectId, [...ids]]);
9
+ const logs = await db.query("SELECT trace_id, json FROM logs WHERE project_id = $1 AND trace_id = ANY($2)", [projectId, [...ids]]);
10
+ return { spans, logs };
11
+ }
12
+ /** Every trace of a project, written one trace at a time so each keeps its environment. */
13
+ async function copyTraces(db, to, projectId, now) {
14
+ let after = null;
15
+ let n = 0;
16
+ for (;;) {
17
+ const page = await tracePage(db, projectId, after);
18
+ if (!page.length)
19
+ return n;
20
+ const { spans, logs } = await partsOf(db, projectId, page.map((t) => t.trace_id));
21
+ for (const t of page) {
22
+ const s = spans.filter((r) => r.trace_id === t.trace_id).map((r) => JSON.parse(r.json));
23
+ const l = logs.filter((r) => r.trace_id === t.trace_id).map((r) => ({ traceId: t.trace_id, log: JSON.parse(r.json) }));
24
+ await to.write(projectId, { sender: { service: s[0]?.service ?? "copy", environment: t.env }, via: "addon", spans: s, logs: l, remotes: [] }, now);
25
+ }
26
+ n += page.length;
27
+ after = [page[page.length - 1].start_ms, page[page.length - 1].trace_id];
28
+ }
29
+ }
30
+ /** Every metric point of a project, oldest first, in batches of one environment, so counters and rates come out as at ingest. */
31
+ async function copyPoints(db, to, projectId, now) {
32
+ let n = 0;
33
+ for (let offset = 0;; offset += PAGE * 10) {
34
+ const rows = await db.query(`SELECT env, json FROM metric_points WHERE project_id = $1 ORDER BY time_ms, series_key LIMIT ${PAGE * 10} OFFSET ${offset}`, [projectId]);
35
+ if (!rows.length)
36
+ return n;
37
+ for (const env of [...new Set(rows.map((r) => r.env))]) {
38
+ const metrics = rows.filter((r) => r.env === env).map((r) => JSON.parse(r.json));
39
+ await to.write(projectId, { sender: { service: "copy", environment: env }, via: "otlp", spans: [], logs: [], remotes: [], metrics }, now);
40
+ }
41
+ n += rows.length;
42
+ }
43
+ }
44
+ /** Copy everything (the target settles it later); projects the target has are skipped, else rollups count twice; `force` copies them too, after the switch. */
45
+ export async function copyTelemetry(db, to, now, log = () => { }, force = false) {
46
+ const out = { traces: 0, points: 0 };
47
+ for (const { id } of await db.query("SELECT id FROM projects ORDER BY id")) {
48
+ if (!force && (await to.counts(id)).traces > 0) {
49
+ log(` ${id}: already copied, skipped`);
50
+ continue;
51
+ }
52
+ const traces = await copyTraces(db, to, id, now);
53
+ const points = await copyPoints(db, to, id, now);
54
+ log(` ${id}: ${traces} traces, ${points} metric points`);
55
+ out.traces += traces;
56
+ out.points += points;
57
+ }
58
+ return out;
59
+ }
60
+ //# sourceMappingURL=copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/telemetry/copy.ts"],"names":[],"mappings":"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"}