@effect/opentelemetry 4.0.0-beta.6 → 4.0.0-beta.62
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 +18 -4
- package/dist/Logger.d.ts.map +1 -1
- package/dist/Logger.js +46 -16
- package/dist/Logger.js.map +1 -1
- package/dist/Metrics.d.ts +3 -3
- package/dist/Metrics.d.ts.map +1 -1
- package/dist/Metrics.js +1 -1
- package/dist/Metrics.js.map +1 -1
- package/dist/NodeSdk.d.ts +3 -3
- package/dist/NodeSdk.d.ts.map +1 -1
- package/dist/Resource.d.ts +2 -2
- package/dist/Resource.d.ts.map +1 -1
- package/dist/Resource.js +3 -3
- package/dist/Resource.js.map +1 -1
- package/dist/Tracer.d.ts +5 -5
- package/dist/Tracer.d.ts.map +1 -1
- package/dist/Tracer.js +32 -32
- package/dist/Tracer.js.map +1 -1
- 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 +50 -18
- package/src/Metrics.ts +4 -4
- package/src/NodeSdk.ts +3 -3
- package/src/Resource.ts +3 -3
- package/src/Tracer.ts +51 -52
- package/src/internal/attributes.ts +7 -0
- package/src/internal/metrics.ts +6 -6
package/src/Tracer.ts
CHANGED
|
@@ -5,14 +5,15 @@ import * as Otel from "@opentelemetry/api"
|
|
|
5
5
|
import * as OtelSemConv from "@opentelemetry/semantic-conventions"
|
|
6
6
|
import * as Cause from "effect/Cause"
|
|
7
7
|
import type * as Clock from "effect/Clock"
|
|
8
|
+
import * as Context from "effect/Context"
|
|
8
9
|
import * as Effect from "effect/Effect"
|
|
9
10
|
import * as Exit from "effect/Exit"
|
|
10
11
|
import { constTrue, dual } from "effect/Function"
|
|
11
12
|
import * as Layer from "effect/Layer"
|
|
13
|
+
import * as Option from "effect/Option"
|
|
12
14
|
import * as Predicate from "effect/Predicate"
|
|
13
|
-
import * as ServiceMap from "effect/ServiceMap"
|
|
14
15
|
import * as Tracer from "effect/Tracer"
|
|
15
|
-
import { recordToAttributes, unknownToAttributeValue } from "./internal/attributes.ts"
|
|
16
|
+
import { nanosToHrTime, recordToAttributes, unknownToAttributeValue } from "./internal/attributes.ts"
|
|
16
17
|
import { Resource } from "./Resource.ts"
|
|
17
18
|
|
|
18
19
|
// =============================================================================
|
|
@@ -23,7 +24,7 @@ import { Resource } from "./Resource.ts"
|
|
|
23
24
|
* @since 1.0.0
|
|
24
25
|
* @category Services
|
|
25
26
|
*/
|
|
26
|
-
export class OtelTracer extends
|
|
27
|
+
export class OtelTracer extends Context.Service<
|
|
27
28
|
OtelTracer,
|
|
28
29
|
Otel.Tracer
|
|
29
30
|
>()("@effect/opentelemetry/Tracer") {}
|
|
@@ -32,7 +33,7 @@ export class OtelTracer extends ServiceMap.Service<
|
|
|
32
33
|
* @since 1.0.0
|
|
33
34
|
* @category Services
|
|
34
35
|
*/
|
|
35
|
-
export class OtelTracerProvider extends
|
|
36
|
+
export class OtelTracerProvider extends Context.Service<
|
|
36
37
|
OtelTracerProvider,
|
|
37
38
|
Otel.TracerProvider
|
|
38
39
|
>()("@effect/opentelemetry/Tracer/OtelTracerProvider") {}
|
|
@@ -41,7 +42,7 @@ export class OtelTracerProvider extends ServiceMap.Service<
|
|
|
41
42
|
* @since 1.0.0
|
|
42
43
|
* @category Services
|
|
43
44
|
*/
|
|
44
|
-
export class OtelTraceFlags extends
|
|
45
|
+
export class OtelTraceFlags extends Context.Service<
|
|
45
46
|
OtelTraceFlags,
|
|
46
47
|
Otel.TraceFlags
|
|
47
48
|
>()("@effect/opentelemetry/Tracer/OtelTraceFlags") {}
|
|
@@ -50,7 +51,7 @@ export class OtelTraceFlags extends ServiceMap.Service<
|
|
|
50
51
|
* @since 1.0.0
|
|
51
52
|
* @category Services
|
|
52
53
|
*/
|
|
53
|
-
export class OtelTraceState extends
|
|
54
|
+
export class OtelTraceState extends Context.Service<
|
|
54
55
|
OtelTraceState,
|
|
55
56
|
Otel.TraceState
|
|
56
57
|
>()("@effect/opentelemetry/Tracer/OtelTraceState") {}
|
|
@@ -100,22 +101,24 @@ export const makeExternalSpan = (options: {
|
|
|
100
101
|
readonly traceFlags?: number | undefined
|
|
101
102
|
readonly traceState?: string | Otel.TraceState | undefined
|
|
102
103
|
}): Tracer.ExternalSpan => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
const annotations = Context.mutate(Context.empty(), (annotations) => {
|
|
105
|
+
let next = annotations
|
|
106
|
+
if (options.traceFlags !== undefined) {
|
|
107
|
+
next = Context.add(next, OtelTraceFlags, options.traceFlags)
|
|
108
|
+
}
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
if (typeof options.traceState === "string") {
|
|
111
|
+
try {
|
|
112
|
+
next = Context.add(next, OtelTraceState, Otel.createTraceState(options.traceState))
|
|
113
|
+
} catch {
|
|
114
|
+
//
|
|
115
|
+
}
|
|
116
|
+
} else if (options.traceState) {
|
|
117
|
+
next = Context.add(next, OtelTraceState, options.traceState)
|
|
115
118
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
+
|
|
120
|
+
return next
|
|
121
|
+
})
|
|
119
122
|
|
|
120
123
|
return {
|
|
121
124
|
_tag: "ExternalSpan",
|
|
@@ -356,14 +359,14 @@ export class OtelSpan implements Tracer.Span {
|
|
|
356
359
|
|
|
357
360
|
readonly name: string
|
|
358
361
|
readonly kind: Tracer.SpanKind
|
|
359
|
-
readonly annotations:
|
|
362
|
+
readonly annotations: Context.Context<never>
|
|
360
363
|
readonly links: Array<Tracer.SpanLink>
|
|
361
364
|
readonly span: Otel.Span
|
|
362
365
|
readonly spanId: string
|
|
363
366
|
readonly traceId: string
|
|
364
367
|
readonly attributes = new Map<string, unknown>()
|
|
365
368
|
readonly sampled: boolean
|
|
366
|
-
readonly parent: Tracer.AnySpan
|
|
369
|
+
readonly parent: Option.Option<Tracer.AnySpan>
|
|
367
370
|
status: Tracer.SpanStatus
|
|
368
371
|
|
|
369
372
|
constructor(
|
|
@@ -378,9 +381,9 @@ export class OtelSpan implements Tracer.Span {
|
|
|
378
381
|
this.links = options.links
|
|
379
382
|
this.kind = options.kind
|
|
380
383
|
const active = contextApi.active()
|
|
381
|
-
this.parent = options.
|
|
382
|
-
getOtelParent(traceApi, active, options.annotations)
|
|
383
|
-
|
|
384
|
+
this.parent = options.root !== true
|
|
385
|
+
? Option.orElse(options.parent, () => getOtelParent(traceApi, active, options.annotations))
|
|
386
|
+
: options.parent
|
|
384
387
|
this.span = tracer.startSpan(
|
|
385
388
|
options.name,
|
|
386
389
|
{
|
|
@@ -393,7 +396,9 @@ export class OtelSpan implements Tracer.Span {
|
|
|
393
396
|
: undefined as any,
|
|
394
397
|
kind: kindMap[this.kind]
|
|
395
398
|
},
|
|
396
|
-
|
|
399
|
+
Option.isSome(this.parent) ?
|
|
400
|
+
populateContext(active, this.parent.value, options.annotations) :
|
|
401
|
+
Otel.trace.deleteSpan(active)
|
|
397
402
|
)
|
|
398
403
|
const spanContext = this.span.spanContext()
|
|
399
404
|
this.spanId = spanContext.spanId
|
|
@@ -469,30 +474,24 @@ export class OtelSpan implements Tracer.Span {
|
|
|
469
474
|
const isSampled = (traceFlags: Otel.TraceFlags): boolean =>
|
|
470
475
|
(traceFlags & Otel.TraceFlags.SAMPLED) === Otel.TraceFlags.SAMPLED
|
|
471
476
|
|
|
472
|
-
const nanosToHrTime = (timestamp: bigint): Otel.HrTime => {
|
|
473
|
-
return [Number(timestamp / bigint1e9), Number(timestamp % bigint1e9)]
|
|
474
|
-
}
|
|
475
|
-
|
|
476
477
|
const getOtelParent = (
|
|
477
478
|
tracer: Otel.TraceAPI,
|
|
478
479
|
context: Otel.Context,
|
|
479
|
-
annotations:
|
|
480
|
-
): Tracer.AnySpan
|
|
481
|
-
const
|
|
482
|
-
|
|
483
|
-
return
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
})
|
|
490
|
-
: undefined
|
|
480
|
+
annotations: Context.Context<never>
|
|
481
|
+
): Option.Option<Tracer.AnySpan> => {
|
|
482
|
+
const otelParent = tracer.getSpan(context)?.spanContext()
|
|
483
|
+
if (!otelParent) return Option.none()
|
|
484
|
+
return Option.some(Tracer.externalSpan({
|
|
485
|
+
spanId: otelParent.spanId,
|
|
486
|
+
traceId: otelParent.traceId,
|
|
487
|
+
sampled: (otelParent.traceFlags & 1) === 1,
|
|
488
|
+
annotations
|
|
489
|
+
}))
|
|
491
490
|
}
|
|
492
491
|
|
|
493
492
|
const makeSpanContext = (
|
|
494
493
|
span: Tracer.AnySpan,
|
|
495
|
-
annotations?:
|
|
494
|
+
annotations?: Context.Context<never>
|
|
496
495
|
): Otel.SpanContext => {
|
|
497
496
|
const traceFlags = makeTraceFlags(span, annotations)
|
|
498
497
|
const traceState = makeTraceState(span, annotations)!
|
|
@@ -507,13 +506,13 @@ const makeSpanContext = (
|
|
|
507
506
|
|
|
508
507
|
const makeTraceFlags = (
|
|
509
508
|
span: Tracer.AnySpan,
|
|
510
|
-
annotations:
|
|
509
|
+
annotations: Context.Context<never> | undefined
|
|
511
510
|
): Otel.TraceFlags => {
|
|
512
511
|
let traceFlags: Otel.TraceFlags | undefined
|
|
513
512
|
if (Predicate.isNotUndefined(annotations)) {
|
|
514
513
|
traceFlags = extractTraceService(span, annotations, OtelTraceFlags)
|
|
515
514
|
if (Predicate.isUndefined(traceFlags)) {
|
|
516
|
-
traceFlags =
|
|
515
|
+
traceFlags = Context.getOrUndefined(span.annotations, OtelTraceFlags)
|
|
517
516
|
}
|
|
518
517
|
}
|
|
519
518
|
return traceFlags ?? Otel.TraceFlags.SAMPLED
|
|
@@ -521,13 +520,13 @@ const makeTraceFlags = (
|
|
|
521
520
|
|
|
522
521
|
const makeTraceState = (
|
|
523
522
|
span: Tracer.AnySpan,
|
|
524
|
-
annotations:
|
|
523
|
+
annotations: Context.Context<never> | undefined
|
|
525
524
|
): Otel.TraceState | undefined => {
|
|
526
525
|
let traceState: Otel.TraceState | undefined
|
|
527
526
|
if (Predicate.isNotUndefined(annotations)) {
|
|
528
527
|
traceState = extractTraceService(span, annotations, OtelTraceState)
|
|
529
528
|
if (Predicate.isUndefined(traceState)) {
|
|
530
|
-
traceState =
|
|
529
|
+
traceState = Context.getOrUndefined(span.annotations, OtelTraceState)
|
|
531
530
|
}
|
|
532
531
|
}
|
|
533
532
|
return traceState
|
|
@@ -535,20 +534,20 @@ const makeTraceState = (
|
|
|
535
534
|
|
|
536
535
|
const extractTraceService = <I, S>(
|
|
537
536
|
parent: Tracer.AnySpan,
|
|
538
|
-
annotations:
|
|
539
|
-
service:
|
|
537
|
+
annotations: Context.Context<never>,
|
|
538
|
+
service: Context.Service<I, S>
|
|
540
539
|
) => {
|
|
541
|
-
const instance =
|
|
540
|
+
const instance = Context.getOrUndefined(annotations, service)
|
|
542
541
|
if (Predicate.isNotUndefined(instance)) {
|
|
543
542
|
return instance
|
|
544
543
|
}
|
|
545
|
-
return
|
|
544
|
+
return Context.getOrUndefined(parent.annotations, service)
|
|
546
545
|
}
|
|
547
546
|
|
|
548
547
|
const populateContext = (
|
|
549
548
|
context: Otel.Context,
|
|
550
549
|
span: Tracer.AnySpan,
|
|
551
|
-
annotations?:
|
|
550
|
+
annotations?: Context.Context<never> | undefined
|
|
552
551
|
): Otel.Context =>
|
|
553
552
|
span instanceof OtelSpan ?
|
|
554
553
|
Otel.trace.setSpan(context, span.span) :
|
|
@@ -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 = {}
|
package/src/internal/metrics.ts
CHANGED
|
@@ -11,8 +11,8 @@ import type {
|
|
|
11
11
|
import { AggregationTemporality, DataPointType, InstrumentType } from "@opentelemetry/sdk-metrics"
|
|
12
12
|
import type { InstrumentDescriptor } from "@opentelemetry/sdk-metrics/build/src/InstrumentDescriptor.js"
|
|
13
13
|
import * as Arr from "effect/Array"
|
|
14
|
+
import type * as Context from "effect/Context"
|
|
14
15
|
import * as Metric from "effect/Metric"
|
|
15
|
-
import type * as ServiceMap from "effect/ServiceMap"
|
|
16
16
|
import type * as Metrics from "../Metrics.ts"
|
|
17
17
|
|
|
18
18
|
const sdkName = "@effect/opentelemetry/Metrics"
|
|
@@ -37,7 +37,7 @@ interface PreviousSummaryState {
|
|
|
37
37
|
/** @internal */
|
|
38
38
|
export class MetricProducerImpl implements MetricProducer {
|
|
39
39
|
resource: Resources.Resource
|
|
40
|
-
|
|
40
|
+
context: Context.Context<never>
|
|
41
41
|
temporality: Metrics.TemporalityPreference
|
|
42
42
|
startTimes: Map<string, HrTime>
|
|
43
43
|
startTimeNanos: HrTime
|
|
@@ -49,11 +49,11 @@ export class MetricProducerImpl implements MetricProducer {
|
|
|
49
49
|
|
|
50
50
|
constructor(
|
|
51
51
|
resource: Resources.Resource,
|
|
52
|
-
|
|
52
|
+
context: Context.Context<never>,
|
|
53
53
|
temporality: Metrics.TemporalityPreference = "cumulative"
|
|
54
54
|
) {
|
|
55
55
|
this.resource = resource
|
|
56
|
-
this.
|
|
56
|
+
this.context = context
|
|
57
57
|
this.temporality = temporality
|
|
58
58
|
this.startTimes = new Map()
|
|
59
59
|
this.startTimeNanos = currentHrTime()
|
|
@@ -73,7 +73,7 @@ export class MetricProducerImpl implements MetricProducer {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
collect(_options?: MetricCollectOptions): Promise<CollectionResult> {
|
|
76
|
-
const snapshot = Metric.snapshotUnsafe(this.
|
|
76
|
+
const snapshot = Metric.snapshotUnsafe(this.context)
|
|
77
77
|
const hrTimeNow = currentHrTime()
|
|
78
78
|
const metricData: Array<MetricData> = []
|
|
79
79
|
const metricDataByName = new Map<string, MetricData>()
|
|
@@ -111,7 +111,7 @@ export class MetricProducerImpl implements MetricProducer {
|
|
|
111
111
|
if (typeof currentCount === "bigint" && typeof previousCount === "bigint") {
|
|
112
112
|
reportValue = currentCount - previousCount
|
|
113
113
|
// Handle reset: if current < previous, report current value
|
|
114
|
-
if (reportValue <
|
|
114
|
+
if (reportValue < BigInt(0)) {
|
|
115
115
|
reportValue = currentCount
|
|
116
116
|
}
|
|
117
117
|
} else {
|