@effect/opentelemetry 0.61.0 → 4.0.0-beta.1

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 (183) 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/index.js +29 -0
  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 +86 -119
  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 -36
  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/OtlpSerialization/package.json +0 -6
  60. package/OtlpTracer/package.json +0 -6
  61. package/Resource/package.json +0 -6
  62. package/Tracer/package.json +0 -6
  63. package/WebSdk/package.json +0 -6
  64. package/dist/cjs/Logger.js +0 -85
  65. package/dist/cjs/Logger.js.map +0 -1
  66. package/dist/cjs/Metrics.js +0 -24
  67. package/dist/cjs/Metrics.js.map +0 -1
  68. package/dist/cjs/NodeSdk.js +0 -53
  69. package/dist/cjs/NodeSdk.js.map +0 -1
  70. package/dist/cjs/Otlp.js +0 -64
  71. package/dist/cjs/Otlp.js.map +0 -1
  72. package/dist/cjs/OtlpLogger.js +0 -163
  73. package/dist/cjs/OtlpLogger.js.map +0 -1
  74. package/dist/cjs/OtlpMetrics.js +0 -357
  75. package/dist/cjs/OtlpMetrics.js.map +0 -1
  76. package/dist/cjs/OtlpResource.js +0 -136
  77. package/dist/cjs/OtlpResource.js.map +0 -1
  78. package/dist/cjs/OtlpSerialization.js +0 -55
  79. package/dist/cjs/OtlpSerialization.js.map +0 -1
  80. package/dist/cjs/OtlpTracer.js +0 -231
  81. package/dist/cjs/OtlpTracer.js.map +0 -1
  82. package/dist/cjs/Resource.js +0 -75
  83. package/dist/cjs/Resource.js.map +0 -1
  84. package/dist/cjs/Tracer.js +0 -87
  85. package/dist/cjs/Tracer.js.map +0 -1
  86. package/dist/cjs/WebSdk.js +0 -42
  87. package/dist/cjs/WebSdk.js.map +0 -1
  88. package/dist/cjs/index.js +0 -32
  89. package/dist/cjs/index.js.map +0 -1
  90. package/dist/cjs/internal/metrics.js +0 -288
  91. package/dist/cjs/internal/metrics.js.map +0 -1
  92. package/dist/cjs/internal/otlpExporter.js +0 -83
  93. package/dist/cjs/internal/otlpExporter.js.map +0 -1
  94. package/dist/cjs/internal/otlpProtobuf.js +0 -430
  95. package/dist/cjs/internal/otlpProtobuf.js.map +0 -1
  96. package/dist/cjs/internal/protobuf.js +0 -183
  97. package/dist/cjs/internal/protobuf.js.map +0 -1
  98. package/dist/cjs/internal/tracer.js +0 -306
  99. package/dist/cjs/internal/tracer.js.map +0 -1
  100. package/dist/cjs/internal/utils.js +0 -34
  101. package/dist/cjs/internal/utils.js.map +0 -1
  102. package/dist/dts/Logger.d.ts.map +0 -1
  103. package/dist/dts/Metrics.d.ts +0 -29
  104. package/dist/dts/Metrics.d.ts.map +0 -1
  105. package/dist/dts/NodeSdk.d.ts.map +0 -1
  106. package/dist/dts/Otlp.d.ts +0 -80
  107. package/dist/dts/Otlp.d.ts.map +0 -1
  108. package/dist/dts/OtlpLogger.d.ts +0 -47
  109. package/dist/dts/OtlpLogger.d.ts.map +0 -1
  110. package/dist/dts/OtlpMetrics.d.ts +0 -41
  111. package/dist/dts/OtlpMetrics.d.ts.map +0 -1
  112. package/dist/dts/OtlpResource.d.ts +0 -104
  113. package/dist/dts/OtlpResource.d.ts.map +0 -1
  114. package/dist/dts/OtlpSerialization.d.ts +0 -53
  115. package/dist/dts/OtlpSerialization.d.ts.map +0 -1
  116. package/dist/dts/OtlpTracer.d.ts +0 -50
  117. package/dist/dts/OtlpTracer.d.ts.map +0 -1
  118. package/dist/dts/Resource.d.ts.map +0 -1
  119. package/dist/dts/Tracer.d.ts +0 -143
  120. package/dist/dts/Tracer.d.ts.map +0 -1
  121. package/dist/dts/WebSdk.d.ts.map +0 -1
  122. package/dist/dts/index.d.ts +0 -54
  123. package/dist/dts/index.d.ts.map +0 -1
  124. package/dist/dts/internal/otlpExporter.d.ts +0 -2
  125. package/dist/dts/internal/otlpExporter.d.ts.map +0 -1
  126. package/dist/dts/internal/otlpProtobuf.d.ts +0 -501
  127. package/dist/dts/internal/otlpProtobuf.d.ts.map +0 -1
  128. package/dist/dts/internal/protobuf.d.ts +0 -100
  129. package/dist/dts/internal/protobuf.d.ts.map +0 -1
  130. package/dist/dts/internal/tracer.d.ts +0 -2
  131. package/dist/dts/internal/tracer.d.ts.map +0 -1
  132. package/dist/dts/internal/utils.d.ts +0 -2
  133. package/dist/dts/internal/utils.d.ts.map +0 -1
  134. package/dist/esm/Logger.js +0 -75
  135. package/dist/esm/Logger.js.map +0 -1
  136. package/dist/esm/Metrics.js +0 -17
  137. package/dist/esm/Metrics.js.map +0 -1
  138. package/dist/esm/NodeSdk.js.map +0 -1
  139. package/dist/esm/Otlp.js +0 -56
  140. package/dist/esm/Otlp.js.map +0 -1
  141. package/dist/esm/OtlpLogger.js +0 -155
  142. package/dist/esm/OtlpLogger.js.map +0 -1
  143. package/dist/esm/OtlpMetrics.js +0 -349
  144. package/dist/esm/OtlpMetrics.js.map +0 -1
  145. package/dist/esm/OtlpResource.js +0 -124
  146. package/dist/esm/OtlpResource.js.map +0 -1
  147. package/dist/esm/OtlpSerialization.js +0 -46
  148. package/dist/esm/OtlpSerialization.js.map +0 -1
  149. package/dist/esm/OtlpTracer.js +0 -223
  150. package/dist/esm/OtlpTracer.js.map +0 -1
  151. package/dist/esm/Resource.js.map +0 -1
  152. package/dist/esm/Tracer.js +0 -80
  153. package/dist/esm/Tracer.js.map +0 -1
  154. package/dist/esm/WebSdk.js +0 -33
  155. package/dist/esm/WebSdk.js.map +0 -1
  156. package/dist/esm/index.js +0 -54
  157. package/dist/esm/index.js.map +0 -1
  158. package/dist/esm/internal/metrics.js +0 -278
  159. package/dist/esm/internal/metrics.js.map +0 -1
  160. package/dist/esm/internal/otlpExporter.js +0 -76
  161. package/dist/esm/internal/otlpExporter.js.map +0 -1
  162. package/dist/esm/internal/otlpProtobuf.js +0 -396
  163. package/dist/esm/internal/otlpProtobuf.js.map +0 -1
  164. package/dist/esm/internal/protobuf.js +0 -155
  165. package/dist/esm/internal/protobuf.js.map +0 -1
  166. package/dist/esm/internal/tracer.js +0 -297
  167. package/dist/esm/internal/tracer.js.map +0 -1
  168. package/dist/esm/internal/utils.js +0 -23
  169. package/dist/esm/internal/utils.js.map +0 -1
  170. package/dist/esm/package.json +0 -4
  171. package/index/package.json +0 -6
  172. package/src/Otlp.ts +0 -118
  173. package/src/OtlpLogger.ts +0 -263
  174. package/src/OtlpMetrics.ts +0 -575
  175. package/src/OtlpResource.ts +0 -232
  176. package/src/OtlpSerialization.ts +0 -64
  177. package/src/OtlpTracer.ts +0 -352
  178. package/src/internal/otlpExporter.ts +0 -126
  179. package/src/internal/otlpProtobuf.ts +0 -729
  180. package/src/internal/protobuf.ts +0 -219
  181. package/src/internal/tracer.ts +0 -448
  182. package/src/internal/utils.ts +0 -31
  183. /package/dist/{dts/internal → internal}/metrics.d.ts +0 -0
package/package.json CHANGED
@@ -1,15 +1,58 @@
1
1
  {
2
2
  "name": "@effect/opentelemetry",
3
- "version": "0.61.0",
4
- "description": "OpenTelemetry integration for Effect",
3
+ "type": "module",
4
+ "version": "4.0.0-beta.1",
5
5
  "license": "MIT",
6
+ "description": "OpenTelemetry integration for Effect",
7
+ "homepage": "https://effect.website",
6
8
  "repository": {
7
9
  "type": "git",
8
- "url": "https://github.com/Effect-TS/effect.git",
10
+ "url": "https://github.com/Effect-TS/effect-smol.git",
9
11
  "directory": "packages/opentelemetry"
10
12
  },
13
+ "bugs": {
14
+ "url": "https://github.com/Effect-TS/effect-smol/issues"
15
+ },
16
+ "tags": [
17
+ "opentelemetry",
18
+ "observability",
19
+ "tracing",
20
+ "metrics",
21
+ "typescript",
22
+ "algebraic-data-types",
23
+ "functional-programming"
24
+ ],
25
+ "keywords": [
26
+ "opentelemetry",
27
+ "observability",
28
+ "tracing",
29
+ "metrics",
30
+ "typescript",
31
+ "algebraic-data-types",
32
+ "functional-programming"
33
+ ],
34
+ "engines": {
35
+ "node": ">=18.0.0"
36
+ },
11
37
  "sideEffects": [],
12
- "homepage": "https://effect.website",
38
+ "exports": {
39
+ "./package.json": "./package.json",
40
+ ".": "./dist/index.js",
41
+ "./*": "./dist/*.js",
42
+ "./internal/*": null,
43
+ "./*/index": null
44
+ },
45
+ "files": [
46
+ "src/**/*.ts",
47
+ "dist/**/*.js",
48
+ "dist/**/*.js.map",
49
+ "dist/**/*.d.ts",
50
+ "dist/**/*.d.ts.map"
51
+ ],
52
+ "publishConfig": {
53
+ "access": "public",
54
+ "provenance": true
55
+ },
13
56
  "peerDependencies": {
14
57
  "@opentelemetry/api": "^1.9",
15
58
  "@opentelemetry/resources": "^2.0.0",
@@ -19,129 +62,53 @@
19
62
  "@opentelemetry/sdk-trace-node": "^2.0.0",
20
63
  "@opentelemetry/sdk-trace-web": "^2.0.0",
21
64
  "@opentelemetry/semantic-conventions": "^1.33.0",
22
- "@effect/platform": "^0.94.2",
23
- "effect": "^3.19.15"
24
- },
25
- "publishConfig": {
26
- "provenance": true
65
+ "effect": "^4.0.0-beta.1"
27
66
  },
28
- "main": "./dist/cjs/index.js",
29
- "module": "./dist/esm/index.js",
30
- "types": "./dist/dts/index.d.ts",
31
- "exports": {
32
- "./package.json": "./package.json",
33
- ".": {
34
- "types": "./dist/dts/index.d.ts",
35
- "import": "./dist/esm/index.js",
36
- "default": "./dist/cjs/index.js"
37
- },
38
- "./Logger": {
39
- "types": "./dist/dts/Logger.d.ts",
40
- "import": "./dist/esm/Logger.js",
41
- "default": "./dist/cjs/Logger.js"
42
- },
43
- "./Metrics": {
44
- "types": "./dist/dts/Metrics.d.ts",
45
- "import": "./dist/esm/Metrics.js",
46
- "default": "./dist/cjs/Metrics.js"
47
- },
48
- "./NodeSdk": {
49
- "types": "./dist/dts/NodeSdk.d.ts",
50
- "import": "./dist/esm/NodeSdk.js",
51
- "default": "./dist/cjs/NodeSdk.js"
67
+ "peerDependenciesMeta": {
68
+ "@opentelemetry/api": {
69
+ "optional": true
52
70
  },
53
- "./Otlp": {
54
- "types": "./dist/dts/Otlp.d.ts",
55
- "import": "./dist/esm/Otlp.js",
56
- "default": "./dist/cjs/Otlp.js"
71
+ "@opentelemetry/resources": {
72
+ "optional": true
57
73
  },
58
- "./OtlpLogger": {
59
- "types": "./dist/dts/OtlpLogger.d.ts",
60
- "import": "./dist/esm/OtlpLogger.js",
61
- "default": "./dist/cjs/OtlpLogger.js"
74
+ "@opentelemetry/sdk-metrics": {
75
+ "optional": true
62
76
  },
63
- "./OtlpMetrics": {
64
- "types": "./dist/dts/OtlpMetrics.d.ts",
65
- "import": "./dist/esm/OtlpMetrics.js",
66
- "default": "./dist/cjs/OtlpMetrics.js"
77
+ "@opentelemetry/sdk-trace-base": {
78
+ "optional": true
67
79
  },
68
- "./OtlpResource": {
69
- "types": "./dist/dts/OtlpResource.d.ts",
70
- "import": "./dist/esm/OtlpResource.js",
71
- "default": "./dist/cjs/OtlpResource.js"
80
+ "@opentelemetry/sdk-trace-node": {
81
+ "optional": true
72
82
  },
73
- "./OtlpSerialization": {
74
- "types": "./dist/dts/OtlpSerialization.d.ts",
75
- "import": "./dist/esm/OtlpSerialization.js",
76
- "default": "./dist/cjs/OtlpSerialization.js"
83
+ "@opentelemetry/sdk-trace-web": {
84
+ "optional": true
77
85
  },
78
- "./OtlpTracer": {
79
- "types": "./dist/dts/OtlpTracer.d.ts",
80
- "import": "./dist/esm/OtlpTracer.js",
81
- "default": "./dist/cjs/OtlpTracer.js"
82
- },
83
- "./Resource": {
84
- "types": "./dist/dts/Resource.d.ts",
85
- "import": "./dist/esm/Resource.js",
86
- "default": "./dist/cjs/Resource.js"
87
- },
88
- "./Tracer": {
89
- "types": "./dist/dts/Tracer.d.ts",
90
- "import": "./dist/esm/Tracer.js",
91
- "default": "./dist/cjs/Tracer.js"
92
- },
93
- "./WebSdk": {
94
- "types": "./dist/dts/WebSdk.d.ts",
95
- "import": "./dist/esm/WebSdk.js",
96
- "default": "./dist/cjs/WebSdk.js"
97
- },
98
- "./index": {
99
- "types": "./dist/dts/index.d.ts",
100
- "import": "./dist/esm/index.js",
101
- "default": "./dist/cjs/index.js"
86
+ "@opentelemetry/sdk-logs": {
87
+ "optional": true
102
88
  }
103
89
  },
104
- "typesVersions": {
105
- "*": {
106
- "Logger": [
107
- "./dist/dts/Logger.d.ts"
108
- ],
109
- "Metrics": [
110
- "./dist/dts/Metrics.d.ts"
111
- ],
112
- "NodeSdk": [
113
- "./dist/dts/NodeSdk.d.ts"
114
- ],
115
- "Otlp": [
116
- "./dist/dts/Otlp.d.ts"
117
- ],
118
- "OtlpLogger": [
119
- "./dist/dts/OtlpLogger.d.ts"
120
- ],
121
- "OtlpMetrics": [
122
- "./dist/dts/OtlpMetrics.d.ts"
123
- ],
124
- "OtlpResource": [
125
- "./dist/dts/OtlpResource.d.ts"
126
- ],
127
- "OtlpSerialization": [
128
- "./dist/dts/OtlpSerialization.d.ts"
129
- ],
130
- "OtlpTracer": [
131
- "./dist/dts/OtlpTracer.d.ts"
132
- ],
133
- "Resource": [
134
- "./dist/dts/Resource.d.ts"
135
- ],
136
- "Tracer": [
137
- "./dist/dts/Tracer.d.ts"
138
- ],
139
- "WebSdk": [
140
- "./dist/dts/WebSdk.d.ts"
141
- ],
142
- "index": [
143
- "./dist/dts/index.d.ts"
144
- ]
145
- }
90
+ "devDependencies": {
91
+ "@opentelemetry/api": "^1.9.0",
92
+ "@opentelemetry/context-async-hooks": "^2.5.0",
93
+ "@opentelemetry/exporter-metrics-otlp-http": "0.211.0",
94
+ "@opentelemetry/exporter-prometheus": "^0.211.0",
95
+ "@opentelemetry/exporter-trace-otlp-http": "^0.211.0",
96
+ "@opentelemetry/otlp-exporter-base": "^0.211.0",
97
+ "@opentelemetry/resources": "^2.5.0",
98
+ "@opentelemetry/sdk-logs": "^0.211.0",
99
+ "@opentelemetry/sdk-metrics": "^2.5.0",
100
+ "@opentelemetry/sdk-trace-base": "^2.5.0",
101
+ "@opentelemetry/sdk-trace-node": "^2.5.0",
102
+ "@opentelemetry/sdk-trace-web": "^2.5.0",
103
+ "@opentelemetry/semantic-conventions": "^1.39.0"
104
+ },
105
+ "scripts": {
106
+ "codegen": "effect-utils codegen",
107
+ "build": "tsc -b tsconfig.json && pnpm babel",
108
+ "build:tsgo": "tsgo -b tsconfig.json && pnpm babel",
109
+ "babel": "babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
110
+ "check": "tsc -b tsconfig.json",
111
+ "test": "vitest",
112
+ "coverage": "vitest --coverage"
146
113
  }
147
114
  }
package/src/Logger.ts CHANGED
@@ -4,30 +4,30 @@
4
4
  import * as Otel from "@opentelemetry/sdk-logs"
5
5
  import type { NonEmptyReadonlyArray } from "effect/Array"
6
6
  import * as Arr from "effect/Array"
7
- import * as Context from "effect/Context"
7
+ import * as Clock from "effect/Clock"
8
8
  import type { DurationInput } from "effect/Duration"
9
9
  import * as Effect from "effect/Effect"
10
- import * as FiberId from "effect/FiberId"
11
- import * as FiberRef from "effect/FiberRef"
12
- import * as FiberRefs from "effect/FiberRefs"
13
10
  import * as Layer from "effect/Layer"
14
11
  import * as Logger from "effect/Logger"
12
+ import * as LogLevel from "effect/LogLevel"
13
+ import * as Predicate from "effect/Predicate"
14
+ import * as ServiceMap from "effect/ServiceMap"
15
15
  import * as Tracer from "effect/Tracer"
16
- import { unknownToAttributeValue } from "./internal/utils.js"
17
- import { Resource } from "./Resource.js"
16
+ import { unknownToAttributeValue } from "./internal/attributes.ts"
17
+ import { Resource } from "./Resource.ts"
18
18
 
19
19
  /**
20
20
  * @since 1.0.0
21
- * @category tags
21
+ * @category Services
22
22
  */
23
- export class OtelLoggerProvider extends Context.Tag("@effect/opentelemetry/Logger/OtelLoggerProvider")<
23
+ export class OtelLoggerProvider extends ServiceMap.Service<
24
24
  OtelLoggerProvider,
25
25
  Otel.LoggerProvider
26
- >() {}
26
+ >()("@effect/opentelemetry/Logger/OtelLoggerProvider") {}
27
27
 
28
28
  /**
29
29
  * @since 1.0.0
30
- * @category constructors
30
+ * @category Constructors
31
31
  */
32
32
  export const make: Effect.Effect<
33
33
  Logger.Logger<unknown, void>,
@@ -35,40 +35,37 @@ export const make: Effect.Effect<
35
35
  OtelLoggerProvider
36
36
  > = Effect.gen(function*() {
37
37
  const loggerProvider = yield* OtelLoggerProvider
38
- const clock = yield* Effect.clock
38
+ const clock = yield* Clock.Clock
39
39
  const otelLogger = loggerProvider.getLogger("@effect/opentelemetry")
40
40
 
41
41
  return Logger.make((options) => {
42
- const now = options.date.getTime()
43
-
44
42
  const attributes: Record<string, any> = {
45
- fiberId: FiberId.threadName(options.fiberId)
43
+ fiberId: options.fiber.id
46
44
  }
47
45
 
48
- const maybeSpan = Context.getOption(
49
- FiberRefs.getOrDefault(options.context, FiberRef.currentContext),
50
- Tracer.ParentSpan
51
- )
46
+ const span = ServiceMap.getOrUndefined(options.fiber.services, Tracer.ParentSpan)
52
47
 
53
- if (maybeSpan._tag === "Some") {
54
- attributes.spanId = maybeSpan.value.spanId
55
- attributes.traceId = maybeSpan.value.traceId
48
+ if (Predicate.isNotUndefined(span)) {
49
+ attributes.spanId = span.spanId
50
+ attributes.traceId = span.traceId
56
51
  }
57
52
 
58
- for (const [key, value] of options.annotations) {
59
- attributes[key] = unknownToAttributeValue(value)
60
- }
61
- for (const span of options.spans) {
62
- attributes[`logSpan.${span.label}`] = `${now - span.startTime}ms`
63
- }
53
+ // TODO: add back after log spans / annotations
54
+ // for (const [key, value] of options.annotations) {
55
+ // attributes[key] = unknownToAttributeValue(value)
56
+ // }
57
+ // const now = options.date.getTime()
58
+ // for (const span of options.spans) {
59
+ // attributes[`logSpan.${span.label}`] = `${now - span.startTime}ms`
60
+ // }
64
61
 
65
62
  const message = Arr.ensure(options.message).map(unknownToAttributeValue)
66
63
  otelLogger.emit({
67
64
  body: message.length === 1 ? message[0] : message,
68
- severityText: options.logLevel.label,
69
- severityNumber: options.logLevel.ordinal,
65
+ severityText: options.logLevel,
66
+ severityNumber: LogLevel.getOrdinal(options.logLevel),
70
67
  timestamp: options.date,
71
- observedTimestamp: clock.unsafeCurrentTimeMillis(),
68
+ observedTimestamp: clock.currentTimeMillisUnsafe(),
72
69
  attributes
73
70
  })
74
71
  })
@@ -76,27 +73,27 @@ export const make: Effect.Effect<
76
73
 
77
74
  /**
78
75
  * @since 1.0.0
79
- * @category layers
76
+ * @category Layers
80
77
  */
81
- export const layerLoggerAdd: Layer.Layer<
82
- never,
83
- never,
84
- OtelLoggerProvider
85
- > = Logger.addEffect(make)
86
-
87
- /**
88
- * @since 1.0.0
89
- * @category layers
90
- */
91
- export const layerLoggerReplace: Layer.Layer<
92
- never,
93
- never,
94
- OtelLoggerProvider
95
- > = Logger.replaceEffect(Logger.defaultLogger, make)
78
+ export const layer = (options: {
79
+ /**
80
+ * If set to `true`, the OpenTelemetry logger will be merged with existing
81
+ * loggers in the application.
82
+ *
83
+ * If set to `false`, the OpenTelemetry logger will replace all existing
84
+ * loggers in the application.
85
+ *
86
+ * Defaults to `true`.
87
+ */
88
+ readonly mergeWithExisting?: boolean | undefined
89
+ }): Layer.Layer<never, never, OtelLoggerProvider> =>
90
+ Logger.layer([make], {
91
+ mergeWithExisting: options.mergeWithExisting ?? true
92
+ })
96
93
 
97
94
  /**
98
95
  * @since 1.0.0
99
- * @category layers
96
+ * @category Layers
100
97
  */
101
98
  export const layerLoggerProvider = (
102
99
  processor: Otel.LogRecordProcessor | NonEmptyReadonlyArray<Otel.LogRecordProcessor>,
@@ -104,10 +101,11 @@ export const layerLoggerProvider = (
104
101
  readonly shutdownTimeout?: DurationInput | undefined
105
102
  }
106
103
  ): Layer.Layer<OtelLoggerProvider, never, Resource> =>
107
- Layer.scoped(
104
+ Layer.effect(
108
105
  OtelLoggerProvider,
109
- Effect.flatMap(Resource, (resource) =>
110
- Effect.acquireRelease(
106
+ Effect.gen(function*() {
107
+ const resource = yield* Resource
108
+ return yield* Effect.acquireRelease(
111
109
  Effect.sync(() =>
112
110
  new Otel.LoggerProvider({
113
111
  ...(config ?? undefined),
@@ -116,12 +114,11 @@ export const layerLoggerProvider = (
116
114
  })
117
115
  ),
118
116
  (provider) =>
119
- Effect.promise(
120
- () => provider.forceFlush().then(() => provider.shutdown())
121
- ).pipe(
122
- Effect.ignoreLogged,
117
+ Effect.promise(() => provider.forceFlush().then(() => provider.shutdown())).pipe(
118
+ Effect.ignore,
123
119
  Effect.interruptible,
124
120
  Effect.timeoutOption(config?.shutdownTimeout ?? 3000)
125
121
  )
126
- ))
122
+ )
123
+ })
127
124
  )
package/src/Metrics.ts CHANGED
@@ -2,39 +2,113 @@
2
2
  * @since 1.0.0
3
3
  */
4
4
  import type { MetricProducer, MetricReader } from "@opentelemetry/sdk-metrics"
5
- import type { NonEmptyReadonlyArray } from "effect/Array"
5
+ import type * as Arr from "effect/Array"
6
6
  import type { DurationInput } from "effect/Duration"
7
- import type * as Effect from "effect/Effect"
7
+ import * as Effect from "effect/Effect"
8
8
  import type { LazyArg } from "effect/Function"
9
- import type { Layer } from "effect/Layer"
9
+ import * as Layer from "effect/Layer"
10
10
  import type * as Scope from "effect/Scope"
11
- import * as internal from "./internal/metrics.js"
12
- import type { Resource } from "./Resource.js"
11
+ import { MetricProducerImpl } from "./internal/metrics.ts"
12
+ import { Resource } from "./Resource.ts"
13
13
 
14
14
  /**
15
+ * Determines how metric values relate to the time interval over which they
16
+ * are aggregated.
17
+ *
18
+ * - `cumulative`: Reports total since a fixed start time. Each data point
19
+ * depends on all previous measurements. This is the default behavior.
20
+ *
21
+ * - `delta`: Reports changes since the last export. Each interval is
22
+ * independent with no dependency on previous measurements.
23
+ *
15
24
  * @since 1.0.0
16
- * @category producer
25
+ * @category Models
17
26
  */
18
- export const makeProducer: Effect.Effect<MetricProducer, never, Resource> = internal.makeProducer
27
+ export type TemporalityPreference = "cumulative" | "delta"
19
28
 
20
29
  /**
30
+ * Creates an OpenTelemetry metric producer from Effect metrics.
31
+ *
21
32
  * @since 1.0.0
22
- * @category producer
33
+ * @category Constructors
23
34
  */
24
- export const registerProducer: (
35
+ export const makeProducer = (temporality?: TemporalityPreference): Effect.Effect<MetricProducer, never, Resource> =>
36
+ Effect.gen(function*() {
37
+ const resource = yield* Resource
38
+ const services = yield* Effect.services<never>()
39
+ return new MetricProducerImpl(resource, services, temporality)
40
+ })
41
+
42
+ /**
43
+ * Registers a metric producer with one or more metric readers.
44
+ *
45
+ * @since 1.0.0
46
+ * @category Constructors
47
+ */
48
+ export const registerProducer = (
25
49
  self: MetricProducer,
26
- metricReader: LazyArg<MetricReader | NonEmptyReadonlyArray<MetricReader>>
27
- ) => Effect.Effect<Array<any>, never, Scope.Scope> = internal.registerProducer
50
+ metricReader: LazyArg<MetricReader | Arr.NonEmptyReadonlyArray<MetricReader>>,
51
+ options?: {
52
+ readonly shutdownTimeout?: DurationInput | undefined
53
+ }
54
+ ): Effect.Effect<Array<any>, never, Scope.Scope> =>
55
+ Effect.acquireRelease(
56
+ Effect.sync(() => {
57
+ const reader = metricReader()
58
+ const readers: Array<MetricReader> = Array.isArray(reader) ? reader : [reader] as any
59
+ readers.forEach((reader) => reader.setMetricProducer(self))
60
+ return readers
61
+ }),
62
+ (readers) =>
63
+ Effect.promise(() =>
64
+ Promise.all(
65
+ readers.map((reader) => reader.shutdown())
66
+ )
67
+ ).pipe(
68
+ Effect.ignore,
69
+ Effect.interruptible,
70
+ Effect.timeoutOption(options?.shutdownTimeout ?? 3000)
71
+ )
72
+ )
28
73
 
29
74
  /**
75
+ * Creates a Layer that registers a metric producer with metric readers.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * import { Metrics } from "@effect/opentelemetry"
80
+ * import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics"
81
+ * import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http"
82
+ *
83
+ * const metricExporter = new OTLPMetricExporter({ url: "<your-otel-url>" })
84
+ *
85
+ * // Use delta temporality for backends like Datadog or Dynatrace
86
+ * const metricsLayer = Metrics.layer(
87
+ * () => new PeriodicExportingMetricReader({
88
+ * exporter: metricExporter,
89
+ * exportIntervalMillis: 10000
90
+ * }),
91
+ * { temporality: "delta" }
92
+ * )
93
+ *
94
+ * // Use cumulative temporality for backends like Prometheus (default)
95
+ * const cumulativeLayer = Metrics.layer(
96
+ * () => new PeriodicExportingMetricReader({ exporter: metricExporter }),
97
+ * { temporality: "cumulative" }
98
+ * )
99
+ * ```
100
+ *
30
101
  * @since 1.0.0
31
- * @category layers
102
+ * @category Layers
32
103
  */
33
- export const layer: (
34
- evaluate: LazyArg<MetricReader | NonEmptyReadonlyArray<MetricReader>>,
104
+ export const layer = (
105
+ evaluate: LazyArg<MetricReader | Arr.NonEmptyReadonlyArray<MetricReader>>,
35
106
  options?: {
36
- readonly shutdownTimeout?:
37
- | DurationInput
38
- | undefined
107
+ readonly shutdownTimeout?: DurationInput | undefined
108
+ readonly temporality?: TemporalityPreference | undefined
39
109
  }
40
- ) => Layer<never, never, Resource> = internal.layer
110
+ ): Layer.Layer<never, never, Resource> =>
111
+ Layer.effectDiscard(Effect.flatMap(
112
+ makeProducer(options?.temporality),
113
+ (producer) => registerProducer(producer, evaluate, options)
114
+ ))