@effect/opentelemetry 0.46.1 → 0.46.3

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 FiberSet = _interopRequireWildcard(require("effect/FiberSet"));
15
+ var Inspectable = _interopRequireWildcard(require("effect/Inspectable"));
16
+ var Layer = _interopRequireWildcard(require("effect/Layer"));
17
+ var Option = _interopRequireWildcard(require("effect/Option"));
18
+ var Schedule = _interopRequireWildcard(require("effect/Schedule"));
19
+ var Scope = _interopRequireWildcard(require("effect/Scope"));
20
+ var Tracer = _interopRequireWildcard(require("effect/Tracer"));
21
+ 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); }
22
+ 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; }
23
+ /**
24
+ * @since 1.0.0
25
+ */
26
+
27
+ /**
28
+ * @since 1.0.0
29
+ * @category Constructors
30
+ */
31
+ const make = exports.make = /*#__PURE__*/Effect.fnUntraced(function* (options) {
32
+ const exporterScope = yield* Effect.scope;
33
+ const exportInterval = options.exportInterval ? Duration.decode(options.exportInterval) : Duration.seconds(5);
34
+ const maxBatchSize = options.maxBatchSize ?? 1000;
35
+ const client = HttpClient.filterStatusOk(yield* HttpClient.HttpClient).pipe(HttpClient.tapError(error => {
36
+ if (error._tag !== "ResponseError" || error.response.status !== 429) {
37
+ return Effect.void;
38
+ }
39
+ const retryAfter = error.response.headers["retry-after"];
40
+ const retryAfterSeconds = retryAfter ? parseInt(retryAfter, 10) : 5;
41
+ return Effect.sleep(Duration.seconds(retryAfterSeconds));
42
+ }), HttpClient.retryTransient({
43
+ schedule: Schedule.spaced(1000)
44
+ }));
45
+ let headers = Headers.unsafeFromRecord({
46
+ "user-agent": "@effect-opentelemetry-OtlpExporter"
47
+ });
48
+ if (options.headers) {
49
+ headers = Headers.merge(Headers.fromInput(options.headers), headers);
50
+ }
51
+ const resourceAttributes = options.resource.attributes ? entriesToAttributes(Object.entries(options.resource.attributes)) : [];
52
+ resourceAttributes.push({
53
+ key: "service.name",
54
+ value: {
55
+ stringValue: options.resource.serviceName
56
+ }
57
+ });
58
+ if (options.resource.serviceVersion) {
59
+ resourceAttributes.push({
60
+ key: "service.version",
61
+ value: {
62
+ stringValue: options.resource.serviceVersion
63
+ }
64
+ });
65
+ }
66
+ const otelResource = {
67
+ attributes: resourceAttributes,
68
+ droppedAttributesCount: 0
69
+ };
70
+ const scope = {
71
+ name: options.resource.serviceName
72
+ };
73
+ let spanBuffer = [];
74
+ const runExport = Effect.suspend(() => {
75
+ if (spanBuffer.length === 0) {
76
+ return Effect.void;
77
+ }
78
+ const spans = spanBuffer;
79
+ spanBuffer = [];
80
+ const data = {
81
+ resourceSpans: [{
82
+ resource: otelResource,
83
+ scopeSpans: [{
84
+ scope,
85
+ spans
86
+ }]
87
+ }]
88
+ };
89
+ return Effect.asVoid(client.execute(HttpClientRequest.post(options.url, {
90
+ body: HttpBody.unsafeJson(data),
91
+ headers
92
+ })));
93
+ }).pipe(Effect.catchAllCause(cause => Effect.logWarning("Failed to export spans", cause)), Effect.annotateLogs({
94
+ package: "@effect/opentelemetry",
95
+ module: "OtlpExporter"
96
+ }));
97
+ yield* Scope.addFinalizer(exporterScope, runExport);
98
+ yield* Effect.sleep(exportInterval).pipe(Effect.zipRight(runExport), Effect.forever, Effect.forkScoped, Effect.interruptible);
99
+ const runFork = yield* FiberSet.makeRuntime().pipe(Effect.interruptible);
100
+ const addSpan = span => {
101
+ spanBuffer.push(makeOtlpSpan(span));
102
+ if (spanBuffer.length >= maxBatchSize) {
103
+ runFork(runExport);
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","FiberSet","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","runExport","suspend","length","spans","data","resourceSpans","scopeSpans","asVoid","execute","post","url","body","unsafeJson","catchAllCause","cause","logWarning","annotateLogs","package","module","addFinalizer","zipRight","forever","forkScoped","interruptible","runFork","makeRuntime","addSpan","span","makeOtlpSpan","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;AAIvC,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,CA4HnC,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 FiberSet from "effect/FiberSet";
12
+ import * as Inspectable from "effect/Inspectable";
13
+ import * as Layer from "effect/Layer";
14
+ import * as Option from "effect/Option";
15
+ import * as Schedule from "effect/Schedule";
16
+ import * as Scope from "effect/Scope";
17
+ import * as Tracer from "effect/Tracer";
18
+ /**
19
+ * @since 1.0.0
20
+ * @category Constructors
21
+ */
22
+ export const make = /*#__PURE__*/Effect.fnUntraced(function* (options) {
23
+ const exporterScope = yield* Effect.scope;
24
+ const exportInterval = options.exportInterval ? Duration.decode(options.exportInterval) : Duration.seconds(5);
25
+ const maxBatchSize = options.maxBatchSize ?? 1000;
26
+ const client = HttpClient.filterStatusOk(yield* HttpClient.HttpClient).pipe(HttpClient.tapError(error => {
27
+ if (error._tag !== "ResponseError" || error.response.status !== 429) {
28
+ return Effect.void;
29
+ }
30
+ const retryAfter = error.response.headers["retry-after"];
31
+ const retryAfterSeconds = retryAfter ? parseInt(retryAfter, 10) : 5;
32
+ return Effect.sleep(Duration.seconds(retryAfterSeconds));
33
+ }), HttpClient.retryTransient({
34
+ schedule: Schedule.spaced(1000)
35
+ }));
36
+ let headers = Headers.unsafeFromRecord({
37
+ "user-agent": "@effect-opentelemetry-OtlpExporter"
38
+ });
39
+ if (options.headers) {
40
+ headers = Headers.merge(Headers.fromInput(options.headers), headers);
41
+ }
42
+ const resourceAttributes = options.resource.attributes ? entriesToAttributes(Object.entries(options.resource.attributes)) : [];
43
+ resourceAttributes.push({
44
+ key: "service.name",
45
+ value: {
46
+ stringValue: options.resource.serviceName
47
+ }
48
+ });
49
+ if (options.resource.serviceVersion) {
50
+ resourceAttributes.push({
51
+ key: "service.version",
52
+ value: {
53
+ stringValue: options.resource.serviceVersion
54
+ }
55
+ });
56
+ }
57
+ const otelResource = {
58
+ attributes: resourceAttributes,
59
+ droppedAttributesCount: 0
60
+ };
61
+ const scope = {
62
+ name: options.resource.serviceName
63
+ };
64
+ let spanBuffer = [];
65
+ const runExport = Effect.suspend(() => {
66
+ if (spanBuffer.length === 0) {
67
+ return Effect.void;
68
+ }
69
+ const spans = spanBuffer;
70
+ spanBuffer = [];
71
+ const data = {
72
+ resourceSpans: [{
73
+ resource: otelResource,
74
+ scopeSpans: [{
75
+ scope,
76
+ spans
77
+ }]
78
+ }]
79
+ };
80
+ return Effect.asVoid(client.execute(HttpClientRequest.post(options.url, {
81
+ body: HttpBody.unsafeJson(data),
82
+ headers
83
+ })));
84
+ }).pipe(Effect.catchAllCause(cause => Effect.logWarning("Failed to export spans", cause)), Effect.annotateLogs({
85
+ package: "@effect/opentelemetry",
86
+ module: "OtlpExporter"
87
+ }));
88
+ yield* Scope.addFinalizer(exporterScope, runExport);
89
+ yield* Effect.sleep(exportInterval).pipe(Effect.zipRight(runExport), Effect.forever, Effect.forkScoped, Effect.interruptible);
90
+ const runFork = yield* FiberSet.makeRuntime().pipe(Effect.interruptible);
91
+ const addSpan = span => {
92
+ spanBuffer.push(makeOtlpSpan(span));
93
+ if (spanBuffer.length >= maxBatchSize) {
94
+ runFork(runExport);
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","FiberSet","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","runExport","suspend","length","spans","data","resourceSpans","scopeSpans","asVoid","execute","post","url","body","unsafeJson","catchAllCause","cause","logWarning","annotateLogs","package","module","addFinalizer","zipRight","forever","forkScoped","interruptible","runFork","makeRuntime","addSpan","span","makeOtlpSpan","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.1",
3
+ "version": "0.46.3",
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/platform": "^0.80.8",
20
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 FiberSet from "effect/FiberSet"
14
+ import * as Inspectable from "effect/Inspectable"
15
+ import * as Layer from "effect/Layer"
16
+ import * as Option from "effect/Option"
17
+ import * as Schedule from "effect/Schedule"
18
+ import * as Scope from "effect/Scope"
19
+ import * as Tracer from "effect/Tracer"
20
+ import type { ExtractTag } from "effect/Types"
21
+
22
+ /**
23
+ * @since 1.0.0
24
+ * @category Constructors
25
+ */
26
+ export const make: (
27
+ options: {
28
+ readonly url: string
29
+ readonly resource: {
30
+ readonly serviceName: string
31
+ readonly serviceVersion?: string | undefined
32
+ readonly attributes?: Record<string, unknown>
33
+ }
34
+ readonly headers?: Headers.Input | undefined
35
+ readonly exportInterval?: Duration.DurationInput | undefined
36
+ readonly maxBatchSize?: number | undefined
37
+ }
38
+ ) => Effect.Effect<
39
+ Tracer.Tracer,
40
+ never,
41
+ HttpClient.HttpClient | Scope.Scope
42
+ > = Effect.fnUntraced(function*(options) {
43
+ const exporterScope = yield* Effect.scope
44
+ const exportInterval = options.exportInterval ? Duration.decode(options.exportInterval) : Duration.seconds(5)
45
+ const maxBatchSize = options.maxBatchSize ?? 1000
46
+
47
+ const client = HttpClient.filterStatusOk(yield* HttpClient.HttpClient).pipe(
48
+ HttpClient.tapError((error) => {
49
+ if (error._tag !== "ResponseError" || error.response.status !== 429) {
50
+ return Effect.void
51
+ }
52
+ const retryAfter = error.response.headers["retry-after"]
53
+ const retryAfterSeconds = retryAfter ? parseInt(retryAfter, 10) : 5
54
+ return Effect.sleep(Duration.seconds(retryAfterSeconds))
55
+ }),
56
+ HttpClient.retryTransient({
57
+ schedule: Schedule.spaced(1000)
58
+ })
59
+ )
60
+
61
+ let headers = Headers.unsafeFromRecord({
62
+ "user-agent": "@effect-opentelemetry-OtlpExporter"
63
+ })
64
+ if (options.headers) {
65
+ headers = Headers.merge(Headers.fromInput(options.headers), headers)
66
+ }
67
+
68
+ const resourceAttributes = options.resource.attributes
69
+ ? entriesToAttributes(Object.entries(options.resource.attributes))
70
+ : []
71
+ resourceAttributes.push({
72
+ key: "service.name",
73
+ value: {
74
+ stringValue: options.resource.serviceName
75
+ }
76
+ })
77
+ if (options.resource.serviceVersion) {
78
+ resourceAttributes.push({
79
+ key: "service.version",
80
+ value: {
81
+ stringValue: options.resource.serviceVersion
82
+ }
83
+ })
84
+ }
85
+
86
+ const otelResource: OtlpResource = {
87
+ attributes: resourceAttributes,
88
+ droppedAttributesCount: 0
89
+ }
90
+ const scope: Scope = {
91
+ name: options.resource.serviceName
92
+ }
93
+
94
+ let spanBuffer: Array<OtlpSpan> = []
95
+
96
+ const runExport = Effect.suspend(() => {
97
+ if (spanBuffer.length === 0) {
98
+ return Effect.void
99
+ }
100
+ const spans = spanBuffer
101
+ spanBuffer = []
102
+ const data: TraceData = {
103
+ resourceSpans: [{
104
+ resource: otelResource,
105
+ scopeSpans: [{
106
+ scope,
107
+ spans
108
+ }]
109
+ }]
110
+ }
111
+ return Effect.asVoid(client.execute(
112
+ HttpClientRequest.post(options.url, {
113
+ body: HttpBody.unsafeJson(data),
114
+ headers
115
+ })
116
+ ))
117
+ }).pipe(
118
+ Effect.catchAllCause((cause) => Effect.logWarning("Failed to export spans", cause)),
119
+ Effect.annotateLogs({
120
+ package: "@effect/opentelemetry",
121
+ module: "OtlpExporter"
122
+ })
123
+ )
124
+
125
+ yield* Scope.addFinalizer(exporterScope, runExport)
126
+
127
+ yield* Effect.sleep(exportInterval).pipe(
128
+ Effect.zipRight(runExport),
129
+ Effect.forever,
130
+ Effect.forkScoped,
131
+ Effect.interruptible
132
+ )
133
+
134
+ const runFork = yield* FiberSet.makeRuntime().pipe(
135
+ Effect.interruptible
136
+ )
137
+ const addSpan = (span: SpanImpl) => {
138
+ spanBuffer.push(makeOtlpSpan(span))
139
+ if (spanBuffer.length >= maxBatchSize) {
140
+ runFork(runExport)
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
  */