@effect/opentelemetry 0.46.0 → 0.46.2

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.
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../dist/cjs/OtlpTracer.js",
3
+ "module": "../dist/esm/OtlpTracer.js",
4
+ "types": "../dist/dts/OtlpTracer.d.ts",
5
+ "sideEffects": []
6
+ }
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.make = exports.layer = void 0;
7
+ var Headers = _interopRequireWildcard(require("@effect/platform/Headers"));
8
+ var HttpBody = _interopRequireWildcard(require("@effect/platform/HttpBody"));
9
+ var HttpClient = _interopRequireWildcard(require("@effect/platform/HttpClient"));
10
+ var HttpClientRequest = _interopRequireWildcard(require("@effect/platform/HttpClientRequest"));
11
+ var Cause = _interopRequireWildcard(require("effect/Cause"));
12
+ var Duration = _interopRequireWildcard(require("effect/Duration"));
13
+ var Effect = _interopRequireWildcard(require("effect/Effect"));
14
+ var Inspectable = _interopRequireWildcard(require("effect/Inspectable"));
15
+ var Layer = _interopRequireWildcard(require("effect/Layer"));
16
+ var Option = _interopRequireWildcard(require("effect/Option"));
17
+ var Schedule = _interopRequireWildcard(require("effect/Schedule"));
18
+ var Scope = _interopRequireWildcard(require("effect/Scope"));
19
+ var Tracer = _interopRequireWildcard(require("effect/Tracer"));
20
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
21
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
22
+ /**
23
+ * @since 1.0.0
24
+ */
25
+
26
+ /**
27
+ * @since 1.0.0
28
+ * @category Constructors
29
+ */
30
+ const make = exports.make = /*#__PURE__*/Effect.fnUntraced(function* (options) {
31
+ const exporterScope = yield* Effect.scope;
32
+ const exportInterval = options.exportInterval ? Duration.decode(options.exportInterval) : Duration.seconds(5);
33
+ const maxBatchSize = options.maxBatchSize ?? 1000;
34
+ const client = HttpClient.filterStatusOk(yield* HttpClient.HttpClient).pipe(HttpClient.tapError(error => {
35
+ if (error._tag !== "ResponseError" || error.response.status !== 429) {
36
+ return Effect.void;
37
+ }
38
+ const retryAfter = error.response.headers["retry-after"];
39
+ const retryAfterSeconds = retryAfter ? parseInt(retryAfter, 10) : 5;
40
+ return Effect.sleep(Duration.seconds(retryAfterSeconds));
41
+ }), HttpClient.retryTransient({
42
+ schedule: Schedule.spaced(1000)
43
+ }));
44
+ let headers = Headers.unsafeFromRecord({
45
+ "user-agent": "@effect-opentelemetry-OtlpExporter"
46
+ });
47
+ if (options.headers) {
48
+ headers = Headers.merge(Headers.fromInput(options.headers), headers);
49
+ }
50
+ const resourceAttributes = options.resource.attributes ? entriesToAttributes(Object.entries(options.resource.attributes)) : [];
51
+ resourceAttributes.push({
52
+ key: "service.name",
53
+ value: {
54
+ stringValue: options.resource.serviceName
55
+ }
56
+ });
57
+ if (options.resource.serviceVersion) {
58
+ resourceAttributes.push({
59
+ key: "service.version",
60
+ value: {
61
+ stringValue: options.resource.serviceVersion
62
+ }
63
+ });
64
+ }
65
+ const otelResource = {
66
+ attributes: resourceAttributes,
67
+ droppedAttributesCount: 0
68
+ };
69
+ const scope = {
70
+ name: options.resource.serviceName
71
+ };
72
+ let spanBuffer = [];
73
+ const exportLatch = Effect.unsafeMakeLatch(false);
74
+ const runExport = Effect.suspend(() => {
75
+ exportLatch.unsafeClose();
76
+ if (spanBuffer.length === 0) {
77
+ return Effect.void;
78
+ }
79
+ const spans = spanBuffer;
80
+ spanBuffer = [];
81
+ const data = {
82
+ resourceSpans: [{
83
+ resource: otelResource,
84
+ scopeSpans: [{
85
+ scope,
86
+ spans
87
+ }]
88
+ }]
89
+ };
90
+ return Effect.asVoid(client.execute(HttpClientRequest.post(options.url, {
91
+ body: HttpBody.unsafeJson(data),
92
+ headers
93
+ })));
94
+ });
95
+ yield* Scope.addFinalizer(exporterScope, Effect.ignore(runExport));
96
+ yield* Effect.sleep(exportInterval).pipe(Effect.race(exportLatch.await), Effect.zipRight(runExport), Effect.catchAllCause(cause => Effect.logInfo("Failed to export spans", cause)), Effect.forever, Effect.forkScoped, Effect.interruptible, Effect.annotateLogs({
97
+ package: "@effect/opentelemetry",
98
+ module: "OtlpExporter"
99
+ }));
100
+ const addSpan = span => {
101
+ spanBuffer.push(makeOtlpSpan(span));
102
+ if (spanBuffer.length >= maxBatchSize) {
103
+ exportLatch.unsafeOpen();
104
+ }
105
+ };
106
+ return Tracer.make({
107
+ span(name, parent, context, links, startTime, kind) {
108
+ return makeSpan({
109
+ name,
110
+ parent,
111
+ context,
112
+ status: {
113
+ _tag: "Started",
114
+ startTime
115
+ },
116
+ attributes: new Map(),
117
+ links,
118
+ sampled: true,
119
+ kind,
120
+ export: addSpan
121
+ });
122
+ },
123
+ context(f, _fiber) {
124
+ return f();
125
+ }
126
+ });
127
+ });
128
+ /**
129
+ * @since 1.0.0
130
+ * @category Layers
131
+ */
132
+ const layer = options => Layer.unwrapScoped(Effect.map(make(options), Layer.setTracer));
133
+ exports.layer = layer;
134
+ const SpanProto = {
135
+ _tag: "Span",
136
+ end(endTime, exit) {
137
+ this.status = {
138
+ _tag: "Ended",
139
+ startTime: this.status.startTime,
140
+ endTime,
141
+ exit
142
+ };
143
+ this.export(this);
144
+ },
145
+ attribute(key, value) {
146
+ this.attributes.set(key, value);
147
+ },
148
+ event(name, startTime, attributes) {
149
+ this.events.push([name, startTime, attributes]);
150
+ },
151
+ addLinks(links) {
152
+ // eslint-disable-next-line no-restricted-syntax
153
+ this.links.push(...links);
154
+ }
155
+ };
156
+ const makeSpan = options => {
157
+ const self = Object.assign(Object.create(SpanProto), options);
158
+ if (Option.isSome(self.parent)) {
159
+ self.traceId = self.parent.value.traceId;
160
+ } else {
161
+ self.traceId = generateId(32);
162
+ }
163
+ self.spanId = generateId(16);
164
+ self.events = [];
165
+ return self;
166
+ };
167
+ const generateId = len => {
168
+ const chars = "0123456789abcdef";
169
+ let result = "";
170
+ for (let i = 0; i < len; i++) {
171
+ result += chars[Math.floor(Math.random() * chars.length)];
172
+ }
173
+ return result;
174
+ };
175
+ const makeOtlpSpan = self => {
176
+ const status = self.status;
177
+ const attributes = entriesToAttributes(self.attributes.entries());
178
+ const events = self.events.map(([name, startTime, attributes]) => ({
179
+ name,
180
+ timeUnixNano: String(startTime),
181
+ attributes: attributes ? entriesToAttributes(Object.entries(attributes)) : [],
182
+ droppedAttributesCount: 0
183
+ }));
184
+ let otelStatus;
185
+ if (status.exit._tag === "Success") {
186
+ otelStatus = constOtelStatusSuccess;
187
+ } else {
188
+ const errors = Cause.prettyErrors(status.exit.cause);
189
+ const firstError = errors[0];
190
+ otelStatus = {
191
+ code: StatusCode.Error,
192
+ message: firstError && firstError.message
193
+ };
194
+ for (const error of errors) {
195
+ events.push({
196
+ name: "exception",
197
+ timeUnixNano: String(status.endTime),
198
+ droppedAttributesCount: 0,
199
+ attributes: [{
200
+ "key": "exception.type",
201
+ "value": {
202
+ "stringValue": error.name
203
+ }
204
+ }, {
205
+ "key": "exception.message",
206
+ "value": {
207
+ "stringValue": error.message
208
+ }
209
+ }, {
210
+ "key": "exception.stacktrace",
211
+ "value": {
212
+ "stringValue": error.stack ?? ""
213
+ }
214
+ }]
215
+ });
216
+ }
217
+ }
218
+ return {
219
+ traceId: self.traceId,
220
+ spanId: self.spanId,
221
+ parentSpanId: Option.isSome(self.parent) ? self.parent.value.spanId : undefined,
222
+ name: self.name,
223
+ kind: SpanKind[self.kind],
224
+ startTimeUnixNano: String(status.startTime),
225
+ endTimeUnixNano: String(status.endTime),
226
+ attributes,
227
+ droppedAttributesCount: 0,
228
+ events,
229
+ droppedEventsCount: 0,
230
+ status: otelStatus,
231
+ links: self.links.map(link => ({
232
+ traceId: link.span.traceId,
233
+ spanId: link.span.spanId,
234
+ attributes: entriesToAttributes(Object.entries(link.attributes)),
235
+ droppedAttributesCount: 0
236
+ })),
237
+ droppedLinksCount: 0
238
+ };
239
+ };
240
+ const unknownToAttributeValue = value => {
241
+ switch (typeof value) {
242
+ case "string":
243
+ return {
244
+ stringValue: value
245
+ };
246
+ case "bigint":
247
+ return {
248
+ intValue: Number(value)
249
+ };
250
+ case "number":
251
+ return Number.isInteger(value) ? {
252
+ intValue: value
253
+ } : {
254
+ doubleValue: value
255
+ };
256
+ case "boolean":
257
+ return {
258
+ boolValue: value
259
+ };
260
+ default:
261
+ return {
262
+ stringValue: Inspectable.toStringUnknown(value)
263
+ };
264
+ }
265
+ };
266
+ const entriesToAttributes = entries => {
267
+ const attributes = [];
268
+ for (const [key, value] of entries) {
269
+ attributes.push({
270
+ key,
271
+ value: unknownToAttributeValue(value)
272
+ });
273
+ }
274
+ return attributes;
275
+ };
276
+ var StatusCode;
277
+ (function (StatusCode) {
278
+ StatusCode[StatusCode["Unset"] = 0] = "Unset";
279
+ StatusCode[StatusCode["Ok"] = 1] = "Ok";
280
+ StatusCode[StatusCode["Error"] = 2] = "Error";
281
+ })(StatusCode || (StatusCode = {}));
282
+ var SpanKind;
283
+ (function (SpanKind) {
284
+ SpanKind[SpanKind["unspecified"] = 0] = "unspecified";
285
+ SpanKind[SpanKind["internal"] = 1] = "internal";
286
+ SpanKind[SpanKind["server"] = 2] = "server";
287
+ SpanKind[SpanKind["client"] = 3] = "client";
288
+ SpanKind[SpanKind["producer"] = 4] = "producer";
289
+ SpanKind[SpanKind["consumer"] = 5] = "consumer";
290
+ })(SpanKind || (SpanKind = {}));
291
+ const constOtelStatusSuccess = {
292
+ code: StatusCode.Ok
293
+ };
294
+ //# sourceMappingURL=OtlpTracer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtlpTracer.js","names":["Headers","_interopRequireWildcard","require","HttpBody","HttpClient","HttpClientRequest","Cause","Duration","Effect","Inspectable","Layer","Option","Schedule","Scope","Tracer","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","make","exports","fnUntraced","options","exporterScope","scope","exportInterval","decode","seconds","maxBatchSize","client","filterStatusOk","pipe","tapError","error","_tag","response","status","void","retryAfter","headers","retryAfterSeconds","parseInt","sleep","retryTransient","schedule","spaced","unsafeFromRecord","merge","fromInput","resourceAttributes","resource","attributes","entriesToAttributes","entries","push","key","value","stringValue","serviceName","serviceVersion","otelResource","droppedAttributesCount","name","spanBuffer","exportLatch","unsafeMakeLatch","runExport","suspend","unsafeClose","length","spans","data","resourceSpans","scopeSpans","asVoid","execute","post","url","body","unsafeJson","addFinalizer","ignore","race","await","zipRight","catchAllCause","cause","logInfo","forever","forkScoped","interruptible","annotateLogs","package","module","addSpan","span","makeOtlpSpan","unsafeOpen","parent","context","links","startTime","kind","makeSpan","Map","sampled","export","f","_fiber","layer","unwrapScoped","map","setTracer","SpanProto","end","endTime","exit","attribute","event","events","addLinks","self","assign","create","isSome","traceId","generateId","spanId","len","chars","result","Math","floor","random","timeUnixNano","String","otelStatus","constOtelStatusSuccess","errors","prettyErrors","firstError","code","StatusCode","Error","message","stack","parentSpanId","undefined","SpanKind","startTimeUnixNano","endTimeUnixNano","droppedEventsCount","link","droppedLinksCount","unknownToAttributeValue","intValue","Number","isInteger","doubleValue","boolValue","toStringUnknown","Ok"],"sources":["../../src/OtlpTracer.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
package/dist/cjs/index.js CHANGED
@@ -3,13 +3,15 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.WebSdk = exports.Tracer = exports.Resource = exports.NodeSdk = exports.Metrics = exports.Logger = void 0;
6
+ exports.WebSdk = exports.Tracer = exports.Resource = exports.OtlpTracer = exports.NodeSdk = exports.Metrics = exports.Logger = void 0;
7
7
  var _Logger = _interopRequireWildcard(require("./Logger.js"));
8
8
  exports.Logger = _Logger;
9
9
  var _Metrics = _interopRequireWildcard(require("./Metrics.js"));
10
10
  exports.Metrics = _Metrics;
11
11
  var _NodeSdk = _interopRequireWildcard(require("./NodeSdk.js"));
12
12
  exports.NodeSdk = _NodeSdk;
13
+ var _OtlpTracer = _interopRequireWildcard(require("./OtlpTracer.js"));
14
+ exports.OtlpTracer = _OtlpTracer;
13
15
  var _Resource = _interopRequireWildcard(require("./Resource.js"));
14
16
  exports.Resource = _Resource;
15
17
  var _Tracer = _interopRequireWildcard(require("./Tracer.js"));
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+ import * as Headers from "@effect/platform/Headers";
5
+ import * as HttpClient from "@effect/platform/HttpClient";
6
+ import * as Duration from "effect/Duration";
7
+ import * as Effect from "effect/Effect";
8
+ import * as Layer from "effect/Layer";
9
+ import * as Scope from "effect/Scope";
10
+ import * as Tracer from "effect/Tracer";
11
+ /**
12
+ * @since 1.0.0
13
+ * @category Constructors
14
+ */
15
+ export declare const make: (options: {
16
+ readonly url: string;
17
+ readonly resource: {
18
+ readonly serviceName: string;
19
+ readonly serviceVersion?: string | undefined;
20
+ readonly attributes?: Record<string, unknown>;
21
+ };
22
+ readonly headers?: Headers.Input | undefined;
23
+ readonly exportInterval?: Duration.DurationInput | undefined;
24
+ readonly maxBatchSize?: number | undefined;
25
+ }) => Effect.Effect<Tracer.Tracer, never, HttpClient.HttpClient | Scope.Scope>;
26
+ /**
27
+ * @since 1.0.0
28
+ * @category Layers
29
+ */
30
+ export declare const layer: (options: {
31
+ readonly url: string;
32
+ readonly resource: {
33
+ readonly serviceName: string;
34
+ readonly serviceVersion?: string | undefined;
35
+ readonly attributes?: Record<string, unknown>;
36
+ };
37
+ readonly headers?: Headers.Input | undefined;
38
+ readonly exportInterval?: Duration.DurationInput | undefined;
39
+ }) => Layer.Layer<never, never, HttpClient.HttpClient>;
40
+ interface Scope {
41
+ readonly name: string;
42
+ }
43
+ export {};
44
+ //# sourceMappingURL=OtlpTracer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtlpTracer.d.ts","sourceRoot":"","sources":["../../src/OtlpTracer.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAA;AAEnD,OAAO,KAAK,UAAU,MAAM,6BAA6B,CAAA;AAIzD,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAGrC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC;;;GAGG;AACH,eAAO,MAAM,IAAI,EAAE,CACjB,OAAO,EAAE;IACP,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;QAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAC9C,CAAA;IACD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,KAAK,GAAG,SAAS,CAAA;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,aAAa,GAAG,SAAS,CAAA;IAC5D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC3C,KACE,MAAM,CAAC,MAAM,CAChB,MAAM,CAAC,MAAM,EACb,KAAK,EACL,UAAU,CAAC,UAAU,GAAG,KAAK,CAAC,KAAK,CA6HnC,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,KAAK,YAAa;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;QAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAC9C,CAAA;IACD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,KAAK,GAAG,SAAS,CAAA;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,aAAa,GAAG,SAAS,CAAA;CAC7D,KAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAmE,CAAA;AA8NtH,UAAU,KAAK;IACb,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB"}
@@ -10,6 +10,10 @@ export * as Metrics from "./Metrics.js";
10
10
  * @since 1.0.0
11
11
  */
12
12
  export * as NodeSdk from "./NodeSdk.js";
13
+ /**
14
+ * @since 1.0.0
15
+ */
16
+ export * as OtlpTracer from "./OtlpTracer.js";
13
17
  /**
14
18
  * @since 1.0.0
15
19
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AAEzC;;GAEG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;GAEG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AAEzC;;GAEG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC;;GAEG;AACH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA"}
@@ -0,0 +1,284 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+ import * as Headers from "@effect/platform/Headers";
5
+ import * as HttpBody from "@effect/platform/HttpBody";
6
+ import * as HttpClient from "@effect/platform/HttpClient";
7
+ import * as HttpClientRequest from "@effect/platform/HttpClientRequest";
8
+ import * as Cause from "effect/Cause";
9
+ import * as Duration from "effect/Duration";
10
+ import * as Effect from "effect/Effect";
11
+ import * as Inspectable from "effect/Inspectable";
12
+ import * as Layer from "effect/Layer";
13
+ import * as Option from "effect/Option";
14
+ import * as Schedule from "effect/Schedule";
15
+ import * as Scope from "effect/Scope";
16
+ import * as Tracer from "effect/Tracer";
17
+ /**
18
+ * @since 1.0.0
19
+ * @category Constructors
20
+ */
21
+ export const make = /*#__PURE__*/Effect.fnUntraced(function* (options) {
22
+ const exporterScope = yield* Effect.scope;
23
+ const exportInterval = options.exportInterval ? Duration.decode(options.exportInterval) : Duration.seconds(5);
24
+ const maxBatchSize = options.maxBatchSize ?? 1000;
25
+ const client = HttpClient.filterStatusOk(yield* HttpClient.HttpClient).pipe(HttpClient.tapError(error => {
26
+ if (error._tag !== "ResponseError" || error.response.status !== 429) {
27
+ return Effect.void;
28
+ }
29
+ const retryAfter = error.response.headers["retry-after"];
30
+ const retryAfterSeconds = retryAfter ? parseInt(retryAfter, 10) : 5;
31
+ return Effect.sleep(Duration.seconds(retryAfterSeconds));
32
+ }), HttpClient.retryTransient({
33
+ schedule: Schedule.spaced(1000)
34
+ }));
35
+ let headers = Headers.unsafeFromRecord({
36
+ "user-agent": "@effect-opentelemetry-OtlpExporter"
37
+ });
38
+ if (options.headers) {
39
+ headers = Headers.merge(Headers.fromInput(options.headers), headers);
40
+ }
41
+ const resourceAttributes = options.resource.attributes ? entriesToAttributes(Object.entries(options.resource.attributes)) : [];
42
+ resourceAttributes.push({
43
+ key: "service.name",
44
+ value: {
45
+ stringValue: options.resource.serviceName
46
+ }
47
+ });
48
+ if (options.resource.serviceVersion) {
49
+ resourceAttributes.push({
50
+ key: "service.version",
51
+ value: {
52
+ stringValue: options.resource.serviceVersion
53
+ }
54
+ });
55
+ }
56
+ const otelResource = {
57
+ attributes: resourceAttributes,
58
+ droppedAttributesCount: 0
59
+ };
60
+ const scope = {
61
+ name: options.resource.serviceName
62
+ };
63
+ let spanBuffer = [];
64
+ const exportLatch = Effect.unsafeMakeLatch(false);
65
+ const runExport = Effect.suspend(() => {
66
+ exportLatch.unsafeClose();
67
+ if (spanBuffer.length === 0) {
68
+ return Effect.void;
69
+ }
70
+ const spans = spanBuffer;
71
+ spanBuffer = [];
72
+ const data = {
73
+ resourceSpans: [{
74
+ resource: otelResource,
75
+ scopeSpans: [{
76
+ scope,
77
+ spans
78
+ }]
79
+ }]
80
+ };
81
+ return Effect.asVoid(client.execute(HttpClientRequest.post(options.url, {
82
+ body: HttpBody.unsafeJson(data),
83
+ headers
84
+ })));
85
+ });
86
+ yield* Scope.addFinalizer(exporterScope, Effect.ignore(runExport));
87
+ yield* Effect.sleep(exportInterval).pipe(Effect.race(exportLatch.await), Effect.zipRight(runExport), Effect.catchAllCause(cause => Effect.logInfo("Failed to export spans", cause)), Effect.forever, Effect.forkScoped, Effect.interruptible, Effect.annotateLogs({
88
+ package: "@effect/opentelemetry",
89
+ module: "OtlpExporter"
90
+ }));
91
+ const addSpan = span => {
92
+ spanBuffer.push(makeOtlpSpan(span));
93
+ if (spanBuffer.length >= maxBatchSize) {
94
+ exportLatch.unsafeOpen();
95
+ }
96
+ };
97
+ return Tracer.make({
98
+ span(name, parent, context, links, startTime, kind) {
99
+ return makeSpan({
100
+ name,
101
+ parent,
102
+ context,
103
+ status: {
104
+ _tag: "Started",
105
+ startTime
106
+ },
107
+ attributes: new Map(),
108
+ links,
109
+ sampled: true,
110
+ kind,
111
+ export: addSpan
112
+ });
113
+ },
114
+ context(f, _fiber) {
115
+ return f();
116
+ }
117
+ });
118
+ });
119
+ /**
120
+ * @since 1.0.0
121
+ * @category Layers
122
+ */
123
+ export const layer = options => Layer.unwrapScoped(Effect.map(make(options), Layer.setTracer));
124
+ const SpanProto = {
125
+ _tag: "Span",
126
+ end(endTime, exit) {
127
+ this.status = {
128
+ _tag: "Ended",
129
+ startTime: this.status.startTime,
130
+ endTime,
131
+ exit
132
+ };
133
+ this.export(this);
134
+ },
135
+ attribute(key, value) {
136
+ this.attributes.set(key, value);
137
+ },
138
+ event(name, startTime, attributes) {
139
+ this.events.push([name, startTime, attributes]);
140
+ },
141
+ addLinks(links) {
142
+ // eslint-disable-next-line no-restricted-syntax
143
+ this.links.push(...links);
144
+ }
145
+ };
146
+ const makeSpan = options => {
147
+ const self = Object.assign(Object.create(SpanProto), options);
148
+ if (Option.isSome(self.parent)) {
149
+ self.traceId = self.parent.value.traceId;
150
+ } else {
151
+ self.traceId = generateId(32);
152
+ }
153
+ self.spanId = generateId(16);
154
+ self.events = [];
155
+ return self;
156
+ };
157
+ const generateId = len => {
158
+ const chars = "0123456789abcdef";
159
+ let result = "";
160
+ for (let i = 0; i < len; i++) {
161
+ result += chars[Math.floor(Math.random() * chars.length)];
162
+ }
163
+ return result;
164
+ };
165
+ const makeOtlpSpan = self => {
166
+ const status = self.status;
167
+ const attributes = entriesToAttributes(self.attributes.entries());
168
+ const events = self.events.map(([name, startTime, attributes]) => ({
169
+ name,
170
+ timeUnixNano: String(startTime),
171
+ attributes: attributes ? entriesToAttributes(Object.entries(attributes)) : [],
172
+ droppedAttributesCount: 0
173
+ }));
174
+ let otelStatus;
175
+ if (status.exit._tag === "Success") {
176
+ otelStatus = constOtelStatusSuccess;
177
+ } else {
178
+ const errors = Cause.prettyErrors(status.exit.cause);
179
+ const firstError = errors[0];
180
+ otelStatus = {
181
+ code: StatusCode.Error,
182
+ message: firstError && firstError.message
183
+ };
184
+ for (const error of errors) {
185
+ events.push({
186
+ name: "exception",
187
+ timeUnixNano: String(status.endTime),
188
+ droppedAttributesCount: 0,
189
+ attributes: [{
190
+ "key": "exception.type",
191
+ "value": {
192
+ "stringValue": error.name
193
+ }
194
+ }, {
195
+ "key": "exception.message",
196
+ "value": {
197
+ "stringValue": error.message
198
+ }
199
+ }, {
200
+ "key": "exception.stacktrace",
201
+ "value": {
202
+ "stringValue": error.stack ?? ""
203
+ }
204
+ }]
205
+ });
206
+ }
207
+ }
208
+ return {
209
+ traceId: self.traceId,
210
+ spanId: self.spanId,
211
+ parentSpanId: Option.isSome(self.parent) ? self.parent.value.spanId : undefined,
212
+ name: self.name,
213
+ kind: SpanKind[self.kind],
214
+ startTimeUnixNano: String(status.startTime),
215
+ endTimeUnixNano: String(status.endTime),
216
+ attributes,
217
+ droppedAttributesCount: 0,
218
+ events,
219
+ droppedEventsCount: 0,
220
+ status: otelStatus,
221
+ links: self.links.map(link => ({
222
+ traceId: link.span.traceId,
223
+ spanId: link.span.spanId,
224
+ attributes: entriesToAttributes(Object.entries(link.attributes)),
225
+ droppedAttributesCount: 0
226
+ })),
227
+ droppedLinksCount: 0
228
+ };
229
+ };
230
+ const unknownToAttributeValue = value => {
231
+ switch (typeof value) {
232
+ case "string":
233
+ return {
234
+ stringValue: value
235
+ };
236
+ case "bigint":
237
+ return {
238
+ intValue: Number(value)
239
+ };
240
+ case "number":
241
+ return Number.isInteger(value) ? {
242
+ intValue: value
243
+ } : {
244
+ doubleValue: value
245
+ };
246
+ case "boolean":
247
+ return {
248
+ boolValue: value
249
+ };
250
+ default:
251
+ return {
252
+ stringValue: Inspectable.toStringUnknown(value)
253
+ };
254
+ }
255
+ };
256
+ const entriesToAttributes = entries => {
257
+ const attributes = [];
258
+ for (const [key, value] of entries) {
259
+ attributes.push({
260
+ key,
261
+ value: unknownToAttributeValue(value)
262
+ });
263
+ }
264
+ return attributes;
265
+ };
266
+ var StatusCode;
267
+ (function (StatusCode) {
268
+ StatusCode[StatusCode["Unset"] = 0] = "Unset";
269
+ StatusCode[StatusCode["Ok"] = 1] = "Ok";
270
+ StatusCode[StatusCode["Error"] = 2] = "Error";
271
+ })(StatusCode || (StatusCode = {}));
272
+ var SpanKind;
273
+ (function (SpanKind) {
274
+ SpanKind[SpanKind["unspecified"] = 0] = "unspecified";
275
+ SpanKind[SpanKind["internal"] = 1] = "internal";
276
+ SpanKind[SpanKind["server"] = 2] = "server";
277
+ SpanKind[SpanKind["client"] = 3] = "client";
278
+ SpanKind[SpanKind["producer"] = 4] = "producer";
279
+ SpanKind[SpanKind["consumer"] = 5] = "consumer";
280
+ })(SpanKind || (SpanKind = {}));
281
+ const constOtelStatusSuccess = {
282
+ code: StatusCode.Ok
283
+ };
284
+ //# sourceMappingURL=OtlpTracer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtlpTracer.js","names":["Headers","HttpBody","HttpClient","HttpClientRequest","Cause","Duration","Effect","Inspectable","Layer","Option","Schedule","Scope","Tracer","make","fnUntraced","options","exporterScope","scope","exportInterval","decode","seconds","maxBatchSize","client","filterStatusOk","pipe","tapError","error","_tag","response","status","void","retryAfter","headers","retryAfterSeconds","parseInt","sleep","retryTransient","schedule","spaced","unsafeFromRecord","merge","fromInput","resourceAttributes","resource","attributes","entriesToAttributes","Object","entries","push","key","value","stringValue","serviceName","serviceVersion","otelResource","droppedAttributesCount","name","spanBuffer","exportLatch","unsafeMakeLatch","runExport","suspend","unsafeClose","length","spans","data","resourceSpans","scopeSpans","asVoid","execute","post","url","body","unsafeJson","addFinalizer","ignore","race","await","zipRight","catchAllCause","cause","logInfo","forever","forkScoped","interruptible","annotateLogs","package","module","addSpan","span","makeOtlpSpan","unsafeOpen","parent","context","links","startTime","kind","makeSpan","Map","sampled","export","f","_fiber","layer","unwrapScoped","map","setTracer","SpanProto","end","endTime","exit","attribute","set","event","events","addLinks","self","assign","create","isSome","traceId","generateId","spanId","len","chars","result","i","Math","floor","random","timeUnixNano","String","otelStatus","constOtelStatusSuccess","errors","prettyErrors","firstError","code","StatusCode","Error","message","stack","parentSpanId","undefined","SpanKind","startTimeUnixNano","endTimeUnixNano","droppedEventsCount","link","droppedLinksCount","unknownToAttributeValue","intValue","Number","isInteger","doubleValue","boolValue","toStringUnknown","Ok"],"sources":["../../src/OtlpTracer.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
package/dist/esm/index.js CHANGED
@@ -10,6 +10,10 @@ export * as Metrics from "./Metrics.js";
10
10
  * @since 1.0.0
11
11
  */
12
12
  export * as NodeSdk from "./NodeSdk.js";
13
+ /**
14
+ * @since 1.0.0
15
+ */
16
+ export * as OtlpTracer from "./OtlpTracer.js";
13
17
  /**
14
18
  * @since 1.0.0
15
19
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["Logger","Metrics","NodeSdk","Resource","Tracer","WebSdk"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAGA,OAAO,KAAKA,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,QAAQ,MAAM,eAAe;AAEzC;;;AAGA,OAAO,KAAKC,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,MAAM,MAAM,aAAa","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["Logger","Metrics","NodeSdk","OtlpTracer","Resource","Tracer","WebSdk"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAGA,OAAO,KAAKA,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,OAAO,MAAM,cAAc;AAEvC;;;AAGA,OAAO,KAAKC,UAAU,MAAM,iBAAiB;AAE7C;;;AAGA,OAAO,KAAKC,QAAQ,MAAM,eAAe;AAEzC;;;AAGA,OAAO,KAAKC,MAAM,MAAM,aAAa;AAErC;;;AAGA,OAAO,KAAKC,MAAM,MAAM,aAAa","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect/opentelemetry",
3
- "version": "0.46.0",
3
+ "version": "0.46.2",
4
4
  "description": "OpenTelemetry integration for Effect",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -17,9 +17,16 @@
17
17
  "@opentelemetry/sdk-trace-node": "^2.0.0",
18
18
  "@opentelemetry/sdk-trace-web": "^2.0.0",
19
19
  "@opentelemetry/semantic-conventions": "^1.30.0",
20
- "effect": "^3.14.7"
20
+ "@effect/platform": "^0.80.8",
21
+ "effect": "^3.14.8"
21
22
  },
22
23
  "peerDependenciesMeta": {
24
+ "@opentelemetry/api": {
25
+ "optional": true
26
+ },
27
+ "@opentelemetry/resources": {
28
+ "optional": true
29
+ },
23
30
  "@opentelemetry/sdk-metrics": {
24
31
  "optional": true
25
32
  },
@@ -64,6 +71,11 @@
64
71
  "import": "./dist/esm/NodeSdk.js",
65
72
  "default": "./dist/cjs/NodeSdk.js"
66
73
  },
74
+ "./OtlpTracer": {
75
+ "types": "./dist/dts/OtlpTracer.d.ts",
76
+ "import": "./dist/esm/OtlpTracer.js",
77
+ "default": "./dist/cjs/OtlpTracer.js"
78
+ },
67
79
  "./Resource": {
68
80
  "types": "./dist/dts/Resource.d.ts",
69
81
  "import": "./dist/esm/Resource.js",
@@ -91,6 +103,9 @@
91
103
  "NodeSdk": [
92
104
  "./dist/dts/NodeSdk.d.ts"
93
105
  ],
106
+ "OtlpTracer": [
107
+ "./dist/dts/OtlpTracer.d.ts"
108
+ ],
94
109
  "Resource": [
95
110
  "./dist/dts/Resource.d.ts"
96
111
  ],
@@ -0,0 +1,459 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+ import * as Headers from "@effect/platform/Headers"
5
+ import * as HttpBody from "@effect/platform/HttpBody"
6
+ import * as HttpClient from "@effect/platform/HttpClient"
7
+ import * as HttpClientRequest from "@effect/platform/HttpClientRequest"
8
+ import * as Cause from "effect/Cause"
9
+ import type * as Context from "effect/Context"
10
+ import * as Duration from "effect/Duration"
11
+ import * as Effect from "effect/Effect"
12
+ import type * as Exit from "effect/Exit"
13
+ import * as Inspectable from "effect/Inspectable"
14
+ import * as Layer from "effect/Layer"
15
+ import * as Option from "effect/Option"
16
+ import * as Schedule from "effect/Schedule"
17
+ import * as Scope from "effect/Scope"
18
+ import * as Tracer from "effect/Tracer"
19
+ import type { ExtractTag } from "effect/Types"
20
+
21
+ /**
22
+ * @since 1.0.0
23
+ * @category Constructors
24
+ */
25
+ export const make: (
26
+ options: {
27
+ readonly url: string
28
+ readonly resource: {
29
+ readonly serviceName: string
30
+ readonly serviceVersion?: string | undefined
31
+ readonly attributes?: Record<string, unknown>
32
+ }
33
+ readonly headers?: Headers.Input | undefined
34
+ readonly exportInterval?: Duration.DurationInput | undefined
35
+ readonly maxBatchSize?: number | undefined
36
+ }
37
+ ) => Effect.Effect<
38
+ Tracer.Tracer,
39
+ never,
40
+ HttpClient.HttpClient | Scope.Scope
41
+ > = Effect.fnUntraced(function*(options) {
42
+ const exporterScope = yield* Effect.scope
43
+ const exportInterval = options.exportInterval ? Duration.decode(options.exportInterval) : Duration.seconds(5)
44
+ const maxBatchSize = options.maxBatchSize ?? 1000
45
+
46
+ const client = HttpClient.filterStatusOk(yield* HttpClient.HttpClient).pipe(
47
+ HttpClient.tapError((error) => {
48
+ if (error._tag !== "ResponseError" || error.response.status !== 429) {
49
+ return Effect.void
50
+ }
51
+ const retryAfter = error.response.headers["retry-after"]
52
+ const retryAfterSeconds = retryAfter ? parseInt(retryAfter, 10) : 5
53
+ return Effect.sleep(Duration.seconds(retryAfterSeconds))
54
+ }),
55
+ HttpClient.retryTransient({
56
+ schedule: Schedule.spaced(1000)
57
+ })
58
+ )
59
+
60
+ let headers = Headers.unsafeFromRecord({
61
+ "user-agent": "@effect-opentelemetry-OtlpExporter"
62
+ })
63
+ if (options.headers) {
64
+ headers = Headers.merge(Headers.fromInput(options.headers), headers)
65
+ }
66
+
67
+ const resourceAttributes = options.resource.attributes
68
+ ? entriesToAttributes(Object.entries(options.resource.attributes))
69
+ : []
70
+ resourceAttributes.push({
71
+ key: "service.name",
72
+ value: {
73
+ stringValue: options.resource.serviceName
74
+ }
75
+ })
76
+ if (options.resource.serviceVersion) {
77
+ resourceAttributes.push({
78
+ key: "service.version",
79
+ value: {
80
+ stringValue: options.resource.serviceVersion
81
+ }
82
+ })
83
+ }
84
+
85
+ const otelResource: OtlpResource = {
86
+ attributes: resourceAttributes,
87
+ droppedAttributesCount: 0
88
+ }
89
+ const scope: Scope = {
90
+ name: options.resource.serviceName
91
+ }
92
+
93
+ let spanBuffer: Array<OtlpSpan> = []
94
+
95
+ const exportLatch = Effect.unsafeMakeLatch(false)
96
+
97
+ const runExport = Effect.suspend(() => {
98
+ exportLatch.unsafeClose()
99
+
100
+ if (spanBuffer.length === 0) {
101
+ return Effect.void
102
+ }
103
+ const spans = spanBuffer
104
+ spanBuffer = []
105
+ const data: TraceData = {
106
+ resourceSpans: [{
107
+ resource: otelResource,
108
+ scopeSpans: [{
109
+ scope,
110
+ spans
111
+ }]
112
+ }]
113
+ }
114
+ return Effect.asVoid(client.execute(
115
+ HttpClientRequest.post(options.url, {
116
+ body: HttpBody.unsafeJson(data),
117
+ headers
118
+ })
119
+ ))
120
+ })
121
+
122
+ yield* Scope.addFinalizer(exporterScope, Effect.ignore(runExport))
123
+
124
+ yield* Effect.sleep(exportInterval).pipe(
125
+ Effect.race(exportLatch.await),
126
+ Effect.zipRight(runExport),
127
+ Effect.catchAllCause((cause) => Effect.logInfo("Failed to export spans", cause)),
128
+ Effect.forever,
129
+ Effect.forkScoped,
130
+ Effect.interruptible,
131
+ Effect.annotateLogs({
132
+ package: "@effect/opentelemetry",
133
+ module: "OtlpExporter"
134
+ })
135
+ )
136
+
137
+ const addSpan = (span: SpanImpl) => {
138
+ spanBuffer.push(makeOtlpSpan(span))
139
+ if (spanBuffer.length >= maxBatchSize) {
140
+ exportLatch.unsafeOpen()
141
+ }
142
+ }
143
+
144
+ return Tracer.make({
145
+ span(name, parent, context, links, startTime, kind) {
146
+ return makeSpan({
147
+ name,
148
+ parent,
149
+ context,
150
+ status: {
151
+ _tag: "Started",
152
+ startTime
153
+ },
154
+ attributes: new Map(),
155
+ links,
156
+ sampled: true,
157
+ kind,
158
+ export: addSpan
159
+ })
160
+ },
161
+ context(f, _fiber) {
162
+ return f()
163
+ }
164
+ })
165
+ })
166
+
167
+ /**
168
+ * @since 1.0.0
169
+ * @category Layers
170
+ */
171
+ export const layer = (options: {
172
+ readonly url: string
173
+ readonly resource: {
174
+ readonly serviceName: string
175
+ readonly serviceVersion?: string | undefined
176
+ readonly attributes?: Record<string, unknown>
177
+ }
178
+ readonly headers?: Headers.Input | undefined
179
+ readonly exportInterval?: Duration.DurationInput | undefined
180
+ }): Layer.Layer<never, never, HttpClient.HttpClient> => Layer.unwrapScoped(Effect.map(make(options), Layer.setTracer))
181
+
182
+ // internal
183
+
184
+ interface SpanImpl extends Tracer.Span {
185
+ readonly export: (span: SpanImpl) => void
186
+ readonly attributes: Map<string, unknown>
187
+ readonly links: Array<Tracer.SpanLink>
188
+ readonly events: Array<[name: string, startTime: bigint, attributes: Record<string, unknown> | undefined]>
189
+ status: Tracer.SpanStatus
190
+ }
191
+
192
+ const SpanProto = {
193
+ _tag: "Span",
194
+ end(this: SpanImpl, endTime: bigint, exit: Exit.Exit<unknown, unknown>) {
195
+ this.status = {
196
+ _tag: "Ended",
197
+ startTime: this.status.startTime,
198
+ endTime,
199
+ exit
200
+ }
201
+ this.export(this)
202
+ },
203
+ attribute(this: SpanImpl, key: string, value: unknown) {
204
+ this.attributes.set(key, value)
205
+ },
206
+ event(this: SpanImpl, name: string, startTime: bigint, attributes?: Record<string, unknown>) {
207
+ this.events.push([name, startTime, attributes])
208
+ },
209
+ addLinks(this: SpanImpl, links: ReadonlyArray<Tracer.SpanLink>) {
210
+ // eslint-disable-next-line no-restricted-syntax
211
+ this.links.push(...links)
212
+ }
213
+ }
214
+
215
+ const makeSpan = (options: {
216
+ readonly name: string
217
+ readonly parent: Option.Option<Tracer.AnySpan>
218
+ readonly context: Context.Context<never>
219
+ readonly status: Tracer.SpanStatus
220
+ readonly attributes: ReadonlyMap<string, unknown>
221
+ readonly links: ReadonlyArray<Tracer.SpanLink>
222
+ readonly sampled: boolean
223
+ readonly kind: Tracer.SpanKind
224
+ readonly export: (span: SpanImpl) => void
225
+ }): SpanImpl => {
226
+ const self = Object.assign(Object.create(SpanProto), options)
227
+ if (Option.isSome(self.parent)) {
228
+ self.traceId = self.parent.value.traceId
229
+ } else {
230
+ self.traceId = generateId(32)
231
+ }
232
+ self.spanId = generateId(16)
233
+ self.events = []
234
+ return self
235
+ }
236
+
237
+ const generateId = (len: number): string => {
238
+ const chars = "0123456789abcdef"
239
+ let result = ""
240
+ for (let i = 0; i < len; i++) {
241
+ result += chars[Math.floor(Math.random() * chars.length)]
242
+ }
243
+ return result
244
+ }
245
+
246
+ const makeOtlpSpan = (self: SpanImpl): OtlpSpan => {
247
+ const status = self.status as ExtractTag<Tracer.SpanStatus, "Ended">
248
+ const attributes = entriesToAttributes(self.attributes.entries())
249
+ const events = self.events.map(([name, startTime, attributes]) => ({
250
+ name,
251
+ timeUnixNano: String(startTime),
252
+ attributes: attributes
253
+ ? entriesToAttributes(Object.entries(attributes))
254
+ : [],
255
+ droppedAttributesCount: 0
256
+ }))
257
+ let otelStatus: Status
258
+
259
+ if (status.exit._tag === "Success") {
260
+ otelStatus = constOtelStatusSuccess
261
+ } else {
262
+ const errors = Cause.prettyErrors(status.exit.cause)
263
+ const firstError = errors[0]
264
+ otelStatus = {
265
+ code: StatusCode.Error,
266
+ message: firstError && firstError.message
267
+ }
268
+ for (const error of errors) {
269
+ events.push({
270
+ name: "exception",
271
+ timeUnixNano: String(status.endTime),
272
+ droppedAttributesCount: 0,
273
+ attributes: [
274
+ {
275
+ "key": "exception.type",
276
+ "value": {
277
+ "stringValue": error.name
278
+ }
279
+ },
280
+ {
281
+ "key": "exception.message",
282
+ "value": {
283
+ "stringValue": error.message
284
+ }
285
+ },
286
+ {
287
+ "key": "exception.stacktrace",
288
+ "value": {
289
+ "stringValue": error.stack ?? ""
290
+ }
291
+ }
292
+ ]
293
+ })
294
+ }
295
+ }
296
+
297
+ return {
298
+ traceId: self.traceId,
299
+ spanId: self.spanId,
300
+ parentSpanId: Option.isSome(self.parent) ? self.parent.value.spanId : undefined,
301
+ name: self.name,
302
+ kind: SpanKind[self.kind],
303
+ startTimeUnixNano: String(status.startTime),
304
+ endTimeUnixNano: String(status.endTime),
305
+ attributes,
306
+ droppedAttributesCount: 0,
307
+ events,
308
+ droppedEventsCount: 0,
309
+ status: otelStatus,
310
+ links: self.links.map((link) => ({
311
+ traceId: link.span.traceId,
312
+ spanId: link.span.spanId,
313
+ attributes: entriesToAttributes(Object.entries(link.attributes)),
314
+ droppedAttributesCount: 0
315
+ })),
316
+ droppedLinksCount: 0
317
+ }
318
+ }
319
+
320
+ const unknownToAttributeValue = (value: unknown): AttributeValue => {
321
+ switch (typeof value) {
322
+ case "string":
323
+ return {
324
+ stringValue: value
325
+ }
326
+ case "bigint":
327
+ return {
328
+ intValue: Number(value)
329
+ }
330
+ case "number":
331
+ return Number.isInteger(value)
332
+ ? {
333
+ intValue: value
334
+ }
335
+ : {
336
+ doubleValue: value
337
+ }
338
+ case "boolean":
339
+ return {
340
+ boolValue: value
341
+ }
342
+ default:
343
+ return {
344
+ stringValue: Inspectable.toStringUnknown(value)
345
+ }
346
+ }
347
+ }
348
+
349
+ const entriesToAttributes = (entries: Iterable<[string, unknown]>): Array<Attribute> => {
350
+ const attributes: Array<Attribute> = []
351
+ for (const [key, value] of entries) {
352
+ attributes.push({
353
+ key,
354
+ value: unknownToAttributeValue(value)
355
+ })
356
+ }
357
+ return attributes
358
+ }
359
+
360
+ interface TraceData {
361
+ readonly resourceSpans: Array<ResourceSpan>
362
+ }
363
+
364
+ interface ResourceSpan {
365
+ readonly resource: OtlpResource
366
+ readonly scopeSpans: Array<ScopeSpan>
367
+ }
368
+
369
+ interface OtlpResource {
370
+ readonly attributes: Array<Attribute>
371
+ readonly droppedAttributesCount: number
372
+ }
373
+
374
+ interface Attribute {
375
+ readonly key: string
376
+ readonly value: AttributeValue
377
+ }
378
+
379
+ type AttributeValue = IntValue | DoubleValue | BoolValue | StringValue
380
+
381
+ interface IntValue {
382
+ readonly intValue: number
383
+ }
384
+
385
+ interface DoubleValue {
386
+ readonly doubleValue: number
387
+ }
388
+
389
+ interface BoolValue {
390
+ readonly boolValue: boolean
391
+ }
392
+
393
+ interface StringValue {
394
+ readonly stringValue: string
395
+ }
396
+
397
+ interface ScopeSpan {
398
+ readonly scope: Scope
399
+ readonly spans: Array<OtlpSpan>
400
+ }
401
+
402
+ interface Scope {
403
+ readonly name: string
404
+ }
405
+
406
+ interface OtlpSpan {
407
+ readonly traceId: string
408
+ readonly spanId: string
409
+ readonly parentSpanId: string | undefined
410
+ readonly name: string
411
+ readonly kind: number
412
+ readonly startTimeUnixNano: string
413
+ readonly endTimeUnixNano: string
414
+ readonly attributes: Array<Attribute>
415
+ readonly droppedAttributesCount: number
416
+ readonly events: Array<Event>
417
+ readonly droppedEventsCount: number
418
+ readonly status: Status
419
+ readonly links: Array<Link>
420
+ readonly droppedLinksCount: number
421
+ }
422
+
423
+ interface Event {
424
+ readonly attributes: Array<Attribute>
425
+ readonly name: string
426
+ readonly timeUnixNano: string
427
+ readonly droppedAttributesCount: number
428
+ }
429
+
430
+ interface Link {
431
+ readonly attributes: Array<Attribute>
432
+ readonly spanId: string
433
+ readonly traceId: string
434
+ readonly droppedAttributesCount: number
435
+ }
436
+
437
+ interface Status {
438
+ readonly code: StatusCode
439
+ readonly message?: string
440
+ }
441
+
442
+ const enum StatusCode {
443
+ Unset = 0,
444
+ Ok = 1,
445
+ Error = 2
446
+ }
447
+
448
+ enum SpanKind {
449
+ unspecified = 0,
450
+ internal = 1,
451
+ server = 2,
452
+ client = 3,
453
+ producer = 4,
454
+ consumer = 5
455
+ }
456
+
457
+ const constOtelStatusSuccess: Status = {
458
+ code: StatusCode.Ok
459
+ }
package/src/index.ts CHANGED
@@ -13,6 +13,11 @@ export * as Metrics from "./Metrics.js"
13
13
  */
14
14
  export * as NodeSdk from "./NodeSdk.js"
15
15
 
16
+ /**
17
+ * @since 1.0.0
18
+ */
19
+ export * as OtlpTracer from "./OtlpTracer.js"
20
+
16
21
  /**
17
22
  * @since 1.0.0
18
23
  */