@smthrs/observability 0.35.0 → 1.0.0-rc.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 (363) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/LICENSE +1 -1
  3. package/README.md +84 -0
  4. package/dist/cjs/BrowserOtel.d.ts +37 -0
  5. package/dist/cjs/BrowserOtel.d.ts.map +1 -0
  6. package/dist/cjs/BrowserOtel.js +47 -0
  7. package/dist/cjs/BrowserOtel.js.map +7 -0
  8. package/dist/cjs/Endpoint.d.ts +70 -0
  9. package/dist/cjs/Endpoint.d.ts.map +1 -0
  10. package/dist/cjs/Endpoint.js +85 -0
  11. package/dist/cjs/Endpoint.js.map +7 -0
  12. package/dist/cjs/JournalLogger.d.ts +232 -0
  13. package/dist/cjs/JournalLogger.d.ts.map +1 -0
  14. package/dist/cjs/JournalLogger.js +388 -0
  15. package/dist/cjs/JournalLogger.js.map +7 -0
  16. package/dist/cjs/Logger.d.ts +55 -0
  17. package/dist/cjs/Logger.d.ts.map +1 -0
  18. package/dist/cjs/Logger.js +72 -0
  19. package/dist/cjs/Logger.js.map +7 -0
  20. package/dist/cjs/Metric.d.ts +67 -0
  21. package/dist/cjs/Metric.d.ts.map +1 -0
  22. package/dist/cjs/Metric.js +68 -0
  23. package/dist/cjs/Metric.js.map +7 -0
  24. package/dist/cjs/NodeOtel.d.ts +42 -0
  25. package/dist/cjs/NodeOtel.d.ts.map +1 -0
  26. package/dist/cjs/NodeOtel.js +78 -0
  27. package/dist/cjs/NodeOtel.js.map +7 -0
  28. package/dist/cjs/Otel.d.ts +62 -0
  29. package/dist/cjs/Otel.d.ts.map +1 -0
  30. package/dist/cjs/Otel.js +75 -0
  31. package/dist/cjs/Otel.js.map +7 -0
  32. package/dist/cjs/Otlp.d.ts +200 -0
  33. package/dist/cjs/Otlp.d.ts.map +1 -0
  34. package/dist/cjs/Otlp.js +235 -0
  35. package/dist/cjs/Otlp.js.map +7 -0
  36. package/dist/cjs/Resource.d.ts +162 -0
  37. package/dist/cjs/Resource.d.ts.map +1 -0
  38. package/dist/cjs/Resource.js +186 -0
  39. package/dist/cjs/Resource.js.map +7 -0
  40. package/dist/cjs/index.d.ts +61 -0
  41. package/dist/cjs/index.d.ts.map +1 -0
  42. package/dist/cjs/index.js +47 -0
  43. package/dist/cjs/index.js.map +7 -0
  44. package/dist/cjs/internal/schemaIssuePath.d.ts +31 -0
  45. package/dist/cjs/internal/schemaIssuePath.d.ts.map +1 -0
  46. package/dist/cjs/internal/schemaIssuePath.js +49 -0
  47. package/dist/cjs/internal/schemaIssuePath.js.map +7 -0
  48. package/dist/cjs/package.json +1 -0
  49. package/dist/esm/BrowserOtel.d.ts +37 -0
  50. package/dist/esm/BrowserOtel.d.ts.map +1 -0
  51. package/dist/esm/BrowserOtel.js +24 -0
  52. package/dist/esm/BrowserOtel.js.map +1 -0
  53. package/dist/esm/Endpoint.d.ts +70 -0
  54. package/dist/esm/Endpoint.d.ts.map +1 -0
  55. package/dist/esm/Endpoint.js +110 -0
  56. package/dist/esm/Endpoint.js.map +1 -0
  57. package/dist/esm/JournalLogger.d.ts +232 -0
  58. package/dist/esm/JournalLogger.d.ts.map +1 -0
  59. package/dist/esm/JournalLogger.js +482 -0
  60. package/dist/esm/JournalLogger.js.map +1 -0
  61. package/dist/esm/Logger.d.ts +55 -0
  62. package/dist/esm/Logger.d.ts.map +1 -0
  63. package/dist/esm/Logger.js +60 -0
  64. package/dist/esm/Logger.js.map +1 -0
  65. package/dist/esm/Metric.d.ts +67 -0
  66. package/dist/esm/Metric.d.ts.map +1 -0
  67. package/dist/esm/Metric.js +80 -0
  68. package/dist/esm/Metric.js.map +1 -0
  69. package/dist/esm/NodeOtel.d.ts +42 -0
  70. package/dist/esm/NodeOtel.d.ts.map +1 -0
  71. package/dist/esm/NodeOtel.js +56 -0
  72. package/dist/esm/NodeOtel.js.map +1 -0
  73. package/dist/esm/Otel.d.ts +62 -0
  74. package/dist/esm/Otel.d.ts.map +1 -0
  75. package/dist/esm/Otel.js +51 -0
  76. package/dist/esm/Otel.js.map +1 -0
  77. package/dist/esm/Otlp.d.ts +200 -0
  78. package/dist/esm/Otlp.d.ts.map +1 -0
  79. package/dist/esm/Otlp.js +350 -0
  80. package/dist/esm/Otlp.js.map +1 -0
  81. package/dist/esm/Resource.d.ts +162 -0
  82. package/dist/esm/Resource.d.ts.map +1 -0
  83. package/dist/esm/Resource.js +237 -0
  84. package/dist/esm/Resource.js.map +1 -0
  85. package/dist/esm/index.d.ts +61 -0
  86. package/dist/esm/index.d.ts.map +1 -0
  87. package/dist/esm/index.js +61 -0
  88. package/dist/esm/index.js.map +1 -0
  89. package/dist/esm/internal/schemaIssuePath.d.ts +31 -0
  90. package/dist/esm/internal/schemaIssuePath.d.ts.map +1 -0
  91. package/dist/esm/internal/schemaIssuePath.js +59 -0
  92. package/dist/esm/internal/schemaIssuePath.js.map +1 -0
  93. package/docs/README.md +162 -0
  94. package/docs/api.md +768 -0
  95. package/docs/concepts/instrumentation-and-export.md +68 -0
  96. package/docs/concepts/layer-map.md +72 -0
  97. package/docs/concepts/validated-acquisition.md +105 -0
  98. package/docs/guides/export-to-a-collector.md +167 -0
  99. package/docs/guides/forward-logs-to-the-journal.md +226 -0
  100. package/docs/guides/install-a-logger.md +111 -0
  101. package/docs/guides/read-runtime-metrics.md +83 -0
  102. package/docs/guides/testing.md +134 -0
  103. package/docs/guides/wire-an-opentelemetry-sdk.md +220 -0
  104. package/docs/installation.md +98 -0
  105. package/docs/quickstart.md +145 -0
  106. package/docs/troubleshooting.md +168 -0
  107. package/package.json +221 -32
  108. package/src/BrowserOtel.ts +51 -0
  109. package/src/Endpoint.ts +131 -0
  110. package/src/JournalLogger.ts +596 -0
  111. package/src/Logger.ts +106 -0
  112. package/src/Metric.ts +88 -0
  113. package/src/NodeOtel.ts +90 -0
  114. package/src/Otel.ts +117 -0
  115. package/src/Otlp.ts +477 -0
  116. package/src/Resource.ts +324 -0
  117. package/src/index.ts +67 -0
  118. package/src/internal/schemaIssuePath.ts +65 -0
  119. package/docker-compose.otel.yml +0 -104
  120. package/grafana/dashboards/smithers-dashboard.json +0 -453
  121. package/grafana/provisioning/dashboards/dashboards.yml +0 -12
  122. package/grafana/provisioning/datasources/datasources.yml +0 -49
  123. package/loki/loki-config.yaml +0 -35
  124. package/otel-collector-config.yml +0 -38
  125. package/prometheus/prometheus.yml +0 -8
  126. package/src/MetricName.ts +0 -1
  127. package/src/MetricsServiceLive.js +0 -9
  128. package/src/README.md +0 -28
  129. package/src/ResolvedSmithersObservabilityOptions.ts +0 -12
  130. package/src/SmithersEvent.ts +0 -843
  131. package/src/SmithersLogFormat.ts +0 -1
  132. package/src/SmithersMetricDefinition.ts +0 -15
  133. package/src/SmithersMetricType.ts +0 -1
  134. package/src/SmithersMetricUnit.ts +0 -1
  135. package/src/SmithersObservability.js +0 -15
  136. package/src/SmithersObservabilityOptions.ts +0 -12
  137. package/src/SmithersObservabilityService.ts +0 -13
  138. package/src/_coreCorrelation/CorrelationContext.ts +0 -10
  139. package/src/_coreCorrelation/CorrelationContextLive.js +0 -11
  140. package/src/_coreCorrelation/CorrelationContextService.js +0 -15
  141. package/src/_coreCorrelation/CorrelationContextServiceShape.ts +0 -12
  142. package/src/_coreCorrelation/CorrelationPatch.ts +0 -3
  143. package/src/_coreCorrelation/README.md +0 -20
  144. package/src/_coreCorrelation/_correlationStorage.js +0 -4
  145. package/src/_coreCorrelation/correlationContextFiberRef.js +0 -5
  146. package/src/_coreCorrelation/correlationContextToLogAnnotations.js +0 -18
  147. package/src/_coreCorrelation/getCurrentCorrelationContext.js +0 -9
  148. package/src/_coreCorrelation/getCurrentCorrelationContextEffect.js +0 -11
  149. package/src/_coreCorrelation/index.js +0 -14
  150. package/src/_coreCorrelation/mergeCorrelationContext.js +0 -51
  151. package/src/_coreCorrelation/runWithCorrelationContext.js +0 -14
  152. package/src/_coreCorrelation/updateCurrentCorrelationContext.js +0 -17
  153. package/src/_coreCorrelation/withCorrelationContext.js +0 -38
  154. package/src/_coreCorrelation/withCurrentCorrelationContext.js +0 -11
  155. package/src/_coreMetrics.js +0 -14
  156. package/src/_coreMetricsShape.ts +0 -44
  157. package/src/_corePrometheus.js +0 -91
  158. package/src/_corePrometheusShape.ts +0 -11
  159. package/src/_coreTracing.js +0 -132
  160. package/src/_coreTracingShape.ts +0 -17
  161. package/src/_otelLogBuilders.js +0 -102
  162. package/src/_sessionFileResolvers.js +0 -164
  163. package/src/_smithersSpanAttributeAliases.js +0 -19
  164. package/src/_smithersTraceSpanStorage.js +0 -3
  165. package/src/_traceEventNormalizers.js +0 -499
  166. package/src/_traceRedaction.js +0 -162
  167. package/src/agentSessionEventToOtelLogRecord.js +0 -55
  168. package/src/agentTrace.ts +0 -144
  169. package/src/agentTraceCapabilities.js +0 -151
  170. package/src/annotateSmithersTrace.js +0 -11
  171. package/src/canonicalTraceEventToOtelLogRecord.js +0 -55
  172. package/src/correlation.js +0 -56
  173. package/src/createSmithersObservabilityLayer.js +0 -59
  174. package/src/createSmithersOtelLayer.js +0 -23
  175. package/src/createSmithersRuntimeLayer.js +0 -2
  176. package/src/detectAgentFamily.js +0 -26
  177. package/src/detectCaptureMode.js +0 -29
  178. package/src/emitOtelLogRecord.js +0 -19
  179. package/src/getCurrentSmithersTraceAnnotations.js +0 -14
  180. package/src/getCurrentSmithersTraceSpan.js +0 -7
  181. package/src/index.d.ts +0 -1392
  182. package/src/index.js +0 -137
  183. package/src/kindPhase.js +0 -17
  184. package/src/logging.js +0 -264
  185. package/src/makeSmithersSpanAttributes.js +0 -20
  186. package/src/metrics/README.md +0 -22
  187. package/src/metrics/SmithersMetricDefinition.ts +0 -17
  188. package/src/metrics/SmithersMetricType.ts +0 -1
  189. package/src/metrics/SmithersMetricUnit.ts +0 -1
  190. package/src/metrics/_asyncExternalWaitCounts.js +0 -4
  191. package/src/metrics/_buckets.js +0 -37
  192. package/src/metrics/_incrementGauge.js +0 -11
  193. package/src/metrics/_processStartMs.js +0 -1
  194. package/src/metrics/activeNodes.js +0 -2
  195. package/src/metrics/activeRuns.js +0 -2
  196. package/src/metrics/agentActionsTotal.js +0 -2
  197. package/src/metrics/agentDurationMs.js +0 -3
  198. package/src/metrics/agentErrorsTotal.js +0 -2
  199. package/src/metrics/agentEventsTotal.js +0 -2
  200. package/src/metrics/agentInvocationsTotal.js +0 -2
  201. package/src/metrics/agentRetriesTotal.js +0 -2
  202. package/src/metrics/agentSessionsTotal.js +0 -2
  203. package/src/metrics/agentTokensTotal.js +0 -2
  204. package/src/metrics/alertDeliveriesAttempted.js +0 -2
  205. package/src/metrics/alertDeliveriesSuppressed.js +0 -2
  206. package/src/metrics/alertsAcknowledgedTotal.js +0 -2
  207. package/src/metrics/alertsActive.js +0 -2
  208. package/src/metrics/alertsEscalatedTotal.js +0 -2
  209. package/src/metrics/alertsFiredTotal.js +0 -2
  210. package/src/metrics/alertsReopenedTotal.js +0 -2
  211. package/src/metrics/alertsResolvedTotal.js +0 -2
  212. package/src/metrics/alertsSilencedTotal.js +0 -2
  213. package/src/metrics/approvalPending.js +0 -2
  214. package/src/metrics/approvalWaitDuration.js +0 -5
  215. package/src/metrics/approvalsDenied.js +0 -2
  216. package/src/metrics/approvalsGranted.js +0 -2
  217. package/src/metrics/approvalsRequested.js +0 -2
  218. package/src/metrics/attemptDuration.js +0 -3
  219. package/src/metrics/attentionBacklog.js +0 -2
  220. package/src/metrics/cacheHits.js +0 -2
  221. package/src/metrics/cacheMisses.js +0 -2
  222. package/src/metrics/dbQueryDuration.js +0 -3
  223. package/src/metrics/dbRetries.js +0 -2
  224. package/src/metrics/dbTransactionDuration.js +0 -3
  225. package/src/metrics/dbTransactionRetries.js +0 -2
  226. package/src/metrics/dbTransactionRollbacks.js +0 -2
  227. package/src/metrics/devtoolsActiveSubscribers.js +0 -2
  228. package/src/metrics/devtoolsBackpressureDisconnectTotal.js +0 -2
  229. package/src/metrics/devtoolsDeltaBuildMs.js +0 -3
  230. package/src/metrics/devtoolsEventBytes.js +0 -3
  231. package/src/metrics/devtoolsEventTotal.js +0 -2
  232. package/src/metrics/devtoolsSnapshotBuildMs.js +0 -5
  233. package/src/metrics/devtoolsSubscribeTotal.js +0 -2
  234. package/src/metrics/errorsTotal.js +0 -2
  235. package/src/metrics/eventsEmittedTotal.js +0 -2
  236. package/src/metrics/externalWaitAsyncPending.js +0 -2
  237. package/src/metrics/gatewayApprovalDecisionsTotal.js +0 -2
  238. package/src/metrics/gatewayAuthEventsTotal.js +0 -2
  239. package/src/metrics/gatewayConnectionsActive.js +0 -2
  240. package/src/metrics/gatewayConnectionsClosedTotal.js +0 -2
  241. package/src/metrics/gatewayConnectionsTotal.js +0 -2
  242. package/src/metrics/gatewayCronTriggersTotal.js +0 -2
  243. package/src/metrics/gatewayErrorsTotal.js +0 -2
  244. package/src/metrics/gatewayHeartbeatTicksTotal.js +0 -2
  245. package/src/metrics/gatewayMessagesReceivedTotal.js +0 -2
  246. package/src/metrics/gatewayMessagesSentTotal.js +0 -2
  247. package/src/metrics/gatewayRpcCallsTotal.js +0 -2
  248. package/src/metrics/gatewayRpcDuration.js +0 -3
  249. package/src/metrics/gatewayRunEventBackpressureDisconnectTotal.js +0 -4
  250. package/src/metrics/gatewayRunsCompletedTotal.js +0 -2
  251. package/src/metrics/gatewayRunsStartedTotal.js +0 -2
  252. package/src/metrics/gatewaySignalsTotal.js +0 -2
  253. package/src/metrics/gatewayWebhooksReceivedTotal.js +0 -2
  254. package/src/metrics/gatewayWebhooksRejectedTotal.js +0 -2
  255. package/src/metrics/gatewayWebhooksVerifiedTotal.js +0 -2
  256. package/src/metrics/heartbeatDataSizeBytes.js +0 -5
  257. package/src/metrics/heartbeatIntervalMs.js +0 -3
  258. package/src/metrics/hotReloadDuration.js +0 -3
  259. package/src/metrics/hotReloadFailures.js +0 -2
  260. package/src/metrics/hotReloads.js +0 -2
  261. package/src/metrics/httpRequestDuration.js +0 -3
  262. package/src/metrics/httpRequests.js +0 -2
  263. package/src/metrics/index.d.ts +0 -1222
  264. package/src/metrics/index.js +0 -168
  265. package/src/metrics/memoryFactReads.js +0 -3
  266. package/src/metrics/memoryFactWrites.js +0 -3
  267. package/src/metrics/memoryMessageSaves.js +0 -3
  268. package/src/metrics/memoryRecallDuration.js +0 -11
  269. package/src/metrics/memoryRecallQueries.js +0 -3
  270. package/src/metrics/metricsServiceAdapter.js +0 -181
  271. package/src/metrics/nodeDuration.js +0 -3
  272. package/src/metrics/nodeRetriesTotal.js +0 -2
  273. package/src/metrics/nodesFailed.js +0 -2
  274. package/src/metrics/nodesFinished.js +0 -2
  275. package/src/metrics/nodesStarted.js +0 -2
  276. package/src/metrics/openApiToolCallErrorsTotal.js +0 -3
  277. package/src/metrics/openApiToolCallsTotal.js +0 -3
  278. package/src/metrics/openApiToolDuration.js +0 -9
  279. package/src/metrics/processHeapUsedBytes.js +0 -2
  280. package/src/metrics/processMemoryRssBytes.js +0 -2
  281. package/src/metrics/processUptimeSeconds.js +0 -2
  282. package/src/metrics/promptSizeBytes.js +0 -3
  283. package/src/metrics/replaysStarted.js +0 -3
  284. package/src/metrics/responseSizeBytes.js +0 -3
  285. package/src/metrics/rewindDurationMs.js +0 -3
  286. package/src/metrics/rewindFramesDeleted.js +0 -3
  287. package/src/metrics/rewindRollbackTotal.js +0 -2
  288. package/src/metrics/rewindSandboxesReverted.js +0 -3
  289. package/src/metrics/rewindTotal.js +0 -2
  290. package/src/metrics/runDuration.js +0 -3
  291. package/src/metrics/runForksCreated.js +0 -3
  292. package/src/metrics/runsAncestryDepth.js +0 -3
  293. package/src/metrics/runsCancelledTotal.js +0 -2
  294. package/src/metrics/runsCarriedStateBytes.js +0 -5
  295. package/src/metrics/runsContinuedTotal.js +0 -2
  296. package/src/metrics/runsFailedTotal.js +0 -2
  297. package/src/metrics/runsFinishedTotal.js +0 -2
  298. package/src/metrics/runsResumedTotal.js +0 -2
  299. package/src/metrics/runsTotal.js +0 -2
  300. package/src/metrics/sandboxActive.js +0 -2
  301. package/src/metrics/sandboxBundleSizeBytes.js +0 -5
  302. package/src/metrics/sandboxCompletedTotal.js +0 -2
  303. package/src/metrics/sandboxCreatedTotal.js +0 -2
  304. package/src/metrics/sandboxDurationMs.js +0 -3
  305. package/src/metrics/sandboxPatchCount.js +0 -3
  306. package/src/metrics/sandboxTransportDurationMs.js +0 -5
  307. package/src/metrics/schedulerConcurrencyUtilization.js +0 -2
  308. package/src/metrics/schedulerQueueDepth.js +0 -2
  309. package/src/metrics/schedulerWaitDuration.js +0 -5
  310. package/src/metrics/scorerDuration.js +0 -9
  311. package/src/metrics/scorerEventsFailed.js +0 -2
  312. package/src/metrics/scorerEventsFinished.js +0 -2
  313. package/src/metrics/scorerEventsStarted.js +0 -2
  314. package/src/metrics/scorersFailed.js +0 -3
  315. package/src/metrics/scorersFinished.js +0 -3
  316. package/src/metrics/scorersStarted.js +0 -3
  317. package/src/metrics/smithersMetricCatalog.js +0 -893
  318. package/src/metrics/smithersMetricCatalogByKey.js +0 -2
  319. package/src/metrics/smithersMetricCatalogByName.js +0 -2
  320. package/src/metrics/smithersMetricCatalogByPrometheusName.js +0 -4
  321. package/src/metrics/snapshotDuration.js +0 -9
  322. package/src/metrics/snapshotsCaptured.js +0 -3
  323. package/src/metrics/supervisorPollDuration.js +0 -5
  324. package/src/metrics/supervisorPollsTotal.js +0 -2
  325. package/src/metrics/supervisorResumeLag.js +0 -5
  326. package/src/metrics/supervisorResumedTotal.js +0 -2
  327. package/src/metrics/supervisorSkippedTotal.js +0 -2
  328. package/src/metrics/supervisorStaleDetected.js +0 -2
  329. package/src/metrics/taskHeartbeatTimeoutTotal.js +0 -2
  330. package/src/metrics/taskHeartbeatsTotal.js +0 -2
  331. package/src/metrics/timerDelayDuration.js +0 -3
  332. package/src/metrics/timersCancelled.js +0 -2
  333. package/src/metrics/timersCreated.js +0 -2
  334. package/src/metrics/timersFired.js +0 -2
  335. package/src/metrics/timersPending.js +0 -2
  336. package/src/metrics/toPrometheusMetricName.js +0 -8
  337. package/src/metrics/tokensCacheReadTotal.js +0 -2
  338. package/src/metrics/tokensCacheWriteTotal.js +0 -2
  339. package/src/metrics/tokensContextWindowBucketTotal.js +0 -2
  340. package/src/metrics/tokensContextWindowPerCall.js +0 -5
  341. package/src/metrics/tokensInputPerCall.js +0 -3
  342. package/src/metrics/tokensInputTotal.js +0 -2
  343. package/src/metrics/tokensOutputPerCall.js +0 -3
  344. package/src/metrics/tokensOutputTotal.js +0 -2
  345. package/src/metrics/tokensReasoningTotal.js +0 -2
  346. package/src/metrics/toolCallErrorsTotal.js +0 -2
  347. package/src/metrics/toolCallsTotal.js +0 -2
  348. package/src/metrics/toolDuration.js +0 -3
  349. package/src/metrics/toolOutputTruncatedTotal.js +0 -2
  350. package/src/metrics/trackEvent.js +0 -608
  351. package/src/metrics/updateAsyncExternalWaitPending.js +0 -18
  352. package/src/metrics/updateProcessMetrics.js +0 -20
  353. package/src/metrics/vcsDuration.js +0 -3
  354. package/src/normalizeStructuredEvent.js +0 -15
  355. package/src/prometheusContentType.js +0 -1
  356. package/src/renderPrometheusMetrics.js +0 -212
  357. package/src/resolveAgentTraceCapabilities.js +0 -59
  358. package/src/resolveSmithersObservabilityOptions.js +0 -109
  359. package/src/smithersMetrics.js +0 -2
  360. package/src/smithersSpanNames.js +0 -6
  361. package/src/unsupportedKindsForCapabilities.js +0 -32
  362. package/src/withSmithersSpan.js +0 -17
  363. package/tempo/tempo.yml +0 -17
@@ -0,0 +1,145 @@
1
+ ---
2
+ title: "Quickstart"
3
+ description: "Export a trace, a log record, and a metric series to a collector you can watch, using a thirty-line collector stand-in and one Effect layer."
4
+ sidebar:
5
+ order: 2
6
+ ---
7
+
8
+ This quickstart exports all three signals from one small program and shows you
9
+ what arrived. It needs no Docker, no vendor account, and no OpenTelemetry SDK:
10
+ a twelve-line Node server stands in for the collector so you can read the
11
+ delivery with your own eyes, and swapping in a real collector is a one-line
12
+ change at the end.
13
+
14
+ ## Prerequisites
15
+
16
+ - Node.js 26.4.0 or later, which runs a `.ts` file directly by stripping its
17
+ types.
18
+ - A package whose `package.json` sets `"type": "module"`, with the
19
+ dependencies installed. Not on npm yet; see [Installation](https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/flow/docs/installation.md#use-the-libraries).
20
+
21
+ ## Start a collector stand-in
22
+
23
+ An OTLP/HTTP collector is an HTTP server that accepts JSON on three paths.
24
+ Create `collector.mjs`:
25
+
26
+ ```js
27
+ import { createServer } from "node:http"
28
+
29
+ createServer((request, response) => {
30
+ const chunks = []
31
+ request.on("data", (chunk) => chunks.push(chunk))
32
+ request.on("end", () => {
33
+ const body = JSON.parse(Buffer.concat(chunks).toString("utf8"))
34
+ console.log(request.url, Object.keys(body).join(" "))
35
+ response.writeHead(200, { "content-type": "application/json" })
36
+ response.end("{}")
37
+ })
38
+ }).listen(4318, "127.0.0.1")
39
+ ```
40
+
41
+ Run it in its own terminal, and leave it running:
42
+
43
+ ```bash
44
+ node collector.mjs
45
+ ```
46
+
47
+ ## Write the program
48
+
49
+ Create `quickstart.ts`. The program opens a span, writes a log record, and
50
+ advances a counter. None of those three lines mentions telemetry: they are
51
+ ordinary Effect, and they are exactly what the Smithers packages already do on
52
+ their own hot paths.
53
+
54
+ ```ts
55
+ import * as Otlp from "@smthrs/observability/Otlp"
56
+ import * as Effect from "effect/Effect"
57
+ import * as Metric from "effect/Metric"
58
+
59
+ const deployments = Metric.counter("quickstart/deployments", {
60
+ description: "Deployments this program recorded"
61
+ })
62
+
63
+ const deploy = Effect.gen(function*() {
64
+ yield* Effect.logInfo("deploying the API")
65
+ yield* Metric.update(deployments, 1)
66
+ }).pipe(Effect.withSpan("deploy"))
67
+ ```
68
+
69
+ Now add the exporter and run it. `layerFetch` posts over the host's global
70
+ `fetch`, so there is nothing else to provide:
71
+
72
+ ```ts
73
+ const telemetry = Otlp.layerFetch({
74
+ baseUrl: "http://localhost:4318",
75
+ serviceName: "quickstart",
76
+ serviceVersion: "1.0.0"
77
+ })
78
+
79
+ await Effect.runPromise(
80
+ deploy.pipe(Effect.provide(telemetry), Effect.orDie, Effect.scoped)
81
+ )
82
+ ```
83
+
84
+ `Effect.orDie` says that an unusable collector endpoint is a startup defect
85
+ rather than something this program recovers from. The layer is scoped, so
86
+ `Effect.scoped` gives it a lifetime, and closing that scope is what flushes.
87
+
88
+ ## Run it
89
+
90
+ ```bash
91
+ node quickstart.ts
92
+ ```
93
+
94
+ The collector terminal prints one line per signal. The three arrive in
95
+ whatever order the exporters flush:
96
+
97
+ ```text
98
+ /v1/traces resourceSpans
99
+ /v1/logs resourceLogs
100
+ /v1/metrics resourceMetrics
101
+ ```
102
+
103
+ If you print a whole body instead of its top-level key, every payload carries
104
+ the resource you named: `service.name` is `quickstart` and `service.version` is
105
+ `1.0.0`.
106
+
107
+ ## What just happened
108
+
109
+ One layer installed three of Effect's own OTLP exporters against your base URL.
110
+ Each signal posts below it on its own path, so `http://localhost:4318` becomes
111
+ `/v1/traces`, `/v1/logs`, and `/v1/metrics`. The exporters batch, so nothing
112
+ was delivered while the program ran; closing the layer's scope force-flushed
113
+ all three, which is why `Effect.scoped` is where the output comes from.
114
+
115
+ The program never mentioned a tracer, a meter, or a logger provider. Effect's
116
+ own tracer and metric registry were already collecting; the layer is only the
117
+ delivery.
118
+
119
+ ## Point it at a real collector
120
+
121
+ Change one field:
122
+
123
+ ```ts
124
+ const telemetry = Otlp.layerFetch({
125
+ baseUrl: "https://otlp.example.com",
126
+ serviceName: "quickstart",
127
+ headers: { authorization: "Bearer YOUR_TOKEN" }
128
+ })
129
+ ```
130
+
131
+ Replace `YOUR_TOKEN` with the token your vendor issued. The endpoint must be an
132
+ absolute `http:` or `https:` URL carrying no credentials; anything else refuses
133
+ the layer at acquisition rather than failing silently later. See
134
+ [Export to an OTLP collector](./guides/export-to-a-collector.md) for the rest
135
+ of the options.
136
+
137
+ ## Next steps
138
+
139
+ - [Export to an OTLP collector](./guides/export-to-a-collector.md): service
140
+ identity, authentication headers, export cadence, and what happens when a
141
+ collector is down.
142
+ - [Instrumentation and export](./concepts/instrumentation-and-export.md): why
143
+ the exporter is one layer and what is already instrumented without it.
144
+ - [Forward logs to the run journal](./guides/forward-logs-to-the-journal.md):
145
+ the second delivery path, durable and readable in process.
@@ -0,0 +1,168 @@
1
+ ---
2
+ title: "Troubleshooting"
3
+ description: "The typed refusals @smthrs/observability reports and the silent failures it cannot: nothing arriving at a collector, a bundler that cannot resolve async_hooks, logs that stopped, and a counter that reads zero."
4
+ ---
5
+
6
+ Two kinds of problem show up here. A typed refusal names its own cause and
7
+ happens while the layer is built. A silent failure is the harder one, because
8
+ export is absorbed by design and a broken exporter looks exactly like a working
9
+ one.
10
+
11
+ ## InvalidExporterEndpoint
12
+
13
+ **What happened.** A builder was handed a collector endpoint it will not
14
+ export to. The failure carries `code` `invalid_exporter_endpoint`, the `path`
15
+ of the option it arrived on (`baseUrl` for `Otlp`, `endpoint` for `NodeOtel`),
16
+ and a message. The rejected value is not in the error.
17
+
18
+ **What to change.** Pass an absolute `http:` or `https:` URL of at most 2,048
19
+ characters that carries no username or password and no spaces or control
20
+ characters. The usual culprits, in order:
21
+
22
+ - A trailing newline off a config file, or a leading space off a paste. Trim
23
+ the value. This one is refused rather than repaired precisely because the
24
+ URL parser would repair it into a URL nobody typed.
25
+ - A missing scheme: `collector:4318` instead of `http://collector:4318`.
26
+ - A signal path already appended. Pass the base URL; the builder adds
27
+ `/v1/traces`, `/v1/metrics`, and `/v1/logs`.
28
+ - Credentials in the URL. Move them to the `headers` option.
29
+
30
+ ## InvalidResourceConfiguration
31
+
32
+ **What happened.** The service identity or the resource attributes failed
33
+ decoding. The failure carries `code` `invalid_resource_configuration` and a
34
+ `path` naming the offending field, such as `serviceName` or an attribute key.
35
+
36
+ **What to change.** Check the value against the bounds: a non-empty service
37
+ name and version of at most 1,024 UTF-16 code units, at most 256 attributes,
38
+ attribute values that are strings of at most 65,536 code units, finite numbers,
39
+ booleans, or homogeneous arrays of those with at most 256 elements. The complete
40
+ resource must fit 128 KiB of OTLP JSON, including keys, identity, the SDK-added
41
+ `telemetry.sdk.name` and `telemetry.sdk.language` fields, wrappers,
42
+ escaping and UTF-8. Many individually valid values can exceed this budget;
43
+ remove or shorten attributes. The refusal names `attributes`, the measured
44
+ lower bound in bytes and the limit, without retaining values. NUL and unpaired surrogates are
45
+ refused anywhere. An empty `serviceName` is the common one, usually an
46
+ environment variable that was not set.
47
+
48
+ ## InvalidJournalLoggerOptions
49
+
50
+ **What happened.** `JournalLogger.layerJournalForwarding` was given a run id or
51
+ a capacity it will not start a worker for. The failure carries `code`
52
+ `invalid_journal_logger_options` and the offending `path`.
53
+
54
+ **What to change.** Decode the run id through `JournalEvent.RunId` rather than
55
+ casting a string, and keep `capacity` between 1 and 65,536. The refusal happens
56
+ before any record is queued, so nothing was silently dropped.
57
+
58
+ ## Nothing arrives at the collector
59
+
60
+ **What happened.** The layer built, the program ran, and the collector holds
61
+ nothing. Export failure is absorbed by design, so this is not reported anywhere
62
+ by default.
63
+
64
+ **What to check, in order.**
65
+
66
+ 1. **Did the scope close?** Exporters batch. A short program delivers on the
67
+ shutdown flush, so read the collector only after `Effect.scoped` completes.
68
+ A program killed with `SIGKILL` never flushes.
69
+ 2. **Is the base URL what you think?** Signals post below it, so
70
+ `http://collector:4318` posts to `http://collector:4318/v1/traces`. If your
71
+ collector expects a prefix, include it in `baseUrl`.
72
+ 3. **Is the collector answering?** Run at `Debug`. The exporter logs
73
+ `Disabling exporter for 60 seconds` when it gives up after three retries.
74
+ 4. **Is the layer actually provided?** A composition that swapped in
75
+ `Otlp.layerNoop` behaves exactly like a healthy one that delivers nothing.
76
+
77
+ ## An OTLP export batch was discarded
78
+
79
+ A `Warn` record with code `otlp_export_discarded` means the transport discarded
80
+ a batch because it exceeded 1 MiB (`oversized`), stalled for ten seconds
81
+ (`stalled`), or found all four request slots occupied (`saturated`). The
82
+ `flows_observability_otlp_dropped` counter records every discarded batch. The
83
+ warning carries the request byte size, limit and running drop count, and is
84
+ limited to one per minute per transport.
85
+
86
+ Warnings go only to the loggers captured before exporter acquisition, without
87
+ logging into this exporter. Keep an ambient sink outside OTLP at level `Warn`
88
+ or lower: it remains useful even when the drop counter cannot reach the
89
+ collector. An empty ambient logger set or a higher minimum level suppresses
90
+ warnings. Reduce unusually large records or metric cardinality for oversized
91
+ batches; check collector availability and latency for stalls and saturation.
92
+ The resource budget reserves 888 KiB for ordinary batches, but cannot bound
93
+ application record sizes.
94
+
95
+ ## Log records stopped reaching the collector
96
+
97
+ **What happened.** Spans and metric series still arrive, and logs do not, after
98
+ a `Logger` layer was added.
99
+
100
+ **What to change.** `Otlp` adds its log exporter to the ambient logger set, and
101
+ a `Logger` layer with the default `mergeWithExisting: false` replaces that set.
102
+ Whether the exporter survives depends on which layer the composition builds
103
+ last, which is not worth reasoning about: pass `mergeWithExisting: true` on the
104
+ `Logger` layer whenever another sink is installed. See
105
+ [Install a logger](./guides/install-a-logger.md).
106
+
107
+ ## A bundler cannot resolve `async_hooks`
108
+
109
+ **What happened.** A browser or edge build failed on `async_hooks`,
110
+ `node:async_hooks`, or a module under `@opentelemetry/context-async-hooks`.
111
+
112
+ **What to change.** Something in the graph imports
113
+ `@smthrs/observability/NodeOtel`, directly or through a module that does.
114
+ `NodeOtel` binds the Node OpenTelemetry SDK and cannot bundle for a browser.
115
+ Use `Otlp.layerFetch` for browser delivery, or `BrowserOtel` when you need the
116
+ web SDK, and keep the `NodeOtel` import behind a Node-only entry point. The
117
+ root entry point itself resolves no `node:` built-in and bundles for a browser
118
+ as it is.
119
+
120
+ ## `Metric.value` reads zero
121
+
122
+ **What happened.** The system is clearly doing work, and a counter reads zero.
123
+
124
+ **What to check.**
125
+
126
+ - **A dimensioned counter read through its bare handle.** Some packages update
127
+ only an attribute-tagged series, so the attribute-less parent stays at zero.
128
+ Read the exported view, for example `EngineStoreMetrics.dispatch.Success`
129
+ from [`@smthrs/engine-store`](/api/engine-store).
130
+ - **A registry provided per test.** Providing `Metric.MetricRegistry` with a
131
+ fresh map isolates state; a read outside that scope sees a different
132
+ registry.
133
+ - **A gauge read as a counter.** A gauge's value is `value`, a counter's is
134
+ `count`.
135
+
136
+ ## `droppedLogRecords` keeps climbing
137
+
138
+ **What happened.** `flows_observability_log_dropped` advances during a run,
139
+ which means log records are not reaching the journal.
140
+
141
+ **What to change.** The counter advances for three distinct losses, and the
142
+ last two also emit a warning annotated with the run id:
143
+
144
+ - **Queue overflow**, with no warning. Raise `capacity` above the default 256,
145
+ up to 65,536.
146
+ - **A journal delivery failure.** Read the warning; the journal itself is the
147
+ problem, not the logger.
148
+ - **A defect from the journal implementation.** Read the warning. The worker
149
+ keeps draining, so the run continues with gaps.
150
+
151
+ Records queued behind an in-flight write can also be dropped when the layer's
152
+ scope closes, and the forwarder exposes no drain barrier. `journal.flush`
153
+ settles only the entries the journal has already admitted, so it returns while
154
+ a record is still waiting in the forwarder's queue. Poll the journal for the
155
+ records you expect while the layer's scope is open, as
156
+ [Forward logs to the run journal](./guides/forward-logs-to-the-journal.md#assert-on-a-short-lived-run)
157
+ shows.
158
+
159
+ ## Reading a refusal's path
160
+
161
+ `path` is a dotted route into the value that failed, built from the decoder's
162
+ own issue path. `serviceName` names the identity field;
163
+ `attributes.region` names the `region` entry inside the `attributes` record. When the decoder cannot attribute the failure to a field,
164
+ the path is the bare `resource`, which means the whole configuration was
165
+ malformed: `null`, or not an object at all.
166
+
167
+ Neither refusal carries the rejected value, so pair the path with the value you
168
+ passed on that field.
package/package.json CHANGED
@@ -1,48 +1,237 @@
1
1
  {
2
2
  "name": "@smthrs/observability",
3
- "version": "0.35.0",
4
- "description": "Concrete Smithers metrics, logging, tracing, and observability integrations",
5
3
  "type": "module",
6
- "sideEffects": false,
4
+ "version": "1.0.0-rc.3",
5
+ "license": "MIT",
6
+ "smthrs": {
7
+ "group": "engine"
8
+ },
9
+ "description": "Observability for flows: default OTLP export wiring plus Effect-native logger, metric, and OpenTelemetry SDK layers",
10
+ "homepage": "https://github.com/smithersai/smithers",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/smithersai/smithers.git",
14
+ "directory": "packages/smithers/flows/observability"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/smithersai/smithers/issues"
18
+ },
19
+ "tags": [
20
+ "typescript",
21
+ "effect",
22
+ "observability",
23
+ "opentelemetry"
24
+ ],
25
+ "keywords": [
26
+ "typescript",
27
+ "effect",
28
+ "observability",
29
+ "opentelemetry"
30
+ ],
31
+ "engines": {
32
+ "node": ">=26.4.0"
33
+ },
34
+ "sideEffects": [],
7
35
  "exports": {
36
+ "./package.json": "./package.json",
8
37
  ".": {
9
- "types": "./src/index.d.ts",
10
- "import": "./src/index.js",
11
- "default": "./src/index.js"
12
- },
13
- "./metrics": {
14
- "types": "./src/metrics/index.d.ts",
15
- "import": "./src/metrics/index.js",
16
- "default": "./src/metrics/index.js"
17
- },
18
- "./*": {
19
- "types": "./src/index.d.ts",
20
- "import": "./src/*.js",
21
- "default": "./src/*.js"
38
+ "import": {
39
+ "types": "./dist/esm/index.d.ts",
40
+ "default": "./dist/esm/index.js"
41
+ },
42
+ "require": {
43
+ "types": "./dist/cjs/index.d.ts",
44
+ "default": "./dist/cjs/index.js"
45
+ }
46
+ },
47
+ "./BrowserOtel": {
48
+ "import": {
49
+ "types": "./dist/esm/BrowserOtel.d.ts",
50
+ "default": "./dist/esm/BrowserOtel.js"
51
+ },
52
+ "require": {
53
+ "types": "./dist/cjs/BrowserOtel.d.ts",
54
+ "default": "./dist/cjs/BrowserOtel.js"
55
+ }
56
+ },
57
+ "./Endpoint": {
58
+ "import": {
59
+ "types": "./dist/esm/Endpoint.d.ts",
60
+ "default": "./dist/esm/Endpoint.js"
61
+ },
62
+ "require": {
63
+ "types": "./dist/cjs/Endpoint.d.ts",
64
+ "default": "./dist/cjs/Endpoint.js"
65
+ }
66
+ },
67
+ "./JournalLogger": {
68
+ "import": {
69
+ "types": "./dist/esm/JournalLogger.d.ts",
70
+ "default": "./dist/esm/JournalLogger.js"
71
+ },
72
+ "require": {
73
+ "types": "./dist/cjs/JournalLogger.d.ts",
74
+ "default": "./dist/cjs/JournalLogger.js"
75
+ }
76
+ },
77
+ "./Logger": {
78
+ "import": {
79
+ "types": "./dist/esm/Logger.d.ts",
80
+ "default": "./dist/esm/Logger.js"
81
+ },
82
+ "require": {
83
+ "types": "./dist/cjs/Logger.d.ts",
84
+ "default": "./dist/cjs/Logger.js"
85
+ }
86
+ },
87
+ "./Metric": {
88
+ "import": {
89
+ "types": "./dist/esm/Metric.d.ts",
90
+ "default": "./dist/esm/Metric.js"
91
+ },
92
+ "require": {
93
+ "types": "./dist/cjs/Metric.d.ts",
94
+ "default": "./dist/cjs/Metric.js"
95
+ }
96
+ },
97
+ "./NodeOtel": {
98
+ "import": {
99
+ "types": "./dist/esm/NodeOtel.d.ts",
100
+ "default": "./dist/esm/NodeOtel.js"
101
+ },
102
+ "require": {
103
+ "types": "./dist/cjs/NodeOtel.d.ts",
104
+ "default": "./dist/cjs/NodeOtel.js"
105
+ }
106
+ },
107
+ "./Otel": {
108
+ "import": {
109
+ "types": "./dist/esm/Otel.d.ts",
110
+ "default": "./dist/esm/Otel.js"
111
+ },
112
+ "require": {
113
+ "types": "./dist/cjs/Otel.d.ts",
114
+ "default": "./dist/cjs/Otel.js"
115
+ }
116
+ },
117
+ "./Otlp": {
118
+ "import": {
119
+ "types": "./dist/esm/Otlp.d.ts",
120
+ "default": "./dist/esm/Otlp.js"
121
+ },
122
+ "require": {
123
+ "types": "./dist/cjs/Otlp.d.ts",
124
+ "default": "./dist/cjs/Otlp.js"
125
+ }
126
+ },
127
+ "./Resource": {
128
+ "import": {
129
+ "types": "./dist/esm/Resource.d.ts",
130
+ "default": "./dist/esm/Resource.js"
131
+ },
132
+ "require": {
133
+ "types": "./dist/cjs/Resource.d.ts",
134
+ "default": "./dist/cjs/Resource.js"
135
+ }
136
+ },
137
+ "./index": {
138
+ "import": {
139
+ "types": "./dist/esm/index.d.ts",
140
+ "default": "./dist/esm/index.js"
141
+ },
142
+ "require": {
143
+ "types": "./dist/cjs/index.d.ts",
144
+ "default": "./dist/cjs/index.js"
145
+ }
22
146
  }
23
147
  },
24
148
  "files": [
25
- "src/",
26
- "docker-compose.otel.yml",
27
- "otel-collector-config.yml",
28
- "prometheus/",
29
- "tempo/",
30
- "loki/",
31
- "grafana/"
149
+ "src/**/*.ts",
150
+ "dist/**/*.js",
151
+ "dist/**/*.js.map",
152
+ "dist/**/*.d.ts",
153
+ "dist/**/*.d.ts.map",
154
+ "dist/**/package.json",
155
+ "LICENSE",
156
+ "README.md",
157
+ "CHANGELOG.md",
158
+ "docs/"
32
159
  ],
160
+ "publishConfig": {
161
+ "access": "public",
162
+ "provenance": true,
163
+ "tag": "next"
164
+ },
33
165
  "dependencies": {
34
- "@effect/opentelemetry": "4.0.0-beta.105",
35
- "@effect/platform-bun": "4.0.0-beta.105",
36
- "@effect/platform-node-shared": "4.0.0-beta.105",
37
- "effect": "4.0.0-beta.105"
166
+ "@opentelemetry/sdk-logs": "0.222.0",
167
+ "@opentelemetry/sdk-metrics": "2.11.0",
168
+ "@smthrs/journal": "1.0.0-rc.3"
38
169
  },
39
170
  "devDependencies": {
40
- "@types/bun": "latest",
41
- "typescript": "~6.0.3"
171
+ "@effect/language-service": "0.87.2",
172
+ "@effect/opentelemetry": "4.0.0-rc.115",
173
+ "@effect/vitest": "4.0.0-rc.115",
174
+ "@eslint/js": "9.39.5",
175
+ "@opentelemetry/api": "1.9.1",
176
+ "@opentelemetry/exporter-logs-otlp-http": "0.222.0",
177
+ "@opentelemetry/exporter-metrics-otlp-http": "0.222.0",
178
+ "@opentelemetry/exporter-trace-otlp-http": "0.222.0",
179
+ "@opentelemetry/sdk-trace-base": "2.11.0",
180
+ "@opentelemetry/sdk-trace-node": "2.11.0",
181
+ "@opentelemetry/sdk-trace-web": "2.11.0",
182
+ "@types/node": "26.4.1",
183
+ "@vitest/coverage-v8": "5.0.0",
184
+ "dprint": "0.57.1",
185
+ "effect": "4.0.0-rc.115",
186
+ "esbuild": "0.28.2",
187
+ "eslint": "9.39.5",
188
+ "eslint-import-resolver-typescript": "4.4.5",
189
+ "eslint-plugin-import": "2.32.0",
190
+ "eslint-plugin-jsdoc": "64.3.4",
191
+ "eslint-plugin-unicorn": "65.0.0",
192
+ "madge": "8.0.0",
193
+ "typescript": "5.9.3",
194
+ "typescript-eslint": "8.69.0",
195
+ "vitest": "5.0.0"
196
+ },
197
+ "peerDependencies": {
198
+ "@effect/opentelemetry": "4.0.0-rc.115",
199
+ "@opentelemetry/api": ">=1.9.1 <2.0.0",
200
+ "@opentelemetry/exporter-logs-otlp-http": ">=0.222.0 <0.300.0",
201
+ "@opentelemetry/exporter-metrics-otlp-http": ">=0.222.0 <0.300.0",
202
+ "@opentelemetry/exporter-trace-otlp-http": ">=0.222.0 <0.300.0",
203
+ "@opentelemetry/sdk-trace-base": ">=2.11.0 <3.0.0",
204
+ "@opentelemetry/sdk-trace-node": ">=2.11.0 <3.0.0",
205
+ "@opentelemetry/sdk-trace-web": ">=2.11.0 <3.0.0",
206
+ "effect": "4.0.0-rc.115"
207
+ },
208
+ "peerDependenciesMeta": {
209
+ "@opentelemetry/exporter-logs-otlp-http": {
210
+ "optional": true
211
+ },
212
+ "@opentelemetry/exporter-metrics-otlp-http": {
213
+ "optional": true
214
+ },
215
+ "@opentelemetry/exporter-trace-otlp-http": {
216
+ "optional": true
217
+ },
218
+ "@opentelemetry/sdk-trace-base": {
219
+ "optional": true
220
+ },
221
+ "@opentelemetry/sdk-trace-node": {
222
+ "optional": true
223
+ },
224
+ "@opentelemetry/sdk-trace-web": {
225
+ "optional": true
226
+ }
42
227
  },
43
228
  "scripts": {
44
- "build": "rm -f src/index.d.ts src/metrics/index.d.ts src/*-*.d.ts && tsup --dts-only",
45
- "test": "bun test tests",
46
- "typecheck": "tsc -p tsconfig.json --noEmit"
229
+ "lint": "eslint src --max-warnings=0 && dprint check",
230
+ "format": "dprint fmt",
231
+ "build": "node scripts/build.mjs",
232
+ "check": "tsc -b tsconfig.json && tsc -p tsconfig.test.json --noEmit",
233
+ "circular": "node scripts/circular.mjs",
234
+ "test": "vitest",
235
+ "coverage": "vitest --coverage"
47
236
  }
48
237
  }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Browser OpenTelemetry setup with explicitly injected providers/readers.
3
+ *
4
+ * @since 0.1.0
5
+ */
6
+
7
+ import * as WebSdk from "@effect/opentelemetry/WebSdk"
8
+ import type { LogRecordProcessor } from "@opentelemetry/sdk-logs"
9
+ import type { MetricReader } from "@opentelemetry/sdk-metrics"
10
+ import type { SpanProcessor } from "@opentelemetry/sdk-trace-base"
11
+ import * as Effect from "effect/Effect"
12
+ import * as Layer from "effect/Layer"
13
+ import * as Resource from "./Resource.ts"
14
+ import type { Configuration as ResourceConfiguration } from "./Resource.ts"
15
+
16
+ /**
17
+ * Browser OTEL layer options. Processors and readers are created by the
18
+ * caller's factories, which keeps this module free of Node imports and browser
19
+ * exporter policy. Every factory is owned: it runs once during layer
20
+ * acquisition, after resource validation, and the layer scope shuts down
21
+ * everything it returned. An empty array installs nothing for that signal.
22
+ *
23
+ * @category models
24
+ * @since 0.1.0
25
+ */
26
+ export interface Options {
27
+ readonly resource: ResourceConfiguration
28
+ readonly spanProcessor?: (() => SpanProcessor | ReadonlyArray<SpanProcessor>) | undefined
29
+ readonly logRecordProcessor?: (() => LogRecordProcessor | ReadonlyArray<LogRecordProcessor>) | undefined
30
+ readonly metricReader?: (() => MetricReader | ReadonlyArray<MetricReader>) | undefined
31
+ readonly loggerMergeWithExisting?: boolean | undefined
32
+ }
33
+
34
+ /**
35
+ * Builds a scoped browser OpenTelemetry layer. The web SDK owns every
36
+ * processor and reader the factories return and shuts them down on release.
37
+ *
38
+ * @category layers
39
+ * @since 0.1.0
40
+ */
41
+ export const layerOtel = (options: Options): Layer.Layer<never, Resource.InvalidResourceConfiguration> =>
42
+ Layer.unwrap(
43
+ Effect.map(Resource.decode(options.resource), (decoded) =>
44
+ WebSdk.layer(() => ({
45
+ resource: Resource.toOpenTelemetryConfiguration(decoded),
46
+ spanProcessor: options.spanProcessor?.(),
47
+ logRecordProcessor: options.logRecordProcessor?.(),
48
+ metricReader: options.metricReader?.(),
49
+ loggerMergeWithExisting: options.loggerMergeWithExisting
50
+ })))
51
+ )