@superblocksteam/telemetry 2.0.173-next.4 → 2.0.174

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 (304) hide show
  1. package/dist/browser/console-logging.js +7 -2
  2. package/dist/browser/console-logging.js.map +1 -1
  3. package/dist/browser/early-console-buffer.js +14 -12
  4. package/dist/browser/early-console-buffer.js.map +1 -1
  5. package/dist/browser/index.js +41 -12
  6. package/dist/browser/index.js.map +1 -1
  7. package/dist/browser/init.d.ts +1 -1
  8. package/dist/browser/init.d.ts.map +1 -1
  9. package/dist/browser/init.js +52 -42
  10. package/dist/browser/init.js.map +1 -1
  11. package/dist/browser/instrumentations.js +15 -11
  12. package/dist/browser/instrumentations.js.map +1 -1
  13. package/dist/browser/logs.d.ts +1 -1
  14. package/dist/browser/logs.d.ts.map +1 -1
  15. package/dist/browser/logs.js +18 -11
  16. package/dist/browser/logs.js.map +1 -1
  17. package/dist/browser/metrics.js +12 -9
  18. package/dist/browser/metrics.js.map +1 -1
  19. package/dist/browser/resilient-exporter.d.ts +1 -1
  20. package/dist/browser/resilient-exporter.d.ts.map +1 -1
  21. package/dist/browser/resilient-exporter.js +12 -8
  22. package/dist/browser/resilient-exporter.js.map +1 -1
  23. package/dist/browser/sanitizer.js +6 -2
  24. package/dist/browser/sanitizer.js.map +1 -1
  25. package/dist/browser/traced-socket.js +18 -14
  26. package/dist/browser/traced-socket.js.map +1 -1
  27. package/dist/common/contracts/tier2-traces.js +44 -33
  28. package/dist/common/contracts/tier2-traces.js.map +1 -1
  29. package/dist/common/deployment-type.js +8 -5
  30. package/dist/common/deployment-type.js.map +1 -1
  31. package/dist/common/guardrails.js +38 -26
  32. package/dist/common/guardrails.js.map +1 -1
  33. package/dist/common/index.js +24 -8
  34. package/dist/common/index.js.map +1 -1
  35. package/dist/common/log-sanitizer.js +55 -37
  36. package/dist/common/log-sanitizer.js.map +1 -1
  37. package/dist/common/policy-evaluator.d.ts +1 -1
  38. package/dist/common/policy-evaluator.d.ts.map +1 -1
  39. package/dist/common/policy-evaluator.js +9 -5
  40. package/dist/common/policy-evaluator.js.map +1 -1
  41. package/dist/common/resource.js +25 -18
  42. package/dist/common/resource.js.map +1 -1
  43. package/dist/common/tier-hints.js +22 -12
  44. package/dist/common/tier-hints.js.map +1 -1
  45. package/dist/common/trace-sanitizer.js +10 -6
  46. package/dist/common/trace-sanitizer.js.map +1 -1
  47. package/dist/common/traced-socket-types.js +2 -1
  48. package/dist/common/traced-socket-types.js.map +1 -1
  49. package/dist/index.js +38 -6
  50. package/dist/index.js.map +1 -1
  51. package/dist/lint/forbidden-attributes.js +24 -19
  52. package/dist/lint/forbidden-attributes.js.map +1 -1
  53. package/dist/lint/index.js +8 -1
  54. package/dist/lint/index.js.map +1 -1
  55. package/dist/llmobs/index.js +9 -2
  56. package/dist/llmobs/index.js.map +1 -1
  57. package/dist/llmobs/tier1-exporter.js +12 -6
  58. package/dist/llmobs/tier1-exporter.js.map +1 -1
  59. package/dist/llmobs/tier2-summarizer.js +5 -1
  60. package/dist/llmobs/tier2-summarizer.js.map +1 -1
  61. package/dist/node/dynamic-attribute-processor.js +7 -2
  62. package/dist/node/dynamic-attribute-processor.js.map +1 -1
  63. package/dist/node/exporters/resilient-exporter.d.ts +1 -1
  64. package/dist/node/exporters/resilient-exporter.d.ts.map +1 -1
  65. package/dist/node/exporters/resilient-exporter.js +12 -8
  66. package/dist/node/exporters/resilient-exporter.js.map +1 -1
  67. package/dist/node/index.js +26 -7
  68. package/dist/node/index.js.map +1 -1
  69. package/dist/node/init.d.ts +3 -3
  70. package/dist/node/init.d.ts.map +1 -1
  71. package/dist/node/init.js +72 -66
  72. package/dist/node/init.js.map +1 -1
  73. package/dist/node/local-obs-mode.js +4 -1
  74. package/dist/node/local-obs-mode.js.map +1 -1
  75. package/dist/node/log-processor.d.ts +1 -1
  76. package/dist/node/log-processor.d.ts.map +1 -1
  77. package/dist/node/log-processor.js +55 -47
  78. package/dist/node/log-processor.js.map +1 -1
  79. package/dist/node/metrics-client.js +5 -1
  80. package/dist/node/metrics-client.js.map +1 -1
  81. package/dist/node/safe-logger.js +12 -8
  82. package/dist/node/safe-logger.js.map +1 -1
  83. package/dist/node/sanitizing-processor.d.ts +2 -2
  84. package/dist/node/sanitizing-processor.d.ts.map +1 -1
  85. package/dist/node/sanitizing-processor.js +10 -6
  86. package/dist/node/sanitizing-processor.js.map +1 -1
  87. package/dist/node/service-tracers.js +10 -7
  88. package/dist/node/service-tracers.js.map +1 -1
  89. package/dist/node/traced-socket.d.ts +3 -3
  90. package/dist/node/traced-socket.d.ts.map +1 -1
  91. package/dist/node/traced-socket.js +52 -48
  92. package/dist/node/traced-socket.js.map +1 -1
  93. package/dist/npm-registry/emitter.js +47 -34
  94. package/dist/npm-registry/emitter.js.map +1 -1
  95. package/dist/npm-registry/index.js +19 -3
  96. package/dist/npm-registry/index.js.map +1 -1
  97. package/dist/npm-registry/sanitize.js +27 -16
  98. package/dist/npm-registry/sanitize.js.map +1 -1
  99. package/dist/npm-registry/spans.js +12 -7
  100. package/dist/npm-registry/spans.js.map +1 -1
  101. package/dist/testing/in-memory-exporter.d.ts +1 -1
  102. package/dist/testing/in-memory-exporter.d.ts.map +1 -1
  103. package/dist/testing/in-memory-exporter.js +12 -6
  104. package/dist/testing/in-memory-exporter.js.map +1 -1
  105. package/dist/testing/index.js +15 -3
  106. package/dist/testing/index.js.map +1 -1
  107. package/dist/testing/metrics-capture.js +15 -12
  108. package/dist/testing/metrics-capture.js.map +1 -1
  109. package/dist/testing/test-init.js +31 -24
  110. package/dist/testing/test-init.js.map +1 -1
  111. package/dist/types/index.js +17 -1
  112. package/dist/types/index.js.map +1 -1
  113. package/dist/types/policy.js +24 -21
  114. package/dist/types/policy.js.map +1 -1
  115. package/dist-esm/browser/console-logging.d.ts +18 -0
  116. package/dist-esm/browser/console-logging.d.ts.map +1 -0
  117. package/dist-esm/browser/console-logging.js +27 -0
  118. package/dist-esm/browser/console-logging.js.map +1 -0
  119. package/dist-esm/browser/early-console-buffer.d.ts +49 -0
  120. package/dist-esm/browser/early-console-buffer.d.ts.map +1 -0
  121. package/dist-esm/browser/early-console-buffer.js +181 -0
  122. package/dist-esm/browser/early-console-buffer.js.map +1 -0
  123. package/dist-esm/browser/index.d.ts +18 -0
  124. package/dist-esm/browser/index.d.ts.map +1 -0
  125. package/dist-esm/browser/index.js +23 -0
  126. package/dist-esm/browser/index.js.map +1 -0
  127. package/dist-esm/browser/init.d.ts +100 -0
  128. package/dist-esm/browser/init.d.ts.map +1 -0
  129. package/dist-esm/browser/init.js +317 -0
  130. package/dist-esm/browser/init.js.map +1 -0
  131. package/dist-esm/browser/instrumentations.d.ts +67 -0
  132. package/dist-esm/browser/instrumentations.d.ts.map +1 -0
  133. package/dist-esm/browser/instrumentations.js +79 -0
  134. package/dist-esm/browser/instrumentations.js.map +1 -0
  135. package/dist-esm/browser/logs.d.ts +57 -0
  136. package/dist-esm/browser/logs.d.ts.map +1 -0
  137. package/dist-esm/browser/logs.js +80 -0
  138. package/dist-esm/browser/logs.js.map +1 -0
  139. package/dist-esm/browser/metrics.d.ts +29 -0
  140. package/dist-esm/browser/metrics.d.ts.map +1 -0
  141. package/dist-esm/browser/metrics.js +46 -0
  142. package/dist-esm/browser/metrics.js.map +1 -0
  143. package/dist-esm/browser/resilient-exporter.d.ts +43 -0
  144. package/dist-esm/browser/resilient-exporter.d.ts.map +1 -0
  145. package/dist-esm/browser/resilient-exporter.js +84 -0
  146. package/dist-esm/browser/resilient-exporter.js.map +1 -0
  147. package/dist-esm/browser/sanitizer.d.ts +35 -0
  148. package/dist-esm/browser/sanitizer.d.ts.map +1 -0
  149. package/dist-esm/browser/sanitizer.js +207 -0
  150. package/dist-esm/browser/sanitizer.js.map +1 -0
  151. package/dist-esm/browser/traced-socket.d.ts +102 -0
  152. package/dist-esm/browser/traced-socket.d.ts.map +1 -0
  153. package/dist-esm/browser/traced-socket.js +199 -0
  154. package/dist-esm/browser/traced-socket.js.map +1 -0
  155. package/dist-esm/common/contracts/tier2-traces.d.ts +116 -0
  156. package/dist-esm/common/contracts/tier2-traces.d.ts.map +1 -0
  157. package/dist-esm/common/contracts/tier2-traces.js +725 -0
  158. package/dist-esm/common/contracts/tier2-traces.js.map +1 -0
  159. package/dist-esm/common/deployment-type.d.ts +18 -0
  160. package/dist-esm/common/deployment-type.d.ts.map +1 -0
  161. package/dist-esm/common/deployment-type.js +27 -0
  162. package/dist-esm/common/deployment-type.js.map +1 -0
  163. package/dist-esm/common/guardrails.d.ts +132 -0
  164. package/dist-esm/common/guardrails.d.ts.map +1 -0
  165. package/dist-esm/common/guardrails.js +230 -0
  166. package/dist-esm/common/guardrails.js.map +1 -0
  167. package/dist-esm/common/index.d.ts +17 -0
  168. package/dist-esm/common/index.d.ts.map +1 -0
  169. package/dist-esm/common/index.js +17 -0
  170. package/dist-esm/common/index.js.map +1 -0
  171. package/dist-esm/common/log-sanitizer.d.ts +163 -0
  172. package/dist-esm/common/log-sanitizer.d.ts.map +1 -0
  173. package/dist-esm/common/log-sanitizer.js +745 -0
  174. package/dist-esm/common/log-sanitizer.js.map +1 -0
  175. package/dist-esm/common/policy-evaluator.d.ts +103 -0
  176. package/dist-esm/common/policy-evaluator.d.ts.map +1 -0
  177. package/dist-esm/common/policy-evaluator.js +196 -0
  178. package/dist-esm/common/policy-evaluator.js.map +1 -0
  179. package/dist-esm/common/resource.d.ts +79 -0
  180. package/dist-esm/common/resource.d.ts.map +1 -0
  181. package/dist-esm/common/resource.js +121 -0
  182. package/dist-esm/common/resource.js.map +1 -0
  183. package/dist-esm/common/tier-hints.d.ts +182 -0
  184. package/dist-esm/common/tier-hints.d.ts.map +1 -0
  185. package/dist-esm/common/tier-hints.js +199 -0
  186. package/dist-esm/common/tier-hints.js.map +1 -0
  187. package/dist-esm/common/trace-sanitizer.d.ts +82 -0
  188. package/dist-esm/common/trace-sanitizer.d.ts.map +1 -0
  189. package/dist-esm/common/trace-sanitizer.js +230 -0
  190. package/dist-esm/common/trace-sanitizer.js.map +1 -0
  191. package/dist-esm/common/traced-socket-types.d.ts +43 -0
  192. package/dist-esm/common/traced-socket-types.d.ts.map +1 -0
  193. package/dist-esm/common/traced-socket-types.js +16 -0
  194. package/dist-esm/common/traced-socket-types.js.map +1 -0
  195. package/dist-esm/index.d.ts +45 -0
  196. package/dist-esm/index.d.ts.map +1 -0
  197. package/dist-esm/index.js +56 -0
  198. package/dist-esm/index.js.map +1 -0
  199. package/dist-esm/lint/forbidden-attributes.d.ts +149 -0
  200. package/dist-esm/lint/forbidden-attributes.d.ts.map +1 -0
  201. package/dist-esm/lint/forbidden-attributes.js +210 -0
  202. package/dist-esm/lint/forbidden-attributes.js.map +1 -0
  203. package/dist-esm/lint/index.d.ts +9 -0
  204. package/dist-esm/lint/index.d.ts.map +1 -0
  205. package/dist-esm/lint/index.js +9 -0
  206. package/dist-esm/lint/index.js.map +1 -0
  207. package/dist-esm/llmobs/index.d.ts +22 -0
  208. package/dist-esm/llmobs/index.d.ts.map +1 -0
  209. package/dist-esm/llmobs/index.js +22 -0
  210. package/dist-esm/llmobs/index.js.map +1 -0
  211. package/dist-esm/llmobs/tier1-exporter.d.ts +146 -0
  212. package/dist-esm/llmobs/tier1-exporter.d.ts.map +1 -0
  213. package/dist-esm/llmobs/tier1-exporter.js +193 -0
  214. package/dist-esm/llmobs/tier1-exporter.js.map +1 -0
  215. package/dist-esm/llmobs/tier2-summarizer.d.ts +268 -0
  216. package/dist-esm/llmobs/tier2-summarizer.d.ts.map +1 -0
  217. package/dist-esm/llmobs/tier2-summarizer.js +652 -0
  218. package/dist-esm/llmobs/tier2-summarizer.js.map +1 -0
  219. package/dist-esm/node/dynamic-attribute-processor.d.ts +43 -0
  220. package/dist-esm/node/dynamic-attribute-processor.d.ts.map +1 -0
  221. package/dist-esm/node/dynamic-attribute-processor.js +74 -0
  222. package/dist-esm/node/dynamic-attribute-processor.js.map +1 -0
  223. package/dist-esm/node/exporters/resilient-exporter.d.ts +91 -0
  224. package/dist-esm/node/exporters/resilient-exporter.d.ts.map +1 -0
  225. package/dist-esm/node/exporters/resilient-exporter.js +132 -0
  226. package/dist-esm/node/exporters/resilient-exporter.js.map +1 -0
  227. package/dist-esm/node/index.d.ts +13 -0
  228. package/dist-esm/node/index.d.ts.map +1 -0
  229. package/dist-esm/node/index.js +13 -0
  230. package/dist-esm/node/index.js.map +1 -0
  231. package/dist-esm/node/init.d.ts +97 -0
  232. package/dist-esm/node/init.d.ts.map +1 -0
  233. package/dist-esm/node/init.js +359 -0
  234. package/dist-esm/node/init.js.map +1 -0
  235. package/dist-esm/node/local-obs-mode.d.ts +17 -0
  236. package/dist-esm/node/local-obs-mode.d.ts.map +1 -0
  237. package/dist-esm/node/local-obs-mode.js +19 -0
  238. package/dist-esm/node/local-obs-mode.js.map +1 -0
  239. package/dist-esm/node/log-processor.d.ts +132 -0
  240. package/dist-esm/node/log-processor.d.ts.map +1 -0
  241. package/dist-esm/node/log-processor.js +389 -0
  242. package/dist-esm/node/log-processor.js.map +1 -0
  243. package/dist-esm/node/metrics-client.d.ts +88 -0
  244. package/dist-esm/node/metrics-client.d.ts.map +1 -0
  245. package/dist-esm/node/metrics-client.js +205 -0
  246. package/dist-esm/node/metrics-client.js.map +1 -0
  247. package/dist-esm/node/safe-logger.d.ts +55 -0
  248. package/dist-esm/node/safe-logger.d.ts.map +1 -0
  249. package/dist-esm/node/safe-logger.js +154 -0
  250. package/dist-esm/node/safe-logger.js.map +1 -0
  251. package/dist-esm/node/sanitizing-processor.d.ts +67 -0
  252. package/dist-esm/node/sanitizing-processor.d.ts.map +1 -0
  253. package/dist-esm/node/sanitizing-processor.js +163 -0
  254. package/dist-esm/node/sanitizing-processor.js.map +1 -0
  255. package/dist-esm/node/service-tracers.d.ts +52 -0
  256. package/dist-esm/node/service-tracers.d.ts.map +1 -0
  257. package/dist-esm/node/service-tracers.js +78 -0
  258. package/dist-esm/node/service-tracers.js.map +1 -0
  259. package/dist-esm/node/traced-socket.d.ts +120 -0
  260. package/dist-esm/node/traced-socket.d.ts.map +1 -0
  261. package/dist-esm/node/traced-socket.js +334 -0
  262. package/dist-esm/node/traced-socket.js.map +1 -0
  263. package/dist-esm/npm-registry/emitter.d.ts +330 -0
  264. package/dist-esm/npm-registry/emitter.d.ts.map +1 -0
  265. package/dist-esm/npm-registry/emitter.js +546 -0
  266. package/dist-esm/npm-registry/emitter.js.map +1 -0
  267. package/dist-esm/npm-registry/index.d.ts +12 -0
  268. package/dist-esm/npm-registry/index.d.ts.map +1 -0
  269. package/dist-esm/npm-registry/index.js +12 -0
  270. package/dist-esm/npm-registry/index.js.map +1 -0
  271. package/dist-esm/npm-registry/sanitize.d.ts +174 -0
  272. package/dist-esm/npm-registry/sanitize.d.ts.map +1 -0
  273. package/dist-esm/npm-registry/sanitize.js +331 -0
  274. package/dist-esm/npm-registry/sanitize.js.map +1 -0
  275. package/dist-esm/npm-registry/spans.d.ts +61 -0
  276. package/dist-esm/npm-registry/spans.d.ts.map +1 -0
  277. package/dist-esm/npm-registry/spans.js +86 -0
  278. package/dist-esm/npm-registry/spans.js.map +1 -0
  279. package/dist-esm/package.json +1 -0
  280. package/dist-esm/testing/in-memory-exporter.d.ts +179 -0
  281. package/dist-esm/testing/in-memory-exporter.d.ts.map +1 -0
  282. package/dist-esm/testing/in-memory-exporter.js +250 -0
  283. package/dist-esm/testing/in-memory-exporter.js.map +1 -0
  284. package/dist-esm/testing/index.d.ts +9 -0
  285. package/dist-esm/testing/index.d.ts.map +1 -0
  286. package/dist-esm/testing/index.js +9 -0
  287. package/dist-esm/testing/index.js.map +1 -0
  288. package/dist-esm/testing/metrics-capture.d.ts +29 -0
  289. package/dist-esm/testing/metrics-capture.d.ts.map +1 -0
  290. package/dist-esm/testing/metrics-capture.js +71 -0
  291. package/dist-esm/testing/metrics-capture.js.map +1 -0
  292. package/dist-esm/testing/test-init.d.ts +80 -0
  293. package/dist-esm/testing/test-init.d.ts.map +1 -0
  294. package/dist-esm/testing/test-init.js +137 -0
  295. package/dist-esm/testing/test-init.js.map +1 -0
  296. package/dist-esm/types/index.d.ts +84 -0
  297. package/dist-esm/types/index.d.ts.map +1 -0
  298. package/dist-esm/types/index.js +7 -0
  299. package/dist-esm/types/index.js.map +1 -0
  300. package/dist-esm/types/policy.d.ts +92 -0
  301. package/dist-esm/types/policy.d.ts.map +1 -0
  302. package/dist-esm/types/policy.js +122 -0
  303. package/dist-esm/types/policy.js.map +1 -0
  304. package/package.json +17 -11
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Early Console Buffer
3
+ *
4
+ * Patches console.log/info/debug/warn/error as early as possible (before OTel
5
+ * initialises) to capture logs in a ring buffer. On OTel init, the buffer is
6
+ * flushed to the OTel Logger and all subsequent console calls are forwarded
7
+ * directly.
8
+ *
9
+ * IMPORTANT: Each patched method ALWAYS calls through to the original console
10
+ * method first, so downstream patchers (Datadog RUM, PostHog, etc.) that wrap
11
+ * console after us continue to receive every call.
12
+ */
13
+ import { SeverityNumber } from "@opentelemetry/api-logs";
14
+ import { safeJsonStringify } from "../common/log-sanitizer.js";
15
+ import { ConsoleLogAttributes } from "./console-logging.js";
16
+ function mergeAllConsoleLogAttributes(args) {
17
+ if (args.length === 0)
18
+ return undefined;
19
+ return args.reduce((merged, arg) => {
20
+ if (arg instanceof ConsoleLogAttributes) {
21
+ return { ...merged, ...arg.attributes };
22
+ }
23
+ return merged;
24
+ }, {});
25
+ }
26
+ class EarlyConsoleBuffer {
27
+ static instance;
28
+ buffer = [];
29
+ maxBufferSize = 1000;
30
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
31
+ originalMethods = {};
32
+ otelLogger = undefined;
33
+ isPatched = false;
34
+ disabled = false;
35
+ static getInstance() {
36
+ if (!EarlyConsoleBuffer.instance) {
37
+ EarlyConsoleBuffer.instance = new EarlyConsoleBuffer();
38
+ }
39
+ return EarlyConsoleBuffer.instance;
40
+ }
41
+ /**
42
+ * Patch console methods immediately with buffering.
43
+ * Safe to call multiple times — subsequent calls are no-ops.
44
+ */
45
+ patchEarly() {
46
+ if (this.isPatched || this.disabled)
47
+ return;
48
+ // Capture current console methods (which may already be patched by Datadog
49
+ // RUM or PostHog). We keep calling through to whatever was here at the time
50
+ // patchEarly() was invoked.
51
+ // eslint-disable-next-line no-console
52
+ this.originalMethods.log = console.log.bind(console);
53
+ this.originalMethods.info = console.info.bind(console);
54
+ this.originalMethods.debug = console.debug.bind(console);
55
+ this.originalMethods.warn = console.warn.bind(console);
56
+ this.originalMethods.error = console.error.bind(console);
57
+ this.patchMethod("log");
58
+ this.patchMethod("info");
59
+ this.patchMethod("debug");
60
+ this.patchMethod("warn");
61
+ this.patchMethod("error");
62
+ this.isPatched = true;
63
+ // Announce via original info to avoid touching the newly patched method
64
+ // (which would buffer this diagnostic message unnecessarily).
65
+ this.originalMethods.info("[EarlyConsoleBuffer] Console patching enabled — buffering logs until OpenTelemetry initializes");
66
+ }
67
+ patchMethod(level) {
68
+ const originalMethod = this.originalMethods[level];
69
+ console[level] = (...args) => {
70
+ // ALWAYS call through to the original first so downstream patchers work.
71
+ originalMethod(...args);
72
+ // Route to OTel or buffer depending on initialization state.
73
+ if (this.otelLogger) {
74
+ this.sendToOpenTelemetry(level, args);
75
+ }
76
+ else {
77
+ this.bufferLog(level, args);
78
+ }
79
+ };
80
+ }
81
+ bufferLog(level, args) {
82
+ if (this.buffer.length >= this.maxBufferSize) {
83
+ this.buffer.shift(); // drop oldest entry
84
+ }
85
+ this.buffer.push({ level, args, timestamp: Date.now() });
86
+ }
87
+ /**
88
+ * Disable the buffer without forwarding to OTel. Discards buffered entries
89
+ * and removes the buffering wrapper so subsequent console calls go straight
90
+ * to the original methods (no memory leak from the ever-growing ring buffer).
91
+ *
92
+ * Use this when log export is disabled (e.g. on-premise deployments) so the
93
+ * buffer-and-evict path doesn't run indefinitely.
94
+ */
95
+ disable() {
96
+ this.disabled = true;
97
+ if (!this.isPatched)
98
+ return;
99
+ for (const level of ["log", "info", "debug", "warn", "error"]) {
100
+ if (this.originalMethods[level]) {
101
+ console[level] =
102
+ this.originalMethods[level];
103
+ }
104
+ }
105
+ const count = this.buffer.length;
106
+ this.buffer = [];
107
+ this.isPatched = false;
108
+ // Use restored console.info directly
109
+ console.info(`[EarlyConsoleBuffer] Disabled — discarded ${count} buffered entries (log export not enabled)`);
110
+ }
111
+ /**
112
+ * Called once OTel is ready. Flushes buffered entries then routes all future
113
+ * console calls directly to the OTel logger.
114
+ */
115
+ enableOpenTelemetry(otelLogger) {
116
+ console.info("[EarlyConsoleBuffer] Enabling OpenTelemetry integration");
117
+ this.otelLogger = otelLogger;
118
+ this.flushBuffer();
119
+ }
120
+ flushBuffer() {
121
+ if (!this.otelLogger)
122
+ return;
123
+ const count = this.buffer.length;
124
+ if (count === 0) {
125
+ console.info("[EarlyConsoleBuffer] No buffered logs to flush");
126
+ return;
127
+ }
128
+ console.info(`[EarlyConsoleBuffer] Flushing ${count} buffered logs to OpenTelemetry`);
129
+ for (const entry of this.buffer) {
130
+ this.sendToOpenTelemetry(entry.level, entry.args, entry.timestamp, true);
131
+ }
132
+ this.buffer = [];
133
+ console.info(`[EarlyConsoleBuffer] Successfully sent ${count} buffered logs to OpenTelemetry logger`);
134
+ }
135
+ sendToOpenTelemetry(level, args, timestamp, fromBuffer) {
136
+ if (!this.otelLogger)
137
+ return;
138
+ const severityMap = {
139
+ debug: SeverityNumber.DEBUG,
140
+ log: SeverityNumber.INFO,
141
+ info: SeverityNumber.INFO,
142
+ warn: SeverityNumber.WARN,
143
+ error: SeverityNumber.ERROR,
144
+ };
145
+ const attributes = {
146
+ ...(fromBuffer ? { source: "early-console-buffer" } : {}),
147
+ ...mergeAllConsoleLogAttributes(args),
148
+ };
149
+ this.otelLogger.emit({
150
+ severityNumber: severityMap[level],
151
+ severityText: level,
152
+ body: this.formatConsoleArgs(args),
153
+ timestamp,
154
+ attributes: attributes,
155
+ });
156
+ }
157
+ formatConsoleArgs(args) {
158
+ return args
159
+ .filter((arg) => !(arg instanceof ConsoleLogAttributes))
160
+ .map((arg) => {
161
+ if (typeof arg === "string")
162
+ return arg;
163
+ if (arg === null)
164
+ return "null";
165
+ if (arg === undefined)
166
+ return "undefined";
167
+ if (typeof arg === "object") {
168
+ try {
169
+ return safeJsonStringify(arg, 2);
170
+ }
171
+ catch {
172
+ return "[object Object]";
173
+ }
174
+ }
175
+ return String(arg);
176
+ })
177
+ .join(" ");
178
+ }
179
+ }
180
+ export default EarlyConsoleBuffer;
181
+ //# sourceMappingURL=early-console-buffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"early-console-buffer.js","sourceRoot":"","sources":["../../src/browser/early-console-buffer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Browser Telemetry Bootstrap
3
+ *
4
+ * This is the ONLY approved way to initialize telemetry in browser contexts.
5
+ */
6
+ export { initBrowserTelemetry, getBrowserTelemetryInstance, isBrowserTelemetryInitialized, resetBrowserTelemetry, getEnvironmentFromHostname, type BrowserTelemetryInstance, } from "./init.js";
7
+ export { initBrowserLogs, resetBrowserLogs, type BrowserLogsConfig, type BrowserLogsInstance, } from "./logs.js";
8
+ export { initBrowserMetrics, type BrowserMetricsConfig, type BrowserMetricsInstance, } from "./metrics.js";
9
+ export { createSanitizingSpanProcessor, createSanitizingLogProcessor, type SanitizingConfig, } from "./sanitizer.js";
10
+ export { createBrowserInstrumentations, registerBrowserContextManager, type BrowserInstrumentationConfig, } from "./instrumentations.js";
11
+ export { ConsoleLogAttributes, consoleLogAttributes, } from "./console-logging.js";
12
+ export { default as EarlyConsoleBuffer } from "./early-console-buffer.js";
13
+ export { safeJsonStringify } from "../common/log-sanitizer.js";
14
+ export { getDefaultPolicy, DeploymentType } from "../types/policy.js";
15
+ export { BrowserTracedSocket, type BrowserTracedSocketConfig, type WebSocketLike, } from "./traced-socket.js";
16
+ export { BatchSpanProcessor, SimpleSpanProcessor, type SpanProcessor, type SpanExporter, type ReadableSpan, } from "@opentelemetry/sdk-trace-base";
17
+ export { type ExportResult, ExportResultCode, hrTimeToMicroseconds, } from "@opentelemetry/core";
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,6BAA6B,EAC7B,qBAAqB,EACrB,0BAA0B,EAC1B,KAAK,wBAAwB,GAC9B,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,GACzB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,EAC5B,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,6BAA6B,EAC7B,6BAA6B,EAC7B,KAAK,4BAA4B,GAClC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAG/D,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,EACL,mBAAmB,EACnB,KAAK,yBAAyB,EAC9B,KAAK,aAAa,GACnB,MAAM,oBAAoB,CAAC;AAM5B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,KAAK,YAAY,EACjB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Browser Telemetry Bootstrap
3
+ *
4
+ * This is the ONLY approved way to initialize telemetry in browser contexts.
5
+ */
6
+ export { initBrowserTelemetry, getBrowserTelemetryInstance, isBrowserTelemetryInitialized, resetBrowserTelemetry, getEnvironmentFromHostname, } from "./init.js";
7
+ export { initBrowserLogs, resetBrowserLogs, } from "./logs.js";
8
+ export { initBrowserMetrics, } from "./metrics.js";
9
+ export { createSanitizingSpanProcessor, createSanitizingLogProcessor, } from "./sanitizer.js";
10
+ export { createBrowserInstrumentations, registerBrowserContextManager, } from "./instrumentations.js";
11
+ export { ConsoleLogAttributes, consoleLogAttributes, } from "./console-logging.js";
12
+ export { default as EarlyConsoleBuffer } from "./early-console-buffer.js";
13
+ export { safeJsonStringify } from "../common/log-sanitizer.js";
14
+ // Re-export policy utilities for convenience
15
+ export { getDefaultPolicy, DeploymentType } from "../types/policy.js";
16
+ export { BrowserTracedSocket, } from "./traced-socket.js";
17
+ // Re-export OTel SDK primitives that consumers need to register custom processors
18
+ // against the provider owned by this package. Consumers must construct these from
19
+ // the version bundled here, not from their own @opentelemetry/sdk-trace-base, so
20
+ // the Span/Context types match the provider.
21
+ export { BatchSpanProcessor, SimpleSpanProcessor, } from "@opentelemetry/sdk-trace-base";
22
+ export { ExportResultCode, hrTimeToMicroseconds, } from "@opentelemetry/core";
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,oBAAoB,EACpB,2BAA2B,EAC3B,6BAA6B,EAC7B,qBAAqB,EACrB,0BAA0B,GAE3B,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,eAAe,EACf,gBAAgB,GAGjB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,kBAAkB,GAGnB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,6BAA6B,EAC7B,4BAA4B,GAE7B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,6BAA6B,EAC7B,6BAA6B,GAE9B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE/D,6CAA6C;AAC7C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,EACL,mBAAmB,GAGpB,MAAM,oBAAoB,CAAC;AAE5B,kFAAkF;AAClF,kFAAkF;AAClF,iFAAiF;AACjF,6CAA6C;AAC7C,OAAO,EACL,kBAAkB,EAClB,mBAAmB,GAIpB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAEL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Browser Telemetry Bootstrap
3
+ *
4
+ * This is the ONLY approved way to initialize telemetry in browser contexts.
5
+ * Direct WebTracerProvider usage outside this package is prohibited.
6
+ *
7
+ * Composes all browser signals: traces, metrics, logs, sanitizers, and
8
+ * auto-instrumentations into a single init call.
9
+ */
10
+ import { type Meter, type Tracer } from "@opentelemetry/api";
11
+ import type { Logger } from "@opentelemetry/api-logs";
12
+ import { type SpanProcessor } from "@opentelemetry/sdk-trace-base";
13
+ import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
14
+ import { TelemetryPolicyEvaluator } from "../common/policy-evaluator.js";
15
+ import type { BrowserTelemetryConfig } from "../types/index.js";
16
+ import { TelemetryPolicy } from "../types/policy.js";
17
+ /**
18
+ * Browser telemetry instance.
19
+ */
20
+ export interface BrowserTelemetryInstance {
21
+ /** The underlying WebTracerProvider */
22
+ provider: WebTracerProvider;
23
+ /** Policy evaluator for runtime decisions */
24
+ policyEvaluator: TelemetryPolicyEvaluator;
25
+ /** Get a tracer */
26
+ getTracer: (name?: string) => Tracer;
27
+ /** Get a meter for recording metrics */
28
+ getMeter: (name?: string) => Meter;
29
+ /** Get a logger for emitting log records */
30
+ getLogger: (name?: string) => Logger;
31
+ /** Set attributes that are injected into every new span (dynamic context like org, user) */
32
+ setGlobalSpanAttributes: (attrs: Record<string, string>) => void;
33
+ /** Register an additional SpanProcessor on the provider (e.g. LocalStorageExporter) */
34
+ addSpanProcessor: (processor: SpanProcessor) => void;
35
+ /** Flush pending logs and spans without tearing down (e.g. on pagehide) */
36
+ forceFlush: () => Promise<void>;
37
+ /** Graceful shutdown */
38
+ shutdown: () => Promise<void>;
39
+ }
40
+ /**
41
+ * Initialize browser telemetry with policy enforcement.
42
+ *
43
+ * Browser telemetry is always sanitized (Tier 2) since it runs in untrusted context.
44
+ * Full fidelity Tier 1 data should never be emitted from the browser.
45
+ *
46
+ * Composes:
47
+ * - Traces: WebTracerProvider with sanitizing + batch processors
48
+ * - Metrics: MeterProvider via initBrowserMetrics
49
+ * - Logs: LoggerProvider via initBrowserLogs (with EarlyConsoleBuffer)
50
+ * - Sanitizers: PII redaction for spans and logs
51
+ * - Instrumentations: XHR + Fetch auto-instrumentation
52
+ * - Context: StackContextManager for async context propagation
53
+ *
54
+ * @param config - Browser configuration (otlpUrl is treated as base URL)
55
+ * @param policy - Telemetry policy (REQUIRED)
56
+ * @returns Browser telemetry instance
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * import { initBrowserTelemetry } from '@superblocksteam/telemetry/browser';
61
+ * import { getDefaultPolicy, DeploymentType } from '@superblocksteam/shared';
62
+ *
63
+ * const policy = getDefaultPolicy(DeploymentType.CLOUD);
64
+ * const telemetry = initBrowserTelemetry({
65
+ * serviceName: 'superblocks-ui',
66
+ * serviceVersion: '1.0.0',
67
+ * environment: 'production',
68
+ * otlpUrl: 'https://app.superblocks.com/api',
69
+ * }, policy);
70
+ *
71
+ * const tracer = telemetry.getTracer();
72
+ * const meter = telemetry.getMeter();
73
+ * const logger = telemetry.getLogger();
74
+ * ```
75
+ */
76
+ export declare function initBrowserTelemetry(config: BrowserTelemetryConfig, policy: TelemetryPolicy): BrowserTelemetryInstance;
77
+ /**
78
+ * Get the current browser telemetry instance.
79
+ *
80
+ * @throws Error if not initialized
81
+ */
82
+ export declare function getBrowserTelemetryInstance(): BrowserTelemetryInstance;
83
+ /**
84
+ * Check if browser telemetry is initialized.
85
+ */
86
+ export declare function isBrowserTelemetryInitialized(): boolean;
87
+ /**
88
+ * Reset browser telemetry (for testing only).
89
+ * @internal
90
+ */
91
+ export declare function resetBrowserTelemetry(): void;
92
+ /**
93
+ * Derive environment from hostname.
94
+ * Utility for browser context where env vars aren't available.
95
+ *
96
+ * @param hostname - The hostname to analyze
97
+ * @returns Environment string
98
+ */
99
+ export declare function getEnvironmentFromHostname(hostname: string): string;
100
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/browser/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAIL,KAAK,KAAK,EACV,KAAK,MAAM,EACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAQtD,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAiB,MAAM,oBAAoB,CAAC;AAWpE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,uCAAuC;IACvC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,6CAA6C;IAC7C,eAAe,EAAE,wBAAwB,CAAC;IAC1C,mBAAmB;IACnB,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,wCAAwC;IACxC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,KAAK,CAAC;IACnC,4CAA4C;IAC5C,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,4FAA4F;IAC5F,uBAAuB,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IACjE,uFAAuF;IACvF,gBAAgB,EAAE,CAAC,SAAS,EAAE,aAAa,KAAK,IAAI,CAAC;IACrD,2EAA2E;IAC3E,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,wBAAwB;IACxB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAyGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,sBAAsB,EAC9B,MAAM,EAAE,eAAe,GACtB,wBAAwB,CAiJ1B;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,wBAAwB,CAOtE;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAEvD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWnE"}
@@ -0,0 +1,317 @@
1
+ /**
2
+ * Browser Telemetry Bootstrap
3
+ *
4
+ * This is the ONLY approved way to initialize telemetry in browser contexts.
5
+ * Direct WebTracerProvider usage outside this package is prohibited.
6
+ *
7
+ * Composes all browser signals: traces, metrics, logs, sanitizers, and
8
+ * auto-instrumentations into a single init call.
9
+ */
10
+ import { context, metrics, trace, } from "@opentelemetry/api";
11
+ import { W3CTraceContextPropagator, W3CBaggagePropagator, CompositePropagator, } from "@opentelemetry/core";
12
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
13
+ import { registerInstrumentations } from "@opentelemetry/instrumentation";
14
+ import { BatchSpanProcessor, } from "@opentelemetry/sdk-trace-base";
15
+ import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
16
+ import { TelemetryPolicyEvaluator } from "../common/policy-evaluator.js";
17
+ import { buildResource } from "../common/resource.js";
18
+ import { TelemetryTier } from "../types/policy.js";
19
+ import EarlyConsoleBuffer from "./early-console-buffer.js";
20
+ import { createBrowserInstrumentations, registerBrowserContextManager, } from "./instrumentations.js";
21
+ import { initBrowserLogs, resetBrowserLogs } from "./logs.js";
22
+ import { initBrowserMetrics } from "./metrics.js";
23
+ import { BrowserResilientExporter } from "./resilient-exporter.js";
24
+ import { createSanitizingSpanProcessor } from "./sanitizer.js";
25
+ // Singleton instance
26
+ let instance;
27
+ /**
28
+ * Validate browser telemetry configuration.
29
+ *
30
+ * @param config - Configuration to validate
31
+ * @throws Error if configuration is invalid
32
+ */
33
+ function validateBrowserTelemetryConfig(config) {
34
+ if (!config.serviceName?.trim()) {
35
+ throw new Error("[Telemetry] serviceName is required and cannot be empty");
36
+ }
37
+ if (!config.serviceVersion?.trim()) {
38
+ throw new Error("[Telemetry] serviceVersion is required and cannot be empty");
39
+ }
40
+ if (!config.environment?.trim()) {
41
+ throw new Error("[Telemetry] environment is required and cannot be empty");
42
+ }
43
+ if (!config.otlpUrl?.trim()) {
44
+ throw new Error("[Telemetry] otlpUrl is required for browser telemetry");
45
+ }
46
+ try {
47
+ new URL(config.otlpUrl);
48
+ }
49
+ catch (error) {
50
+ throw new Error(`[Telemetry] Invalid otlpUrl: ${config.otlpUrl} (${error.message})`);
51
+ }
52
+ }
53
+ /**
54
+ * Strips trailing slash from a URL string.
55
+ */
56
+ function normalizeBaseUrl(url) {
57
+ return url.replace(/\/+$/, "");
58
+ }
59
+ /**
60
+ * SpanProcessor that injects mutable global attributes into every span on start.
61
+ * Since OTel Resource is immutable, dynamic context (org ID, user ID, app ID)
62
+ * must be applied at the span level.
63
+ */
64
+ class GlobalAttributeSpanProcessor {
65
+ attrs = {};
66
+ setAttributes(attrs) {
67
+ this.attrs = { ...attrs };
68
+ }
69
+ onStart(span, _parentContext) {
70
+ for (const [key, value] of Object.entries(this.attrs)) {
71
+ span.setAttribute(key, value);
72
+ }
73
+ }
74
+ onEnd(_span) { }
75
+ async shutdown() { }
76
+ async forceFlush() { }
77
+ }
78
+ /**
79
+ * Composite SpanProcessor that delegates to a mutable list of inner processors.
80
+ * Supports runtime additions such as the UI's LocalStorageExporter.
81
+ */
82
+ class DynamicCompositeSpanProcessor {
83
+ processors = [];
84
+ add(processor) {
85
+ this.processors.push(processor);
86
+ }
87
+ onStart(span, parentContext) {
88
+ for (const p of this.processors) {
89
+ try {
90
+ p.onStart(span, parentContext);
91
+ }
92
+ catch (err) {
93
+ console.error("[Telemetry] SpanProcessor.onStart failed", err);
94
+ }
95
+ }
96
+ }
97
+ onEnd(span) {
98
+ for (const p of this.processors) {
99
+ try {
100
+ p.onEnd(span);
101
+ }
102
+ catch (err) {
103
+ console.error("[Telemetry] SpanProcessor.onEnd failed", err);
104
+ }
105
+ }
106
+ }
107
+ async shutdown() {
108
+ await Promise.all(this.processors.map((p) => p.shutdown()));
109
+ }
110
+ async forceFlush() {
111
+ await Promise.all(this.processors.map((p) => p.forceFlush()));
112
+ }
113
+ }
114
+ /**
115
+ * Initialize browser telemetry with policy enforcement.
116
+ *
117
+ * Browser telemetry is always sanitized (Tier 2) since it runs in untrusted context.
118
+ * Full fidelity Tier 1 data should never be emitted from the browser.
119
+ *
120
+ * Composes:
121
+ * - Traces: WebTracerProvider with sanitizing + batch processors
122
+ * - Metrics: MeterProvider via initBrowserMetrics
123
+ * - Logs: LoggerProvider via initBrowserLogs (with EarlyConsoleBuffer)
124
+ * - Sanitizers: PII redaction for spans and logs
125
+ * - Instrumentations: XHR + Fetch auto-instrumentation
126
+ * - Context: StackContextManager for async context propagation
127
+ *
128
+ * @param config - Browser configuration (otlpUrl is treated as base URL)
129
+ * @param policy - Telemetry policy (REQUIRED)
130
+ * @returns Browser telemetry instance
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * import { initBrowserTelemetry } from '@superblocksteam/telemetry/browser';
135
+ * import { getDefaultPolicy, DeploymentType } from '@superblocksteam/shared';
136
+ *
137
+ * const policy = getDefaultPolicy(DeploymentType.CLOUD);
138
+ * const telemetry = initBrowserTelemetry({
139
+ * serviceName: 'superblocks-ui',
140
+ * serviceVersion: '1.0.0',
141
+ * environment: 'production',
142
+ * otlpUrl: 'https://app.superblocks.com/api',
143
+ * }, policy);
144
+ *
145
+ * const tracer = telemetry.getTracer();
146
+ * const meter = telemetry.getMeter();
147
+ * const logger = telemetry.getLogger();
148
+ * ```
149
+ */
150
+ export function initBrowserTelemetry(config, policy) {
151
+ // Policy is required
152
+ if (!policy) {
153
+ throw new Error("[Telemetry] Policy is required. Cannot initialize telemetry without a policy.");
154
+ }
155
+ // Validate config
156
+ validateBrowserTelemetryConfig(config);
157
+ // Return existing instance if already initialized
158
+ if (instance) {
159
+ console.warn("[Telemetry] Browser provider already initialized");
160
+ return instance;
161
+ }
162
+ const baseUrl = normalizeBaseUrl(config.otlpUrl);
163
+ // 1. Register StackContextManager for async context propagation
164
+ registerBrowserContextManager();
165
+ const policyEvaluator = new TelemetryPolicyEvaluator(policy);
166
+ const resource = buildResource(config);
167
+ // 2. Build span processors: global attrs -> sanitizer -> batch exporter
168
+ // Wrapped in a DynamicCompositeSpanProcessor so addSpanProcessor() works
169
+ // at runtime (OTel SDK v2.x removed addSpanProcessor from the provider).
170
+ const globalAttrProcessor = new GlobalAttributeSpanProcessor();
171
+ const compositeProcessor = new DynamicCompositeSpanProcessor();
172
+ compositeProcessor.add(globalAttrProcessor);
173
+ // Add sanitizing processor (always on in browser)
174
+ compositeProcessor.add(createSanitizingSpanProcessor());
175
+ // Add batch exporter if policy allows export
176
+ if (policyEvaluator.isExportEnabled(TelemetryTier.TIER_2_OPERATIONAL)) {
177
+ compositeProcessor.add(new BatchSpanProcessor(new BrowserResilientExporter({
178
+ delegate: new OTLPTraceExporter({
179
+ url: `${baseUrl}/v1/traces`,
180
+ }),
181
+ })));
182
+ }
183
+ // Create provider with the composite processor (OTEL v2.x API)
184
+ const provider = new WebTracerProvider({
185
+ resource,
186
+ spanProcessors: [compositeProcessor],
187
+ });
188
+ // Register with composite propagator for W3C TraceContext and Baggage
189
+ provider.register({
190
+ propagator: new CompositePropagator({
191
+ propagators: [
192
+ new W3CBaggagePropagator(),
193
+ new W3CTraceContextPropagator(),
194
+ ],
195
+ }),
196
+ });
197
+ // 3. Create auto-instrumentations (XHR + fetch)
198
+ const instrumentations = createBrowserInstrumentations({
199
+ propagateTraceUrls: config.propagateTraceUrls,
200
+ ignoreUrls: config.ignoreUrls,
201
+ });
202
+ registerInstrumentations({
203
+ instrumentations,
204
+ tracerProvider: provider,
205
+ });
206
+ // 4. Initialize metrics
207
+ let metricsInstance;
208
+ if (policyEvaluator.isExportEnabled(TelemetryTier.TIER_2_OPERATIONAL)) {
209
+ metricsInstance = initBrowserMetrics({
210
+ otlpUrl: `${baseUrl}/v1/metrics`,
211
+ serviceName: config.serviceName,
212
+ resource,
213
+ });
214
+ }
215
+ // 5. Initialize logs (with EarlyConsoleBuffer flush)
216
+ let logsInstance;
217
+ if (policyEvaluator.isExportEnabled(TelemetryTier.TIER_2_OPERATIONAL)) {
218
+ logsInstance = initBrowserLogs({
219
+ otlpUrl: `${baseUrl}/v1/logs`,
220
+ serviceName: config.serviceName,
221
+ resource,
222
+ });
223
+ }
224
+ else {
225
+ // Log export disabled (e.g. on-premise) — disable the EarlyConsoleBuffer
226
+ // so it stops buffering indefinitely and restores original console methods.
227
+ EarlyConsoleBuffer.getInstance().disable();
228
+ }
229
+ instance = {
230
+ provider,
231
+ policyEvaluator,
232
+ getTracer: (name) => trace.getTracer(name ?? config.serviceName, config.serviceVersion),
233
+ getMeter: (name) => {
234
+ if (metricsInstance) {
235
+ return metricsInstance.getMeter(name);
236
+ }
237
+ // Return a no-op meter from the global API when metrics are disabled
238
+ return metrics.getMeter(name ?? config.serviceName);
239
+ },
240
+ getLogger: (name) => {
241
+ if (logsInstance) {
242
+ return logsInstance.getLogger(name);
243
+ }
244
+ // Return a no-op logger when logs are disabled
245
+ return {
246
+ emit: () => { },
247
+ enabled: () => false,
248
+ };
249
+ },
250
+ setGlobalSpanAttributes: (attrs) => {
251
+ globalAttrProcessor.setAttributes(attrs);
252
+ },
253
+ addSpanProcessor: (processor) => {
254
+ compositeProcessor.add(processor);
255
+ },
256
+ forceFlush: async () => {
257
+ await Promise.all([logsInstance?.forceFlush(), provider.forceFlush()]);
258
+ },
259
+ shutdown: async () => {
260
+ await provider.shutdown();
261
+ if (metricsInstance) {
262
+ await metricsInstance.shutdown();
263
+ }
264
+ if (logsInstance) {
265
+ await logsInstance.shutdown();
266
+ }
267
+ context.disable();
268
+ instance = undefined;
269
+ },
270
+ };
271
+ return instance;
272
+ }
273
+ /**
274
+ * Get the current browser telemetry instance.
275
+ *
276
+ * @throws Error if not initialized
277
+ */
278
+ export function getBrowserTelemetryInstance() {
279
+ if (!instance) {
280
+ throw new Error("[Telemetry] Not initialized. Call initBrowserTelemetry() first.");
281
+ }
282
+ return instance;
283
+ }
284
+ /**
285
+ * Check if browser telemetry is initialized.
286
+ */
287
+ export function isBrowserTelemetryInitialized() {
288
+ return instance !== undefined;
289
+ }
290
+ /**
291
+ * Reset browser telemetry (for testing only).
292
+ * @internal
293
+ */
294
+ export function resetBrowserTelemetry() {
295
+ instance = undefined;
296
+ resetBrowserLogs();
297
+ }
298
+ /**
299
+ * Derive environment from hostname.
300
+ * Utility for browser context where env vars aren't available.
301
+ *
302
+ * @param hostname - The hostname to analyze
303
+ * @returns Environment string
304
+ */
305
+ export function getEnvironmentFromHostname(hostname) {
306
+ if (hostname.includes("localhost") || hostname.includes("127.0.0.1")) {
307
+ return "local";
308
+ }
309
+ if (hostname.includes("staging") || hostname.includes("stg")) {
310
+ return "staging";
311
+ }
312
+ if (hostname.includes("dev") || hostname.includes("development")) {
313
+ return "development";
314
+ }
315
+ return "production";
316
+ }
317
+ //# sourceMappingURL=init.js.map