@effect/opentelemetry 4.0.0-beta.7 → 4.0.0-beta.71
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.
- package/dist/Logger.d.ts +86 -11
- package/dist/Logger.d.ts.map +1 -1
- package/dist/Logger.js +112 -25
- package/dist/Logger.js.map +1 -1
- package/dist/Metrics.d.ts +62 -14
- package/dist/Metrics.d.ts.map +1 -1
- package/dist/Metrics.js +23 -8
- package/dist/Metrics.js.map +1 -1
- package/dist/NodeSdk.d.ts +97 -12
- package/dist/NodeSdk.d.ts.map +1 -1
- package/dist/NodeSdk.js +28 -5
- package/dist/NodeSdk.js.map +1 -1
- package/dist/Resource.d.ts +73 -13
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +43 -13
- package/dist/Resource.js.map +1 -1
- package/dist/Tracer.d.ts +109 -51
- package/dist/Tracer.d.ts.map +1 -1
- package/dist/Tracer.js +122 -68
- package/dist/Tracer.js.map +1 -1
- package/dist/WebSdk.d.ts +104 -11
- package/dist/WebSdk.d.ts.map +1 -1
- package/dist/WebSdk.js +27 -4
- package/dist/WebSdk.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +7 -7
- package/dist/internal/attributes.js +5 -0
- package/dist/internal/attributes.js.map +1 -1
- package/dist/internal/metrics.js +5 -5
- package/dist/internal/metrics.js.map +1 -1
- package/package.json +20 -15
- package/src/Logger.ts +118 -25
- package/src/Metrics.ts +63 -15
- package/src/NodeSdk.ts +97 -12
- package/src/Resource.ts +74 -14
- package/src/Tracer.ts +155 -98
- package/src/WebSdk.ts +104 -11
- package/src/index.ts +7 -7
- package/src/internal/attributes.ts +7 -0
- package/src/internal/metrics.ts +6 -6
package/src/Tracer.ts
CHANGED
|
@@ -1,18 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Bridges Effect tracing into OpenTelemetry by installing an Effect `Tracer`
|
|
3
|
+
* that creates OpenTelemetry spans, records attributes, events, links, errors,
|
|
4
|
+
* and status, and keeps OpenTelemetry context active while traced effects run.
|
|
5
|
+
* Use this module when an application already has an OpenTelemetry
|
|
6
|
+
* `TracerProvider`, or when the Node and Web SDK layers should expose Effect
|
|
7
|
+
* spans to OTLP, console, or other OpenTelemetry-compatible exporters.
|
|
8
|
+
*
|
|
9
|
+
* The layer constructors wire Effect's tracer service to either the global
|
|
10
|
+
* OpenTelemetry tracer provider or an explicitly provided `OtelTracer`. This
|
|
11
|
+
* module does not create exporters or span processors by itself, so spans are
|
|
12
|
+
* exported only when the provider has been configured by the application or by
|
|
13
|
+
* the Node/Web SDK layers. Parentage is taken from Effect spans first and can
|
|
14
|
+
* also attach to the active OpenTelemetry context, while `makeExternalSpan` and
|
|
15
|
+
* `withSpanContext` are the entry points for continuing an incoming remote
|
|
16
|
+
* trace. Preserve `traceFlags` and `traceState` when building external spans;
|
|
17
|
+
* otherwise sampling defaults to sampled and trace state cannot be propagated.
|
|
18
|
+
*
|
|
19
|
+
* @since 4.0.0
|
|
3
20
|
*/
|
|
4
21
|
import * as Otel from "@opentelemetry/api"
|
|
5
22
|
import * as OtelSemConv from "@opentelemetry/semantic-conventions"
|
|
6
23
|
import * as Cause from "effect/Cause"
|
|
7
24
|
import type * as Clock from "effect/Clock"
|
|
25
|
+
import * as Context from "effect/Context"
|
|
8
26
|
import * as Effect from "effect/Effect"
|
|
9
27
|
import * as Exit from "effect/Exit"
|
|
10
28
|
import { constTrue, dual } from "effect/Function"
|
|
11
29
|
import * as Layer from "effect/Layer"
|
|
30
|
+
import * as Option from "effect/Option"
|
|
12
31
|
import * as Predicate from "effect/Predicate"
|
|
13
|
-
import * as ServiceMap from "effect/ServiceMap"
|
|
14
32
|
import * as Tracer from "effect/Tracer"
|
|
15
|
-
import { recordToAttributes, unknownToAttributeValue } from "./internal/attributes.ts"
|
|
33
|
+
import { nanosToHrTime, recordToAttributes, unknownToAttributeValue } from "./internal/attributes.ts"
|
|
16
34
|
import { Resource } from "./Resource.ts"
|
|
17
35
|
|
|
18
36
|
// =============================================================================
|
|
@@ -20,37 +38,45 @@ import { Resource } from "./Resource.ts"
|
|
|
20
38
|
// =============================================================================
|
|
21
39
|
|
|
22
40
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
41
|
+
* Context service containing the OpenTelemetry `Tracer` used to create spans for Effect tracing.
|
|
42
|
+
*
|
|
43
|
+
* @category services
|
|
44
|
+
* @since 4.0.0
|
|
25
45
|
*/
|
|
26
|
-
export class OtelTracer extends
|
|
46
|
+
export class OtelTracer extends Context.Service<
|
|
27
47
|
OtelTracer,
|
|
28
48
|
Otel.Tracer
|
|
29
49
|
>()("@effect/opentelemetry/Tracer") {}
|
|
30
50
|
|
|
31
51
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
52
|
+
* Context service containing the OpenTelemetry `TracerProvider` used to obtain tracers.
|
|
53
|
+
*
|
|
54
|
+
* @category services
|
|
55
|
+
* @since 4.0.0
|
|
34
56
|
*/
|
|
35
|
-
export class OtelTracerProvider extends
|
|
57
|
+
export class OtelTracerProvider extends Context.Service<
|
|
36
58
|
OtelTracerProvider,
|
|
37
59
|
Otel.TracerProvider
|
|
38
60
|
>()("@effect/opentelemetry/Tracer/OtelTracerProvider") {}
|
|
39
61
|
|
|
40
62
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
63
|
+
* Context service containing OpenTelemetry trace flags used when constructing external span contexts.
|
|
64
|
+
*
|
|
65
|
+
* @category services
|
|
66
|
+
* @since 4.0.0
|
|
43
67
|
*/
|
|
44
|
-
export class OtelTraceFlags extends
|
|
68
|
+
export class OtelTraceFlags extends Context.Service<
|
|
45
69
|
OtelTraceFlags,
|
|
46
70
|
Otel.TraceFlags
|
|
47
71
|
>()("@effect/opentelemetry/Tracer/OtelTraceFlags") {}
|
|
48
72
|
|
|
49
73
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
74
|
+
* Context service containing OpenTelemetry trace state used when constructing external span contexts.
|
|
75
|
+
*
|
|
76
|
+
* @category services
|
|
77
|
+
* @since 4.0.0
|
|
52
78
|
*/
|
|
53
|
-
export class OtelTraceState extends
|
|
79
|
+
export class OtelTraceState extends Context.Service<
|
|
54
80
|
OtelTraceState,
|
|
55
81
|
Otel.TraceState
|
|
56
82
|
>()("@effect/opentelemetry/Tracer/OtelTraceState") {}
|
|
@@ -60,8 +86,10 @@ export class OtelTraceState extends ServiceMap.Service<
|
|
|
60
86
|
// =============================================================================
|
|
61
87
|
|
|
62
88
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
89
|
+
* Creates an Effect `Tracer` implementation backed by the configured OpenTelemetry tracer.
|
|
90
|
+
*
|
|
91
|
+
* @category constructors
|
|
92
|
+
* @since 4.0.0
|
|
65
93
|
*/
|
|
66
94
|
export const make: Effect.Effect<Tracer.Tracer, never, OtelTracer> = Effect.map(
|
|
67
95
|
Effect.service(OtelTracer),
|
|
@@ -91,8 +119,10 @@ export const make: Effect.Effect<Tracer.Tracer, never, OtelTracer> = Effect.map(
|
|
|
91
119
|
)
|
|
92
120
|
|
|
93
121
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
122
|
+
* Creates an Effect external span from an OpenTelemetry span context, preserving trace flags and trace state when provided.
|
|
123
|
+
*
|
|
124
|
+
* @category constructors
|
|
125
|
+
* @since 4.0.0
|
|
96
126
|
*/
|
|
97
127
|
export const makeExternalSpan = (options: {
|
|
98
128
|
readonly traceId: string
|
|
@@ -100,22 +130,24 @@ export const makeExternalSpan = (options: {
|
|
|
100
130
|
readonly traceFlags?: number | undefined
|
|
101
131
|
readonly traceState?: string | Otel.TraceState | undefined
|
|
102
132
|
}): Tracer.ExternalSpan => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
133
|
+
const annotations = Context.mutate(Context.empty(), (annotations) => {
|
|
134
|
+
let next = annotations
|
|
135
|
+
if (options.traceFlags !== undefined) {
|
|
136
|
+
next = Context.add(next, OtelTraceFlags, options.traceFlags)
|
|
137
|
+
}
|
|
108
138
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
139
|
+
if (typeof options.traceState === "string") {
|
|
140
|
+
try {
|
|
141
|
+
next = Context.add(next, OtelTraceState, Otel.createTraceState(options.traceState))
|
|
142
|
+
} catch {
|
|
143
|
+
//
|
|
144
|
+
}
|
|
145
|
+
} else if (options.traceState) {
|
|
146
|
+
next = Context.add(next, OtelTraceState, options.traceState)
|
|
115
147
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
148
|
+
|
|
149
|
+
return next
|
|
150
|
+
})
|
|
119
151
|
|
|
120
152
|
return {
|
|
121
153
|
_tag: "ExternalSpan",
|
|
@@ -131,8 +163,10 @@ export const makeExternalSpan = (options: {
|
|
|
131
163
|
// =============================================================================
|
|
132
164
|
|
|
133
165
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
166
|
+
* Layer that provides the current global OpenTelemetry tracer provider.
|
|
167
|
+
*
|
|
168
|
+
* @category layers
|
|
169
|
+
* @since 4.0.0
|
|
136
170
|
*/
|
|
137
171
|
export const layerGlobalProvider: Layer.Layer<OtelTracerProvider> = Layer.sync(
|
|
138
172
|
OtelTracerProvider,
|
|
@@ -140,8 +174,10 @@ export const layerGlobalProvider: Layer.Layer<OtelTracerProvider> = Layer.sync(
|
|
|
140
174
|
)
|
|
141
175
|
|
|
142
176
|
/**
|
|
143
|
-
*
|
|
144
|
-
*
|
|
177
|
+
* Layer that creates an OpenTelemetry tracer from the provided tracer provider and resource metadata.
|
|
178
|
+
*
|
|
179
|
+
* @category layers
|
|
180
|
+
* @since 4.0.0
|
|
145
181
|
*/
|
|
146
182
|
export const layerTracer: Layer.Layer<OtelTracer, never, OtelTracerProvider | Resource> = Layer.effect(
|
|
147
183
|
OtelTracer,
|
|
@@ -156,30 +192,48 @@ export const layerTracer: Layer.Layer<OtelTracer, never, OtelTracerProvider | Re
|
|
|
156
192
|
)
|
|
157
193
|
|
|
158
194
|
/**
|
|
159
|
-
*
|
|
160
|
-
*
|
|
195
|
+
* Layer that creates an OpenTelemetry tracer from the global tracer provider and the current resource.
|
|
196
|
+
*
|
|
197
|
+
* @category layers
|
|
198
|
+
* @since 4.0.0
|
|
161
199
|
*/
|
|
162
200
|
export const layerGlobalTracer: Layer.Layer<OtelTracer, never, Resource> = layerTracer.pipe(
|
|
163
201
|
Layer.provide(layerGlobalProvider)
|
|
164
202
|
)
|
|
165
203
|
|
|
166
204
|
/**
|
|
167
|
-
*
|
|
168
|
-
*
|
|
205
|
+
* Layer that installs an Effect tracer backed by the global OpenTelemetry tracer provider.
|
|
206
|
+
*
|
|
207
|
+
* @category layers
|
|
208
|
+
* @since 4.0.0
|
|
169
209
|
*/
|
|
170
210
|
export const layerGlobal: Layer.Layer<OtelTracer, never, Resource> = Layer.effect(Tracer.Tracer, make).pipe(
|
|
171
211
|
Layer.provideMerge(layerGlobalTracer)
|
|
172
212
|
)
|
|
173
213
|
|
|
174
214
|
/**
|
|
175
|
-
*
|
|
176
|
-
*
|
|
215
|
+
* Layer that installs the Effect tracer using an `OtelTracer` already provided in the environment.
|
|
216
|
+
*
|
|
217
|
+
* @category layers
|
|
218
|
+
* @since 4.0.0
|
|
177
219
|
*/
|
|
178
220
|
export const layerWithoutOtelTracer: Layer.Layer<never, never, OtelTracer> = Layer.effect(Tracer.Tracer, make)
|
|
179
221
|
|
|
180
222
|
/**
|
|
181
|
-
*
|
|
182
|
-
*
|
|
223
|
+
* Layer that creates an OpenTelemetry tracer from a provider and resource, then installs it as the Effect tracer.
|
|
224
|
+
*
|
|
225
|
+
* **When to use**
|
|
226
|
+
*
|
|
227
|
+
* Use when your application already supplies an `OtelTracerProvider` and a
|
|
228
|
+
* `Resource`, and you want Effect spans to be created by an OpenTelemetry
|
|
229
|
+
* tracer derived from those services.
|
|
230
|
+
*
|
|
231
|
+
* @see {@link layerTracer} for creating only the OpenTelemetry tracer service
|
|
232
|
+
* @see {@link layerGlobal} for installing the Effect tracer from the global provider
|
|
233
|
+
* @see {@link layerWithoutOtelTracer} for installing an already-provided `OtelTracer`
|
|
234
|
+
*
|
|
235
|
+
* @category layers
|
|
236
|
+
* @since 4.0.0
|
|
183
237
|
*/
|
|
184
238
|
export const layer: Layer.Layer<OtelTracer, never, OtelTracerProvider | Resource> = layerWithoutOtelTracer.pipe(
|
|
185
239
|
Layer.provideMerge(layerTracer)
|
|
@@ -193,16 +247,17 @@ const bigint1e6 = BigInt(1_000_000)
|
|
|
193
247
|
const bigint1e9 = BigInt(1_000_000_000)
|
|
194
248
|
|
|
195
249
|
/**
|
|
196
|
-
*
|
|
250
|
+
* Gets the current OpenTelemetry span.
|
|
197
251
|
*
|
|
198
|
-
*
|
|
199
|
-
* `NodeSdk.layer`, etc.) and the lightweight OTLP module (`OtlpTracer.layer`).
|
|
252
|
+
* **Details**
|
|
200
253
|
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
254
|
+
* This accessor works with both the official OpenTelemetry API, such as
|
|
255
|
+
* `Tracer.layer` and `NodeSdk.layer`, and the lightweight OTLP module, such as
|
|
256
|
+
* `OtlpTracer.layer`. When using OTLP, the returned span is a wrapper that
|
|
257
|
+
* conforms to the OpenTelemetry `Span` interface.
|
|
203
258
|
*
|
|
204
|
-
* @since 1.0.0
|
|
205
259
|
* @category accessors
|
|
260
|
+
* @since 4.0.0
|
|
206
261
|
*/
|
|
207
262
|
export const currentOtelSpan: Effect.Effect<Otel.Span, Cause.NoSuchElementError> = Effect.clockWith((clock) =>
|
|
208
263
|
Effect.map(Effect.currentSpan, (span) =>
|
|
@@ -299,35 +354,41 @@ const convertOtelTimeInput = (input: Otel.TimeInput | undefined, clock: Clock.Cl
|
|
|
299
354
|
}
|
|
300
355
|
|
|
301
356
|
/**
|
|
302
|
-
*
|
|
357
|
+
* Sets an effect's parent span from the given OpenTelemetry `SpanContext`.
|
|
303
358
|
*
|
|
304
|
-
*
|
|
305
|
-
* attach to a parent span.
|
|
359
|
+
* **When to use**
|
|
306
360
|
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
361
|
+
* Use when OpenTelemetry instrumentation outside Effect has already
|
|
362
|
+
* produced a parent span context and an effect should continue that trace.
|
|
363
|
+
*
|
|
364
|
+
* @category propagation
|
|
365
|
+
* @since 4.0.0
|
|
309
366
|
*/
|
|
310
367
|
export const withSpanContext: {
|
|
311
368
|
/**
|
|
312
|
-
*
|
|
369
|
+
* Sets an effect's parent span from the given OpenTelemetry `SpanContext`.
|
|
370
|
+
*
|
|
371
|
+
* **When to use**
|
|
313
372
|
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
373
|
+
* Use when OpenTelemetry instrumentation outside Effect has already
|
|
374
|
+
* produced a parent span context and an effect should continue that trace.
|
|
316
375
|
*
|
|
317
|
-
* @
|
|
318
|
-
* @
|
|
376
|
+
* @category propagation
|
|
377
|
+
* @since 4.0.0
|
|
319
378
|
*/
|
|
320
379
|
(spanContext: Otel.SpanContext): <A, E, R>(
|
|
321
380
|
self: Effect.Effect<A, E, R>
|
|
322
381
|
) => Effect.Effect<A, E, Exclude<R, Tracer.ParentSpan>>
|
|
323
382
|
/**
|
|
324
|
-
*
|
|
383
|
+
* Sets an effect's parent span from the given OpenTelemetry `SpanContext`.
|
|
325
384
|
*
|
|
326
|
-
*
|
|
327
|
-
* attach to a parent span.
|
|
385
|
+
* **When to use**
|
|
328
386
|
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
387
|
+
* Use when OpenTelemetry instrumentation outside Effect has already
|
|
388
|
+
* produced a parent span context and an effect should continue that trace.
|
|
389
|
+
*
|
|
390
|
+
* @category propagation
|
|
391
|
+
* @since 4.0.0
|
|
331
392
|
*/
|
|
332
393
|
<A, E, R>(self: Effect.Effect<A, E, R>, spanContext: Otel.SpanContext): Effect.Effect<A, E, Exclude<R, Tracer.ParentSpan>>
|
|
333
394
|
} = dual(2, <A, E, R>(
|
|
@@ -356,14 +417,14 @@ export class OtelSpan implements Tracer.Span {
|
|
|
356
417
|
|
|
357
418
|
readonly name: string
|
|
358
419
|
readonly kind: Tracer.SpanKind
|
|
359
|
-
readonly annotations:
|
|
420
|
+
readonly annotations: Context.Context<never>
|
|
360
421
|
readonly links: Array<Tracer.SpanLink>
|
|
361
422
|
readonly span: Otel.Span
|
|
362
423
|
readonly spanId: string
|
|
363
424
|
readonly traceId: string
|
|
364
425
|
readonly attributes = new Map<string, unknown>()
|
|
365
426
|
readonly sampled: boolean
|
|
366
|
-
readonly parent: Tracer.AnySpan
|
|
427
|
+
readonly parent: Option.Option<Tracer.AnySpan>
|
|
367
428
|
status: Tracer.SpanStatus
|
|
368
429
|
|
|
369
430
|
constructor(
|
|
@@ -378,9 +439,9 @@ export class OtelSpan implements Tracer.Span {
|
|
|
378
439
|
this.links = options.links
|
|
379
440
|
this.kind = options.kind
|
|
380
441
|
const active = contextApi.active()
|
|
381
|
-
this.parent = options.
|
|
382
|
-
getOtelParent(traceApi, active, options.annotations)
|
|
383
|
-
|
|
442
|
+
this.parent = options.root !== true
|
|
443
|
+
? Option.orElse(options.parent, () => getOtelParent(traceApi, active, options.annotations))
|
|
444
|
+
: options.parent
|
|
384
445
|
this.span = tracer.startSpan(
|
|
385
446
|
options.name,
|
|
386
447
|
{
|
|
@@ -393,7 +454,9 @@ export class OtelSpan implements Tracer.Span {
|
|
|
393
454
|
: undefined as any,
|
|
394
455
|
kind: kindMap[this.kind]
|
|
395
456
|
},
|
|
396
|
-
|
|
457
|
+
Option.isSome(this.parent) ?
|
|
458
|
+
populateContext(active, this.parent.value, options.annotations) :
|
|
459
|
+
Otel.trace.deleteSpan(active)
|
|
397
460
|
)
|
|
398
461
|
const spanContext = this.span.spanContext()
|
|
399
462
|
this.spanId = spanContext.spanId
|
|
@@ -469,30 +532,24 @@ export class OtelSpan implements Tracer.Span {
|
|
|
469
532
|
const isSampled = (traceFlags: Otel.TraceFlags): boolean =>
|
|
470
533
|
(traceFlags & Otel.TraceFlags.SAMPLED) === Otel.TraceFlags.SAMPLED
|
|
471
534
|
|
|
472
|
-
const nanosToHrTime = (timestamp: bigint): Otel.HrTime => {
|
|
473
|
-
return [Number(timestamp / bigint1e9), Number(timestamp % bigint1e9)]
|
|
474
|
-
}
|
|
475
|
-
|
|
476
535
|
const getOtelParent = (
|
|
477
536
|
tracer: Otel.TraceAPI,
|
|
478
537
|
context: Otel.Context,
|
|
479
|
-
annotations:
|
|
480
|
-
): Tracer.AnySpan
|
|
481
|
-
const
|
|
482
|
-
|
|
483
|
-
return
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
})
|
|
490
|
-
: undefined
|
|
538
|
+
annotations: Context.Context<never>
|
|
539
|
+
): Option.Option<Tracer.AnySpan> => {
|
|
540
|
+
const otelParent = tracer.getSpan(context)?.spanContext()
|
|
541
|
+
if (!otelParent) return Option.none()
|
|
542
|
+
return Option.some(Tracer.externalSpan({
|
|
543
|
+
spanId: otelParent.spanId,
|
|
544
|
+
traceId: otelParent.traceId,
|
|
545
|
+
sampled: (otelParent.traceFlags & 1) === 1,
|
|
546
|
+
annotations
|
|
547
|
+
}))
|
|
491
548
|
}
|
|
492
549
|
|
|
493
550
|
const makeSpanContext = (
|
|
494
551
|
span: Tracer.AnySpan,
|
|
495
|
-
annotations?:
|
|
552
|
+
annotations?: Context.Context<never>
|
|
496
553
|
): Otel.SpanContext => {
|
|
497
554
|
const traceFlags = makeTraceFlags(span, annotations)
|
|
498
555
|
const traceState = makeTraceState(span, annotations)!
|
|
@@ -507,13 +564,13 @@ const makeSpanContext = (
|
|
|
507
564
|
|
|
508
565
|
const makeTraceFlags = (
|
|
509
566
|
span: Tracer.AnySpan,
|
|
510
|
-
annotations:
|
|
567
|
+
annotations: Context.Context<never> | undefined
|
|
511
568
|
): Otel.TraceFlags => {
|
|
512
569
|
let traceFlags: Otel.TraceFlags | undefined
|
|
513
570
|
if (Predicate.isNotUndefined(annotations)) {
|
|
514
571
|
traceFlags = extractTraceService(span, annotations, OtelTraceFlags)
|
|
515
572
|
if (Predicate.isUndefined(traceFlags)) {
|
|
516
|
-
traceFlags =
|
|
573
|
+
traceFlags = Context.getOrUndefined(span.annotations, OtelTraceFlags)
|
|
517
574
|
}
|
|
518
575
|
}
|
|
519
576
|
return traceFlags ?? Otel.TraceFlags.SAMPLED
|
|
@@ -521,13 +578,13 @@ const makeTraceFlags = (
|
|
|
521
578
|
|
|
522
579
|
const makeTraceState = (
|
|
523
580
|
span: Tracer.AnySpan,
|
|
524
|
-
annotations:
|
|
581
|
+
annotations: Context.Context<never> | undefined
|
|
525
582
|
): Otel.TraceState | undefined => {
|
|
526
583
|
let traceState: Otel.TraceState | undefined
|
|
527
584
|
if (Predicate.isNotUndefined(annotations)) {
|
|
528
585
|
traceState = extractTraceService(span, annotations, OtelTraceState)
|
|
529
586
|
if (Predicate.isUndefined(traceState)) {
|
|
530
|
-
traceState =
|
|
587
|
+
traceState = Context.getOrUndefined(span.annotations, OtelTraceState)
|
|
531
588
|
}
|
|
532
589
|
}
|
|
533
590
|
return traceState
|
|
@@ -535,20 +592,20 @@ const makeTraceState = (
|
|
|
535
592
|
|
|
536
593
|
const extractTraceService = <I, S>(
|
|
537
594
|
parent: Tracer.AnySpan,
|
|
538
|
-
annotations:
|
|
539
|
-
service:
|
|
595
|
+
annotations: Context.Context<never>,
|
|
596
|
+
service: Context.Service<I, S>
|
|
540
597
|
) => {
|
|
541
|
-
const instance =
|
|
598
|
+
const instance = Context.getOrUndefined(annotations, service)
|
|
542
599
|
if (Predicate.isNotUndefined(instance)) {
|
|
543
600
|
return instance
|
|
544
601
|
}
|
|
545
|
-
return
|
|
602
|
+
return Context.getOrUndefined(parent.annotations, service)
|
|
546
603
|
}
|
|
547
604
|
|
|
548
605
|
const populateContext = (
|
|
549
606
|
context: Otel.Context,
|
|
550
607
|
span: Tracer.AnySpan,
|
|
551
|
-
annotations?:
|
|
608
|
+
annotations?: Context.Context<never> | undefined
|
|
552
609
|
): Otel.Context =>
|
|
553
610
|
span instanceof OtelSpan ?
|
|
554
611
|
Otel.trace.setSpan(context, span.span) :
|
package/src/WebSdk.ts
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Provides an Effect layer for configuring OpenTelemetry in browser
|
|
3
|
+
* applications. The module builds a shared resource from explicit service
|
|
4
|
+
* metadata and wires Effect tracing, metrics, and logging into OpenTelemetry
|
|
5
|
+
* SDK providers when span processors, metric readers, or log record processors
|
|
6
|
+
* are supplied.
|
|
7
|
+
*
|
|
8
|
+
* Use this module in client-side applications that need Effect spans, metrics,
|
|
9
|
+
* and logs exported from browser runtimes, such as single-page apps,
|
|
10
|
+
* multi-page apps with hydrated Effect code, frontend workers, or UI flows
|
|
11
|
+
* that should be correlated with backend traces. Telemetry is enabled only for
|
|
12
|
+
* the configured signal types, so tracing, metrics, and logging can be
|
|
13
|
+
* installed independently from the same layer.
|
|
14
|
+
*
|
|
15
|
+
* Browser SDKs cannot rely on process environment resource configuration, so
|
|
16
|
+
* provide stable service metadata explicitly and use resource attributes for
|
|
17
|
+
* application, release, deployment, or page-shell identity rather than
|
|
18
|
+
* per-event data. This module does not create exporters; supply
|
|
19
|
+
* browser-compatible processors, readers, and exporters yourself, and make sure
|
|
20
|
+
* their endpoints are reachable from the browser with the required CORS and
|
|
21
|
+
* authentication behavior. The layer is scoped: tracer providers are
|
|
22
|
+
* force-flushed and shut down when the scope is released, while metric readers
|
|
23
|
+
* and logger providers follow their respective layer lifecycles. Keep the
|
|
24
|
+
* scope alive for the lifetime of the browser application and release it during
|
|
25
|
+
* application teardown when possible so batched exporters and periodic metric
|
|
26
|
+
* readers can deliver buffered telemetry before the page is unloaded.
|
|
27
|
+
*
|
|
28
|
+
* @since 4.0.0
|
|
3
29
|
*/
|
|
4
30
|
import type * as Otel from "@opentelemetry/api"
|
|
5
31
|
import type { LoggerProviderConfig, LogRecordProcessor } from "@opentelemetry/sdk-logs"
|
|
@@ -17,8 +43,10 @@ import * as Resource from "./Resource.ts"
|
|
|
17
43
|
import * as Tracer from "./Tracer.ts"
|
|
18
44
|
|
|
19
45
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
46
|
+
* Configuration for the Web OpenTelemetry layer, including resource metadata and optional tracing, metrics, and logging settings.
|
|
47
|
+
*
|
|
48
|
+
* @category models
|
|
49
|
+
* @since 4.0.0
|
|
22
50
|
*/
|
|
23
51
|
export interface Configuration {
|
|
24
52
|
readonly spanProcessor?: SpanProcessor | ReadonlyArray<SpanProcessor> | undefined
|
|
@@ -36,8 +64,10 @@ export interface Configuration {
|
|
|
36
64
|
}
|
|
37
65
|
|
|
38
66
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
67
|
+
* Creates a scoped Web OpenTelemetry tracer provider from one or more span processors and shuts it down when the layer is released.
|
|
68
|
+
*
|
|
69
|
+
* @category layers
|
|
70
|
+
* @since 4.0.0
|
|
41
71
|
*/
|
|
42
72
|
export const layerTracerProvider = (
|
|
43
73
|
processor: SpanProcessor | NonEmptyReadonlyArray<SpanProcessor>,
|
|
@@ -65,18 +95,81 @@ export const layerTracerProvider = (
|
|
|
65
95
|
)
|
|
66
96
|
|
|
67
97
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
98
|
+
* Creates a Web OpenTelemetry layer from configuration, providing the resource and enabling tracing, metrics, and logging when configured.
|
|
99
|
+
*
|
|
100
|
+
* **When to use**
|
|
101
|
+
*
|
|
102
|
+
* Use to install browser OpenTelemetry support for an Effect application when
|
|
103
|
+
* service metadata is provided in code and tracing, metrics, or logging should
|
|
104
|
+
* be enabled from supplied span processors, metric readers, or log record
|
|
105
|
+
* processors.
|
|
106
|
+
*
|
|
107
|
+
* **Details**
|
|
108
|
+
*
|
|
109
|
+
* The configuration can be provided lazily or effectfully. The layer always
|
|
110
|
+
* provides `Resource.Resource`; tracing, metrics, and logging are installed only
|
|
111
|
+
* when the corresponding processors or readers are non-empty.
|
|
112
|
+
*
|
|
113
|
+
* **Gotchas**
|
|
114
|
+
*
|
|
115
|
+
* Browser resource metadata is explicit; this layer does not read
|
|
116
|
+
* OpenTelemetry environment variables. Empty processor or reader arrays are
|
|
117
|
+
* treated as not configured.
|
|
118
|
+
*
|
|
119
|
+
* @category layers
|
|
120
|
+
* @since 4.0.0
|
|
70
121
|
*/
|
|
71
122
|
export const layer: {
|
|
72
123
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
124
|
+
* Creates a Web OpenTelemetry layer from configuration, providing the resource and enabling tracing, metrics, and logging when configured.
|
|
125
|
+
*
|
|
126
|
+
* **When to use**
|
|
127
|
+
*
|
|
128
|
+
* Use to install browser OpenTelemetry support for an Effect application when
|
|
129
|
+
* service metadata is provided in code and tracing, metrics, or logging should
|
|
130
|
+
* be enabled from supplied span processors, metric readers, or log record
|
|
131
|
+
* processors.
|
|
132
|
+
*
|
|
133
|
+
* **Details**
|
|
134
|
+
*
|
|
135
|
+
* The configuration can be provided lazily or effectfully. The layer always
|
|
136
|
+
* provides `Resource.Resource`; tracing, metrics, and logging are installed only
|
|
137
|
+
* when the corresponding processors or readers are non-empty.
|
|
138
|
+
*
|
|
139
|
+
* **Gotchas**
|
|
140
|
+
*
|
|
141
|
+
* Browser resource metadata is explicit; this layer does not read
|
|
142
|
+
* OpenTelemetry environment variables. Empty processor or reader arrays are
|
|
143
|
+
* treated as not configured.
|
|
144
|
+
*
|
|
145
|
+
* @category layers
|
|
146
|
+
* @since 4.0.0
|
|
75
147
|
*/
|
|
76
148
|
(evaluate: LazyArg<Configuration>): Layer.Layer<Resource.Resource>
|
|
77
149
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
150
|
+
* Creates a Web OpenTelemetry layer from configuration, providing the resource and enabling tracing, metrics, and logging when configured.
|
|
151
|
+
*
|
|
152
|
+
* **When to use**
|
|
153
|
+
*
|
|
154
|
+
* Use to install browser OpenTelemetry support for an Effect application when
|
|
155
|
+
* service metadata is provided in code and tracing, metrics, or logging should
|
|
156
|
+
* be enabled from supplied span processors, metric readers, or log record
|
|
157
|
+
* processors.
|
|
158
|
+
*
|
|
159
|
+
* **Details**
|
|
160
|
+
*
|
|
161
|
+
* The configuration can be provided lazily or effectfully. The layer always
|
|
162
|
+
* provides `Resource.Resource`; tracing, metrics, and logging are installed only
|
|
163
|
+
* when the corresponding processors or readers are non-empty.
|
|
164
|
+
*
|
|
165
|
+
* **Gotchas**
|
|
166
|
+
*
|
|
167
|
+
* Browser resource metadata is explicit; this layer does not read
|
|
168
|
+
* OpenTelemetry environment variables. Empty processor or reader arrays are
|
|
169
|
+
* treated as not configured.
|
|
170
|
+
*
|
|
171
|
+
* @category layers
|
|
172
|
+
* @since 4.0.0
|
|
80
173
|
*/
|
|
81
174
|
<E, R>(evaluate: Effect.Effect<Configuration, E, R>): Layer.Layer<Resource.Resource, E, R>
|
|
82
175
|
} = (
|
package/src/index.ts
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since
|
|
2
|
+
* @since 4.0.0
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
// @barrel: Auto-generated exports. Do not edit manually.
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @since
|
|
8
|
+
* @since 4.0.0
|
|
9
9
|
*/
|
|
10
10
|
export * as Logger from "./Logger.ts"
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* @since
|
|
13
|
+
* @since 4.0.0
|
|
14
14
|
*/
|
|
15
15
|
export * as Metrics from "./Metrics.ts"
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* @since
|
|
18
|
+
* @since 4.0.0
|
|
19
19
|
*/
|
|
20
20
|
export * as NodeSdk from "./NodeSdk.ts"
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* @since
|
|
23
|
+
* @since 4.0.0
|
|
24
24
|
*/
|
|
25
25
|
export * as Resource from "./Resource.ts"
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* @since
|
|
28
|
+
* @since 4.0.0
|
|
29
29
|
*/
|
|
30
30
|
export * as Tracer from "./Tracer.ts"
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
* @since
|
|
33
|
+
* @since 4.0.0
|
|
34
34
|
*/
|
|
35
35
|
export * as WebSdk from "./WebSdk.ts"
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type * as Otel from "@opentelemetry/api"
|
|
2
2
|
import * as Inspectable from "effect/Inspectable"
|
|
3
3
|
|
|
4
|
+
const bigint1e9 = BigInt(1_000_000_000)
|
|
5
|
+
|
|
6
|
+
/** @internal */
|
|
7
|
+
export const nanosToHrTime = (timestamp: bigint): Otel.HrTime => {
|
|
8
|
+
return [Number(timestamp / bigint1e9), Number(timestamp % bigint1e9)]
|
|
9
|
+
}
|
|
10
|
+
|
|
4
11
|
/** @internal */
|
|
5
12
|
export const recordToAttributes = (record: Record<string, unknown>): Otel.Attributes => {
|
|
6
13
|
const attributes: Otel.Attributes = {}
|