@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/Logger.ts
CHANGED
|
@@ -1,33 +1,104 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Connects Effect logging to the OpenTelemetry Logs SDK.
|
|
3
|
+
*
|
|
4
|
+
* This module turns Effect log events into OpenTelemetry log records. It
|
|
5
|
+
* provides the `OtelLoggerProvider` service, a `Logger` implementation created
|
|
6
|
+
* by {@link make}, a {@link layer} that installs it into Effect logging, and
|
|
7
|
+
* {@link layerLoggerProvider} for creating a scoped SDK `LoggerProvider` from
|
|
8
|
+
* one or more `LogRecordProcessor`s.
|
|
9
|
+
*
|
|
10
|
+
* **Mental model**
|
|
11
|
+
*
|
|
12
|
+
* Effect decides when a log is emitted and supplies the message, fiber id, log
|
|
13
|
+
* level, annotations, log spans, and active parent span. This module maps that
|
|
14
|
+
* data into an OpenTelemetry log record, including severity text/number, trace
|
|
15
|
+
* and span identifiers when available, and timestamps from the Effect `Clock`.
|
|
16
|
+
*
|
|
17
|
+
* **Common tasks**
|
|
18
|
+
*
|
|
19
|
+
* Use {@link layerLoggerProvider} when the application wants this package to own
|
|
20
|
+
* the OpenTelemetry logger provider lifecycle. Provide it with processors such
|
|
21
|
+
* as OTLP, console, or vendor-specific exporters, then install {@link layer} so
|
|
22
|
+
* regular Effect logging emits records through that provider. If the provider is
|
|
23
|
+
* created elsewhere, supply `OtelLoggerProvider` yourself and still use
|
|
24
|
+
* {@link layer} or {@link make}.
|
|
25
|
+
*
|
|
26
|
+
* **Gotchas**
|
|
27
|
+
*
|
|
28
|
+
* This module does not choose an exporter. Export behavior, batching, retries,
|
|
29
|
+
* and delivery guarantees come from the configured OpenTelemetry processors.
|
|
30
|
+
* The scoped provider is force-flushed and shut down when the layer is released,
|
|
31
|
+
* using the configured shutdown timeout; externally managed providers should be
|
|
32
|
+
* flushed and shut down by the owner to avoid dropping buffered logs.
|
|
33
|
+
*
|
|
34
|
+
* @since 4.0.0
|
|
3
35
|
*/
|
|
36
|
+
import { SeverityNumber } from "@opentelemetry/api-logs"
|
|
4
37
|
import * as Otel from "@opentelemetry/sdk-logs"
|
|
5
38
|
import type { NonEmptyReadonlyArray } from "effect/Array"
|
|
6
39
|
import * as Arr from "effect/Array"
|
|
7
40
|
import * as Clock from "effect/Clock"
|
|
41
|
+
import * as Context from "effect/Context"
|
|
8
42
|
import type * as Duration from "effect/Duration"
|
|
9
43
|
import * as Effect from "effect/Effect"
|
|
10
44
|
import * as Layer from "effect/Layer"
|
|
11
45
|
import * as Logger from "effect/Logger"
|
|
12
|
-
import * as LogLevel from "effect/LogLevel"
|
|
46
|
+
import type * as LogLevel from "effect/LogLevel"
|
|
13
47
|
import * as Predicate from "effect/Predicate"
|
|
14
|
-
import * as
|
|
48
|
+
import * as References from "effect/References"
|
|
15
49
|
import * as Tracer from "effect/Tracer"
|
|
16
|
-
import { unknownToAttributeValue } from "./internal/attributes.ts"
|
|
50
|
+
import { nanosToHrTime, unknownToAttributeValue } from "./internal/attributes.ts"
|
|
17
51
|
import { Resource } from "./Resource.ts"
|
|
18
52
|
|
|
19
53
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
54
|
+
* Context service containing the OpenTelemetry `LoggerProvider` used to emit Effect log records.
|
|
55
|
+
*
|
|
56
|
+
* @category services
|
|
57
|
+
* @since 4.0.0
|
|
22
58
|
*/
|
|
23
|
-
export class OtelLoggerProvider extends
|
|
59
|
+
export class OtelLoggerProvider extends Context.Service<
|
|
24
60
|
OtelLoggerProvider,
|
|
25
61
|
Otel.LoggerProvider
|
|
26
62
|
>()("@effect/opentelemetry/Logger/OtelLoggerProvider") {}
|
|
27
63
|
|
|
28
64
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
65
|
+
* Maps an Effect `LogLevel` to the corresponding OpenTelemetry `SeverityNumber`.
|
|
66
|
+
*
|
|
67
|
+
* **Details**
|
|
68
|
+
*
|
|
69
|
+
* OpenTelemetry log severity numbers are in the range `1` through `24`. This
|
|
70
|
+
* function maps from Effect's log levels instead of using
|
|
71
|
+
* `LogLevel.getOrdinal`, whose internal sort ordinals, such as the `Info`
|
|
72
|
+
* ordinal `20000`, fall outside the OpenTelemetry logs data model and can be
|
|
73
|
+
* treated as `UNSPECIFIED` by validating backends.
|
|
74
|
+
*
|
|
75
|
+
* @category converting
|
|
76
|
+
* @since 4.0.0
|
|
77
|
+
*/
|
|
78
|
+
export const logLevelToSeverityNumber = (level: LogLevel.LogLevel): SeverityNumber => {
|
|
79
|
+
switch (level) {
|
|
80
|
+
case "Trace":
|
|
81
|
+
return SeverityNumber.TRACE
|
|
82
|
+
case "Debug":
|
|
83
|
+
return SeverityNumber.DEBUG
|
|
84
|
+
case "Info":
|
|
85
|
+
return SeverityNumber.INFO
|
|
86
|
+
case "Warn":
|
|
87
|
+
return SeverityNumber.WARN
|
|
88
|
+
case "Error":
|
|
89
|
+
return SeverityNumber.ERROR
|
|
90
|
+
case "Fatal":
|
|
91
|
+
return SeverityNumber.FATAL
|
|
92
|
+
default:
|
|
93
|
+
return SeverityNumber.UNSPECIFIED
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Creates an Effect logger that emits log records through the configured OpenTelemetry logger provider.
|
|
99
|
+
*
|
|
100
|
+
* @category constructors
|
|
101
|
+
* @since 4.0.0
|
|
31
102
|
*/
|
|
32
103
|
export const make: Effect.Effect<
|
|
33
104
|
Logger.Logger<unknown, void>,
|
|
@@ -43,40 +114,60 @@ export const make: Effect.Effect<
|
|
|
43
114
|
fiberId: options.fiber.id
|
|
44
115
|
}
|
|
45
116
|
|
|
46
|
-
const span =
|
|
117
|
+
const span = Context.getOrUndefined(options.fiber.context, Tracer.ParentSpan)
|
|
47
118
|
|
|
48
119
|
if (Predicate.isNotUndefined(span)) {
|
|
49
120
|
attributes.spanId = span.spanId
|
|
50
121
|
attributes.traceId = span.traceId
|
|
51
122
|
}
|
|
52
123
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// }
|
|
124
|
+
for (const [key, value] of Object.entries(options.fiber.getRef(References.CurrentLogAnnotations))) {
|
|
125
|
+
attributes[key] = unknownToAttributeValue(value)
|
|
126
|
+
}
|
|
127
|
+
const now = options.date.getTime()
|
|
128
|
+
for (const [label, startTime] of options.fiber.getRef(References.CurrentLogSpans)) {
|
|
129
|
+
attributes[`logSpan.${label}`] = `${now - startTime}ms`
|
|
130
|
+
}
|
|
61
131
|
|
|
62
132
|
const message = Arr.ensure(options.message).map(unknownToAttributeValue)
|
|
133
|
+
const hrTime = nanosToHrTime(clock.currentTimeNanosUnsafe())
|
|
63
134
|
otelLogger.emit({
|
|
64
135
|
body: message.length === 1 ? message[0] : message,
|
|
65
136
|
severityText: options.logLevel,
|
|
66
|
-
severityNumber:
|
|
67
|
-
timestamp:
|
|
68
|
-
observedTimestamp:
|
|
137
|
+
severityNumber: logLevelToSeverityNumber(options.logLevel),
|
|
138
|
+
timestamp: hrTime,
|
|
139
|
+
observedTimestamp: hrTime,
|
|
69
140
|
attributes
|
|
70
141
|
})
|
|
71
142
|
})
|
|
72
143
|
})
|
|
73
144
|
|
|
74
145
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
146
|
+
* Creates a layer that installs the OpenTelemetry-backed Effect logger, merging with existing loggers by default.
|
|
147
|
+
*
|
|
148
|
+
* **When to use**
|
|
149
|
+
*
|
|
150
|
+
* Use to install the OpenTelemetry-backed Effect logger in an application that
|
|
151
|
+
* has an `OtelLoggerProvider`, so standard Effect logging emits OpenTelemetry
|
|
152
|
+
* log records.
|
|
153
|
+
*
|
|
154
|
+
* **Details**
|
|
155
|
+
*
|
|
156
|
+
* The layer installs the logger created by `make`. `mergeWithExisting` defaults
|
|
157
|
+
* to `true`; set it to `false` to replace the current logger set.
|
|
158
|
+
*
|
|
159
|
+
* @see {@link make} for constructing the logger directly
|
|
160
|
+
* @see {@link layerLoggerProvider} for creating the required logger provider
|
|
161
|
+
*
|
|
162
|
+
* @category layers
|
|
163
|
+
* @since 4.0.0
|
|
77
164
|
*/
|
|
78
165
|
export const layer = (options: {
|
|
79
166
|
/**
|
|
167
|
+
* Whether to merge the OpenTelemetry logger with existing loggers.
|
|
168
|
+
*
|
|
169
|
+
* **Details**
|
|
170
|
+
*
|
|
80
171
|
* If set to `true`, the OpenTelemetry logger will be merged with existing
|
|
81
172
|
* loggers in the application.
|
|
82
173
|
*
|
|
@@ -92,8 +183,10 @@ export const layer = (options: {
|
|
|
92
183
|
})
|
|
93
184
|
|
|
94
185
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
186
|
+
* Creates a scoped OpenTelemetry logger provider from one or more log record processors, using the current `Resource` and flushing and shutting down the provider when the layer is released.
|
|
187
|
+
*
|
|
188
|
+
* @category layers
|
|
189
|
+
* @since 4.0.0
|
|
97
190
|
*/
|
|
98
191
|
export const layerLoggerProvider = (
|
|
99
192
|
processor: Otel.LogRecordProcessor | NonEmptyReadonlyArray<Otel.LogRecordProcessor>,
|
package/src/Metrics.ts
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* OpenTelemetry metric export bridge for Effect metrics.
|
|
3
|
+
*
|
|
4
|
+
* Effect applications record metrics through Effect's metric APIs. This module
|
|
5
|
+
* exposes the current Effect metric snapshot as an OpenTelemetry
|
|
6
|
+
* `MetricProducer` and registers it with SDK `MetricReader`s so existing
|
|
7
|
+
* OpenTelemetry exporters can deliver those metrics to OTLP, Prometheus, or
|
|
8
|
+
* vendor backends.
|
|
9
|
+
*
|
|
10
|
+
* **Mental model**
|
|
11
|
+
*
|
|
12
|
+
* {@link makeProducer} captures the current Effect context and `Resource` and
|
|
13
|
+
* builds a producer that OpenTelemetry readers can pull from.
|
|
14
|
+
* {@link registerProducer} attaches that producer to one or more readers for
|
|
15
|
+
* the lifetime of a scope. {@link layer} composes both steps and is the path
|
|
16
|
+
* used by the Node and Web SDK layers when metric readers are configured.
|
|
17
|
+
*
|
|
18
|
+
* **Common tasks**
|
|
19
|
+
*
|
|
20
|
+
* - Install Effect metrics into OpenTelemetry with {@link layer}
|
|
21
|
+
* - Build a producer manually with {@link makeProducer}
|
|
22
|
+
* - Attach an existing producer to readers with {@link registerProducer}
|
|
23
|
+
* - Choose cumulative or delta export with {@link TemporalityPreference}
|
|
24
|
+
*
|
|
25
|
+
* **Gotchas**
|
|
26
|
+
*
|
|
27
|
+
* Readers are shut down when the layer scope closes, so periodic exporters need
|
|
28
|
+
* the application runtime to stay alive long enough for collection and export.
|
|
29
|
+
* This module defaults to cumulative temporality; configure
|
|
30
|
+
* `temporality: "delta"` only when the backend expects interval values. Export
|
|
31
|
+
* protocol, batching, and delivery behavior come from the OpenTelemetry
|
|
32
|
+
* reader/exporter, not from this bridge.
|
|
33
|
+
*
|
|
34
|
+
* @since 4.0.0
|
|
3
35
|
*/
|
|
4
36
|
import type { MetricProducer, MetricReader } from "@opentelemetry/sdk-metrics"
|
|
5
37
|
import type * as Arr from "effect/Array"
|
|
@@ -15,35 +47,50 @@ import { Resource } from "./Resource.ts"
|
|
|
15
47
|
* Determines how metric values relate to the time interval over which they
|
|
16
48
|
* are aggregated.
|
|
17
49
|
*
|
|
18
|
-
*
|
|
19
|
-
* depends on all previous measurements. This is the default behavior.
|
|
50
|
+
* **Details**
|
|
20
51
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
52
|
+
* `cumulative` reports total since a fixed start time. Each data point depends
|
|
53
|
+
* on all previous measurements. This is the default behavior. `delta` reports
|
|
54
|
+
* changes since the last export. Each interval is independent with no
|
|
55
|
+
* dependency on previous measurements.
|
|
23
56
|
*
|
|
24
|
-
* @
|
|
25
|
-
* @
|
|
57
|
+
* @category models
|
|
58
|
+
* @since 4.0.0
|
|
26
59
|
*/
|
|
27
60
|
export type TemporalityPreference = "cumulative" | "delta"
|
|
28
61
|
|
|
29
62
|
/**
|
|
30
63
|
* Creates an OpenTelemetry metric producer from Effect metrics.
|
|
31
64
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
65
|
+
* **When to use**
|
|
66
|
+
*
|
|
67
|
+
* Use to create a `MetricProducer` when you need to wire Effect metrics into
|
|
68
|
+
* OpenTelemetry manually instead of using the scoped `layer` helper.
|
|
69
|
+
*
|
|
70
|
+
* **Details**
|
|
71
|
+
*
|
|
72
|
+
* Requires the current OpenTelemetry `Resource`, captures the current Effect
|
|
73
|
+
* context, and uses cumulative temporality by default. Pass `"delta"` for
|
|
74
|
+
* interval-based values.
|
|
75
|
+
*
|
|
76
|
+
* @see {@link registerProducer} for attaching a producer to metric readers
|
|
77
|
+
* @see {@link layer} for creating and registering a producer in a scoped layer
|
|
78
|
+
*
|
|
79
|
+
* @category constructors
|
|
80
|
+
* @since 4.0.0
|
|
34
81
|
*/
|
|
35
82
|
export const makeProducer = (temporality?: TemporalityPreference): Effect.Effect<MetricProducer, never, Resource> =>
|
|
36
83
|
Effect.gen(function*() {
|
|
37
84
|
const resource = yield* Resource
|
|
38
|
-
const services = yield* Effect.
|
|
85
|
+
const services = yield* Effect.context<never>()
|
|
39
86
|
return new MetricProducerImpl(resource, services, temporality)
|
|
40
87
|
})
|
|
41
88
|
|
|
42
89
|
/**
|
|
43
90
|
* Registers a metric producer with one or more metric readers.
|
|
44
91
|
*
|
|
45
|
-
* @
|
|
46
|
-
* @
|
|
92
|
+
* @category constructors
|
|
93
|
+
* @since 4.0.0
|
|
47
94
|
*/
|
|
48
95
|
export const registerProducer = (
|
|
49
96
|
self: MetricProducer,
|
|
@@ -74,7 +121,8 @@ export const registerProducer = (
|
|
|
74
121
|
/**
|
|
75
122
|
* Creates a Layer that registers a metric producer with metric readers.
|
|
76
123
|
*
|
|
77
|
-
*
|
|
124
|
+
* **Example** (Creating a metrics layer with temporality)
|
|
125
|
+
*
|
|
78
126
|
* ```ts
|
|
79
127
|
* import { Metrics } from "@effect/opentelemetry"
|
|
80
128
|
* import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics"
|
|
@@ -98,8 +146,8 @@ export const registerProducer = (
|
|
|
98
146
|
* )
|
|
99
147
|
* ```
|
|
100
148
|
*
|
|
101
|
-
* @
|
|
102
|
-
* @
|
|
149
|
+
* @category layers
|
|
150
|
+
* @since 4.0.0
|
|
103
151
|
*/
|
|
104
152
|
export const layer = (
|
|
105
153
|
evaluate: LazyArg<MetricReader | Arr.NonEmptyReadonlyArray<MetricReader>>,
|
package/src/NodeSdk.ts
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Provides an Effect layer for configuring OpenTelemetry in Node.js
|
|
3
|
+
* processes. The module wires the Effect tracer, metrics producer, and logger
|
|
4
|
+
* into OpenTelemetry SDK providers when span processors, metric readers, or log
|
|
5
|
+
* record processors are supplied, and it builds the shared resource from
|
|
6
|
+
* `OTEL_SERVICE_NAME`, `OTEL_RESOURCE_ATTRIBUTES`, and optional explicit
|
|
7
|
+
* service metadata.
|
|
8
|
+
*
|
|
9
|
+
* Use this module in Node services, workers, CLIs, or server runtimes that need
|
|
10
|
+
* Effect spans, metrics, and logs exported through OpenTelemetry processors and
|
|
11
|
+
* exporters. Telemetry is enabled only for the configured signal types, so an
|
|
12
|
+
* application can install tracing alone, metrics alone, logging alone, or any
|
|
13
|
+
* combination of them from the same layer.
|
|
14
|
+
*
|
|
15
|
+
* The layer is scoped. Tracer and logger providers are force-flushed and shut
|
|
16
|
+
* down when the scope is released, metric readers are shut down with the same
|
|
17
|
+
* lifecycle, and all shutdown waits are bounded by `shutdownTimeout` with a
|
|
18
|
+
* default of three seconds. Keep the layer scope alive for the lifetime of the
|
|
19
|
+
* process and release it during graceful shutdown so batched exporters have a
|
|
20
|
+
* chance to export final telemetry. When combining this layer with Node
|
|
21
|
+
* auto-instrumentations, register instrumentation before importing modules that
|
|
22
|
+
* should be patched, because many Node instrumentations hook module loading.
|
|
23
|
+
*
|
|
24
|
+
* @since 4.0.0
|
|
3
25
|
*/
|
|
4
26
|
import type * as Otel from "@opentelemetry/api"
|
|
5
27
|
import type { LoggerProviderConfig, LogRecordProcessor } from "@opentelemetry/sdk-logs"
|
|
@@ -18,8 +40,10 @@ import * as Resource from "./Resource.ts"
|
|
|
18
40
|
import * as Tracer from "./Tracer.ts"
|
|
19
41
|
|
|
20
42
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
43
|
+
* Configuration for the Node OpenTelemetry layer, including optional tracing, metrics, logging, resource, and shutdown settings.
|
|
44
|
+
*
|
|
45
|
+
* @category models
|
|
46
|
+
* @since 4.0.0
|
|
23
47
|
*/
|
|
24
48
|
export interface Configuration {
|
|
25
49
|
readonly spanProcessor?: SpanProcessor | ReadonlyArray<SpanProcessor> | undefined
|
|
@@ -38,8 +62,10 @@ export interface Configuration {
|
|
|
38
62
|
}
|
|
39
63
|
|
|
40
64
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
65
|
+
* Creates a scoped Node OpenTelemetry tracer provider from one or more span processors and shuts it down when the layer is released.
|
|
66
|
+
*
|
|
67
|
+
* @category layers
|
|
68
|
+
* @since 4.0.0
|
|
43
69
|
*/
|
|
44
70
|
export const layerTracerProvider = (
|
|
45
71
|
processor: SpanProcessor | NonEmptyReadonlyArray<SpanProcessor>,
|
|
@@ -71,18 +97,75 @@ export const layerTracerProvider = (
|
|
|
71
97
|
)
|
|
72
98
|
|
|
73
99
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
100
|
+
* Creates a Node OpenTelemetry layer from configuration, enabling tracing, metrics, and logging only when their processors or readers are supplied.
|
|
101
|
+
*
|
|
102
|
+
* **When to use**
|
|
103
|
+
*
|
|
104
|
+
* Use to install OpenTelemetry support for a Node.js Effect application from
|
|
105
|
+
* one configuration object, enabling tracing, metrics, logging, or any
|
|
106
|
+
* combination of those signals based on the processors and readers supplied.
|
|
107
|
+
*
|
|
108
|
+
* **Details**
|
|
109
|
+
*
|
|
110
|
+
* The configuration can be provided lazily or effectfully. The layer always
|
|
111
|
+
* provides `Resource.Resource`, building it from environment variables and any
|
|
112
|
+
* explicit resource metadata in the configuration.
|
|
113
|
+
*
|
|
114
|
+
* **Gotchas**
|
|
115
|
+
*
|
|
116
|
+
* Register Node auto-instrumentations before importing modules that should be
|
|
117
|
+
* patched, because many Node instrumentations hook module loading.
|
|
118
|
+
*
|
|
119
|
+
* @category layers
|
|
120
|
+
* @since 4.0.0
|
|
76
121
|
*/
|
|
77
122
|
export const layer: {
|
|
78
123
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
124
|
+
* Creates a Node OpenTelemetry layer from configuration, enabling tracing, metrics, and logging only when their processors or readers are supplied.
|
|
125
|
+
*
|
|
126
|
+
* **When to use**
|
|
127
|
+
*
|
|
128
|
+
* Use to install OpenTelemetry support for a Node.js Effect application from
|
|
129
|
+
* one configuration object, enabling tracing, metrics, logging, or any
|
|
130
|
+
* combination of those signals based on the processors and readers supplied.
|
|
131
|
+
*
|
|
132
|
+
* **Details**
|
|
133
|
+
*
|
|
134
|
+
* The configuration can be provided lazily or effectfully. The layer always
|
|
135
|
+
* provides `Resource.Resource`, building it from environment variables and any
|
|
136
|
+
* explicit resource metadata in the configuration.
|
|
137
|
+
*
|
|
138
|
+
* **Gotchas**
|
|
139
|
+
*
|
|
140
|
+
* Register Node auto-instrumentations before importing modules that should be
|
|
141
|
+
* patched, because many Node instrumentations hook module loading.
|
|
142
|
+
*
|
|
143
|
+
* @category layers
|
|
144
|
+
* @since 4.0.0
|
|
81
145
|
*/
|
|
82
146
|
(evaluate: LazyArg<Configuration>): Layer.Layer<Resource.Resource>
|
|
83
147
|
/**
|
|
84
|
-
*
|
|
85
|
-
*
|
|
148
|
+
* Creates a Node OpenTelemetry layer from configuration, enabling tracing, metrics, and logging only when their processors or readers are supplied.
|
|
149
|
+
*
|
|
150
|
+
* **When to use**
|
|
151
|
+
*
|
|
152
|
+
* Use to install OpenTelemetry support for a Node.js Effect application from
|
|
153
|
+
* one configuration object, enabling tracing, metrics, logging, or any
|
|
154
|
+
* combination of those signals based on the processors and readers supplied.
|
|
155
|
+
*
|
|
156
|
+
* **Details**
|
|
157
|
+
*
|
|
158
|
+
* The configuration can be provided lazily or effectfully. The layer always
|
|
159
|
+
* provides `Resource.Resource`, building it from environment variables and any
|
|
160
|
+
* explicit resource metadata in the configuration.
|
|
161
|
+
*
|
|
162
|
+
* **Gotchas**
|
|
163
|
+
*
|
|
164
|
+
* Register Node auto-instrumentations before importing modules that should be
|
|
165
|
+
* patched, because many Node instrumentations hook module loading.
|
|
166
|
+
*
|
|
167
|
+
* @category layers
|
|
168
|
+
* @since 4.0.0
|
|
86
169
|
*/
|
|
87
170
|
<R, E>(evaluate: Effect.Effect<Configuration, E, R>): Layer.Layer<Resource.Resource, E, R>
|
|
88
171
|
} = (
|
|
@@ -130,7 +213,9 @@ export const layer: {
|
|
|
130
213
|
)
|
|
131
214
|
|
|
132
215
|
/**
|
|
216
|
+
* Layer that provides an empty OpenTelemetry `Resource`.
|
|
217
|
+
*
|
|
218
|
+
* @category layers
|
|
133
219
|
* @since 2.0.0
|
|
134
|
-
* @category layer
|
|
135
220
|
*/
|
|
136
221
|
export const layerEmpty: Layer.Layer<Resource.Resource> = Resource.layerEmpty
|
package/src/Resource.ts
CHANGED
|
@@ -1,27 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* OpenTelemetry resource service for Effect telemetry layers.
|
|
3
|
+
*
|
|
4
|
+
* An OpenTelemetry resource identifies the process or service that emits spans,
|
|
5
|
+
* metrics, and logs. This module stores that resource in Effect context so
|
|
6
|
+
* tracer, metric, logger, Node SDK, and Web SDK layers can create providers with
|
|
7
|
+
* consistent service metadata.
|
|
8
|
+
*
|
|
9
|
+
* **Mental model**
|
|
10
|
+
*
|
|
11
|
+
* Resource attributes describe stable producer metadata such as `service.name`,
|
|
12
|
+
* `service.version`, deployment, process, or environment attributes. They are
|
|
13
|
+
* attached to telemetry providers, not to individual spans or log records.
|
|
14
|
+
*
|
|
15
|
+
* **Common tasks**
|
|
16
|
+
*
|
|
17
|
+
* Use `layer` when service metadata is configured in code, `layerFromEnv` when
|
|
18
|
+
* deployment supplies `OTEL_SERVICE_NAME` or `OTEL_RESOURCE_ATTRIBUTES`, and
|
|
19
|
+
* `layerEmpty` for tests or integrations that intentionally provide no resource
|
|
20
|
+
* attributes. `configToAttributes` converts the explicit configuration shape
|
|
21
|
+
* into OpenTelemetry semantic-convention attributes for composition with other
|
|
22
|
+
* resource sources.
|
|
23
|
+
*
|
|
24
|
+
* **Gotchas**
|
|
25
|
+
*
|
|
26
|
+
* `layer` merges custom attributes first and then writes `service.name` and
|
|
27
|
+
* `telemetry.sdk.*`, so those keys are controlled by this package. In
|
|
28
|
+
* `layerFromEnv`, `OTEL_SERVICE_NAME` overrides `service.name` from
|
|
29
|
+
* `OTEL_RESOURCE_ATTRIBUTES`, and any additional attributes passed to the layer
|
|
30
|
+
* are merged last.
|
|
31
|
+
*
|
|
32
|
+
* @since 4.0.0
|
|
3
33
|
*/
|
|
4
34
|
import type * as OtelApi from "@opentelemetry/api"
|
|
5
35
|
import * as Resources from "@opentelemetry/resources"
|
|
6
36
|
import * as OtelSemConv from "@opentelemetry/semantic-conventions"
|
|
7
37
|
import * as Arr from "effect/Array"
|
|
8
38
|
import * as Config from "effect/Config"
|
|
39
|
+
import * as Context from "effect/Context"
|
|
9
40
|
import * as Effect from "effect/Effect"
|
|
10
41
|
import * as Layer from "effect/Layer"
|
|
11
|
-
import * as ServiceMap from "effect/ServiceMap"
|
|
12
42
|
|
|
13
43
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
44
|
+
* Context service containing the OpenTelemetry `Resource` associated with emitted telemetry.
|
|
45
|
+
*
|
|
46
|
+
* @category services
|
|
47
|
+
* @since 4.0.0
|
|
16
48
|
*/
|
|
17
|
-
export class Resource extends
|
|
49
|
+
export class Resource extends Context.Service<
|
|
18
50
|
Resource,
|
|
19
51
|
Resources.Resource
|
|
20
52
|
>()("@effect/opentelemetry/Resource") {}
|
|
21
53
|
|
|
22
54
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
55
|
+
* Creates a `Resource` layer from service metadata and additional OpenTelemetry attributes.
|
|
56
|
+
*
|
|
57
|
+
* @category layers
|
|
58
|
+
* @since 4.0.0
|
|
25
59
|
*/
|
|
26
60
|
export const layer = (config: {
|
|
27
61
|
readonly serviceName: string
|
|
@@ -34,8 +68,30 @@ export const layer = (config: {
|
|
|
34
68
|
)
|
|
35
69
|
|
|
36
70
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
71
|
+
* Converts resource configuration into OpenTelemetry attributes, adding service name, optional service version, and telemetry SDK metadata.
|
|
72
|
+
*
|
|
73
|
+
* **When to use**
|
|
74
|
+
*
|
|
75
|
+
* Use to turn explicit service metadata into a raw OpenTelemetry attribute map
|
|
76
|
+
* for lower-level resource construction or for merging with environment-derived
|
|
77
|
+
* attributes via `layerFromEnv`.
|
|
78
|
+
*
|
|
79
|
+
* **Details**
|
|
80
|
+
*
|
|
81
|
+
* The returned record copies `attributes` first, then sets `service.name`,
|
|
82
|
+
* `telemetry.sdk.name`, and `telemetry.sdk.language`. `service.version` is
|
|
83
|
+
* included only when `serviceVersion` is provided.
|
|
84
|
+
*
|
|
85
|
+
* **Gotchas**
|
|
86
|
+
*
|
|
87
|
+
* Custom values for `service.name` and `telemetry.sdk.*` are overwritten by this
|
|
88
|
+
* helper. An empty `serviceVersion` is treated as absent.
|
|
89
|
+
*
|
|
90
|
+
* @see {@link layer} for creating a `Resource` layer from explicit metadata
|
|
91
|
+
* @see {@link layerFromEnv} for merging attributes with OpenTelemetry environment variables
|
|
92
|
+
*
|
|
93
|
+
* @category configuration
|
|
94
|
+
* @since 4.0.0
|
|
39
95
|
*/
|
|
40
96
|
export const configToAttributes = (options: {
|
|
41
97
|
readonly serviceName: string
|
|
@@ -57,8 +113,10 @@ export const configToAttributes = (options: {
|
|
|
57
113
|
}
|
|
58
114
|
|
|
59
115
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
116
|
+
* Creates a `Resource` layer from OpenTelemetry environment variables, optionally merging additional attributes.
|
|
117
|
+
*
|
|
118
|
+
* @category layers
|
|
119
|
+
* @since 4.0.0
|
|
62
120
|
*/
|
|
63
121
|
export const layerFromEnv = (
|
|
64
122
|
additionalAttributes?:
|
|
@@ -70,7 +128,7 @@ export const layerFromEnv = (
|
|
|
70
128
|
Effect.gen(function*() {
|
|
71
129
|
const serviceName = yield* Config.option(Config.string("OTEL_SERVICE_NAME"))
|
|
72
130
|
const attributes = yield* Config.string("OTEL_RESOURCE_ATTRIBUTES").pipe(
|
|
73
|
-
Config.withDefault(
|
|
131
|
+
Config.withDefault(""),
|
|
74
132
|
Config.map((s) => {
|
|
75
133
|
const attrs = s.split(",")
|
|
76
134
|
return Arr.reduce(attrs, {} as OtelApi.Attributes, (acc, attr) => {
|
|
@@ -94,8 +152,10 @@ export const layerFromEnv = (
|
|
|
94
152
|
)
|
|
95
153
|
|
|
96
154
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
155
|
+
* Layer that provides an empty OpenTelemetry resource.
|
|
156
|
+
*
|
|
157
|
+
* @category layers
|
|
158
|
+
* @since 4.0.0
|
|
99
159
|
*/
|
|
100
160
|
export const layerEmpty = Layer.succeed(
|
|
101
161
|
Resource,
|