@effect/opentelemetry 0.20.0 → 0.21.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 (37) hide show
  1. package/NodeSdk/dist/effect-opentelemetry-NodeSdk.cjs.dev.js +17 -13
  2. package/NodeSdk/dist/effect-opentelemetry-NodeSdk.cjs.mjs +2 -2
  3. package/NodeSdk/dist/effect-opentelemetry-NodeSdk.cjs.prod.js +17 -13
  4. package/NodeSdk/dist/effect-opentelemetry-NodeSdk.esm.js +16 -15
  5. package/Tracer/dist/effect-opentelemetry-Tracer.cjs.dev.js +44 -11
  6. package/Tracer/dist/effect-opentelemetry-Tracer.cjs.mjs +5 -2
  7. package/Tracer/dist/effect-opentelemetry-Tracer.cjs.prod.js +44 -11
  8. package/Tracer/dist/effect-opentelemetry-Tracer.esm.js +22 -4
  9. package/WebSdk/dist/effect-opentelemetry-WebSdk.cjs.d.mts +2 -0
  10. package/WebSdk/dist/effect-opentelemetry-WebSdk.cjs.d.mts.map +1 -0
  11. package/WebSdk/dist/effect-opentelemetry-WebSdk.cjs.d.ts +2 -0
  12. package/WebSdk/dist/effect-opentelemetry-WebSdk.cjs.d.ts.map +1 -0
  13. package/WebSdk/dist/effect-opentelemetry-WebSdk.cjs.dev.js +81 -0
  14. package/WebSdk/dist/effect-opentelemetry-WebSdk.cjs.js +7 -0
  15. package/WebSdk/dist/effect-opentelemetry-WebSdk.cjs.mjs +4 -0
  16. package/WebSdk/dist/effect-opentelemetry-WebSdk.cjs.prod.js +81 -0
  17. package/WebSdk/dist/effect-opentelemetry-WebSdk.esm.js +42 -0
  18. package/WebSdk/package.json +4 -0
  19. package/dist/declarations/src/NodeSdk.d.ts +18 -6
  20. package/dist/declarations/src/NodeSdk.d.ts.map +1 -1
  21. package/dist/declarations/src/Tracer.d.ts +20 -5
  22. package/dist/declarations/src/Tracer.d.ts.map +1 -1
  23. package/dist/declarations/src/WebSdk.d.ts +35 -0
  24. package/dist/declarations/src/WebSdk.d.ts.map +1 -0
  25. package/dist/declarations/src/index.d.ts +4 -0
  26. package/dist/declarations/src/index.d.ts.map +1 -1
  27. package/dist/effect-opentelemetry.cjs.dev.js +3 -0
  28. package/dist/effect-opentelemetry.cjs.mjs +2 -1
  29. package/dist/effect-opentelemetry.cjs.prod.js +3 -0
  30. package/dist/effect-opentelemetry.esm.js +2 -0
  31. package/internal/tracer.esm.js +19 -7
  32. package/package.json +25 -15
  33. package/src/NodeSdk.ts +53 -25
  34. package/src/Tracer.ts +23 -5
  35. package/src/WebSdk.ts +79 -0
  36. package/src/index.ts +5 -0
  37. package/src/internal/tracer.ts +40 -22
package/src/Tracer.ts CHANGED
@@ -6,7 +6,7 @@ import type { Tag } from "effect/Context"
6
6
  import type { Effect } from "effect/Effect"
7
7
  import type { Layer } from "effect/Layer"
8
8
  import type * as Option from "effect/Option"
9
- import type { ExternalSpan, Tracer } from "effect/Tracer"
9
+ import type { ExternalSpan, Tracer as EffectTracer } from "effect/Tracer"
10
10
  import * as internal from "./internal/tracer"
11
11
  import type { Resource } from "./Resource"
12
12
 
@@ -14,7 +14,7 @@ import type { Resource } from "./Resource"
14
14
  * @since 1.0.0
15
15
  * @category constructors
16
16
  */
17
- export const make: Effect<Otel.Tracer, never, Tracer> = internal.make
17
+ export const make: Effect<Otel.Tracer, never, EffectTracer> = internal.make
18
18
 
19
19
  /**
20
20
  * @since 1.0.0
@@ -39,19 +39,37 @@ export const currentOtelSpan: Effect<never, never, Option.Option<Otel.Span>> = i
39
39
  * @since 1.0.0
40
40
  * @category layers
41
41
  */
42
- export const layer: Layer<Resource, never, never> = internal.layer
42
+ export const layer: Layer<Resource | Otel.TracerProvider, never, never> = internal.layer
43
43
 
44
44
  /**
45
45
  * @since 1.0.0
46
46
  * @category layers
47
47
  */
48
- export const layerOtelTracer: Layer<Resource, never, Otel.Tracer> = internal.layerOtelTracer
48
+ export const layerGlobal: Layer<Resource, never, never> = internal.layerGlobal
49
+
50
+ /**
51
+ * @since 1.0.0
52
+ * @category layers
53
+ */
54
+ export const layerTracer: Layer<Resource | Otel.TracerProvider, never, Otel.Tracer> = internal.layerTracer
55
+
56
+ /**
57
+ * @since 1.0.0
58
+ * @category layers
59
+ */
60
+ export const layerGlobalTracer: Layer<Resource, never, Otel.Tracer> = internal.layerGlobalTracer
61
+
62
+ /**
63
+ * @since 1.0.0
64
+ * @category tags
65
+ */
66
+ export const TracerProvider: Tag<Otel.TracerProvider, Otel.TracerProvider> = internal.TracerProvider
49
67
 
50
68
  /**
51
69
  * @since 1.0.0
52
70
  * @category tags
53
71
  */
54
- export const OtelTracer: Tag<Otel.Tracer, Otel.Tracer> = internal.OtelTracer
72
+ export const Tracer: Tag<Otel.Tracer, Otel.Tracer> = internal.Tracer
55
73
 
56
74
  /**
57
75
  * @since 1.0.0
package/src/WebSdk.ts ADDED
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+ import type { TracerProvider } from "@opentelemetry/api"
5
+ import type * as Resources from "@opentelemetry/resources"
6
+ import type { MetricReader } from "@opentelemetry/sdk-metrics"
7
+ import type { SpanProcessor, TracerConfig } from "@opentelemetry/sdk-trace-base"
8
+ import { WebTracerProvider } from "@opentelemetry/sdk-trace-web"
9
+ import * as Effect from "effect/Effect"
10
+ import type { LazyArg } from "effect/Function"
11
+ import * as Layer from "effect/Layer"
12
+ import * as Metrics from "./Metrics"
13
+ import * as Resource from "./Resource"
14
+ import * as Tracer from "./Tracer"
15
+
16
+ /**
17
+ * @since 1.0.0
18
+ * @category model
19
+ */
20
+ export interface Configuration {
21
+ readonly spanProcessor?: SpanProcessor
22
+ readonly tracerConfig?: Omit<TracerConfig, "resource">
23
+ readonly metricReader?: MetricReader
24
+ readonly resource: {
25
+ readonly serviceName: string
26
+ readonly serviceVersion?: string
27
+ readonly attributes?: Resources.ResourceAttributes
28
+ }
29
+ }
30
+
31
+ /**
32
+ * @since 1.0.0
33
+ * @category layers
34
+ */
35
+ export const layerTracerProvider = (
36
+ processor: SpanProcessor,
37
+ config?: Omit<TracerConfig, "resource">
38
+ ): Layer.Layer<Resource.Resource, never, TracerProvider> =>
39
+ Layer.scoped(
40
+ Tracer.TracerProvider,
41
+ Effect.flatMap(
42
+ Resource.Resource,
43
+ (resource) =>
44
+ Effect.acquireRelease(
45
+ Effect.sync(() => {
46
+ const provider = new WebTracerProvider({
47
+ ...(config ?? {}),
48
+ resource
49
+ })
50
+ provider.addSpanProcessor(processor)
51
+ return provider
52
+ }),
53
+ (provider) => Effect.promise(() => provider.shutdown())
54
+ )
55
+ )
56
+ )
57
+
58
+ /**
59
+ * @since 1.0.0
60
+ * @category layer
61
+ */
62
+ export const layer = (
63
+ evaluate: LazyArg<Configuration>
64
+ ): Layer.Layer<never, never, Resource.Resource> =>
65
+ Layer.unwrapEffect(
66
+ Effect.sync(() => {
67
+ const config = evaluate()
68
+ const ResourceLive = Resource.layer(config.resource)
69
+ const TracerLive = config.spanProcessor ?
70
+ Tracer.layer.pipe(Layer.use(layerTracerProvider(config.spanProcessor, config.tracerConfig)))
71
+ : Layer.effectDiscard(Effect.unit)
72
+ const MetricsLive = config.metricReader
73
+ ? Metrics.layer(() => config.metricReader!)
74
+ : Layer.effectDiscard(Effect.unit)
75
+ return Layer.merge(TracerLive, MetricsLive).pipe(
76
+ Layer.useMerge(ResourceLive)
77
+ )
78
+ })
79
+ )
package/src/index.ts CHANGED
@@ -17,3 +17,8 @@ export * as Resource from "@effect/opentelemetry/Resource"
17
17
  * @since 1.0.0
18
18
  */
19
19
  export * as Tracer from "@effect/opentelemetry/Tracer"
20
+
21
+ /**
22
+ * @since 1.0.0
23
+ */
24
+ export * as WebSdk from "@effect/opentelemetry/WebSdk"
@@ -6,11 +6,11 @@ import type { Exit } from "effect/Exit"
6
6
  import * as FiberRef from "effect/FiberRef"
7
7
  import * as Layer from "effect/Layer"
8
8
  import * as Option from "effect/Option"
9
- import * as Tracer from "effect/Tracer"
9
+ import * as EffectTracer from "effect/Tracer"
10
10
  import { Resource } from "../Resource"
11
11
 
12
12
  /** @internal */
13
- export class OtelSpan implements Tracer.Span {
13
+ export class OtelSpan implements EffectTracer.Span {
14
14
  readonly _tag = "Span"
15
15
 
16
16
  readonly span: OtelApi.Span
@@ -18,15 +18,15 @@ export class OtelSpan implements Tracer.Span {
18
18
  readonly traceId: string
19
19
  readonly attributes = new Map<string, unknown>()
20
20
  readonly sampled: boolean
21
- status: Tracer.SpanStatus
21
+ status: EffectTracer.SpanStatus
22
22
 
23
23
  constructor(
24
24
  contextApi: OtelApi.ContextAPI,
25
25
  tracer: OtelApi.Tracer,
26
26
  readonly name: string,
27
- readonly parent: Option.Option<Tracer.ParentSpan>,
27
+ readonly parent: Option.Option<EffectTracer.ParentSpan>,
28
28
  readonly context: Context.Context<never>,
29
- readonly links: ReadonlyArray<Tracer.SpanLink>,
29
+ readonly links: ReadonlyArray<EffectTracer.SpanLink>,
30
30
  startTime: bigint
31
31
  ) {
32
32
  const active = contextApi.active()
@@ -100,11 +100,14 @@ export class OtelSpan implements Tracer.Span {
100
100
  }
101
101
 
102
102
  /** @internal */
103
- export const OtelTracer = Context.Tag<OtelApi.Tracer>("@effect/opentelemetry/Tracer/OtelTracer")
103
+ export const TracerProvider = Context.Tag<OtelApi.TracerProvider>("@effect/opentelemetry/Tracer/TracerProvider")
104
104
 
105
105
  /** @internal */
106
- export const make = Effect.map(OtelTracer, (tracer) =>
107
- Tracer.make({
106
+ export const Tracer = Context.Tag<OtelApi.Tracer>("@effect/opentelemetry/Tracer/Tracer")
107
+
108
+ /** @internal */
109
+ export const make = Effect.map(Tracer, (tracer) =>
110
+ EffectTracer.make({
108
111
  span(name, parent, context, links, startTime) {
109
112
  return new OtelSpan(
110
113
  OtelApi.context,
@@ -117,8 +120,8 @@ export const make = Effect.map(OtelTracer, (tracer) =>
117
120
  )
118
121
  },
119
122
  context(execution, fiber) {
120
- const currentSpan = fiber.getFiberRef(FiberRef.currentContext).unsafeMap.get(Tracer.ParentSpan) as
121
- | Tracer.ParentSpan
123
+ const currentSpan = fiber.getFiberRef(FiberRef.currentContext).unsafeMap.get(EffectTracer.ParentSpan) as
124
+ | EffectTracer.ParentSpan
122
125
  | undefined
123
126
 
124
127
  if (currentSpan === undefined) {
@@ -144,7 +147,7 @@ export const makeExternalSpan = (options: {
144
147
  readonly spanId: string
145
148
  readonly traceFlags?: number
146
149
  readonly traceState?: string | OtelApi.TraceState
147
- }): Tracer.ExternalSpan => {
150
+ }): EffectTracer.ExternalSpan => {
148
151
  let context = Context.empty()
149
152
 
150
153
  if (options.traceFlags) {
@@ -182,13 +185,19 @@ export const currentOtelSpan = Effect.map(
182
185
  )
183
186
 
184
187
  /** @internal */
185
- export const layerOtelTracer = Layer.effect(
186
- OtelTracer,
188
+ export const layerGlobalProvider = Layer.sync(
189
+ TracerProvider,
190
+ () => OtelApi.trace.getTracerProvider()
191
+ )
192
+
193
+ /** @internal */
194
+ export const layerTracer = Layer.effect(
195
+ Tracer,
187
196
  Effect.flatMap(
188
- Resource,
189
- (resource) =>
197
+ Effect.zip(Resource, TracerProvider),
198
+ ([resource, provider]) =>
190
199
  Effect.sync(() =>
191
- OtelApi.trace.getTracer(
200
+ provider.getTracer(
192
201
  resource.attributes["service.name"] as string,
193
202
  resource.attributes["service.version"] as string
194
203
  )
@@ -197,9 +206,18 @@ export const layerOtelTracer = Layer.effect(
197
206
  )
198
207
 
199
208
  /** @internal */
200
- export const layer = Layer.provide(
201
- layerOtelTracer,
202
- Layer.unwrapEffect(Effect.map(make, Layer.setTracer))
209
+ export const layerGlobalTracer = layerTracer.pipe(
210
+ Layer.use(layerGlobalProvider)
211
+ )
212
+
213
+ /** @internal */
214
+ export const layerGlobal = Layer.unwrapEffect(Effect.map(make, Layer.setTracer)).pipe(
215
+ Layer.use(layerGlobalTracer)
216
+ )
217
+
218
+ /** @internal */
219
+ export const layer = Layer.unwrapEffect(Effect.map(make, Layer.setTracer)).pipe(
220
+ Layer.use(layerTracer)
203
221
  )
204
222
 
205
223
  // -------------------------------------------------------------------------------------
@@ -215,14 +233,14 @@ const createTraceState = Option.liftThrowable(OtelApi.createTraceState)
215
233
 
216
234
  const populateContext = (
217
235
  otelContext: OtelApi.Context,
218
- span: Tracer.ParentSpan,
236
+ span: EffectTracer.ParentSpan,
219
237
  context?: Context.Context<never>
220
238
  ): OtelApi.Context =>
221
239
  span instanceof OtelSpan ?
222
240
  OtelApi.trace.setSpan(otelContext, span.span) :
223
241
  OtelApi.trace.setSpanContext(otelContext, makeSpanContext(span, context))
224
242
 
225
- const makeSpanContext = (span: Tracer.ParentSpan, context?: Context.Context<never>): OtelApi.SpanContext => ({
243
+ const makeSpanContext = (span: EffectTracer.ParentSpan, context?: Context.Context<never>): OtelApi.SpanContext => ({
226
244
  spanId: span.spanId,
227
245
  traceId: span.traceId,
228
246
  isRemote: span._tag === "ExternalSpan",
@@ -240,7 +258,7 @@ const makeSpanContext = (span: Tracer.ParentSpan, context?: Context.Context<neve
240
258
  })
241
259
 
242
260
  const extractTraceTag = <I, S>(
243
- parent: Tracer.ParentSpan,
261
+ parent: EffectTracer.ParentSpan,
244
262
  context: Context.Context<never>,
245
263
  tag: Context.Tag<I, S>
246
264
  ) =>