@dxos/observability 0.8.4-main.fffef41 → 0.9.0

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 (330) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +14 -11
  3. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  4. package/dist/lib/browser/chunk-PSFTIG54.mjs +20 -0
  5. package/dist/lib/browser/chunk-PSFTIG54.mjs.map +7 -0
  6. package/dist/lib/browser/index.mjs +1011 -34
  7. package/dist/lib/browser/index.mjs.map +4 -4
  8. package/dist/lib/browser/log-processor-MZCTEVJC.mjs +46 -0
  9. package/dist/lib/browser/log-processor-MZCTEVJC.mjs.map +7 -0
  10. package/dist/lib/browser/logs-UTNIFYHF.mjs +116 -0
  11. package/dist/lib/browser/logs-UTNIFYHF.mjs.map +7 -0
  12. package/dist/lib/browser/meta.json +1 -1
  13. package/dist/lib/browser/metrics-PRGSYAZJ.mjs +116 -0
  14. package/dist/lib/browser/metrics-PRGSYAZJ.mjs.map +7 -0
  15. package/dist/lib/browser/traces-browser-XRINKQUA.mjs +154 -0
  16. package/dist/lib/browser/traces-browser-XRINKQUA.mjs.map +7 -0
  17. package/dist/lib/node-esm/chunk-EDDZWPYV.mjs +22 -0
  18. package/dist/lib/node-esm/chunk-EDDZWPYV.mjs.map +7 -0
  19. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  20. package/dist/lib/node-esm/index.mjs +1016 -34
  21. package/dist/lib/node-esm/index.mjs.map +4 -4
  22. package/dist/lib/node-esm/log-processor-GA24XTJF.mjs +47 -0
  23. package/dist/lib/node-esm/log-processor-GA24XTJF.mjs.map +7 -0
  24. package/dist/lib/node-esm/logs-ARJUVN3T.mjs +117 -0
  25. package/dist/lib/node-esm/logs-ARJUVN3T.mjs.map +7 -0
  26. package/dist/lib/node-esm/meta.json +1 -1
  27. package/dist/lib/node-esm/metrics-DREJOOAC.mjs +117 -0
  28. package/dist/lib/node-esm/metrics-DREJOOAC.mjs.map +7 -0
  29. package/dist/lib/node-esm/traces-74F7JUKF.mjs +125 -0
  30. package/dist/lib/node-esm/traces-74F7JUKF.mjs.map +7 -0
  31. package/dist/types/src/cli-observability-secrets.json +3 -4
  32. package/dist/types/src/extensions/index.d.ts +3 -0
  33. package/dist/types/src/extensions/index.d.ts.map +1 -0
  34. package/dist/types/src/extensions/index.js +6 -0
  35. package/dist/types/src/extensions/index.js.map +1 -0
  36. package/dist/types/src/extensions/otel/extension.d.ts +23 -0
  37. package/dist/types/src/extensions/otel/extension.d.ts.map +1 -0
  38. package/dist/types/src/extensions/otel/extension.js +222 -0
  39. package/dist/types/src/extensions/otel/extension.js.map +1 -0
  40. package/dist/types/src/extensions/otel/index.d.ts +2 -0
  41. package/dist/types/src/extensions/otel/index.d.ts.map +1 -0
  42. package/dist/types/src/extensions/otel/index.js +5 -0
  43. package/dist/types/src/extensions/otel/index.js.map +1 -0
  44. package/dist/types/src/{otel → extensions/otel}/logs.d.ts +4 -3
  45. package/dist/types/src/extensions/otel/logs.d.ts.map +1 -0
  46. package/dist/types/src/extensions/otel/logs.js +107 -0
  47. package/dist/types/src/extensions/otel/logs.js.map +1 -0
  48. package/dist/types/src/extensions/otel/metrics.d.ts.map +1 -0
  49. package/dist/types/src/{otel → extensions/otel}/metrics.js +4 -12
  50. package/dist/types/src/extensions/otel/metrics.js.map +1 -0
  51. package/dist/types/src/extensions/otel/otel.d.ts +19 -0
  52. package/dist/types/src/extensions/otel/otel.d.ts.map +1 -0
  53. package/dist/types/src/extensions/otel/otel.js +23 -0
  54. package/dist/types/src/extensions/otel/otel.js.map +1 -0
  55. package/dist/types/src/extensions/otel/span-processors.d.ts +25 -0
  56. package/dist/types/src/extensions/otel/span-processors.d.ts.map +1 -0
  57. package/dist/types/src/extensions/otel/span-processors.js +41 -0
  58. package/dist/types/src/extensions/otel/span-processors.js.map +1 -0
  59. package/dist/types/src/extensions/otel/traces-browser.d.ts +25 -0
  60. package/dist/types/src/extensions/otel/traces-browser.d.ts.map +1 -0
  61. package/dist/types/src/extensions/otel/traces-browser.js +105 -0
  62. package/dist/types/src/extensions/otel/traces-browser.js.map +1 -0
  63. package/dist/types/src/extensions/otel/traces.d.ts +25 -0
  64. package/dist/types/src/extensions/otel/traces.d.ts.map +1 -0
  65. package/dist/types/src/extensions/otel/traces.js +88 -0
  66. package/dist/types/src/extensions/otel/traces.js.map +1 -0
  67. package/dist/types/src/extensions/posthog/extension.d.ts +28 -0
  68. package/dist/types/src/extensions/posthog/extension.d.ts.map +1 -0
  69. package/dist/types/src/extensions/posthog/extension.js +156 -0
  70. package/dist/types/src/extensions/posthog/extension.js.map +1 -0
  71. package/dist/types/src/extensions/posthog/index.d.ts +2 -0
  72. package/dist/types/src/extensions/posthog/index.d.ts.map +1 -0
  73. package/dist/types/src/extensions/posthog/index.js +5 -0
  74. package/dist/types/src/extensions/posthog/index.js.map +1 -0
  75. package/dist/types/src/extensions/posthog/log-processor.d.ts +3 -0
  76. package/dist/types/src/extensions/posthog/log-processor.d.ts.map +1 -0
  77. package/dist/types/src/extensions/posthog/log-processor.js +45 -0
  78. package/dist/types/src/extensions/posthog/log-processor.js.map +1 -0
  79. package/dist/types/src/extensions/posthog/log-processor.test.d.ts +2 -0
  80. package/dist/types/src/extensions/posthog/log-processor.test.d.ts.map +1 -0
  81. package/dist/types/src/extensions/posthog/log-processor.test.js +146 -0
  82. package/dist/types/src/extensions/posthog/log-processor.test.js.map +1 -0
  83. package/dist/types/src/extensions/stub.d.ts +3 -0
  84. package/dist/types/src/extensions/stub.d.ts.map +1 -0
  85. package/dist/types/src/extensions/stub.js +16 -0
  86. package/dist/types/src/extensions/stub.js.map +1 -0
  87. package/dist/types/src/index.d.ts +3 -2
  88. package/dist/types/src/index.d.ts.map +1 -1
  89. package/dist/types/src/index.js +4 -3
  90. package/dist/types/src/index.js.map +1 -1
  91. package/dist/types/src/observability-extension.d.ts +74 -0
  92. package/dist/types/src/observability-extension.d.ts.map +1 -0
  93. package/dist/types/src/observability-extension.js +5 -0
  94. package/dist/types/src/observability-extension.js.map +1 -0
  95. package/dist/types/src/observability.d.ts +32 -110
  96. package/dist/types/src/observability.d.ts.map +1 -1
  97. package/dist/types/src/observability.js +179 -465
  98. package/dist/types/src/observability.js.map +1 -1
  99. package/dist/types/src/observability.test.d.ts +2 -0
  100. package/dist/types/src/observability.test.d.ts.map +1 -0
  101. package/dist/types/src/observability.test.js +312 -0
  102. package/dist/types/src/observability.test.js.map +1 -0
  103. package/dist/types/src/providers/client-observability.d.ts +11 -0
  104. package/dist/types/src/providers/client-observability.d.ts.map +1 -0
  105. package/dist/types/src/providers/client-observability.js +202 -0
  106. package/dist/types/src/providers/client-observability.js.map +1 -0
  107. package/dist/types/src/providers/index.d.ts +4 -0
  108. package/dist/types/src/providers/index.d.ts.map +1 -0
  109. package/dist/types/src/providers/index.js +7 -0
  110. package/dist/types/src/providers/index.js.map +1 -0
  111. package/dist/types/src/providers/ip-data.d.ts +5 -0
  112. package/dist/types/src/providers/ip-data.d.ts.map +1 -0
  113. package/dist/types/src/providers/ip-data.js +65 -0
  114. package/dist/types/src/providers/ip-data.js.map +1 -0
  115. package/dist/types/src/providers/storage.d.ts +3 -0
  116. package/dist/types/src/providers/storage.d.ts.map +1 -0
  117. package/dist/types/src/providers/storage.js +19 -0
  118. package/dist/types/src/providers/storage.js.map +1 -0
  119. package/dist/types/src/storage/browser.d.ts +27 -0
  120. package/dist/types/src/storage/browser.d.ts.map +1 -0
  121. package/dist/types/src/storage/browser.js +98 -0
  122. package/dist/types/src/storage/browser.js.map +1 -0
  123. package/dist/types/src/storage/index.d.ts +2 -0
  124. package/dist/types/src/storage/index.d.ts.map +1 -0
  125. package/dist/types/src/storage/index.js.map +1 -0
  126. package/dist/types/src/storage/node.d.ts +30 -0
  127. package/dist/types/src/storage/node.d.ts.map +1 -0
  128. package/dist/types/src/storage/node.js +96 -0
  129. package/dist/types/src/storage/node.js.map +1 -0
  130. package/dist/types/src/storage/node.test.d.ts +2 -0
  131. package/dist/types/src/storage/node.test.d.ts.map +1 -0
  132. package/dist/types/src/storage/node.test.js +103 -0
  133. package/dist/types/src/storage/node.test.js.map +1 -0
  134. package/dist/types/tsconfig.tsbuildinfo +1 -1
  135. package/package.json +46 -66
  136. package/src/cli-observability-secrets.json +3 -4
  137. package/src/extensions/index.ts +6 -0
  138. package/src/extensions/otel/extension.ts +282 -0
  139. package/src/extensions/otel/index.ts +5 -0
  140. package/src/extensions/otel/logs.ts +137 -0
  141. package/src/{otel → extensions/otel}/metrics.ts +4 -14
  142. package/src/extensions/otel/otel.ts +34 -0
  143. package/src/extensions/otel/span-processors.ts +45 -0
  144. package/src/extensions/otel/traces-browser.ts +139 -0
  145. package/src/extensions/otel/traces.ts +113 -0
  146. package/src/extensions/posthog/extension.ts +199 -0
  147. package/src/extensions/posthog/index.ts +5 -0
  148. package/src/extensions/posthog/log-processor.test.ts +186 -0
  149. package/src/extensions/posthog/log-processor.ts +53 -0
  150. package/src/extensions/stub.ts +19 -0
  151. package/src/index.ts +4 -3
  152. package/src/observability-extension.ts +94 -0
  153. package/src/observability.test.ts +531 -0
  154. package/src/observability.ts +238 -577
  155. package/src/providers/client-observability.ts +255 -0
  156. package/src/providers/index.ts +7 -0
  157. package/src/providers/ip-data.ts +100 -0
  158. package/src/providers/storage.ts +23 -0
  159. package/src/storage/browser.ts +99 -0
  160. package/src/{segment → storage}/index.ts +0 -1
  161. package/src/storage/node.test.ts +129 -0
  162. package/src/{helpers/node-observability.ts → storage/node.ts} +47 -71
  163. package/src/vite-import-meta.d.ts +14 -0
  164. package/dist/lib/browser/chunk-5ICT2XF2.mjs +0 -1
  165. package/dist/lib/browser/chunk-VIGEEYDR.mjs +0 -1019
  166. package/dist/lib/browser/chunk-VIGEEYDR.mjs.map +0 -7
  167. package/dist/lib/browser/chunk-XNAF22QM.mjs +0 -148
  168. package/dist/lib/browser/chunk-XNAF22QM.mjs.map +0 -7
  169. package/dist/lib/browser/chunk-ZI3ZS3PA.mjs +0 -164
  170. package/dist/lib/browser/chunk-ZI3ZS3PA.mjs.map +0 -7
  171. package/dist/lib/browser/observability-I65SW7NE.mjs +0 -10
  172. package/dist/lib/browser/otel-UH7ZRWC2.mjs +0 -287
  173. package/dist/lib/browser/otel-UH7ZRWC2.mjs.map +0 -7
  174. package/dist/lib/browser/segment/index.mjs +0 -11
  175. package/dist/lib/browser/segment/index.mjs.map +0 -7
  176. package/dist/lib/browser/sentry/index.mjs +0 -24
  177. package/dist/lib/browser/sentry/index.mjs.map +0 -7
  178. package/dist/lib/browser/sentry-log-processor-5VGDTKZN.mjs +0 -146
  179. package/dist/lib/browser/sentry-log-processor-5VGDTKZN.mjs.map +0 -7
  180. package/dist/lib/node-esm/chunk-MTKIPRBH.mjs +0 -1020
  181. package/dist/lib/node-esm/chunk-MTKIPRBH.mjs.map +0 -7
  182. package/dist/lib/node-esm/chunk-OJV247NY.mjs +0 -204
  183. package/dist/lib/node-esm/chunk-OJV247NY.mjs.map +0 -7
  184. package/dist/lib/node-esm/chunk-QK5IUYVA.mjs +0 -135
  185. package/dist/lib/node-esm/chunk-QK5IUYVA.mjs.map +0 -7
  186. package/dist/lib/node-esm/chunk-QUZL7LKE.mjs +0 -2
  187. package/dist/lib/node-esm/chunk-QUZL7LKE.mjs.map +0 -7
  188. package/dist/lib/node-esm/observability-5KKD7B6J.mjs +0 -11
  189. package/dist/lib/node-esm/observability-5KKD7B6J.mjs.map +0 -7
  190. package/dist/lib/node-esm/otel-7PUCFSTY.mjs +0 -270
  191. package/dist/lib/node-esm/otel-7PUCFSTY.mjs.map +0 -7
  192. package/dist/lib/node-esm/segment/index.mjs +0 -12
  193. package/dist/lib/node-esm/segment/index.mjs.map +0 -7
  194. package/dist/lib/node-esm/sentry/index.mjs +0 -25
  195. package/dist/lib/node-esm/sentry/index.mjs.map +0 -7
  196. package/dist/lib/node-esm/sentry-log-processor-A2EV7P3Y.mjs +0 -147
  197. package/dist/lib/node-esm/sentry-log-processor-A2EV7P3Y.mjs.map +0 -7
  198. package/dist/types/src/helpers/browser-observability.d.ts +0 -17
  199. package/dist/types/src/helpers/browser-observability.d.ts.map +0 -1
  200. package/dist/types/src/helpers/browser-observability.js +0 -138
  201. package/dist/types/src/helpers/browser-observability.js.map +0 -1
  202. package/dist/types/src/helpers/common.d.ts +0 -12
  203. package/dist/types/src/helpers/common.d.ts.map +0 -1
  204. package/dist/types/src/helpers/common.js +0 -23
  205. package/dist/types/src/helpers/common.js.map +0 -1
  206. package/dist/types/src/helpers/index.d.ts +0 -6
  207. package/dist/types/src/helpers/index.d.ts.map +0 -1
  208. package/dist/types/src/helpers/index.js +0 -9
  209. package/dist/types/src/helpers/index.js.map +0 -1
  210. package/dist/types/src/helpers/map-spaces.d.ts +0 -18
  211. package/dist/types/src/helpers/map-spaces.d.ts.map +0 -1
  212. package/dist/types/src/helpers/map-spaces.js +0 -36
  213. package/dist/types/src/helpers/map-spaces.js.map +0 -1
  214. package/dist/types/src/helpers/node-observability.d.ts +0 -24
  215. package/dist/types/src/helpers/node-observability.d.ts.map +0 -1
  216. package/dist/types/src/helpers/node-observability.js +0 -97
  217. package/dist/types/src/helpers/node-observability.js.map +0 -1
  218. package/dist/types/src/helpers/setup-telemetry-listeners.d.ts +0 -4
  219. package/dist/types/src/helpers/setup-telemetry-listeners.d.ts.map +0 -1
  220. package/dist/types/src/helpers/setup-telemetry-listeners.js +0 -94
  221. package/dist/types/src/helpers/setup-telemetry-listeners.js.map +0 -1
  222. package/dist/types/src/otel/index.d.ts +0 -5
  223. package/dist/types/src/otel/index.d.ts.map +0 -1
  224. package/dist/types/src/otel/index.js +0 -8
  225. package/dist/types/src/otel/index.js.map +0 -1
  226. package/dist/types/src/otel/logs.d.ts.map +0 -1
  227. package/dist/types/src/otel/logs.js +0 -74
  228. package/dist/types/src/otel/logs.js.map +0 -1
  229. package/dist/types/src/otel/metrics.d.ts.map +0 -1
  230. package/dist/types/src/otel/metrics.js.map +0 -1
  231. package/dist/types/src/otel/otel.d.ts +0 -12
  232. package/dist/types/src/otel/otel.d.ts.map +0 -1
  233. package/dist/types/src/otel/otel.js +0 -11
  234. package/dist/types/src/otel/otel.js.map +0 -1
  235. package/dist/types/src/otel/traces-browser.d.ts +0 -8
  236. package/dist/types/src/otel/traces-browser.d.ts.map +0 -1
  237. package/dist/types/src/otel/traces-browser.js +0 -53
  238. package/dist/types/src/otel/traces-browser.js.map +0 -1
  239. package/dist/types/src/otel/traces.d.ts +0 -8
  240. package/dist/types/src/otel/traces.d.ts.map +0 -1
  241. package/dist/types/src/otel/traces.js +0 -46
  242. package/dist/types/src/otel/traces.js.map +0 -1
  243. package/dist/types/src/segment/base.d.ts +0 -15
  244. package/dist/types/src/segment/base.d.ts.map +0 -1
  245. package/dist/types/src/segment/base.js +0 -51
  246. package/dist/types/src/segment/base.js.map +0 -1
  247. package/dist/types/src/segment/browser.d.ts +0 -15
  248. package/dist/types/src/segment/browser.d.ts.map +0 -1
  249. package/dist/types/src/segment/browser.js +0 -63
  250. package/dist/types/src/segment/browser.js.map +0 -1
  251. package/dist/types/src/segment/index.d.ts +0 -3
  252. package/dist/types/src/segment/index.d.ts.map +0 -1
  253. package/dist/types/src/segment/index.js +0 -6
  254. package/dist/types/src/segment/index.js.map +0 -1
  255. package/dist/types/src/segment/node.d.ts +0 -16
  256. package/dist/types/src/segment/node.d.ts.map +0 -1
  257. package/dist/types/src/segment/node.js +0 -84
  258. package/dist/types/src/segment/node.js.map +0 -1
  259. package/dist/types/src/segment/types.d.ts +0 -52
  260. package/dist/types/src/segment/types.d.ts.map +0 -1
  261. package/dist/types/src/segment/types.js +0 -18
  262. package/dist/types/src/segment/types.js.map +0 -1
  263. package/dist/types/src/sentry/browser.d.ts +0 -32
  264. package/dist/types/src/sentry/browser.d.ts.map +0 -1
  265. package/dist/types/src/sentry/browser.js +0 -110
  266. package/dist/types/src/sentry/browser.js.map +0 -1
  267. package/dist/types/src/sentry/index.d.ts +0 -3
  268. package/dist/types/src/sentry/index.d.ts.map +0 -1
  269. package/dist/types/src/sentry/index.js.map +0 -1
  270. package/dist/types/src/sentry/node.d.ts +0 -32
  271. package/dist/types/src/sentry/node.d.ts.map +0 -1
  272. package/dist/types/src/sentry/node.js +0 -106
  273. package/dist/types/src/sentry/node.js.map +0 -1
  274. package/dist/types/src/sentry/node.node.test.d.ts +0 -2
  275. package/dist/types/src/sentry/node.node.test.d.ts.map +0 -1
  276. package/dist/types/src/sentry/node.node.test.js +0 -32
  277. package/dist/types/src/sentry/node.node.test.js.map +0 -1
  278. package/dist/types/src/sentry/sentry-log-processor.d.ts +0 -9
  279. package/dist/types/src/sentry/sentry-log-processor.d.ts.map +0 -1
  280. package/dist/types/src/sentry/sentry-log-processor.js +0 -144
  281. package/dist/types/src/sentry/sentry-log-processor.js.map +0 -1
  282. package/dist/types/src/sentry/sentry.node.test.d.ts +0 -2
  283. package/dist/types/src/sentry/sentry.node.test.d.ts.map +0 -1
  284. package/dist/types/src/sentry/sentry.node.test.js +0 -28
  285. package/dist/types/src/sentry/sentry.node.test.js.map +0 -1
  286. package/dist/types/src/sentry/types.d.ts +0 -18
  287. package/dist/types/src/sentry/types.d.ts.map +0 -1
  288. package/dist/types/src/sentry/types.js +0 -4
  289. package/dist/types/src/sentry/types.js.map +0 -1
  290. package/dist/types/src/testing/index.d.ts +0 -2
  291. package/dist/types/src/testing/index.d.ts.map +0 -1
  292. package/dist/types/src/testing/index.js +0 -5
  293. package/dist/types/src/testing/index.js.map +0 -1
  294. package/dist/types/src/testing/testkit/browser.d.ts +0 -2
  295. package/dist/types/src/testing/testkit/browser.d.ts.map +0 -1
  296. package/dist/types/src/testing/testkit/browser.js +0 -7
  297. package/dist/types/src/testing/testkit/browser.js.map +0 -1
  298. package/dist/types/src/testing/testkit/index.d.ts +0 -2
  299. package/dist/types/src/testing/testkit/index.d.ts.map +0 -1
  300. package/dist/types/src/testing/testkit/index.js +0 -6
  301. package/dist/types/src/testing/testkit/index.js.map +0 -1
  302. package/src/helpers/browser-observability.ts +0 -178
  303. package/src/helpers/common.ts +0 -38
  304. package/src/helpers/index.ts +0 -9
  305. package/src/helpers/map-spaces.ts +0 -48
  306. package/src/helpers/setup-telemetry-listeners.ts +0 -109
  307. package/src/otel/index.ts +0 -8
  308. package/src/otel/logs.ts +0 -102
  309. package/src/otel/otel.ts +0 -21
  310. package/src/otel/traces-browser.ts +0 -62
  311. package/src/otel/traces.ts +0 -60
  312. package/src/segment/base.ts +0 -69
  313. package/src/segment/browser.ts +0 -69
  314. package/src/segment/node.ts +0 -95
  315. package/src/segment/types.ts +0 -57
  316. package/src/sentry/browser.ts +0 -133
  317. package/src/sentry/index.ts +0 -6
  318. package/src/sentry/node.node.test.ts +0 -40
  319. package/src/sentry/node.ts +0 -126
  320. package/src/sentry/sentry-log-processor.ts +0 -176
  321. package/src/sentry/sentry.node.test.ts +0 -35
  322. package/src/sentry/types.ts +0 -22
  323. package/src/testing/index.ts +0 -5
  324. package/src/testing/testkit/browser.ts +0 -8
  325. package/src/testing/testkit/index.ts +0 -7
  326. package/src/testing/testkit/shims.d.ts +0 -5
  327. /package/dist/lib/browser/{chunk-5ICT2XF2.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
  328. /package/dist/lib/{browser/observability-I65SW7NE.mjs.map → node-esm/chunk-HSLMI22Q.mjs.map} +0 -0
  329. /package/dist/types/src/{otel → extensions/otel}/metrics.d.ts +0 -0
  330. /package/dist/types/src/{sentry → storage}/index.js +0 -0
package/package.json CHANGED
@@ -1,97 +1,77 @@
1
1
  {
2
2
  "name": "@dxos/observability",
3
- "version": "0.8.4-main.fffef41",
3
+ "version": "0.9.0",
4
4
  "description": "Provides a common interface for app and platform observability",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
7
- "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
11
+ "license": "FSL-1.1-Apache-2.0",
8
12
  "author": "DXOS.org",
9
- "sideEffects": true,
13
+ "sideEffects": false,
10
14
  "type": "module",
11
15
  "exports": {
12
16
  ".": {
13
- "source": "./src/index.ts",
14
17
  "types": "./dist/types/src/index.d.ts",
15
18
  "browser": "./dist/lib/browser/index.mjs",
16
19
  "node": "./dist/lib/node-esm/index.mjs"
17
- },
18
- "./segment": {
19
- "source": "./src/segment/index.ts",
20
- "types": "./dist/types/src/segment/index.d.ts",
21
- "browser": "./dist/lib/browser/segment/index.mjs",
22
- "node": "./dist/lib/node-esm/segment/index.mjs"
23
- },
24
- "./sentry": {
25
- "source": "./src/sentry/index.ts",
26
- "types": "./dist/types/src/sentry/index.d.ts",
27
- "browser": "./dist/lib/browser/sentry/index.mjs",
28
- "node": "./dist/lib/node-esm/sentry/index.mjs"
29
20
  }
30
21
  },
31
22
  "browser": {
32
- "./src/segment/node.ts": "./src/segment/browser.ts",
33
- "./src/sentry/node.ts": "./src/sentry/browser.ts",
34
- "./testing/testkit/index.ts": "./testing/testkit/browser.ts",
35
- "./src/otel/traces.ts": "./src/otel/traces-browser.ts"
23
+ "./src/storage/node.ts": "./src/storage/browser.ts",
24
+ "./src/extensions/otel/traces.ts": "./src/extensions/otel/traces-browser.ts"
36
25
  },
37
26
  "types": "dist/types/src/index.d.ts",
38
- "typesVersions": {
39
- "*": {
40
- "segment": [
41
- "dist/types/src/segment/index.d.ts"
42
- ],
43
- "sentry": [
44
- "dist/types/src/sentry/index.d.ts"
45
- ]
46
- }
47
- },
48
27
  "files": [
49
28
  "dist",
50
29
  "src"
51
30
  ],
52
31
  "dependencies": {
53
- "@opentelemetry/api": "^1.9.0",
54
- "@opentelemetry/api-logs": "^0.203.0",
55
- "@opentelemetry/auto-instrumentations-web": "^0.51.0",
56
- "@opentelemetry/exporter-logs-otlp-http": "^0.203.0",
57
- "@opentelemetry/exporter-metrics-otlp-http": "^0.203.0",
58
- "@opentelemetry/exporter-trace-otlp-http": "^0.203.0",
59
- "@opentelemetry/instrumentation": "^0.203.0",
60
- "@opentelemetry/resources": "^2.1.0",
61
- "@opentelemetry/sdk-logs": "^0.203.0",
62
- "@opentelemetry/sdk-metrics": "^2.1.0",
63
- "@opentelemetry/sdk-trace-base": "^2.1.0",
64
- "@opentelemetry/sdk-trace-web": "^2.1.0",
65
- "@opentelemetry/semantic-conventions": "^1.37.0",
66
- "@segment/analytics-node": "^2.1.0",
67
- "@segment/snippet": "^4.15.3",
68
- "@sentry/browser": "^8.8.0",
69
- "@sentry/node": "^8.8.0",
70
- "debug": "^4.3.4",
71
- "js-yaml": "^4.1.0",
32
+ "@opentelemetry/api": "^1.9.1",
33
+ "@opentelemetry/api-logs": "^0.218.0",
34
+ "@opentelemetry/auto-instrumentations-web": "^0.63.0",
35
+ "@opentelemetry/core": "^2.7.1",
36
+ "@opentelemetry/exporter-logs-otlp-http": "^0.218.0",
37
+ "@opentelemetry/exporter-metrics-otlp-http": "^0.218.0",
38
+ "@opentelemetry/exporter-trace-otlp-http": "^0.218.0",
39
+ "@opentelemetry/instrumentation": "^0.218.0",
40
+ "@opentelemetry/resources": "^2.7.1",
41
+ "@opentelemetry/sdk-logs": "^0.218.0",
42
+ "@opentelemetry/sdk-metrics": "^2.7.1",
43
+ "@opentelemetry/sdk-trace-base": "^2.7.1",
44
+ "@opentelemetry/sdk-trace-web": "^2.7.1",
45
+ "@opentelemetry/semantic-conventions": "^1.41.1",
46
+ "js-yaml": "4.1.1",
72
47
  "localforage": "^1.10.0",
48
+ "posthog-js": "^1.353.0",
73
49
  "uuid": "^9.0.0",
74
- "@dxos/async": "0.8.4-main.fffef41",
75
- "@dxos/client": "0.8.4-main.fffef41",
76
- "@dxos/client-protocol": "0.8.4-main.fffef41",
77
- "@dxos/config": "0.8.4-main.fffef41",
78
- "@dxos/context": "0.8.4-main.fffef41",
79
- "@dxos/client-services": "0.8.4-main.fffef41",
80
- "@dxos/debug": "0.8.4-main.fffef41",
81
- "@dxos/log": "0.8.4-main.fffef41",
82
- "@dxos/network-manager": "0.8.4-main.fffef41",
83
- "@dxos/protocols": "0.8.4-main.fffef41",
84
- "@dxos/node-std": "0.8.4-main.fffef41",
85
- "@dxos/tracing": "0.8.4-main.fffef41",
86
- "@dxos/invariant": "0.8.4-main.fffef41",
87
- "@dxos/util": "0.8.4-main.fffef41"
50
+ "zone.js": "^0.15.0",
51
+ "@dxos/async": "0.9.0",
52
+ "@dxos/client": "0.9.0",
53
+ "@dxos/client-services": "0.9.0",
54
+ "@dxos/context": "0.9.0",
55
+ "@dxos/config": "0.9.0",
56
+ "@dxos/log": "0.9.0",
57
+ "@dxos/invariant": "0.9.0",
58
+ "@dxos/log-store-idb": "0.9.0",
59
+ "@dxos/node-std": "0.9.0",
60
+ "@dxos/protocols": "0.9.0",
61
+ "@dxos/tracing": "0.9.0",
62
+ "@dxos/util": "0.9.0",
63
+ "@dxos/network-manager": "0.9.0"
88
64
  },
89
65
  "devDependencies": {
90
- "@sentry/types": "^8.8.0",
66
+ "@effect/platform": "0.96.1",
91
67
  "@types/debug": "^4.1.10",
92
68
  "@types/js-yaml": "^4.0.5",
93
- "sentry-testkit": "^5.0.5",
94
- "zone.js": ">=0.11.4 <0.12.0-0 || >=0.13.0 <0.14.0-0 || >=0.14.0 <0.15.0-0"
69
+ "@dxos/effect": "0.9.0",
70
+ "@dxos/messaging": "0.9.0"
71
+ },
72
+ "peerDependencies": {
73
+ "@effect/platform": "0.96.1",
74
+ "effect": "3.21.3"
95
75
  },
96
76
  "publishConfig": {
97
77
  "access": "public"
@@ -1,7 +1,6 @@
1
1
  {
2
- "SENTRY_DESTINATION": "https://2647916221e643869965e78469479aa4@o4504012000067584.ingest.sentry.io/4504012027265029",
3
- "TELEMETRY_API_KEY": "B00QG6PtJJrJ0VVFe0H5a6bcUUShKyZM",
2
+ "POSTHOG_API_KEY": null,
4
3
  "IPDATA_API_KEY": "73dfdecdf979c18f07d50cf841bbdd9e589f237256326ac8cca23786",
5
- "OTEL_ENDPOINT": "https://otlp-proxy.dxos.workers.dev",
6
- "OTEL_AUTHORIZATION": "Basic OTA3MzIzOmdsY19leUp2SWpvaU1URXdNVEl6TnlJc0ltNGlPaUp6ZEdGamF5MDVNRGN6TWpNdGFXNTBaV2R5WVhScGIyNHRZMnh2ZFdSbWJHRnlaUzF2ZEd4d0xYQnliM2g1SWl3aWF5STZJalZ2Tkd4cFYydE5iRmszTlRNMGJUVXpTemRTVjNBeVNpSXNJbTBpT25zaWNpSTZJbkJ5YjJRdGRYTXRaV0Z6ZEMwd0luMTk="
4
+ "OTEL_ENDPOINT": "/api/otel",
5
+ "OTEL_HEADERS": null
7
6
  }
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * as Otel from './otel';
6
+ export * as PostHog from './posthog';
@@ -0,0 +1,282 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { defaultResource, resourceFromAttributes } from '@opentelemetry/resources';
6
+ import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
7
+ import * as Effect from 'effect/Effect';
8
+ import * as Match from 'effect/Match';
9
+ import * as Option from 'effect/Option';
10
+ import * as Ref from 'effect/Ref';
11
+
12
+ import { type Config, resolveTelemetryTag } from '@dxos/config';
13
+ import { LogLevel, log } from '@dxos/log';
14
+ import { isNode, isNonNullable } from '@dxos/util';
15
+
16
+ import buildSecrets from '../../cli-observability-secrets.json';
17
+ import { type Extension, type ExtensionApi } from '../../observability-extension';
18
+ import { getOtelLogLevel, isObservabilityDisabled, storeObservabilityDisabled } from '../../storage';
19
+ import { stubExtension } from '../stub';
20
+
21
+ export type ExtensionsOptions = {
22
+ /** For the OTEL, the name of the entity for which signals (metrics or trace) are collected. */
23
+ serviceName: string;
24
+ /** For the OTEL, the version of the entity for which signals (metrics or trace) are collected. */
25
+ serviceVersion: string;
26
+ /** For the OTEL, the environment of the entity for which signals (metrics or trace) are collected. */
27
+ environment: string;
28
+ config: Config;
29
+ endpoint?: string;
30
+ headers?: Record<string, string>;
31
+ logs?: boolean;
32
+ /** Minimum log level to export. Defaults to INFO (i.e. info, warn, error). */
33
+ logLevel?: LogLevel;
34
+ metrics?: boolean;
35
+ traces?: boolean;
36
+ };
37
+
38
+ /** Create an OTEL-backed observability extension for logs, metrics, and/or traces. */
39
+ export const extensions: (options: ExtensionsOptions) => Effect.Effect<Extension> = Effect.fn(function* ({
40
+ serviceName,
41
+ serviceVersion,
42
+ environment,
43
+ config,
44
+ endpoint: _endpoint,
45
+ headers: _headers,
46
+ // TODO(wittjosiah): Logging integration.
47
+ // - logger should run even if observability is disabled
48
+ // - logs should be cached locally in a circular buffer
49
+ // - logs should be flushed to the server if user opts to include them in a bug report
50
+ logs: logsEnabled = false,
51
+ logLevel = LogLevel.INFO,
52
+ metrics: metricsEnabled = false,
53
+ traces: tracesEnabled = false,
54
+ }) {
55
+ const { OtelLogs } = yield* Effect.promise(() => import('./logs'));
56
+ const { OtelMetrics } = yield* Effect.promise(() => import('./metrics'));
57
+ const { OtelTraces } = yield* Effect.promise(() => import('./traces'));
58
+
59
+ const cachedDisabled = yield* Effect.promise(() => isObservabilityDisabled(serviceName));
60
+ const disabled = cachedDisabled || isObservabilityDisabledSync(serviceName);
61
+ const storedLogLevel = yield* Effect.promise(() => getOtelLogLevel(serviceName));
62
+ const resolvedLogLevel =
63
+ storedLogLevel != null ? (LogLevel[storedLogLevel.toUpperCase() as keyof typeof LogLevel] ?? logLevel) : logLevel;
64
+ const enabledRef = yield* Ref.make(!disabled);
65
+ const tags = new Map<string, string>();
66
+
67
+ const rawEndpoint = isNode()
68
+ ? (process.env.DX_OTEL_ENDPOINT ?? _endpoint ?? buildSecrets.OTEL_ENDPOINT)
69
+ : (config.values.runtime?.app?.env?.DX_OTEL_ENDPOINT ?? _endpoint);
70
+ // The OTLP exporter (>= 0.203) validates URLs and rejects relative paths.
71
+ // In the browser/worker, resolve relative endpoints against the current origin
72
+ // so callers can keep using paths like `/api/otel` for proxied deployments.
73
+ const endpoint = !isNode() && rawEndpoint?.startsWith('/') ? resolveRelativeEndpoint(rawEndpoint) : rawEndpoint;
74
+ const headers =
75
+ _headers ??
76
+ Match.value(isNode()).pipe(
77
+ Match.when(true, () => Option.fromNullable(process.env.DX_OTEL_HEADERS ?? buildSecrets.OTEL_HEADERS)),
78
+ Match.when(false, () => Option.fromNullable(config.values.runtime?.app?.env?.DX_OTEL_HEADERS)),
79
+ Match.exhaustive,
80
+ Option.map((raw) => parseHeaders(raw)),
81
+ Option.getOrElse(() => undefined),
82
+ );
83
+
84
+ if (!endpoint) {
85
+ log.info('Missing OTEL_ENDPOINT');
86
+ return stubExtension;
87
+ }
88
+ // Headers are optional when using a proxy that injects auth server-side.
89
+ const resolvedHeaders = headers ?? {};
90
+ // OTLP HTTP exporters require an absolute URL. Resolve relative paths using the current origin.
91
+ // globalThis.location is defined in all browser contexts (main thread, dedicated/service workers).
92
+ const resolvedEndpoint =
93
+ !isNode() && endpoint.startsWith('/') ? `${globalThis.location.origin}${endpoint}` : endpoint;
94
+
95
+ // Matches edge's `ctx.tag` span attribute (stamped by the edge log middleware
96
+ // when it reads the `X-DXOS-Client-Tag` header, see
97
+ // /edge/packages/services/edge/src/log-middleware.ts).
98
+ //
99
+ // Stamped in TWO places:
100
+ // 1. Resource attribute — so logs and metrics emitted from this extension
101
+ // also carry it, and for zero per-span cost.
102
+ // 2. Span attribute via `tags` — because edge puts `ctx.tag` in the span-
103
+ // attribute context (not resource), and SigNoz indexes the two contexts
104
+ // separately. Stamping it on span attributes here keeps a single
105
+ // `ctx.tag = <value>` filter matching spans from both tiers in SigNoz
106
+ // without requiring qualified `attribute.ctx.tag`/`resource.ctx.tag` syntax.
107
+ const clientTag = resolveTelemetryTag(config);
108
+ if (clientTag) {
109
+ tags.set('ctx.tag', clientTag);
110
+ }
111
+
112
+ const resource = defaultResource().merge(
113
+ resourceFromAttributes({
114
+ [ATTR_SERVICE_NAME]: serviceName,
115
+ [ATTR_SERVICE_VERSION]: serviceVersion,
116
+ 'session.id': crypto.randomUUID(),
117
+ 'deployment.environment': environment,
118
+ 'dxos.process.type': detectProcessType(),
119
+ ...(clientTag ? { 'ctx.tag': clientTag } : {}),
120
+ }),
121
+ );
122
+
123
+ const logs = logsEnabled
124
+ ? new OtelLogs({
125
+ endpoint: resolvedEndpoint,
126
+ headers: resolvedHeaders,
127
+ resource,
128
+ getTags: () => Object.fromEntries(tags),
129
+ logLevel: resolvedLogLevel,
130
+ })
131
+ : undefined;
132
+
133
+ const metrics = metricsEnabled
134
+ ? new OtelMetrics({
135
+ endpoint: resolvedEndpoint,
136
+ headers: resolvedHeaders,
137
+ resource,
138
+ getTags: () => Object.fromEntries(tags),
139
+ })
140
+ : undefined;
141
+
142
+ const traces = tracesEnabled
143
+ ? new OtelTraces({
144
+ endpoint: resolvedEndpoint,
145
+ headers: resolvedHeaders,
146
+ resource,
147
+ getTags: () => Object.fromEntries(tags),
148
+ })
149
+ : undefined;
150
+
151
+ const extension: Extension = {
152
+ initialize: () =>
153
+ Effect.sync(() => {
154
+ if (disabled) {
155
+ return;
156
+ }
157
+
158
+ if (logs) {
159
+ log.runtimeConfig.processors.push(logs.logProcessor);
160
+ }
161
+ if (traces) {
162
+ traces.start();
163
+ }
164
+ }),
165
+ enable: Effect.fn(function* () {
166
+ yield* Effect.promise(() => storeObservabilityDisabled(serviceName, false));
167
+ yield* Ref.update(enabledRef, () => true);
168
+ }),
169
+ disable: Effect.fn(function* () {
170
+ yield* Effect.promise(() => storeObservabilityDisabled(serviceName, true));
171
+ yield* Ref.update(enabledRef, () => false);
172
+ }),
173
+ close: () =>
174
+ Effect.promise(async () => {
175
+ // Run logs/metrics close concurrently and swallow their failures so the
176
+ // tracer provider shutdown below ALWAYS runs. Without this, a rejection
177
+ // from logs or metrics would drop the tracer provider's BatchSpanProcessor
178
+ // queue on process exit, manifesting as "Missing Span" in SigNoz for any
179
+ // already-exported children.
180
+ const results = await Promise.allSettled([logs?.close(), metrics?.close()]);
181
+ for (const result of results) {
182
+ if (result.status === 'rejected') {
183
+ log.catch(result.reason);
184
+ }
185
+ }
186
+ // Critical: shut down the tracer provider so BatchSpanProcessor drains its
187
+ // queue. Otherwise spans enqueued in the last 5s (close/teardown spans)
188
+ // are dropped on process exit.
189
+ await traces?.close();
190
+ }),
191
+ flush: () =>
192
+ Effect.promise(async () => {
193
+ const results = await Promise.allSettled([logs?.flush(), metrics?.flush()]);
194
+ for (const result of results) {
195
+ if (result.status === 'rejected') {
196
+ log.catch(result.reason);
197
+ }
198
+ }
199
+ await traces?.flush();
200
+ }),
201
+ setTags: (incomingTags) => {
202
+ for (const [key, value] of Object.entries(incomingTags)) {
203
+ tags.set(key, value);
204
+ }
205
+ },
206
+ get enabled() {
207
+ return Ref.get(enabledRef).pipe(Effect.runSync);
208
+ },
209
+ apis: [
210
+ { kind: 'logs', isAvailable: () => Effect.succeed(!!logs) } satisfies ExtensionApi,
211
+ metrics
212
+ ? ({
213
+ kind: 'metrics',
214
+ isAvailable: () => Effect.succeed(true),
215
+ gauge: (name, value, tags) => metrics.gauge(name, value, tags),
216
+ increment: (name, value, tags) => metrics.increment(name, value, tags),
217
+ distribution: (name, value, tags) => metrics.distribution(name, value, tags),
218
+ } satisfies ExtensionApi)
219
+ : undefined,
220
+ traces ? ({ kind: 'traces', isAvailable: () => Effect.succeed(true) } satisfies ExtensionApi) : undefined,
221
+ ].filter(isNonNullable),
222
+ };
223
+
224
+ return extension;
225
+ });
226
+
227
+ /**
228
+ * Synchronous best-effort check for observability opt-out.
229
+ * Prevents telemetry from being emitted before the async storage check completes.
230
+ */
231
+ const isObservabilityDisabledSync = (serviceName: string): boolean => {
232
+ if (isNode()) {
233
+ return process.env.DX_DISABLE_OBSERVABILITY === 'true';
234
+ }
235
+ try {
236
+ if (typeof localStorage !== 'undefined') {
237
+ return localStorage.getItem(`${serviceName}/observability-disabled`) === 'true';
238
+ }
239
+ } catch {
240
+ // localStorage not available (e.g., in workers).
241
+ }
242
+ return false;
243
+ };
244
+
245
+ /** Best-effort detection of the JavaScript execution context type. */
246
+ const detectProcessType = (): string => {
247
+ if (isNode()) {
248
+ return 'node';
249
+ }
250
+ if (typeof window !== 'undefined') {
251
+ return 'browser';
252
+ }
253
+ if (typeof (globalThis as any).ServiceWorkerGlobalScope !== 'undefined') {
254
+ return 'service-worker';
255
+ }
256
+ if (typeof (globalThis as any).SharedWorkerGlobalScope !== 'undefined') {
257
+ return 'shared-worker';
258
+ }
259
+ return 'dedicated-worker';
260
+ };
261
+
262
+ /**
263
+ * Resolves a relative OTLP endpoint path against the current global origin.
264
+ * Workers expose the same `globalThis.location` as the page that spawned them;
265
+ * if neither is available we fall back to the original path and let the OTLP
266
+ * exporter surface the configuration error.
267
+ */
268
+ const resolveRelativeEndpoint = (path: string): string => {
269
+ const origin = (globalThis as { location?: { origin?: string } }).location?.origin;
270
+ return origin ? `${origin}${path}` : path;
271
+ };
272
+
273
+ const parseHeaders = (unparsedHeaders: string): Record<string, string> => {
274
+ return unparsedHeaders.split(';').reduce((acc: Record<string, string>, header) => {
275
+ const [key, ...rest] = header.split(':');
276
+ if (key && rest.length > 0) {
277
+ acc[key.trim().toLowerCase()] = rest.join(':').trim();
278
+ }
279
+
280
+ return acc;
281
+ }, {});
282
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './extension';
@@ -0,0 +1,137 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { SeverityNumber } from '@opentelemetry/api-logs';
6
+ import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
7
+ import { BatchLogRecordProcessor, LoggerProvider } from '@opentelemetry/sdk-logs';
8
+ import { ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
9
+
10
+ import {
11
+ type LogConfig,
12
+ type LogEntry,
13
+ LogLevel,
14
+ type LogProcessor,
15
+ getContextFromEntry,
16
+ getRelativeFilename,
17
+ } from '@dxos/log';
18
+
19
+ import { type OtelOptions, resolveOtlpUrl, setDiagLogger } from './otel';
20
+
21
+ const FLATTEN_DEPTH = 1;
22
+
23
+ export type OtelLogOptions = OtelOptions & {
24
+ logLevel: LogLevel;
25
+ /**
26
+ * Include logs forwarded from the shared worker via LoggingService.
27
+ *
28
+ * @deprecated
29
+ */
30
+ includeSharedWorkerLogs?: boolean;
31
+ };
32
+
33
+ export class OtelLogs {
34
+ private _loggerProvider: LoggerProvider;
35
+ constructor(private readonly options: OtelLogOptions) {
36
+ setDiagLogger(options.consoleDiagLogLevel);
37
+ const logExporter = new OTLPLogExporter({
38
+ url: resolveOtlpUrl(this.options.endpoint + '/v1/logs'),
39
+ headers: this.options.headers,
40
+ concurrencyLimit: 10, // an optional limit on pending requests
41
+ });
42
+ this._loggerProvider = new LoggerProvider({
43
+ resource: this.options.resource,
44
+ processors: [new BatchLogRecordProcessor(logExporter)],
45
+ });
46
+ }
47
+
48
+ public readonly logProcessor: LogProcessor = (_config: LogConfig, entry: LogEntry) => {
49
+ const logger = this._loggerProvider.getLogger(
50
+ 'dxos-observability',
51
+ this.options.resource.attributes[ATTR_SERVICE_VERSION]?.toString(),
52
+ );
53
+
54
+ if (
55
+ entry.level < this.options.logLevel ||
56
+ (!this.options.includeSharedWorkerLogs && entry.meta?.S?.remoteSessionId)
57
+ ) {
58
+ return;
59
+ }
60
+
61
+ const attributes = {
62
+ ...this.options.getTags(),
63
+ ...(entry.meta ? { meta: { file: getRelativeFilename(entry.meta.F), line: entry.meta.L } } : {}),
64
+ ...(entry.error ? { error: entry.error.stack } : {}),
65
+ ...stringifyValues(getContextFromEntry(entry), 'ctx_'),
66
+ };
67
+
68
+ logger.emit({
69
+ severityNumber: convertLevel(entry.level),
70
+ body: entry.message,
71
+ attributes,
72
+ });
73
+ };
74
+
75
+ flush(): Promise<void> {
76
+ return this._loggerProvider.forceFlush();
77
+ }
78
+
79
+ close(): Promise<void> {
80
+ return this._loggerProvider.shutdown();
81
+ }
82
+ }
83
+
84
+ /** Maps {@link LogLevel} to OpenTelemetry {@link SeverityNumber}. */
85
+ const convertLevel = (level: LogLevel): SeverityNumber => {
86
+ switch (level) {
87
+ case LogLevel.TRACE:
88
+ return SeverityNumber.TRACE;
89
+ case LogLevel.DEBUG:
90
+ return SeverityNumber.DEBUG;
91
+ case LogLevel.VERBOSE:
92
+ return SeverityNumber.INFO;
93
+ case LogLevel.INFO:
94
+ return SeverityNumber.INFO;
95
+ case LogLevel.WARN:
96
+ return SeverityNumber.WARN;
97
+ case LogLevel.ERROR:
98
+ return SeverityNumber.ERROR;
99
+ default:
100
+ return SeverityNumber.UNSPECIFIED;
101
+ }
102
+ };
103
+
104
+ const safeStringify = (value: unknown): string => {
105
+ try {
106
+ return JSON.stringify(value);
107
+ } catch {
108
+ return '[Circular]';
109
+ }
110
+ };
111
+
112
+ // TODO(wittjosiah): Reconcile logging utils w/ EDGE.
113
+ const stringifyValues = (object: object | undefined, keyPrefix?: string, depth: number = 1) => {
114
+ if (!object) {
115
+ return {};
116
+ }
117
+ const result: Record<string, string> = {};
118
+ for (const [key, value] of Object.entries(object)) {
119
+ if (value === undefined) {
120
+ continue;
121
+ }
122
+ const newKey = keyPrefix ? `${keyPrefix}${key}` : key;
123
+ if (typeof value === 'object') {
124
+ if (!value || Array.isArray(value) || depth > FLATTEN_DEPTH) {
125
+ result[newKey] = safeStringify(value);
126
+ } else {
127
+ const flattened = stringifyValues(value, `${newKey}_`, depth + 1);
128
+ for (const [flattenedKey, flattenedValue] of Object.entries(flattened)) {
129
+ result[flattenedKey] = flattenedValue;
130
+ }
131
+ }
132
+ } else {
133
+ result[newKey] = String(value);
134
+ }
135
+ }
136
+ return result;
137
+ };
@@ -4,14 +4,12 @@
4
4
 
5
5
  import { type Meter } from '@opentelemetry/api';
6
6
  import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
7
- import { defaultResource, resourceFromAttributes } from '@opentelemetry/resources';
8
7
  import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
9
- import { SEMRESATTRS_SERVICE_NAME, SEMRESATTRS_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
10
8
 
11
9
  import { log } from '@dxos/log';
12
10
  import { type MetricData, TRACE_PROCESSOR } from '@dxos/tracing';
13
11
 
14
- import { type OtelOptions, setDiagLogger } from './otel';
12
+ import { type OtelOptions, resolveOtlpUrl, setDiagLogger } from './otel';
15
13
 
16
14
  const EXPORT_INTERVAL = 60 * 1000;
17
15
 
@@ -23,25 +21,17 @@ export class OtelMetrics {
23
21
  // TODO: improve error handling/logging
24
22
  // https://github.com/open-telemetry/opentelemetry-js/issues/4823
25
23
  setDiagLogger(options.consoleDiagLogLevel);
26
- const resource = defaultResource().merge(
27
- resourceFromAttributes({
28
- [SEMRESATTRS_SERVICE_NAME]: this.options.serviceName,
29
- [SEMRESATTRS_SERVICE_VERSION]: this.options.serviceVersion,
30
- }),
31
- );
32
24
 
33
25
  const grafanaMetricReader = new PeriodicExportingMetricReader({
34
26
  exporter: new OTLPMetricExporter({
35
- url: this.options.endpoint + '/v1/metrics',
36
- headers: {
37
- Authorization: this.options.authorizationHeader,
38
- },
27
+ url: resolveOtlpUrl(this.options.endpoint + '/v1/metrics'),
28
+ headers: this.options.headers,
39
29
  }),
40
30
  exportIntervalMillis: EXPORT_INTERVAL,
41
31
  });
42
32
 
43
33
  this._meterProvider = new MeterProvider({
44
- resource,
34
+ resource: this.options.resource,
45
35
  readers: [grafanaMetricReader],
46
36
  });
47
37
  this._meter = this._meterProvider.getMeter('dxos-observability');
@@ -0,0 +1,34 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { DiagConsoleLogger, DiagLogLevel, diag } from '@opentelemetry/api';
6
+ import { type Resource } from '@opentelemetry/resources';
7
+
8
+ export type OtelOptions = {
9
+ endpoint: string;
10
+ headers: Record<string, string>;
11
+ resource: Resource;
12
+ getTags: () => { [key: string]: string };
13
+ consoleDiagLogLevel?: string;
14
+ };
15
+
16
+ export const setDiagLogger = (level?: string) => {
17
+ const logLevel = DiagLogLevel[level as keyof typeof DiagLogLevel];
18
+ if (logLevel) {
19
+ diag.setLogger(new DiagConsoleLogger(), logLevel);
20
+ }
21
+ };
22
+
23
+ /**
24
+ * Resolve a possibly-relative OTLP exporter URL to an absolute URL.
25
+ * The OpenTelemetry browser HTTP exporter validates user-provided URLs with `new URL(url)`,
26
+ * which throws on relative paths like `/api/otel/v1/logs`. In a browser context we resolve
27
+ * against `window.location.origin`; outside the browser we return the input unchanged.
28
+ */
29
+ export const resolveOtlpUrl = (url: string): string => {
30
+ if (typeof window !== 'undefined' && url.startsWith('/')) {
31
+ return new URL(url, window.location.origin).toString();
32
+ }
33
+ return url;
34
+ };