@effect/opentelemetry 0.42.9 → 0.43.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.
- package/Logger/package.json +6 -0
- package/dist/cjs/Logger.js +85 -0
- package/dist/cjs/Logger.js.map +1 -0
- package/dist/cjs/NodeSdk.js +8 -4
- package/dist/cjs/NodeSdk.js.map +1 -1
- package/dist/cjs/Resource.js +14 -8
- package/dist/cjs/Resource.js.map +1 -1
- package/dist/cjs/WebSdk.js +7 -3
- package/dist/cjs/WebSdk.js.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/internal/tracer.js +6 -24
- package/dist/cjs/internal/tracer.js.map +1 -1
- package/dist/cjs/internal/utils.js +35 -0
- package/dist/cjs/internal/utils.js.map +1 -0
- package/dist/dts/Logger.d.ts +39 -0
- package/dist/dts/Logger.d.ts.map +1 -0
- package/dist/dts/NodeSdk.d.ts +4 -1
- package/dist/dts/NodeSdk.d.ts.map +1 -1
- package/dist/dts/Resource.d.ts +9 -0
- package/dist/dts/Resource.d.ts.map +1 -1
- package/dist/dts/WebSdk.d.ts +4 -1
- package/dist/dts/WebSdk.d.ts.map +1 -1
- package/dist/dts/index.d.ts +4 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/utils.d.ts +2 -0
- package/dist/dts/internal/utils.d.ts.map +1 -0
- package/dist/esm/Logger.js +74 -0
- package/dist/esm/Logger.js.map +1 -0
- package/dist/esm/NodeSdk.js +8 -4
- package/dist/esm/NodeSdk.js.map +1 -1
- package/dist/esm/Resource.js +11 -6
- package/dist/esm/Resource.js.map +1 -1
- package/dist/esm/WebSdk.js +7 -3
- package/dist/esm/WebSdk.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/tracer.js +1 -19
- package/dist/esm/internal/tracer.js.map +1 -1
- package/dist/esm/internal/utils.js +23 -0
- package/dist/esm/internal/utils.js.map +1 -0
- package/package.json +13 -2
- package/src/Logger.ts +111 -0
- package/src/NodeSdk.ts +24 -15
- package/src/Resource.ts +20 -9
- package/src/WebSdk.ts +23 -10
- package/src/index.ts +5 -0
- package/src/internal/tracer.ts +1 -22
- package/src/internal/utils.ts +31 -0
package/src/NodeSdk.ts
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
4
|
import type * as Resources from "@opentelemetry/resources"
|
|
5
|
+
import type { LoggerProviderConfig, LogRecordProcessor } from "@opentelemetry/sdk-logs"
|
|
5
6
|
import type { MetricReader } from "@opentelemetry/sdk-metrics"
|
|
6
7
|
import type { SpanProcessor, TracerConfig } from "@opentelemetry/sdk-trace-base"
|
|
7
8
|
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"
|
|
8
9
|
import type { NonEmptyReadonlyArray } from "effect/Array"
|
|
9
10
|
import * as Effect from "effect/Effect"
|
|
10
|
-
import type
|
|
11
|
+
import { constant, type LazyArg } from "effect/Function"
|
|
11
12
|
import * as Layer from "effect/Layer"
|
|
13
|
+
import { isNonEmpty } from "./internal/utils.js"
|
|
14
|
+
import * as Logger from "./Logger.js"
|
|
12
15
|
import * as Metrics from "./Metrics.js"
|
|
13
16
|
import * as Resource from "./Resource.js"
|
|
14
17
|
import * as Tracer from "./Tracer.js"
|
|
@@ -21,6 +24,8 @@ export interface Configuration {
|
|
|
21
24
|
readonly spanProcessor?: SpanProcessor | ReadonlyArray<SpanProcessor> | undefined
|
|
22
25
|
readonly tracerConfig?: Omit<TracerConfig, "resource"> | undefined
|
|
23
26
|
readonly metricReader?: MetricReader | ReadonlyArray<MetricReader> | undefined
|
|
27
|
+
readonly logRecordProcessor?: LogRecordProcessor | ReadonlyArray<LogRecordProcessor> | undefined
|
|
28
|
+
readonly loggerProviderConfig?: Omit<LoggerProviderConfig, "resource"> | undefined
|
|
24
29
|
readonly resource?: {
|
|
25
30
|
readonly serviceName: string
|
|
26
31
|
readonly serviceVersion?: string
|
|
@@ -83,20 +88,24 @@ export const layer: {
|
|
|
83
88
|
? evaluate as Effect.Effect<Configuration>
|
|
84
89
|
: Effect.sync(evaluate),
|
|
85
90
|
(config) => {
|
|
86
|
-
const ResourceLive = config.resource
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
91
|
+
const ResourceLive = Resource.layerFromEnv(config.resource && Resource.configToAttributes(config.resource))
|
|
92
|
+
|
|
93
|
+
const TracerLive = isNonEmpty(config.spanProcessor)
|
|
94
|
+
? Layer.provide(Tracer.layer, layerTracerProvider(config.spanProcessor, config.tracerConfig))
|
|
95
|
+
: Layer.empty
|
|
96
|
+
|
|
97
|
+
const MetricsLive = isNonEmpty(config.metricReader)
|
|
98
|
+
? Metrics.layer(constant(config.metricReader))
|
|
99
|
+
: Layer.empty
|
|
100
|
+
|
|
101
|
+
const LoggerLive = isNonEmpty(config.logRecordProcessor)
|
|
102
|
+
? Layer.provide(
|
|
103
|
+
Logger.layerLoggerAdd,
|
|
104
|
+
Logger.layerLoggerProvider(config.logRecordProcessor, config.loggerProviderConfig)
|
|
105
|
+
)
|
|
106
|
+
: Layer.empty
|
|
107
|
+
|
|
108
|
+
return Layer.mergeAll(TracerLive, MetricsLive, LoggerLive).pipe(
|
|
100
109
|
Layer.provideMerge(ResourceLive)
|
|
101
110
|
)
|
|
102
111
|
}
|
package/src/Resource.ts
CHANGED
|
@@ -39,22 +39,33 @@ export const layer = (config: {
|
|
|
39
39
|
readonly serviceName: string
|
|
40
40
|
readonly serviceVersion?: string
|
|
41
41
|
readonly attributes?: Resources.ResourceAttributes
|
|
42
|
-
}) =>
|
|
42
|
+
}) =>
|
|
43
|
+
Layer.succeed(
|
|
44
|
+
Resource,
|
|
45
|
+
new Resources.Resource(configToAttributes(config))
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @since 1.0.0
|
|
50
|
+
* @category config
|
|
51
|
+
*/
|
|
52
|
+
export const configToAttributes = (options: {
|
|
53
|
+
readonly serviceName: string
|
|
54
|
+
readonly serviceVersion?: string
|
|
55
|
+
readonly attributes?: Resources.ResourceAttributes
|
|
56
|
+
}): Record<string, string> => {
|
|
43
57
|
const attributes: Record<string, string> = {
|
|
44
|
-
...(
|
|
45
|
-
[SEMRESATTRS_SERVICE_NAME]:
|
|
58
|
+
...(options.attributes ?? undefined),
|
|
59
|
+
[SEMRESATTRS_SERVICE_NAME]: options.serviceName,
|
|
46
60
|
[SEMRESATTRS_TELEMETRY_SDK_NAME]: "@effect/opentelemetry",
|
|
47
61
|
[SEMRESATTRS_TELEMETRY_SDK_LANGUAGE]: typeof (globalThis as any).document === "undefined"
|
|
48
62
|
? TELEMETRYSDKLANGUAGEVALUES_NODEJS
|
|
49
63
|
: TELEMETRYSDKLANGUAGEVALUES_WEBJS
|
|
50
64
|
}
|
|
51
|
-
if (
|
|
52
|
-
attributes[SEMRESATTRS_SERVICE_VERSION] =
|
|
65
|
+
if (options.serviceVersion) {
|
|
66
|
+
attributes[SEMRESATTRS_SERVICE_VERSION] = options.serviceVersion
|
|
53
67
|
}
|
|
54
|
-
return
|
|
55
|
-
Resource,
|
|
56
|
-
new Resources.Resource(attributes)
|
|
57
|
-
)
|
|
68
|
+
return attributes
|
|
58
69
|
}
|
|
59
70
|
|
|
60
71
|
/**
|
package/src/WebSdk.ts
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
4
|
import type * as Resources from "@opentelemetry/resources"
|
|
5
|
+
import type { LoggerProviderConfig, LogRecordProcessor } from "@opentelemetry/sdk-logs"
|
|
5
6
|
import type { MetricReader } from "@opentelemetry/sdk-metrics"
|
|
6
7
|
import type { SpanProcessor, TracerConfig } from "@opentelemetry/sdk-trace-base"
|
|
7
8
|
import { WebTracerProvider } from "@opentelemetry/sdk-trace-web"
|
|
8
9
|
import type { NonEmptyReadonlyArray } from "effect/Array"
|
|
9
10
|
import * as Effect from "effect/Effect"
|
|
10
|
-
import type
|
|
11
|
+
import { constant, type LazyArg } from "effect/Function"
|
|
11
12
|
import * as Layer from "effect/Layer"
|
|
13
|
+
import { isNonEmpty } from "./internal/utils.js"
|
|
14
|
+
import * as Logger from "./Logger.js"
|
|
12
15
|
import * as Metrics from "./Metrics.js"
|
|
13
16
|
import * as Resource from "./Resource.js"
|
|
14
17
|
import * as Tracer from "./Tracer.js"
|
|
@@ -21,6 +24,8 @@ export interface Configuration {
|
|
|
21
24
|
readonly spanProcessor?: SpanProcessor | ReadonlyArray<SpanProcessor> | undefined
|
|
22
25
|
readonly tracerConfig?: Omit<TracerConfig, "resource">
|
|
23
26
|
readonly metricReader?: MetricReader | ReadonlyArray<MetricReader> | undefined
|
|
27
|
+
readonly logRecordProcessor?: LogRecordProcessor | ReadonlyArray<LogRecordProcessor> | undefined
|
|
28
|
+
readonly loggerProviderConfig?: Omit<LoggerProviderConfig, "resource"> | undefined
|
|
24
29
|
readonly resource: {
|
|
25
30
|
readonly serviceName: string
|
|
26
31
|
readonly serviceVersion?: string
|
|
@@ -84,15 +89,23 @@ export const layer: {
|
|
|
84
89
|
: Effect.sync(evaluate),
|
|
85
90
|
(config) => {
|
|
86
91
|
const ResourceLive = Resource.layer(config.resource)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
|
|
93
|
+
const TracerLive = isNonEmpty(config.spanProcessor)
|
|
94
|
+
? Layer.provide(Tracer.layer, layerTracerProvider(config.spanProcessor, config.tracerConfig))
|
|
95
|
+
: Layer.empty
|
|
96
|
+
|
|
97
|
+
const LoggerLive = isNonEmpty(config.logRecordProcessor)
|
|
98
|
+
? Layer.provide(
|
|
99
|
+
Logger.layerLoggerAdd,
|
|
100
|
+
Logger.layerLoggerProvider(config.logRecordProcessor, config.loggerProviderConfig)
|
|
101
|
+
)
|
|
102
|
+
: Layer.empty
|
|
103
|
+
|
|
104
|
+
const MetricsLive = isNonEmpty(config.metricReader)
|
|
105
|
+
? Metrics.layer(constant(config.metricReader))
|
|
106
|
+
: Layer.empty
|
|
107
|
+
|
|
108
|
+
return Layer.mergeAll(TracerLive, MetricsLive, LoggerLive).pipe(
|
|
96
109
|
Layer.provideMerge(ResourceLive)
|
|
97
110
|
)
|
|
98
111
|
}
|
package/src/index.ts
CHANGED
package/src/internal/tracer.ts
CHANGED
|
@@ -4,12 +4,12 @@ import * as Context from "effect/Context"
|
|
|
4
4
|
import * as Effect from "effect/Effect"
|
|
5
5
|
import type { Exit } from "effect/Exit"
|
|
6
6
|
import { dual } from "effect/Function"
|
|
7
|
-
import * as Inspectable from "effect/Inspectable"
|
|
8
7
|
import * as Layer from "effect/Layer"
|
|
9
8
|
import * as Option from "effect/Option"
|
|
10
9
|
import * as EffectTracer from "effect/Tracer"
|
|
11
10
|
import { Resource } from "../Resource.js"
|
|
12
11
|
import type { OtelTraceFlags, OtelTracer, OtelTracerProvider, OtelTraceState } from "../Tracer.js"
|
|
12
|
+
import { nanosToHrTime, recordToAttributes, unknownToAttributeValue } from "./utils.js"
|
|
13
13
|
|
|
14
14
|
const OtelSpanTypeId = Symbol.for("@effect/opentelemetry/Tracer/OtelSpan")
|
|
15
15
|
|
|
@@ -257,11 +257,6 @@ export const layer = layerWithoutOtelTracer.pipe(
|
|
|
257
257
|
// utils
|
|
258
258
|
// -------------------------------------------------------------------------------------
|
|
259
259
|
|
|
260
|
-
const bigint1e9 = 1_000_000_000n
|
|
261
|
-
const nanosToHrTime = (timestamp: bigint): OtelApi.HrTime => {
|
|
262
|
-
return [Number(timestamp / bigint1e9), Number(timestamp % bigint1e9)]
|
|
263
|
-
}
|
|
264
|
-
|
|
265
260
|
const createTraceState = Option.liftThrowable(OtelApi.createTraceState)
|
|
266
261
|
|
|
267
262
|
const populateContext = (
|
|
@@ -300,22 +295,6 @@ const extractTraceTag = <I, S>(
|
|
|
300
295
|
() => Context.getOption(parent.context, tag)
|
|
301
296
|
)
|
|
302
297
|
|
|
303
|
-
const recordToAttributes = (value: Record<string, unknown>): OtelApi.Attributes => {
|
|
304
|
-
return Object.entries(value).reduce((acc, [key, value]) => {
|
|
305
|
-
acc[key] = unknownToAttributeValue(value)
|
|
306
|
-
return acc
|
|
307
|
-
}, {} as OtelApi.Attributes)
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const unknownToAttributeValue = (value: unknown): OtelApi.AttributeValue => {
|
|
311
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
312
|
-
return value
|
|
313
|
-
} else if (typeof value === "bigint") {
|
|
314
|
-
return Number(value)
|
|
315
|
-
}
|
|
316
|
-
return Inspectable.toStringUnknown(value)
|
|
317
|
-
}
|
|
318
|
-
|
|
319
298
|
/** @internal */
|
|
320
299
|
export const withSpanContext = dual<
|
|
321
300
|
(
|
|
@@ -0,0 +1,31 @@
|
|
|
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 Number(value)
|
|
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)
|