@effect/opentelemetry 0.60.0 → 4.0.0-beta.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 (160) hide show
  1. package/LICENSE +1 -1
  2. package/dist/{dts/Logger.d.ts → Logger.d.ts} +19 -13
  3. package/dist/Logger.d.ts.map +1 -0
  4. package/dist/Logger.js +76 -0
  5. package/dist/Logger.js.map +1 -0
  6. package/dist/Metrics.d.ts +76 -0
  7. package/dist/Metrics.d.ts.map +1 -0
  8. package/dist/Metrics.js +59 -0
  9. package/dist/Metrics.js.map +1 -0
  10. package/dist/{dts/NodeSdk.d.ts → NodeSdk.d.ts} +12 -9
  11. package/dist/NodeSdk.d.ts.map +1 -0
  12. package/dist/{esm/NodeSdk.js → NodeSdk.js} +23 -14
  13. package/dist/NodeSdk.js.map +1 -0
  14. package/dist/{dts/Resource.d.ts → Resource.d.ts} +10 -13
  15. package/dist/Resource.d.ts.map +1 -0
  16. package/dist/{esm/Resource.js → Resource.js} +12 -13
  17. package/dist/Resource.js.map +1 -0
  18. package/dist/Tracer.d.ts +129 -0
  19. package/dist/Tracer.d.ts.map +1 -0
  20. package/dist/Tracer.js +391 -0
  21. package/dist/Tracer.js.map +1 -0
  22. package/dist/{dts/WebSdk.d.ts → WebSdk.d.ts} +12 -9
  23. package/dist/WebSdk.d.ts.map +1 -0
  24. package/dist/WebSdk.js +41 -0
  25. package/dist/WebSdk.js.map +1 -0
  26. package/dist/index.d.ts +28 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/{esm/index.js → index.js} +4 -20
  29. package/dist/index.js.map +1 -0
  30. package/dist/internal/attributes.d.ts +2 -0
  31. package/dist/internal/attributes.d.ts.map +1 -0
  32. package/dist/internal/attributes.js +19 -0
  33. package/dist/internal/attributes.js.map +1 -0
  34. package/dist/{dts/internal → internal}/metrics.d.ts.map +1 -1
  35. package/dist/internal/metrics.js +406 -0
  36. package/dist/internal/metrics.js.map +1 -0
  37. package/dist/internal/utilities.d.ts +2 -0
  38. package/dist/internal/utilities.d.ts.map +1 -0
  39. package/dist/internal/utilities.js +3 -0
  40. package/dist/internal/utilities.js.map +1 -0
  41. package/package.json +70 -118
  42. package/src/Logger.ts +52 -55
  43. package/src/Metrics.ts +92 -18
  44. package/src/NodeSdk.ts +67 -64
  45. package/src/Resource.ts +16 -24
  46. package/src/Tracer.ts +469 -78
  47. package/src/WebSdk.ts +59 -51
  48. package/src/index.ts +7 -26
  49. package/src/internal/attributes.ts +21 -0
  50. package/src/internal/metrics.ts +381 -250
  51. package/src/internal/utilities.ts +5 -0
  52. package/Logger/package.json +0 -6
  53. package/Metrics/package.json +0 -6
  54. package/NodeSdk/package.json +0 -6
  55. package/Otlp/package.json +0 -6
  56. package/OtlpLogger/package.json +0 -6
  57. package/OtlpMetrics/package.json +0 -6
  58. package/OtlpResource/package.json +0 -6
  59. package/OtlpTracer/package.json +0 -6
  60. package/Resource/package.json +0 -6
  61. package/Tracer/package.json +0 -6
  62. package/WebSdk/package.json +0 -6
  63. package/dist/cjs/Logger.js +0 -85
  64. package/dist/cjs/Logger.js.map +0 -1
  65. package/dist/cjs/Metrics.js +0 -24
  66. package/dist/cjs/Metrics.js.map +0 -1
  67. package/dist/cjs/NodeSdk.js +0 -53
  68. package/dist/cjs/NodeSdk.js.map +0 -1
  69. package/dist/cjs/Otlp.js +0 -46
  70. package/dist/cjs/Otlp.js.map +0 -1
  71. package/dist/cjs/OtlpLogger.js +0 -158
  72. package/dist/cjs/OtlpLogger.js.map +0 -1
  73. package/dist/cjs/OtlpMetrics.js +0 -354
  74. package/dist/cjs/OtlpMetrics.js.map +0 -1
  75. package/dist/cjs/OtlpResource.js +0 -136
  76. package/dist/cjs/OtlpResource.js.map +0 -1
  77. package/dist/cjs/OtlpTracer.js +0 -229
  78. package/dist/cjs/OtlpTracer.js.map +0 -1
  79. package/dist/cjs/Resource.js +0 -75
  80. package/dist/cjs/Resource.js.map +0 -1
  81. package/dist/cjs/Tracer.js +0 -87
  82. package/dist/cjs/Tracer.js.map +0 -1
  83. package/dist/cjs/WebSdk.js +0 -42
  84. package/dist/cjs/WebSdk.js.map +0 -1
  85. package/dist/cjs/index.js +0 -30
  86. package/dist/cjs/index.js.map +0 -1
  87. package/dist/cjs/internal/metrics.js +0 -288
  88. package/dist/cjs/internal/metrics.js.map +0 -1
  89. package/dist/cjs/internal/otlpExporter.js +0 -81
  90. package/dist/cjs/internal/otlpExporter.js.map +0 -1
  91. package/dist/cjs/internal/tracer.js +0 -299
  92. package/dist/cjs/internal/tracer.js.map +0 -1
  93. package/dist/cjs/internal/utils.js +0 -34
  94. package/dist/cjs/internal/utils.js.map +0 -1
  95. package/dist/dts/Logger.d.ts.map +0 -1
  96. package/dist/dts/Metrics.d.ts +0 -29
  97. package/dist/dts/Metrics.d.ts.map +0 -1
  98. package/dist/dts/NodeSdk.d.ts.map +0 -1
  99. package/dist/dts/Otlp.d.ts +0 -31
  100. package/dist/dts/Otlp.d.ts.map +0 -1
  101. package/dist/dts/OtlpLogger.d.ts +0 -46
  102. package/dist/dts/OtlpLogger.d.ts.map +0 -1
  103. package/dist/dts/OtlpMetrics.d.ts +0 -40
  104. package/dist/dts/OtlpMetrics.d.ts.map +0 -1
  105. package/dist/dts/OtlpResource.d.ts +0 -104
  106. package/dist/dts/OtlpResource.d.ts.map +0 -1
  107. package/dist/dts/OtlpTracer.d.ts +0 -49
  108. package/dist/dts/OtlpTracer.d.ts.map +0 -1
  109. package/dist/dts/Resource.d.ts.map +0 -1
  110. package/dist/dts/Tracer.d.ts +0 -143
  111. package/dist/dts/Tracer.d.ts.map +0 -1
  112. package/dist/dts/WebSdk.d.ts.map +0 -1
  113. package/dist/dts/index.d.ts +0 -45
  114. package/dist/dts/index.d.ts.map +0 -1
  115. package/dist/dts/internal/otlpExporter.d.ts +0 -2
  116. package/dist/dts/internal/otlpExporter.d.ts.map +0 -1
  117. package/dist/dts/internal/tracer.d.ts +0 -2
  118. package/dist/dts/internal/tracer.d.ts.map +0 -1
  119. package/dist/dts/internal/utils.d.ts +0 -2
  120. package/dist/dts/internal/utils.d.ts.map +0 -1
  121. package/dist/esm/Logger.js +0 -75
  122. package/dist/esm/Logger.js.map +0 -1
  123. package/dist/esm/Metrics.js +0 -17
  124. package/dist/esm/Metrics.js.map +0 -1
  125. package/dist/esm/NodeSdk.js.map +0 -1
  126. package/dist/esm/Otlp.js +0 -38
  127. package/dist/esm/Otlp.js.map +0 -1
  128. package/dist/esm/OtlpLogger.js +0 -150
  129. package/dist/esm/OtlpLogger.js.map +0 -1
  130. package/dist/esm/OtlpMetrics.js +0 -346
  131. package/dist/esm/OtlpMetrics.js.map +0 -1
  132. package/dist/esm/OtlpResource.js +0 -124
  133. package/dist/esm/OtlpResource.js.map +0 -1
  134. package/dist/esm/OtlpTracer.js +0 -221
  135. package/dist/esm/OtlpTracer.js.map +0 -1
  136. package/dist/esm/Resource.js.map +0 -1
  137. package/dist/esm/Tracer.js +0 -80
  138. package/dist/esm/Tracer.js.map +0 -1
  139. package/dist/esm/WebSdk.js +0 -33
  140. package/dist/esm/WebSdk.js.map +0 -1
  141. package/dist/esm/index.js.map +0 -1
  142. package/dist/esm/internal/metrics.js +0 -278
  143. package/dist/esm/internal/metrics.js.map +0 -1
  144. package/dist/esm/internal/otlpExporter.js +0 -74
  145. package/dist/esm/internal/otlpExporter.js.map +0 -1
  146. package/dist/esm/internal/tracer.js +0 -290
  147. package/dist/esm/internal/tracer.js.map +0 -1
  148. package/dist/esm/internal/utils.js +0 -23
  149. package/dist/esm/internal/utils.js.map +0 -1
  150. package/dist/esm/package.json +0 -4
  151. package/index/package.json +0 -6
  152. package/src/Otlp.ts +0 -66
  153. package/src/OtlpLogger.ts +0 -258
  154. package/src/OtlpMetrics.ts +0 -571
  155. package/src/OtlpResource.ts +0 -232
  156. package/src/OtlpTracer.ts +0 -349
  157. package/src/internal/otlpExporter.ts +0 -124
  158. package/src/internal/tracer.ts +0 -437
  159. package/src/internal/utils.ts +0 -31
  160. /package/dist/{dts/internal → internal}/metrics.d.ts +0 -0
@@ -1,437 +0,0 @@
1
- import * as OtelApi from "@opentelemetry/api"
2
- import * as OtelSemConv from "@opentelemetry/semantic-conventions"
3
- import * as Cause from "effect/Cause"
4
- import type * as Clock from "effect/Clock"
5
- import * as Context from "effect/Context"
6
- import * as Effect from "effect/Effect"
7
- import * as Exit from "effect/Exit"
8
- import { constTrue, dual } from "effect/Function"
9
- import * as Layer from "effect/Layer"
10
- import * as Option from "effect/Option"
11
- import * as EffectTracer from "effect/Tracer"
12
- import { Resource } from "../Resource.js"
13
- import type { OtelTraceFlags, OtelTracer, OtelTracerProvider, OtelTraceState } from "../Tracer.js"
14
- import { nanosToHrTime, recordToAttributes, unknownToAttributeValue } from "./utils.js"
15
-
16
- const OtelSpanTypeId = Symbol.for("@effect/opentelemetry/Tracer/OtelSpan")
17
-
18
- const kindMap = {
19
- "internal": OtelApi.SpanKind.INTERNAL,
20
- "client": OtelApi.SpanKind.CLIENT,
21
- "server": OtelApi.SpanKind.SERVER,
22
- "producer": OtelApi.SpanKind.PRODUCER,
23
- "consumer": OtelApi.SpanKind.CONSUMER
24
- }
25
-
26
- const getOtelParent = (tracer: OtelApi.TraceAPI, otelContext: OtelApi.Context, context: Context.Context<never>) => {
27
- const active = tracer.getSpan(otelContext)
28
- const otelParent = active ? active.spanContext() : undefined
29
- return otelParent
30
- ? Option.some(
31
- EffectTracer.externalSpan({
32
- spanId: otelParent.spanId,
33
- traceId: otelParent.traceId,
34
- sampled: (otelParent.traceFlags & 1) === 1,
35
- context
36
- })
37
- )
38
- : Option.none()
39
- }
40
-
41
- /** @internal */
42
- export class OtelSpan implements EffectTracer.Span {
43
- readonly [OtelSpanTypeId]: typeof OtelSpanTypeId
44
- readonly _tag = "Span"
45
-
46
- readonly span: OtelApi.Span
47
- readonly spanId: string
48
- readonly traceId: string
49
- readonly attributes = new Map<string, unknown>()
50
- readonly sampled: boolean
51
- readonly parent: Option.Option<EffectTracer.AnySpan>
52
- status: EffectTracer.SpanStatus
53
-
54
- constructor(
55
- contextApi: OtelApi.ContextAPI,
56
- traceApi: OtelApi.TraceAPI,
57
- tracer: OtelApi.Tracer,
58
- readonly name: string,
59
- effectParent: Option.Option<EffectTracer.AnySpan>,
60
- readonly context: Context.Context<never>,
61
- readonly links: Array<EffectTracer.SpanLink>,
62
- startTime: bigint,
63
- readonly kind: EffectTracer.SpanKind,
64
- options?: EffectTracer.SpanOptions
65
- ) {
66
- this[OtelSpanTypeId] = OtelSpanTypeId
67
- const active = contextApi.active()
68
- this.parent = effectParent._tag === "Some"
69
- ? effectParent
70
- : (options?.root !== true)
71
- ? getOtelParent(traceApi, active, context)
72
- : Option.none()
73
- this.span = tracer.startSpan(
74
- name,
75
- {
76
- startTime: nanosToHrTime(startTime),
77
- links: links.length > 0
78
- ? links.map((link) => ({
79
- context: makeSpanContext(link.span),
80
- attributes: recordToAttributes(link.attributes)
81
- }))
82
- : undefined as any,
83
- kind: kindMap[this.kind]
84
- },
85
- this.parent._tag === "Some"
86
- ? populateContext(active, this.parent.value, context)
87
- : OtelApi.trace.deleteSpan(active)
88
- )
89
- const spanContext = this.span.spanContext()
90
- this.spanId = spanContext.spanId
91
- this.traceId = spanContext.traceId
92
- this.status = {
93
- _tag: "Started",
94
- startTime
95
- }
96
- this.sampled = (spanContext.traceFlags & OtelApi.TraceFlags.SAMPLED) === OtelApi.TraceFlags.SAMPLED
97
- }
98
-
99
- attribute(key: string, value: unknown) {
100
- this.span.setAttribute(key, unknownToAttributeValue(value))
101
- this.attributes.set(key, value)
102
- }
103
-
104
- addLinks(links: ReadonlyArray<EffectTracer.SpanLink>): void {
105
- // eslint-disable-next-line no-restricted-syntax
106
- this.links.push(...links)
107
- this.span.addLinks(links.map((link) => ({
108
- context: makeSpanContext(link.span),
109
- attributes: recordToAttributes(link.attributes)
110
- })))
111
- }
112
-
113
- end(endTime: bigint, exit: Exit.Exit<unknown, unknown>) {
114
- const hrTime = nanosToHrTime(endTime)
115
- this.status = {
116
- _tag: "Ended",
117
- endTime,
118
- exit,
119
- startTime: this.status.startTime
120
- }
121
-
122
- if (exit._tag === "Success") {
123
- this.span.setStatus({ code: OtelApi.SpanStatusCode.OK })
124
- } else {
125
- if (Cause.isInterruptedOnly(exit.cause)) {
126
- this.span.setStatus({
127
- code: OtelApi.SpanStatusCode.OK,
128
- message: Cause.pretty(exit.cause)
129
- })
130
- this.span.setAttribute("span.label", "⚠︎ Interrupted")
131
- this.span.setAttribute("status.interrupted", true)
132
- } else {
133
- const firstError = Cause.prettyErrors(exit.cause)[0]
134
- if (firstError) {
135
- firstError.stack = Cause.pretty(exit.cause, { renderErrorCause: true })
136
- this.span.recordException(firstError, hrTime)
137
- this.span.setStatus({
138
- code: OtelApi.SpanStatusCode.ERROR,
139
- message: firstError.message
140
- })
141
- } else {
142
- // empty cause means no error
143
- this.span.setStatus({ code: OtelApi.SpanStatusCode.OK })
144
- }
145
- }
146
- }
147
- this.span.end(hrTime)
148
- }
149
-
150
- event(name: string, startTime: bigint, attributes?: Record<string, unknown>) {
151
- this.span.addEvent(
152
- name,
153
- attributes ? recordToAttributes(attributes) : undefined,
154
- nanosToHrTime(startTime)
155
- )
156
- }
157
- }
158
-
159
- /** @internal */
160
- export const TracerProvider = Context.GenericTag<OtelTracerProvider, OtelApi.TracerProvider>(
161
- "@effect/opentelemetry/Tracer/OtelTracerProvider"
162
- )
163
-
164
- /** @internal */
165
- export const Tracer = Context.GenericTag<OtelTracer, OtelApi.Tracer>("@effect/opentelemetry/Tracer/OtelTracer")
166
-
167
- /** @internal */
168
- export const make = Effect.map(Tracer, (tracer) =>
169
- EffectTracer.make({
170
- span(name, parent, context, links, startTime, kind, options) {
171
- return new OtelSpan(
172
- OtelApi.context,
173
- OtelApi.trace,
174
- tracer,
175
- name,
176
- parent,
177
- context,
178
- links.slice(),
179
- startTime,
180
- kind,
181
- options
182
- )
183
- },
184
- context(execution, fiber) {
185
- const currentSpan = fiber.currentSpan
186
-
187
- if (currentSpan === undefined) {
188
- return execution()
189
- }
190
-
191
- return OtelApi.context.with(
192
- populateContext(OtelApi.context.active(), currentSpan),
193
- execution
194
- )
195
- }
196
- }))
197
-
198
- /** @internal */
199
- export const traceFlagsTag = Context.GenericTag<OtelTraceFlags, OtelApi.TraceFlags>(
200
- "@effect/opentelemetry/Tracer/OtelTraceFlags"
201
- )
202
-
203
- /** @internal */
204
- export const traceStateTag = Context.GenericTag<OtelTraceState, OtelApi.TraceState>(
205
- "@effect/opentelemetry/Tracer/OtelTraceState"
206
- )
207
-
208
- /** @internal */
209
- export const makeExternalSpan = (options: {
210
- readonly traceId: string
211
- readonly spanId: string
212
- readonly traceFlags?: number | undefined
213
- readonly traceState?: string | OtelApi.TraceState | undefined
214
- }): EffectTracer.ExternalSpan => {
215
- let context = Context.empty()
216
-
217
- if (options.traceFlags !== undefined) {
218
- context = Context.add(context, traceFlagsTag, options.traceFlags)
219
- }
220
-
221
- if (typeof options.traceState === "string") {
222
- context = Option.match(createTraceState(options.traceState), {
223
- onNone: () => context,
224
- onSome: (traceState) => Context.add(context, traceStateTag, traceState)
225
- })
226
- } else if (options.traceState) {
227
- context = Context.add(context, traceStateTag, options.traceState)
228
- }
229
-
230
- return {
231
- _tag: "ExternalSpan",
232
- traceId: options.traceId,
233
- spanId: options.spanId,
234
- sampled: options.traceFlags !== undefined
235
- ? (options.traceFlags & OtelApi.TraceFlags.SAMPLED) === OtelApi.TraceFlags.SAMPLED
236
- : true,
237
- context
238
- }
239
- }
240
-
241
- const makeOtelSpan = (span: EffectTracer.Span, clock: Clock.Clock): OtelApi.Span => {
242
- const spanContext: OtelApi.SpanContext = {
243
- traceId: span.traceId,
244
- spanId: span.spanId,
245
- traceFlags: span.sampled ? OtelApi.TraceFlags.SAMPLED : OtelApi.TraceFlags.NONE,
246
- isRemote: false
247
- }
248
-
249
- let exit = Exit.void
250
-
251
- const self: OtelApi.Span = {
252
- spanContext: () => spanContext,
253
- setAttribute(key, value) {
254
- span.attribute(key, value)
255
- return self
256
- },
257
- setAttributes(attributes) {
258
- for (const [key, value] of Object.entries(attributes)) {
259
- span.attribute(key, value)
260
- }
261
- return self
262
- },
263
- addEvent(name) {
264
- let attributes: OtelApi.Attributes | undefined = undefined
265
- let startTime: OtelApi.TimeInput | undefined = undefined
266
- if (arguments.length === 3) {
267
- attributes = arguments[1]
268
- startTime = arguments[2]
269
- } else {
270
- startTime = arguments[1]
271
- }
272
- span.event(name, convertOtelTimeInput(startTime, clock), attributes)
273
- return self
274
- },
275
- addLink(link) {
276
- span.addLinks([{
277
- _tag: "SpanLink",
278
- span: makeExternalSpan(link.context),
279
- attributes: link.attributes ?? {}
280
- }])
281
- return self
282
- },
283
- addLinks(links) {
284
- span.addLinks(links.map((link) => ({
285
- _tag: "SpanLink",
286
- span: makeExternalSpan(link.context),
287
- attributes: link.attributes ?? {}
288
- })))
289
- return self
290
- },
291
- setStatus(status) {
292
- exit = OtelApi.SpanStatusCode.ERROR
293
- ? Exit.die(status.message ?? "Unknown error")
294
- : Exit.void
295
- return self
296
- },
297
- updateName: () => self,
298
- end(endTime) {
299
- const time = convertOtelTimeInput(endTime, clock)
300
- span.end(time, exit)
301
- return self
302
- },
303
- isRecording: constTrue,
304
- recordException(exception, timeInput) {
305
- const time = convertOtelTimeInput(timeInput, clock)
306
- const cause = Cause.fail(exception)
307
- const error = Cause.prettyErrors(cause)[0]
308
- span.event(error.message, time, {
309
- "exception.type": error.name,
310
- "exception.message": error.message,
311
- "exception.stacktrace": error.stack ?? ""
312
- })
313
- }
314
- }
315
- return self
316
- }
317
-
318
- const bigint1e6 = BigInt(1_000_000)
319
- const bigint1e9 = BigInt(1_000_000_000)
320
-
321
- const convertOtelTimeInput = (input: OtelApi.TimeInput | undefined, clock: Clock.Clock): bigint => {
322
- if (input === undefined) {
323
- return clock.unsafeCurrentTimeNanos()
324
- } else if (typeof input === "number") {
325
- return BigInt(Math.round(input * 1_000_000))
326
- } else if (input instanceof Date) {
327
- return BigInt(input.getTime()) * bigint1e6
328
- }
329
- const [seconds, nanos] = input
330
- return BigInt(seconds) * bigint1e9 + BigInt(nanos)
331
- }
332
-
333
- /** @internal */
334
- export const currentOtelSpan: Effect.Effect<OtelApi.Span, Cause.NoSuchElementException> = Effect.clockWith((clock) =>
335
- Effect.map(Effect.currentSpan, (span): OtelApi.Span => {
336
- if (OtelSpanTypeId in span) {
337
- return (span as OtelSpan).span
338
- }
339
- return makeOtelSpan(span, clock)
340
- })
341
- )
342
-
343
- /** @internal */
344
- export const layerGlobalProvider = Layer.sync(
345
- TracerProvider,
346
- () => OtelApi.trace.getTracerProvider()
347
- )
348
-
349
- /** @internal */
350
- export const layerTracer = Layer.effect(
351
- Tracer,
352
- Effect.flatMap(
353
- Effect.zip(Resource, TracerProvider),
354
- ([resource, provider]) =>
355
- Effect.sync(() =>
356
- provider.getTracer(
357
- resource.attributes[OtelSemConv.ATTR_SERVICE_NAME] as string,
358
- resource.attributes[OtelSemConv.ATTR_SERVICE_VERSION] as string
359
- )
360
- )
361
- )
362
- )
363
-
364
- /** @internal */
365
- export const layerGlobalTracer = layerTracer.pipe(
366
- Layer.provide(layerGlobalProvider)
367
- )
368
-
369
- /** @internal */
370
- export const layerGlobal = Layer.unwrapEffect(Effect.map(make, Layer.setTracer)).pipe(
371
- Layer.provideMerge(layerGlobalTracer)
372
- )
373
-
374
- /** @internal */
375
- export const layerWithoutOtelTracer = Layer.unwrapEffect(Effect.map(make, Layer.setTracer))
376
-
377
- /** @internal */
378
- export const layer = layerWithoutOtelTracer.pipe(
379
- Layer.provideMerge(layerTracer)
380
- )
381
-
382
- // -------------------------------------------------------------------------------------
383
- // utils
384
- // -------------------------------------------------------------------------------------
385
-
386
- const createTraceState = Option.liftThrowable(OtelApi.createTraceState)
387
-
388
- const populateContext = (
389
- otelContext: OtelApi.Context,
390
- span: EffectTracer.AnySpan,
391
- context?: Context.Context<never>
392
- ): OtelApi.Context =>
393
- span instanceof OtelSpan ?
394
- OtelApi.trace.setSpan(otelContext, span.span) :
395
- OtelApi.trace.setSpanContext(otelContext, makeSpanContext(span, context))
396
-
397
- const makeSpanContext = (span: EffectTracer.AnySpan, context?: Context.Context<never>): OtelApi.SpanContext => ({
398
- spanId: span.spanId,
399
- traceId: span.traceId,
400
- isRemote: span._tag === "ExternalSpan",
401
- traceFlags: Option.getOrElse(
402
- context ?
403
- extractTraceTag(span, context, traceFlagsTag) :
404
- Context.getOption(span.context, traceFlagsTag),
405
- () => OtelApi.TraceFlags.SAMPLED
406
- ),
407
- traceState: Option.getOrUndefined(
408
- context ?
409
- extractTraceTag(span, context, traceStateTag) :
410
- Context.getOption(span.context, traceStateTag)
411
- ) as OtelApi.TraceState
412
- })
413
-
414
- const extractTraceTag = <I, S>(
415
- parent: EffectTracer.AnySpan,
416
- context: Context.Context<never>,
417
- tag: Context.Tag<I, S>
418
- ) =>
419
- Option.orElse(
420
- Context.getOption(context, tag),
421
- () => Context.getOption(parent.context, tag)
422
- )
423
-
424
- /** @internal */
425
- export const withSpanContext = dual<
426
- (
427
- spanContext: OtelApi.SpanContext
428
- ) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, EffectTracer.ParentSpan>>,
429
- <A, E, R>(
430
- effect: Effect.Effect<A, E, R>,
431
- spanContext: OtelApi.SpanContext
432
- ) => Effect.Effect<A, E, Exclude<R, EffectTracer.ParentSpan>>
433
- >(2, <A, E, R>(
434
- effect: Effect.Effect<A, E, R>,
435
- spanContext: OtelApi.SpanContext
436
- ): Effect.Effect<A, E, Exclude<R, EffectTracer.ParentSpan>> =>
437
- Effect.withParentSpan(effect, makeExternalSpan(spanContext)))
@@ -1,31 +0,0 @@
1
- import type * as OtelApi from "@opentelemetry/api"
2
- import type { NonEmptyReadonlyArray } from "effect/Array"
3
- import * as Inspectable from "effect/Inspectable"
4
-
5
- const bigint1e9 = 1_000_000_000n
6
-
7
- /** @internal */
8
- export const nanosToHrTime = (timestamp: bigint): OtelApi.HrTime => {
9
- return [Number(timestamp / bigint1e9), Number(timestamp % bigint1e9)]
10
- }
11
-
12
- /** @internal */
13
- export const recordToAttributes = (value: Record<string, unknown>): OtelApi.Attributes =>
14
- Object.entries(value).reduce((acc, [key, value]) => {
15
- acc[key] = unknownToAttributeValue(value)
16
- return acc
17
- }, {} as OtelApi.Attributes)
18
-
19
- /** @internal */
20
- export const unknownToAttributeValue = (value: unknown): OtelApi.AttributeValue => {
21
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
22
- return value
23
- } else if (typeof value === "bigint") {
24
- return value.toString()
25
- }
26
- return Inspectable.toStringUnknown(value)
27
- }
28
-
29
- /** @internal */
30
- export const isNonEmpty = <A>(a: A | ReadonlyArray<A> | undefined): a is A | NonEmptyReadonlyArray<A> =>
31
- a !== undefined && !(Array.isArray(a) && a.length === 0)
File without changes