@logtape/otel 1.4.0-dev.465 → 1.4.0-dev.466

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/deno.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  //#region deno.json
3
3
  var name = "@logtape/otel";
4
- var version = "1.4.0-dev.465+a3cb852e";
4
+ var version = "1.4.0-dev.466+6520471a";
5
5
  var license = "MIT";
6
6
  var exports$1 = { ".": "./src/mod.ts" };
7
7
  var tasks = {
package/dist/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  //#region deno.json
2
2
  var name = "@logtape/otel";
3
- var version = "1.4.0-dev.465+a3cb852e";
3
+ var version = "1.4.0-dev.466+6520471a";
4
4
  var license = "MIT";
5
5
  var exports = { ".": "./src/mod.ts" };
6
6
  var tasks = {
package/dist/deno.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"deno.js","names":[],"sources":["../deno.json"],"sourcesContent":["{\n \"name\": \"@logtape/otel\",\n \"version\": \"1.4.0-dev.465+a3cb852e\",\n \"license\": \"MIT\",\n \"exports\": {\n \".\": \"./src/mod.ts\"\n },\n \"tasks\": {\n \"build\": \"pnpm build\",\n \"test\": \"deno test --allow-net --allow-env\"\n }\n}\n"],"mappings":";WACU;cACG;cACA;cACA,EACT,KAAK,eACN;YACQ;CACP,SAAS;CACT,QAAQ;AACT;mBAVH;;;;;;AAWC"}
1
+ {"version":3,"file":"deno.js","names":[],"sources":["../deno.json"],"sourcesContent":["{\n \"name\": \"@logtape/otel\",\n \"version\": \"1.4.0-dev.466+6520471a\",\n \"license\": \"MIT\",\n \"exports\": {\n \".\": \"./src/mod.ts\"\n },\n \"tasks\": {\n \"build\": \"pnpm build\",\n \"test\": \"deno test --allow-net --allow-env\"\n }\n}\n"],"mappings":";WACU;cACG;cACA;cACA,EACT,KAAK,eACN;YACQ;CACP,SAAS;CACT,QAAQ;AACT;mBAVH;;;;;;AAWC"}
package/dist/mod.cjs CHANGED
@@ -112,14 +112,15 @@ async function initializeLoggerProvider(options) {
112
112
  */
113
113
  function emitLogRecord(logger, record, options) {
114
114
  const objectRenderer = options.objectRenderer ?? "inspect";
115
+ const exceptionMode = options.exceptionAttributes ?? "semconv";
115
116
  const { category, level, message, timestamp, properties } = record;
116
117
  const severityNumber = mapLevelToSeverityNumber(level);
117
- const attributes = convertToAttributes(properties, objectRenderer);
118
+ const attributes = convertToAttributes(properties, objectRenderer, exceptionMode);
118
119
  attributes["category"] = [...category];
119
120
  logger.emit({
120
121
  severityNumber,
121
122
  severityText: level,
122
- body: typeof options.messageType === "function" ? convertMessageToCustomBodyFormat(message, objectRenderer, options.messageType) : options.messageType === "array" ? convertMessageToArray(message, objectRenderer) : convertMessageToString(message, objectRenderer),
123
+ body: typeof options.messageType === "function" ? convertMessageToCustomBodyFormat(message, objectRenderer, exceptionMode, options.messageType) : options.messageType === "array" ? convertMessageToArray(message, objectRenderer, exceptionMode) : convertMessageToString(message, objectRenderer, exceptionMode),
123
124
  attributes,
124
125
  timestamp: new Date(timestamp)
125
126
  });
@@ -202,23 +203,30 @@ function mapLevelToSeverityNumber(level) {
202
203
  default: return __opentelemetry_api_logs.SeverityNumber.UNSPECIFIED;
203
204
  }
204
205
  }
205
- function convertToAttributes(properties, objectRenderer) {
206
+ function convertToAttributes(properties, objectRenderer, exceptionMode) {
206
207
  const attributes = {};
207
208
  for (const [name, value] of Object.entries(properties)) {
208
209
  if (value == null) continue;
210
+ if (value instanceof Error && exceptionMode === "semconv") {
211
+ attributes["exception.type"] = value.name;
212
+ attributes["exception.message"] = value.message;
213
+ if (typeof value.stack === "string") attributes["exception.stacktrace"] = value.stack;
214
+ continue;
215
+ }
209
216
  if (Array.isArray(value)) {
210
217
  let t = null;
211
218
  for (const v of value) {
212
219
  if (v == null) continue;
213
220
  if (t != null && typeof v !== t) {
214
- attributes[name] = value.map((v$1) => convertToString(v$1, objectRenderer));
221
+ attributes[name] = value.map((v$1) => convertToString(v$1, objectRenderer, exceptionMode));
215
222
  break;
216
223
  }
217
224
  t = typeof v;
218
225
  }
219
226
  attributes[name] = value;
220
- } else {
221
- const encoded = convertToString(value, objectRenderer);
227
+ } else if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") attributes[name] = value;
228
+ else {
229
+ const encoded = convertToString(value, objectRenderer, exceptionMode);
222
230
  if (encoded == null) continue;
223
231
  attributes[name] = encoded;
224
232
  }
@@ -246,39 +254,39 @@ function serializeValue(value) {
246
254
  }
247
255
  return value;
248
256
  }
249
- function convertToString(value, objectRenderer) {
257
+ function convertToString(value, objectRenderer, exceptionMode) {
250
258
  if (value === null || value === void 0 || typeof value === "string") return value;
251
259
  if (objectRenderer === "inspect") return inspect(value);
252
260
  if (typeof value === "number" || typeof value === "boolean") return value.toString();
253
261
  else if (value instanceof Date) return value.toISOString();
254
- else if (value instanceof Error) return JSON.stringify(serializeValue(value));
262
+ else if (value instanceof Error && (exceptionMode === "raw" || exceptionMode === "semconv")) return JSON.stringify(serializeValue(value));
255
263
  else return JSON.stringify(value);
256
264
  }
257
- function convertMessageToArray(message, objectRenderer) {
265
+ function convertMessageToArray(message, objectRenderer, exceptionMode) {
258
266
  const body = [];
259
267
  for (let i = 0; i < message.length; i += 2) {
260
268
  const msg = message[i];
261
269
  body.push(msg);
262
270
  if (message.length <= i + 1) break;
263
271
  const val = message[i + 1];
264
- body.push(convertToString(val, objectRenderer));
272
+ body.push(convertToString(val, objectRenderer, exceptionMode));
265
273
  }
266
274
  return body;
267
275
  }
268
- function convertMessageToString(message, objectRenderer) {
276
+ function convertMessageToString(message, objectRenderer, exceptionMode) {
269
277
  let body = "";
270
278
  for (let i = 0; i < message.length; i += 2) {
271
279
  const msg = message[i];
272
280
  body += msg;
273
281
  if (message.length <= i + 1) break;
274
282
  const val = message[i + 1];
275
- const extra = convertToString(val, objectRenderer);
283
+ const extra = convertToString(val, objectRenderer, exceptionMode);
276
284
  body += extra ?? JSON.stringify(extra);
277
285
  }
278
286
  return body;
279
287
  }
280
- function convertMessageToCustomBodyFormat(message, objectRenderer, bodyFormatter) {
281
- const body = message.map((msg) => convertToString(msg, objectRenderer));
288
+ function convertMessageToCustomBodyFormat(message, objectRenderer, exceptionMode, bodyFormatter) {
289
+ const body = message.map((msg) => convertToString(msg, objectRenderer, exceptionMode));
282
290
  return bodyFormatter(body);
283
291
  }
284
292
  /**
package/dist/mod.d.cts CHANGED
@@ -35,6 +35,11 @@ type BodyFormatter = (message: Message) => AnyValue;
35
35
  * @since 0.9.0
36
36
  */
37
37
  type OtlpProtocol = "grpc" | "http/protobuf" | "http/json";
38
+ /**
39
+ * How to serialize `Error` objects in log attributes.
40
+ * @since 1.4.0
41
+ */
42
+ type ExceptionAttributeMode = "semconv" | "raw" | false;
38
43
  /**
39
44
  * Base options shared by all OpenTelemetry sink configurations.
40
45
  */
@@ -56,6 +61,20 @@ interface OpenTelemetrySinkOptionsBase {
56
61
  * `Deno.inspect` in Deno. `"inspect"` by default.
57
62
  */
58
63
  objectRenderer?: ObjectRenderer;
64
+ /**
65
+ * How to serialize `Error` objects in log attributes.
66
+ *
67
+ * - `"semconv"` (default): Follow OpenTelemetry semantic conventions,
68
+ * converting `Error` objects to `exception.type`, `exception.message`,
69
+ * and `exception.stacktrace` attributes.
70
+ * - `"raw"`: Serialize `Error` objects as JSON strings with fields like
71
+ * `name`, `message`, `stack`, etc.
72
+ * - `false`: Treat `Error` objects like regular objects without special
73
+ * handling.
74
+ *
75
+ * @since 1.4.0
76
+ */
77
+ exceptionAttributes?: ExceptionAttributeMode;
59
78
  /**
60
79
  * Whether to log diagnostics. Diagnostic logs are logged to
61
80
  * the `["logtape", "meta", "otel"]` category.
@@ -176,5 +195,5 @@ interface OpenTelemetrySink extends Sink, AsyncDisposable {
176
195
  */
177
196
  declare function getOpenTelemetrySink(options?: OpenTelemetrySinkOptions): OpenTelemetrySink;
178
197
  //#endregion
179
- export { BodyFormatter, ObjectRenderer, OpenTelemetrySink, OpenTelemetrySinkExporterOptions, OpenTelemetrySinkOptions, OpenTelemetrySinkProviderOptions, OtlpProtocol, getOpenTelemetrySink };
198
+ export { BodyFormatter, ExceptionAttributeMode, ObjectRenderer, OpenTelemetrySink, OpenTelemetrySinkExporterOptions, OpenTelemetrySinkOptions, OpenTelemetrySinkProviderOptions, OtlpProtocol, getOpenTelemetrySink };
180
199
  //# sourceMappingURL=mod.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAgByD;KAoJpD,eAAA,GAAkB,cAAH,GAAA;EAAA;;AAOM;AAS1B;AAAgD;AAQhD;EAAyB,QAAA,CAAA,EAAA,GAAA,GAjBN,OAiBM,CAAA,IAAA,CAAA;CAAA;;AAAiC;AAM1D;AAAkE;;;AAuB/C,KArCP,cAAA,GAqCO,MAAA,GAAA,SAAA;AAAc,KAnC5B,OAAA,GAmC4B,CAAA,MAAA,GAAA,IAAA,GAAA,SAAA,CAAA,EAAA;AAmBjC;;;;AACsC,KAjD1B,aAAA,GAiD0B,CAAA,OAAA,EAjDA,OAiDA,EAAA,GAjDY,QAiDZ;AAkBtC;;;;AACU,KA9DE,YAAA,GA8DF,MAAA,GAAA,eAAA,GAAA,WAAA;AAA4B;AA0DtC;;UAnHU,4BAAA,CAoHN;EAAgC;AACA;AAsFpC;;;;;AAAgE;AA2BhE;EAAoC,WAAA,CAAA,EAAA,QAAA,GAAA,OAAA,GA5NC,aA4ND;EAAA;;AAEhB;;;;mBAtND;;;;;;;;;;;;;;;;;UAmBF,gCAAA,SACP;;;;kBAIQ;;;;;;;;;;;;;UAcD,gCAAA,SACP;;;;;;;;;uBAUa;;;;;;;;;;uBAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoCX,wBAAA,GACR,mCACA;;;;;UAsFa,iBAAA,SAA0B,MAAM;;;;;;;;;;;;;;kBAc/B;;;;;;;;;;;;iBAaF,oBAAA,WACL,2BACR"}
1
+ {"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAgByD;KAoJpD,eAAA,GAAkB,cAAH,GAAA;EAAA;;AAOM;AAS1B;AAAgD;AAQhD;EAAyB,QAAA,CAAA,EAAA,GAAA,GAjBN,OAiBM,CAAA,IAAA,CAAA;CAAA;;AAAiC;AAM1D;AAMA;AAA+D;;AAe1B,KAnCzB,cAAA,GAmCyB,MAAA,GAAA,SAAA;KAjChC,OAAA,GAyCc,CAAA,MAAA,GAAA,IAAA,GAAA,SAAA,CAAA,EAAA;;AAe2B;AAmB9C;;AAKkB,KA1EN,aAAA,GA0EM,CAAA,OAAA,EA1EoB,OA0EpB,EAAA,GA1EgC,QA0EhC;;AAJoB;AAkBtC;;AAWuB,KA7FX,YAAA,GA6FW,MAAA,GAAA,eAAA,GAAA,WAAA;;;AAVe;AA0DtC;AAAoC,KAvIxB,sBAAA,GAuIwB,SAAA,GAAA,KAAA,GAAA,KAAA;;;AAEA;AA4FpC,UAhOU,4BAAA,CAgOyB;EAAA;;;;AAA6B;AA2BhE;;;;EAEoB,WAAA,CAAA,EAAA,QAAA,GAAA,OAAA,GAnPiB,aAmPjB;;;;;;;mBA3OD;;;;;;;;;;;;;;wBAeK;;;;;;;;;;;;;;;;;UAmBP,gCAAA,SACP;;;;kBAIQ;;;;;;;;;;;;;UAcD,gCAAA,SACP;;;;;;;;;uBAUa;;;;;;;;;;uBAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoCX,wBAAA,GACR,mCACA;;;;;UA4Fa,iBAAA,SAA0B,MAAM;;;;;;;;;;;;;;kBAc/B;;;;;;;;;;;;iBAaF,oBAAA,WACL,2BACR"}
package/dist/mod.d.ts CHANGED
@@ -35,6 +35,11 @@ type BodyFormatter = (message: Message) => AnyValue;
35
35
  * @since 0.9.0
36
36
  */
37
37
  type OtlpProtocol = "grpc" | "http/protobuf" | "http/json";
38
+ /**
39
+ * How to serialize `Error` objects in log attributes.
40
+ * @since 1.4.0
41
+ */
42
+ type ExceptionAttributeMode = "semconv" | "raw" | false;
38
43
  /**
39
44
  * Base options shared by all OpenTelemetry sink configurations.
40
45
  */
@@ -56,6 +61,20 @@ interface OpenTelemetrySinkOptionsBase {
56
61
  * `Deno.inspect` in Deno. `"inspect"` by default.
57
62
  */
58
63
  objectRenderer?: ObjectRenderer;
64
+ /**
65
+ * How to serialize `Error` objects in log attributes.
66
+ *
67
+ * - `"semconv"` (default): Follow OpenTelemetry semantic conventions,
68
+ * converting `Error` objects to `exception.type`, `exception.message`,
69
+ * and `exception.stacktrace` attributes.
70
+ * - `"raw"`: Serialize `Error` objects as JSON strings with fields like
71
+ * `name`, `message`, `stack`, etc.
72
+ * - `false`: Treat `Error` objects like regular objects without special
73
+ * handling.
74
+ *
75
+ * @since 1.4.0
76
+ */
77
+ exceptionAttributes?: ExceptionAttributeMode;
59
78
  /**
60
79
  * Whether to log diagnostics. Diagnostic logs are logged to
61
80
  * the `["logtape", "meta", "otel"]` category.
@@ -176,5 +195,5 @@ interface OpenTelemetrySink extends Sink, AsyncDisposable {
176
195
  */
177
196
  declare function getOpenTelemetrySink(options?: OpenTelemetrySinkOptions): OpenTelemetrySink;
178
197
  //#endregion
179
- export { BodyFormatter, ObjectRenderer, OpenTelemetrySink, OpenTelemetrySinkExporterOptions, OpenTelemetrySinkOptions, OpenTelemetrySinkProviderOptions, OtlpProtocol, getOpenTelemetrySink };
198
+ export { BodyFormatter, ExceptionAttributeMode, ObjectRenderer, OpenTelemetrySink, OpenTelemetrySinkExporterOptions, OpenTelemetrySinkOptions, OpenTelemetrySinkProviderOptions, OtlpProtocol, getOpenTelemetrySink };
180
199
  //# sourceMappingURL=mod.d.ts.map
package/dist/mod.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAgByD;KAoJpD,eAAA,GAAkB,cAAH,GAAA;EAAA;;AAOM;AAS1B;AAAgD;AAQhD;EAAyB,QAAA,CAAA,EAAA,GAAA,GAjBN,OAiBM,CAAA,IAAA,CAAA;CAAA;;AAAiC;AAM1D;AAAkE;;;AAuB/C,KArCP,cAAA,GAqCO,MAAA,GAAA,SAAA;AAAc,KAnC5B,OAAA,GAmC4B,CAAA,MAAA,GAAA,IAAA,GAAA,SAAA,CAAA,EAAA;AAmBjC;;;;AACsC,KAjD1B,aAAA,GAiD0B,CAAA,OAAA,EAjDA,OAiDA,EAAA,GAjDY,QAiDZ;AAkBtC;;;;AACU,KA9DE,YAAA,GA8DF,MAAA,GAAA,eAAA,GAAA,WAAA;AAA4B;AA0DtC;;UAnHU,4BAAA,CAoHN;EAAgC;AACA;AAsFpC;;;;;AAAgE;AA2BhE;EAAoC,WAAA,CAAA,EAAA,QAAA,GAAA,OAAA,GA5NC,aA4ND;EAAA;;AAEhB;;;;mBAtND;;;;;;;;;;;;;;;;;UAmBF,gCAAA,SACP;;;;kBAIQ;;;;;;;;;;;;;UAcD,gCAAA,SACP;;;;;;;;;uBAUa;;;;;;;;;;uBAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoCX,wBAAA,GACR,mCACA;;;;;UAsFa,iBAAA,SAA0B,MAAM;;;;;;;;;;;;;;kBAc/B;;;;;;;;;;;;iBAaF,oBAAA,WACL,2BACR"}
1
+ {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAgByD;KAoJpD,eAAA,GAAkB,cAAH,GAAA;EAAA;;AAOM;AAS1B;AAAgD;AAQhD;EAAyB,QAAA,CAAA,EAAA,GAAA,GAjBN,OAiBM,CAAA,IAAA,CAAA;CAAA;;AAAiC;AAM1D;AAMA;AAA+D;;AAe1B,KAnCzB,cAAA,GAmCyB,MAAA,GAAA,SAAA;KAjChC,OAAA,GAyCc,CAAA,MAAA,GAAA,IAAA,GAAA,SAAA,CAAA,EAAA;;AAe2B;AAmB9C;;AAKkB,KA1EN,aAAA,GA0EM,CAAA,OAAA,EA1EoB,OA0EpB,EAAA,GA1EgC,QA0EhC;;AAJoB;AAkBtC;;AAWuB,KA7FX,YAAA,GA6FW,MAAA,GAAA,eAAA,GAAA,WAAA;;;AAVe;AA0DtC;AAAoC,KAvIxB,sBAAA,GAuIwB,SAAA,GAAA,KAAA,GAAA,KAAA;;;AAEA;AA4FpC,UAhOU,4BAAA,CAgOyB;EAAA;;;;AAA6B;AA2BhE;;;;EAEoB,WAAA,CAAA,EAAA,QAAA,GAAA,OAAA,GAnPiB,aAmPjB;;;;;;;mBA3OD;;;;;;;;;;;;;;wBAeK;;;;;;;;;;;;;;;;;UAmBP,gCAAA,SACP;;;;kBAIQ;;;;;;;;;;;;;UAcD,gCAAA,SACP;;;;;;;;;uBAUa;;;;;;;;;;uBAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoCX,wBAAA,GACR,mCACA;;;;;UA4Fa,iBAAA,SAA0B,MAAM;;;;;;;;;;;;;;kBAc/B;;;;;;;;;;;;iBAaF,oBAAA,WACL,2BACR"}
package/dist/mod.js CHANGED
@@ -111,14 +111,15 @@ async function initializeLoggerProvider(options) {
111
111
  */
112
112
  function emitLogRecord(logger, record, options) {
113
113
  const objectRenderer = options.objectRenderer ?? "inspect";
114
+ const exceptionMode = options.exceptionAttributes ?? "semconv";
114
115
  const { category, level, message, timestamp, properties } = record;
115
116
  const severityNumber = mapLevelToSeverityNumber(level);
116
- const attributes = convertToAttributes(properties, objectRenderer);
117
+ const attributes = convertToAttributes(properties, objectRenderer, exceptionMode);
117
118
  attributes["category"] = [...category];
118
119
  logger.emit({
119
120
  severityNumber,
120
121
  severityText: level,
121
- body: typeof options.messageType === "function" ? convertMessageToCustomBodyFormat(message, objectRenderer, options.messageType) : options.messageType === "array" ? convertMessageToArray(message, objectRenderer) : convertMessageToString(message, objectRenderer),
122
+ body: typeof options.messageType === "function" ? convertMessageToCustomBodyFormat(message, objectRenderer, exceptionMode, options.messageType) : options.messageType === "array" ? convertMessageToArray(message, objectRenderer, exceptionMode) : convertMessageToString(message, objectRenderer, exceptionMode),
122
123
  attributes,
123
124
  timestamp: new Date(timestamp)
124
125
  });
@@ -201,23 +202,30 @@ function mapLevelToSeverityNumber(level) {
201
202
  default: return SeverityNumber.UNSPECIFIED;
202
203
  }
203
204
  }
204
- function convertToAttributes(properties, objectRenderer) {
205
+ function convertToAttributes(properties, objectRenderer, exceptionMode) {
205
206
  const attributes = {};
206
207
  for (const [name, value] of Object.entries(properties)) {
207
208
  if (value == null) continue;
209
+ if (value instanceof Error && exceptionMode === "semconv") {
210
+ attributes["exception.type"] = value.name;
211
+ attributes["exception.message"] = value.message;
212
+ if (typeof value.stack === "string") attributes["exception.stacktrace"] = value.stack;
213
+ continue;
214
+ }
208
215
  if (Array.isArray(value)) {
209
216
  let t = null;
210
217
  for (const v of value) {
211
218
  if (v == null) continue;
212
219
  if (t != null && typeof v !== t) {
213
- attributes[name] = value.map((v$1) => convertToString(v$1, objectRenderer));
220
+ attributes[name] = value.map((v$1) => convertToString(v$1, objectRenderer, exceptionMode));
214
221
  break;
215
222
  }
216
223
  t = typeof v;
217
224
  }
218
225
  attributes[name] = value;
219
- } else {
220
- const encoded = convertToString(value, objectRenderer);
226
+ } else if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") attributes[name] = value;
227
+ else {
228
+ const encoded = convertToString(value, objectRenderer, exceptionMode);
221
229
  if (encoded == null) continue;
222
230
  attributes[name] = encoded;
223
231
  }
@@ -245,39 +253,39 @@ function serializeValue(value) {
245
253
  }
246
254
  return value;
247
255
  }
248
- function convertToString(value, objectRenderer) {
256
+ function convertToString(value, objectRenderer, exceptionMode) {
249
257
  if (value === null || value === void 0 || typeof value === "string") return value;
250
258
  if (objectRenderer === "inspect") return inspect(value);
251
259
  if (typeof value === "number" || typeof value === "boolean") return value.toString();
252
260
  else if (value instanceof Date) return value.toISOString();
253
- else if (value instanceof Error) return JSON.stringify(serializeValue(value));
261
+ else if (value instanceof Error && (exceptionMode === "raw" || exceptionMode === "semconv")) return JSON.stringify(serializeValue(value));
254
262
  else return JSON.stringify(value);
255
263
  }
256
- function convertMessageToArray(message, objectRenderer) {
264
+ function convertMessageToArray(message, objectRenderer, exceptionMode) {
257
265
  const body = [];
258
266
  for (let i = 0; i < message.length; i += 2) {
259
267
  const msg = message[i];
260
268
  body.push(msg);
261
269
  if (message.length <= i + 1) break;
262
270
  const val = message[i + 1];
263
- body.push(convertToString(val, objectRenderer));
271
+ body.push(convertToString(val, objectRenderer, exceptionMode));
264
272
  }
265
273
  return body;
266
274
  }
267
- function convertMessageToString(message, objectRenderer) {
275
+ function convertMessageToString(message, objectRenderer, exceptionMode) {
268
276
  let body = "";
269
277
  for (let i = 0; i < message.length; i += 2) {
270
278
  const msg = message[i];
271
279
  body += msg;
272
280
  if (message.length <= i + 1) break;
273
281
  const val = message[i + 1];
274
- const extra = convertToString(val, objectRenderer);
282
+ const extra = convertToString(val, objectRenderer, exceptionMode);
275
283
  body += extra ?? JSON.stringify(extra);
276
284
  }
277
285
  return body;
278
286
  }
279
- function convertMessageToCustomBodyFormat(message, objectRenderer, bodyFormatter) {
280
- const body = message.map((msg) => convertToString(msg, objectRenderer));
287
+ function convertMessageToCustomBodyFormat(message, objectRenderer, exceptionMode, bodyFormatter) {
288
+ const body = message.map((msg) => convertToString(msg, objectRenderer, exceptionMode));
281
289
  return bodyFormatter(body);
282
290
  }
283
291
  /**
package/dist/mod.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.js","names":["name: string","config?: OTLPExporterNodeConfigBase","noopLoggerProvider: ILoggerProvider","options: OpenTelemetrySinkExporterOptions","LoggerProvider","logger: OTLogger","record: LogRecord","options: OpenTelemetrySinkOptions","loggerProvider","logger","metadata","sink: OpenTelemetrySink","sink","loggerProvider: ILoggerProvider | null","logger: OTLogger | null","initPromise: Promise<void> | null","initError: Error | null","pendingRecords: LogRecord[]","level: string","properties: Record<string, unknown>","objectRenderer: ObjectRenderer","attributes: Record<string, AnyValue>","v","value: unknown","serialized: Record<string, unknown>","message: readonly unknown[]","body: (string | null | undefined)[]","bodyFormatter: BodyFormatter","inspect: (value: unknown) => string","msg: string","#escape"],"sources":["../src/mod.ts"],"sourcesContent":["import {\n getLogger,\n type Logger,\n type LogRecord,\n type Sink,\n} from \"@logtape/logtape\";\nimport { diag, type DiagLogger, DiagLogLevel } from \"@opentelemetry/api\";\nimport {\n type AnyValue,\n type Logger as OTLogger,\n type LoggerProvider as LoggerProviderBase,\n type LogRecord as OTLogRecord,\n NOOP_LOGGER,\n SeverityNumber,\n} from \"@opentelemetry/api-logs\";\nimport type { OTLPExporterNodeConfigBase } from \"@opentelemetry/otlp-exporter-base\";\nimport type { Resource } from \"@opentelemetry/resources\";\nimport {\n defaultResource,\n resourceFromAttributes,\n} from \"@opentelemetry/resources\";\nimport {\n LoggerProvider,\n SimpleLogRecordProcessor,\n} from \"@opentelemetry/sdk-logs\";\nimport { ATTR_SERVICE_NAME } from \"@opentelemetry/semantic-conventions\";\nimport metadata from \"../deno.json\" with { type: \"json\" };\n\n/**\n * Gets an environment variable value across different JavaScript runtimes.\n * @param name The environment variable name.\n * @returns The environment variable value, or undefined if not found.\n */\nfunction getEnvironmentVariable(name: string): string | undefined {\n // Deno runtime\n if (typeof Deno !== \"undefined\" && Deno.env) {\n try {\n return Deno.env.get(name);\n } catch {\n // Deno.env.get() can throw if permissions are not granted\n return undefined;\n }\n }\n\n // Node.js/Bun runtime\n if (\n typeof globalThis !== \"undefined\" && \"process\" in globalThis &&\n // @ts-ignore: process exists in Node.js/Bun\n typeof globalThis.process !== \"undefined\" &&\n // @ts-ignore: process.env exists in Node.js/Bun\n typeof globalThis.process.env === \"object\" &&\n // @ts-ignore: process.env exists in Node.js/Bun\n globalThis.process.env !== null\n ) {\n // @ts-ignore: process.env exists in Node.js/Bun\n return globalThis.process.env[name];\n }\n\n // Browser/other environments - no environment variables available\n return undefined;\n}\n\n/**\n * Checks if an OTLP endpoint is configured via environment variables or options.\n * Checks the following environment variables:\n * - `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` (logs-specific endpoint)\n * - `OTEL_EXPORTER_OTLP_ENDPOINT` (general OTLP endpoint)\n *\n * @param config Optional exporter configuration that may contain a URL.\n * @returns `true` if an endpoint is configured, `false` otherwise.\n */\nfunction hasOtlpEndpoint(config?: OTLPExporterNodeConfigBase): boolean {\n // Check if URL is provided in config\n if (config?.url) {\n return true;\n }\n\n // Check environment variables\n const logsEndpoint = getEnvironmentVariable(\n \"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT\",\n );\n if (logsEndpoint) {\n return true;\n }\n\n const endpoint = getEnvironmentVariable(\"OTEL_EXPORTER_OTLP_ENDPOINT\");\n if (endpoint) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Detects the OTLP protocol from environment variables.\n * Priority:\n * 1. `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL`\n * 2. `OTEL_EXPORTER_OTLP_PROTOCOL`\n * 3. Default: `\"http/json\"` (for backward compatibility)\n *\n * @returns The detected OTLP protocol.\n */\nfunction detectOtlpProtocol(): OtlpProtocol {\n const logsProtocol = getEnvironmentVariable(\n \"OTEL_EXPORTER_OTLP_LOGS_PROTOCOL\",\n );\n if (\n logsProtocol === \"grpc\" ||\n logsProtocol === \"http/protobuf\" ||\n logsProtocol === \"http/json\"\n ) {\n return logsProtocol;\n }\n\n const protocol = getEnvironmentVariable(\"OTEL_EXPORTER_OTLP_PROTOCOL\");\n if (\n protocol === \"grpc\" ||\n protocol === \"http/protobuf\" ||\n protocol === \"http/json\"\n ) {\n return protocol;\n }\n\n return \"http/json\";\n}\n\n/**\n * Creates an OTLP log exporter based on the detected protocol.\n * Uses dynamic imports to maintain browser compatibility when gRPC is not used.\n * @param config Optional exporter configuration.\n * @returns A promise that resolves to the appropriate OTLP log exporter.\n */\nasync function createOtlpExporter(\n config?: OTLPExporterNodeConfigBase,\n // deno-lint-ignore no-explicit-any\n): Promise<any> {\n const protocol = detectOtlpProtocol();\n\n switch (protocol) {\n case \"grpc\": {\n const { OTLPLogExporter } = await import(\n \"@opentelemetry/exporter-logs-otlp-grpc\"\n );\n return new OTLPLogExporter(config);\n }\n case \"http/protobuf\": {\n const { OTLPLogExporter } = await import(\n \"@opentelemetry/exporter-logs-otlp-proto\"\n );\n return new OTLPLogExporter(config);\n }\n case \"http/json\":\n default: {\n const { OTLPLogExporter } = await import(\n \"@opentelemetry/exporter-logs-otlp-http\"\n );\n return new OTLPLogExporter(config);\n }\n }\n}\n\n/**\n * The OpenTelemetry logger provider.\n */\ntype ILoggerProvider = LoggerProviderBase & {\n /**\n * Flush all buffered data and shut down the LoggerProvider and all registered\n * LogRecordProcessor.\n *\n * Returns a promise which is resolved when all flushes are complete.\n */\n shutdown?: () => Promise<void>;\n};\n\n/**\n * The way to render the object in the log record. If `\"json\"`,\n * the object is rendered as a JSON string. If `\"inspect\"`,\n * the object is rendered using `util.inspect` in Node.js/Bun, or\n * `Deno.inspect` in Deno.\n */\nexport type ObjectRenderer = \"json\" | \"inspect\";\n\ntype Message = (string | null | undefined)[];\n\n/**\n * Custom `body` attribute formatter.\n * @since 0.3.0\n */\nexport type BodyFormatter = (message: Message) => AnyValue;\n\n/**\n * The OTLP protocol to use for exporting logs.\n * @since 0.9.0\n */\nexport type OtlpProtocol = \"grpc\" | \"http/protobuf\" | \"http/json\";\n\n/**\n * Base options shared by all OpenTelemetry sink configurations.\n */\ninterface OpenTelemetrySinkOptionsBase {\n /**\n * The way to render the message in the log record. If `\"string\"`,\n * the message is rendered as a single string with the values are\n * interpolated into the message. If `\"array\"`, the message is\n * rendered as an array of strings. `\"string\"` by default.\n *\n * Or even fully customizable with a {@link BodyFormatter} function.\n * @since 0.2.0\n */\n messageType?: \"string\" | \"array\" | BodyFormatter;\n\n /**\n * The way to render the object in the log record. If `\"json\"`,\n * the object is rendered as a JSON string. If `\"inspect\"`,\n * the object is rendered using `util.inspect` in Node.js/Bun, or\n * `Deno.inspect` in Deno. `\"inspect\"` by default.\n */\n objectRenderer?: ObjectRenderer;\n\n /**\n * Whether to log diagnostics. Diagnostic logs are logged to\n * the `[\"logtape\", \"meta\", \"otel\"]` category.\n * Turned off by default.\n */\n diagnostics?: boolean;\n}\n\n/**\n * Options for creating an OpenTelemetry sink with a custom logger provider.\n * When using this configuration, you are responsible for setting up the\n * logger provider with appropriate exporters and processors.\n *\n * This is the recommended approach for production use as it gives you\n * full control over the OpenTelemetry configuration.\n * @since 0.9.0\n */\nexport interface OpenTelemetrySinkProviderOptions\n extends OpenTelemetrySinkOptionsBase {\n /**\n * The OpenTelemetry logger provider to use.\n */\n loggerProvider: ILoggerProvider;\n}\n\n/**\n * Options for creating an OpenTelemetry sink with automatic exporter creation.\n * The protocol is determined by environment variables:\n * - `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL` (highest priority)\n * - `OTEL_EXPORTER_OTLP_PROTOCOL` (fallback)\n * - Default: `\"http/json\"`\n *\n * For production use, consider providing your own {@link ILoggerProvider}\n * via {@link OpenTelemetrySinkProviderOptions} for more control.\n * @since 0.9.0\n */\nexport interface OpenTelemetrySinkExporterOptions\n extends OpenTelemetrySinkOptionsBase {\n /**\n * The OpenTelemetry logger provider to use.\n * Must be undefined or omitted when using exporter options.\n */\n loggerProvider?: undefined;\n\n /**\n * The OpenTelemetry OTLP exporter configuration to use.\n */\n otlpExporterConfig?: OTLPExporterNodeConfigBase;\n\n /**\n * The service name to use. If not provided, the service name is\n * taken from the `OTEL_SERVICE_NAME` environment variable.\n */\n serviceName?: string;\n\n /**\n * An additional resource to merge with the default resource.\n * @since 1.3.0\n */\n additionalResource?: Resource;\n}\n\n/**\n * Options for creating an OpenTelemetry sink.\n *\n * This is a union type that accepts either:\n * - {@link OpenTelemetrySinkProviderOptions}: Provide your own `loggerProvider`\n * (recommended for production)\n * - {@link OpenTelemetrySinkExporterOptions}: Let the sink create an exporter\n * automatically based on environment variables\n *\n * When no `loggerProvider` is provided, the protocol is determined by:\n * 1. `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL` environment variable\n * 2. `OTEL_EXPORTER_OTLP_PROTOCOL` environment variable\n * 3. Default: `\"http/json\"`\n *\n * @example Using a custom logger provider (recommended)\n * ```typescript\n * import { LoggerProvider, SimpleLogRecordProcessor } from \"@opentelemetry/sdk-logs\";\n * import { OTLPLogExporter } from \"@opentelemetry/exporter-logs-otlp-grpc\";\n *\n * const provider = new LoggerProvider();\n * provider.addLogRecordProcessor(new SimpleLogRecordProcessor(new OTLPLogExporter()));\n *\n * const sink = getOpenTelemetrySink({ loggerProvider: provider });\n * ```\n *\n * @example Using automatic exporter creation\n * ```typescript\n * // Protocol determined by OTEL_EXPORTER_OTLP_PROTOCOL env var\n * const sink = getOpenTelemetrySink({\n * serviceName: \"my-service\",\n * });\n * ```\n */\nexport type OpenTelemetrySinkOptions =\n | OpenTelemetrySinkProviderOptions\n | OpenTelemetrySinkExporterOptions;\n\n/**\n * A no-op logger provider that returns NOOP_LOGGER for all requests.\n * Used when no OTLP endpoint is configured to avoid repeated connection errors.\n */\nconst noopLoggerProvider: ILoggerProvider = {\n getLogger: () => NOOP_LOGGER,\n};\n\n/**\n * Initializes the logger provider asynchronously.\n * This is used when the user doesn't provide a custom logger provider.\n *\n * If no OTLP endpoint is configured (via options or environment variables),\n * returns a noop logger provider to avoid repeated connection errors.\n *\n * @param options The exporter options.\n * @returns A promise that resolves to the initialized logger provider.\n */\nasync function initializeLoggerProvider(\n options: OpenTelemetrySinkExporterOptions,\n): Promise<ILoggerProvider> {\n // If no endpoint is configured, use noop logger provider to avoid\n // repeated transport errors\n if (!hasOtlpEndpoint(options.otlpExporterConfig)) {\n return noopLoggerProvider;\n }\n\n const resource = defaultResource().merge(\n resourceFromAttributes({\n [ATTR_SERVICE_NAME]: options.serviceName ??\n getEnvironmentVariable(\"OTEL_SERVICE_NAME\"),\n })\n .merge(options.additionalResource ?? null),\n );\n const otlpExporter = await createOtlpExporter(options.otlpExporterConfig);\n const loggerProvider = new LoggerProvider({\n resource,\n processors: [\n // @ts-ignore: it works anyway...\n new SimpleLogRecordProcessor(otlpExporter),\n ],\n });\n return loggerProvider;\n}\n\n/**\n * Emits a log record to the OpenTelemetry logger.\n * @param logger The OpenTelemetry logger.\n * @param record The LogTape log record.\n * @param options The sink options.\n */\nfunction emitLogRecord(\n logger: OTLogger,\n record: LogRecord,\n options: OpenTelemetrySinkOptions,\n): void {\n const objectRenderer = options.objectRenderer ?? \"inspect\";\n const { category, level, message, timestamp, properties } = record;\n const severityNumber = mapLevelToSeverityNumber(level);\n const attributes = convertToAttributes(properties, objectRenderer);\n attributes[\"category\"] = [...category];\n logger.emit(\n {\n severityNumber,\n severityText: level,\n body: typeof options.messageType === \"function\"\n ? convertMessageToCustomBodyFormat(\n message,\n objectRenderer,\n options.messageType,\n )\n : options.messageType === \"array\"\n ? convertMessageToArray(message, objectRenderer)\n : convertMessageToString(message, objectRenderer),\n attributes,\n timestamp: new Date(timestamp),\n } satisfies OTLogRecord,\n );\n}\n\n/**\n * An OpenTelemetry sink with async disposal and initialization tracking.\n * @since 1.3.1\n */\nexport interface OpenTelemetrySink extends Sink, AsyncDisposable {\n /**\n * A promise that resolves when the sink's lazy initialization completes.\n * For sinks created with an explicit `loggerProvider`, this resolves\n * immediately. For sinks using automatic exporter creation, this resolves\n * once the OpenTelemetry logger provider is fully initialized.\n *\n * This is useful for:\n * - Ensuring all buffered log records have been sent before shutdown\n * - Testing scenarios where you need to verify emitted records\n * - Waiting for initialization before proceeding with critical operations\n *\n * @since 1.3.1\n */\n readonly ready: Promise<void>;\n}\n\n/**\n * Creates a sink that forwards log records to OpenTelemetry.\n *\n * When a custom `loggerProvider` is provided, it is used directly.\n * Otherwise, the sink will lazily initialize a logger provider on the first\n * log record, using the protocol determined by environment variables.\n *\n * @param options Options for creating the sink.\n * @returns The sink.\n */\nexport function getOpenTelemetrySink(\n options: OpenTelemetrySinkOptions = {},\n): OpenTelemetrySink {\n if (options.diagnostics) {\n diag.setLogger(new DiagLoggerAdaptor(), DiagLogLevel.DEBUG);\n }\n\n // If loggerProvider is provided, use the synchronous path\n if (options.loggerProvider != null) {\n const loggerProvider = options.loggerProvider;\n const logger = loggerProvider.getLogger(metadata.name, metadata.version);\n const shutdown = loggerProvider.shutdown?.bind(loggerProvider);\n const sink: OpenTelemetrySink = Object.assign(\n (record: LogRecord) => {\n const { category } = record;\n if (\n category[0] === \"logtape\" && category[1] === \"meta\" &&\n category[2] === \"otel\"\n ) {\n return;\n }\n emitLogRecord(logger, record, options);\n },\n {\n ready: Promise.resolve(),\n async [Symbol.asyncDispose](): Promise<void> {\n if (shutdown != null) await shutdown();\n },\n },\n );\n return sink;\n }\n\n // Lazy initialization for automatic exporter creation\n let loggerProvider: ILoggerProvider | null = null;\n let logger: OTLogger | null = null;\n let initPromise: Promise<void> | null = null;\n let initError: Error | null = null;\n // Buffer for log records that arrive during initialization\n let pendingRecords: LogRecord[] = [];\n\n const sink: OpenTelemetrySink = Object.assign(\n (record: LogRecord) => {\n const { category } = record;\n if (\n category[0] === \"logtape\" && category[1] === \"meta\" &&\n category[2] === \"otel\"\n ) {\n return;\n }\n\n // If already initialized, emit the log\n if (logger != null) {\n emitLogRecord(logger, record, options);\n return;\n }\n\n // If initialization failed, skip silently\n if (initError != null) {\n return;\n }\n\n // Buffer the record for later emission\n pendingRecords.push(record);\n\n // Start initialization if not already started\n if (initPromise == null) {\n initPromise = initializeLoggerProvider(options)\n .then((provider) => {\n loggerProvider = provider;\n logger = provider.getLogger(metadata.name, metadata.version);\n // Emit all buffered records\n for (const pendingRecord of pendingRecords) {\n emitLogRecord(logger, pendingRecord, options);\n }\n pendingRecords = [];\n })\n .catch((error) => {\n initError = error;\n pendingRecords = [];\n // Log initialization error to console as a fallback\n // deno-lint-ignore no-console\n console.error(\"Failed to initialize OpenTelemetry logger:\", error);\n });\n }\n },\n {\n get ready(): Promise<void> {\n return initPromise ?? Promise.resolve();\n },\n async [Symbol.asyncDispose](): Promise<void> {\n // Wait for initialization to complete if in progress\n if (initPromise != null) {\n try {\n await initPromise;\n } catch {\n // Initialization failed, nothing to shut down\n return;\n }\n }\n if (loggerProvider?.shutdown != null) {\n await loggerProvider.shutdown();\n }\n },\n },\n );\n\n return sink;\n}\n\nfunction mapLevelToSeverityNumber(level: string): number {\n switch (level) {\n case \"trace\":\n return SeverityNumber.TRACE;\n case \"debug\":\n return SeverityNumber.DEBUG;\n case \"info\":\n return SeverityNumber.INFO;\n case \"warning\":\n return SeverityNumber.WARN;\n case \"error\":\n return SeverityNumber.ERROR;\n case \"fatal\":\n return SeverityNumber.FATAL;\n default:\n return SeverityNumber.UNSPECIFIED;\n }\n}\n\nfunction convertToAttributes(\n properties: Record<string, unknown>,\n objectRenderer: ObjectRenderer,\n): Record<string, AnyValue> {\n const attributes: Record<string, AnyValue> = {};\n for (const [name, value] of Object.entries(properties)) {\n if (value == null) continue;\n if (Array.isArray(value)) {\n let t = null;\n for (const v of value) {\n if (v == null) continue;\n if (t != null && typeof v !== t) {\n attributes[name] = value.map((v) =>\n convertToString(v, objectRenderer)\n );\n break;\n }\n t = typeof v;\n }\n attributes[name] = value;\n } else {\n const encoded = convertToString(value, objectRenderer);\n if (encoded == null) continue;\n attributes[name] = encoded;\n }\n }\n return attributes;\n}\n\nfunction serializeValue(value: unknown): unknown {\n if (value instanceof Error) {\n const serialized: Record<string, unknown> = {\n name: value.name,\n message: value.message,\n };\n\n if (typeof value.stack === \"string\") {\n serialized.stack = value.stack;\n }\n\n const cause = (value as { cause?: unknown }).cause;\n if (cause !== undefined) {\n serialized.cause = serializeValue(cause);\n }\n\n if (\n typeof AggregateError !== \"undefined\" &&\n value instanceof AggregateError\n ) {\n serialized.errors = value.errors.map(serializeValue);\n }\n\n for (const key of Object.keys(value)) {\n if (!(key in serialized)) {\n serialized[key] = serializeValue(\n (value as unknown as Record<string, unknown>)[key],\n );\n }\n }\n\n return serialized;\n }\n\n if (Array.isArray(value)) {\n return value.map(serializeValue);\n }\n\n if (value !== null && typeof value === \"object\") {\n const serialized: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n serialized[key] = serializeValue(val);\n }\n return serialized;\n }\n\n return value;\n}\n\nfunction convertToString(\n value: unknown,\n objectRenderer: ObjectRenderer,\n): string | null | undefined {\n if (value === null || value === undefined || typeof value === \"string\") {\n return value;\n }\n if (objectRenderer === \"inspect\") return inspect(value);\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return value.toString();\n } else if (value instanceof Date) return value.toISOString();\n else if (value instanceof Error) {\n return JSON.stringify(serializeValue(value));\n } else return JSON.stringify(value);\n}\n\nfunction convertMessageToArray(\n message: readonly unknown[],\n objectRenderer: ObjectRenderer,\n): AnyValue {\n const body: (string | null | undefined)[] = [];\n for (let i = 0; i < message.length; i += 2) {\n const msg = message[i] as string;\n body.push(msg);\n if (message.length <= i + 1) break;\n const val = message[i + 1];\n body.push(convertToString(val, objectRenderer));\n }\n return body;\n}\n\nfunction convertMessageToString(\n message: readonly unknown[],\n objectRenderer: ObjectRenderer,\n): AnyValue {\n let body = \"\";\n for (let i = 0; i < message.length; i += 2) {\n const msg = message[i] as string;\n body += msg;\n if (message.length <= i + 1) break;\n const val = message[i + 1];\n const extra = convertToString(val, objectRenderer);\n body += extra ?? JSON.stringify(extra);\n }\n return body;\n}\n\nfunction convertMessageToCustomBodyFormat(\n message: readonly unknown[],\n objectRenderer: ObjectRenderer,\n bodyFormatter: BodyFormatter,\n): AnyValue {\n const body = message.map((msg) => convertToString(msg, objectRenderer));\n return bodyFormatter(body);\n}\n\n/**\n * A platform-specific inspect function. In Deno, this is {@link Deno.inspect},\n * and in Node.js/Bun it is {@link util.inspect}. If neither is available, it\n * falls back to {@link JSON.stringify}.\n *\n * @param value The value to inspect.\n * @returns The string representation of the value.\n */\nconst inspect: (value: unknown) => string =\n // @ts-ignore: Deno global\n \"Deno\" in globalThis && \"inspect\" in globalThis.Deno &&\n // @ts-ignore: Deno global\n typeof globalThis.Deno.inspect === \"function\"\n // @ts-ignore: Deno global\n ? globalThis.Deno.inspect\n // @ts-ignore: Node.js global\n : \"util\" in globalThis && \"inspect\" in globalThis.util &&\n // @ts-ignore: Node.js global\n globalThis.util.inspect === \"function\"\n // @ts-ignore: Node.js global\n ? globalThis.util.inspect\n : JSON.stringify;\n\nclass DiagLoggerAdaptor implements DiagLogger {\n logger: Logger;\n\n constructor() {\n this.logger = getLogger([\"logtape\", \"meta\", \"otel\"]);\n }\n\n #escape(msg: string): string {\n return msg.replaceAll(\"{\", \"{{\").replaceAll(\"}\", \"}}\");\n }\n\n error(msg: string, ...values: unknown[]): void {\n this.logger.error(`${this.#escape(msg)}: {values}`, { values });\n }\n\n warn(msg: string, ...values: unknown[]): void {\n this.logger.warn(`${this.#escape(msg)}: {values}`, { values });\n }\n\n info(msg: string, ...values: unknown[]): void {\n this.logger.info(`${this.#escape(msg)}: {values}`, { values });\n }\n\n debug(msg: string, ...values: unknown[]): void {\n this.logger.debug(`${this.#escape(msg)}: {values}`, { values });\n }\n\n verbose(msg: string, ...values: unknown[]): void {\n this.logger.debug(`${this.#escape(msg)}: {values}`, { values });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"mod.js","names":["name: string","config?: OTLPExporterNodeConfigBase","noopLoggerProvider: ILoggerProvider","options: OpenTelemetrySinkExporterOptions","LoggerProvider","logger: OTLogger","record: LogRecord","options: OpenTelemetrySinkOptions","loggerProvider","logger","metadata","sink: OpenTelemetrySink","sink","loggerProvider: ILoggerProvider | null","logger: OTLogger | null","initPromise: Promise<void> | null","initError: Error | null","pendingRecords: LogRecord[]","level: string","properties: Record<string, unknown>","objectRenderer: ObjectRenderer","exceptionMode: ExceptionAttributeMode","attributes: Record<string, AnyValue>","v","value: unknown","serialized: Record<string, unknown>","message: readonly unknown[]","body: (string | null | undefined)[]","bodyFormatter: BodyFormatter","inspect: (value: unknown) => string","msg: string","#escape"],"sources":["../src/mod.ts"],"sourcesContent":["import {\n getLogger,\n type Logger,\n type LogRecord,\n type Sink,\n} from \"@logtape/logtape\";\nimport { diag, type DiagLogger, DiagLogLevel } from \"@opentelemetry/api\";\nimport {\n type AnyValue,\n type Logger as OTLogger,\n type LoggerProvider as LoggerProviderBase,\n type LogRecord as OTLogRecord,\n NOOP_LOGGER,\n SeverityNumber,\n} from \"@opentelemetry/api-logs\";\nimport type { OTLPExporterNodeConfigBase } from \"@opentelemetry/otlp-exporter-base\";\nimport type { Resource } from \"@opentelemetry/resources\";\nimport {\n defaultResource,\n resourceFromAttributes,\n} from \"@opentelemetry/resources\";\nimport {\n LoggerProvider,\n SimpleLogRecordProcessor,\n} from \"@opentelemetry/sdk-logs\";\nimport { ATTR_SERVICE_NAME } from \"@opentelemetry/semantic-conventions\";\nimport metadata from \"../deno.json\" with { type: \"json\" };\n\n/**\n * Gets an environment variable value across different JavaScript runtimes.\n * @param name The environment variable name.\n * @returns The environment variable value, or undefined if not found.\n */\nfunction getEnvironmentVariable(name: string): string | undefined {\n // Deno runtime\n if (typeof Deno !== \"undefined\" && Deno.env) {\n try {\n return Deno.env.get(name);\n } catch {\n // Deno.env.get() can throw if permissions are not granted\n return undefined;\n }\n }\n\n // Node.js/Bun runtime\n if (\n typeof globalThis !== \"undefined\" && \"process\" in globalThis &&\n // @ts-ignore: process exists in Node.js/Bun\n typeof globalThis.process !== \"undefined\" &&\n // @ts-ignore: process.env exists in Node.js/Bun\n typeof globalThis.process.env === \"object\" &&\n // @ts-ignore: process.env exists in Node.js/Bun\n globalThis.process.env !== null\n ) {\n // @ts-ignore: process.env exists in Node.js/Bun\n return globalThis.process.env[name];\n }\n\n // Browser/other environments - no environment variables available\n return undefined;\n}\n\n/**\n * Checks if an OTLP endpoint is configured via environment variables or options.\n * Checks the following environment variables:\n * - `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` (logs-specific endpoint)\n * - `OTEL_EXPORTER_OTLP_ENDPOINT` (general OTLP endpoint)\n *\n * @param config Optional exporter configuration that may contain a URL.\n * @returns `true` if an endpoint is configured, `false` otherwise.\n */\nfunction hasOtlpEndpoint(config?: OTLPExporterNodeConfigBase): boolean {\n // Check if URL is provided in config\n if (config?.url) {\n return true;\n }\n\n // Check environment variables\n const logsEndpoint = getEnvironmentVariable(\n \"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT\",\n );\n if (logsEndpoint) {\n return true;\n }\n\n const endpoint = getEnvironmentVariable(\"OTEL_EXPORTER_OTLP_ENDPOINT\");\n if (endpoint) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Detects the OTLP protocol from environment variables.\n * Priority:\n * 1. `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL`\n * 2. `OTEL_EXPORTER_OTLP_PROTOCOL`\n * 3. Default: `\"http/json\"` (for backward compatibility)\n *\n * @returns The detected OTLP protocol.\n */\nfunction detectOtlpProtocol(): OtlpProtocol {\n const logsProtocol = getEnvironmentVariable(\n \"OTEL_EXPORTER_OTLP_LOGS_PROTOCOL\",\n );\n if (\n logsProtocol === \"grpc\" ||\n logsProtocol === \"http/protobuf\" ||\n logsProtocol === \"http/json\"\n ) {\n return logsProtocol;\n }\n\n const protocol = getEnvironmentVariable(\"OTEL_EXPORTER_OTLP_PROTOCOL\");\n if (\n protocol === \"grpc\" ||\n protocol === \"http/protobuf\" ||\n protocol === \"http/json\"\n ) {\n return protocol;\n }\n\n return \"http/json\";\n}\n\n/**\n * Creates an OTLP log exporter based on the detected protocol.\n * Uses dynamic imports to maintain browser compatibility when gRPC is not used.\n * @param config Optional exporter configuration.\n * @returns A promise that resolves to the appropriate OTLP log exporter.\n */\nasync function createOtlpExporter(\n config?: OTLPExporterNodeConfigBase,\n // deno-lint-ignore no-explicit-any\n): Promise<any> {\n const protocol = detectOtlpProtocol();\n\n switch (protocol) {\n case \"grpc\": {\n const { OTLPLogExporter } = await import(\n \"@opentelemetry/exporter-logs-otlp-grpc\"\n );\n return new OTLPLogExporter(config);\n }\n case \"http/protobuf\": {\n const { OTLPLogExporter } = await import(\n \"@opentelemetry/exporter-logs-otlp-proto\"\n );\n return new OTLPLogExporter(config);\n }\n case \"http/json\":\n default: {\n const { OTLPLogExporter } = await import(\n \"@opentelemetry/exporter-logs-otlp-http\"\n );\n return new OTLPLogExporter(config);\n }\n }\n}\n\n/**\n * The OpenTelemetry logger provider.\n */\ntype ILoggerProvider = LoggerProviderBase & {\n /**\n * Flush all buffered data and shut down the LoggerProvider and all registered\n * LogRecordProcessor.\n *\n * Returns a promise which is resolved when all flushes are complete.\n */\n shutdown?: () => Promise<void>;\n};\n\n/**\n * The way to render the object in the log record. If `\"json\"`,\n * the object is rendered as a JSON string. If `\"inspect\"`,\n * the object is rendered using `util.inspect` in Node.js/Bun, or\n * `Deno.inspect` in Deno.\n */\nexport type ObjectRenderer = \"json\" | \"inspect\";\n\ntype Message = (string | null | undefined)[];\n\n/**\n * Custom `body` attribute formatter.\n * @since 0.3.0\n */\nexport type BodyFormatter = (message: Message) => AnyValue;\n\n/**\n * The OTLP protocol to use for exporting logs.\n * @since 0.9.0\n */\nexport type OtlpProtocol = \"grpc\" | \"http/protobuf\" | \"http/json\";\n\n/**\n * How to serialize `Error` objects in log attributes.\n * @since 1.4.0\n */\nexport type ExceptionAttributeMode = \"semconv\" | \"raw\" | false;\n\n/**\n * Base options shared by all OpenTelemetry sink configurations.\n */\ninterface OpenTelemetrySinkOptionsBase {\n /**\n * The way to render the message in the log record. If `\"string\"`,\n * the message is rendered as a single string with the values are\n * interpolated into the message. If `\"array\"`, the message is\n * rendered as an array of strings. `\"string\"` by default.\n *\n * Or even fully customizable with a {@link BodyFormatter} function.\n * @since 0.2.0\n */\n messageType?: \"string\" | \"array\" | BodyFormatter;\n\n /**\n * The way to render the object in the log record. If `\"json\"`,\n * the object is rendered as a JSON string. If `\"inspect\"`,\n * the object is rendered using `util.inspect` in Node.js/Bun, or\n * `Deno.inspect` in Deno. `\"inspect\"` by default.\n */\n objectRenderer?: ObjectRenderer;\n\n /**\n * How to serialize `Error` objects in log attributes.\n *\n * - `\"semconv\"` (default): Follow OpenTelemetry semantic conventions,\n * converting `Error` objects to `exception.type`, `exception.message`,\n * and `exception.stacktrace` attributes.\n * - `\"raw\"`: Serialize `Error` objects as JSON strings with fields like\n * `name`, `message`, `stack`, etc.\n * - `false`: Treat `Error` objects like regular objects without special\n * handling.\n *\n * @since 1.4.0\n */\n exceptionAttributes?: ExceptionAttributeMode;\n\n /**\n * Whether to log diagnostics. Diagnostic logs are logged to\n * the `[\"logtape\", \"meta\", \"otel\"]` category.\n * Turned off by default.\n */\n diagnostics?: boolean;\n}\n\n/**\n * Options for creating an OpenTelemetry sink with a custom logger provider.\n * When using this configuration, you are responsible for setting up the\n * logger provider with appropriate exporters and processors.\n *\n * This is the recommended approach for production use as it gives you\n * full control over the OpenTelemetry configuration.\n * @since 0.9.0\n */\nexport interface OpenTelemetrySinkProviderOptions\n extends OpenTelemetrySinkOptionsBase {\n /**\n * The OpenTelemetry logger provider to use.\n */\n loggerProvider: ILoggerProvider;\n}\n\n/**\n * Options for creating an OpenTelemetry sink with automatic exporter creation.\n * The protocol is determined by environment variables:\n * - `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL` (highest priority)\n * - `OTEL_EXPORTER_OTLP_PROTOCOL` (fallback)\n * - Default: `\"http/json\"`\n *\n * For production use, consider providing your own {@link ILoggerProvider}\n * via {@link OpenTelemetrySinkProviderOptions} for more control.\n * @since 0.9.0\n */\nexport interface OpenTelemetrySinkExporterOptions\n extends OpenTelemetrySinkOptionsBase {\n /**\n * The OpenTelemetry logger provider to use.\n * Must be undefined or omitted when using exporter options.\n */\n loggerProvider?: undefined;\n\n /**\n * The OpenTelemetry OTLP exporter configuration to use.\n */\n otlpExporterConfig?: OTLPExporterNodeConfigBase;\n\n /**\n * The service name to use. If not provided, the service name is\n * taken from the `OTEL_SERVICE_NAME` environment variable.\n */\n serviceName?: string;\n\n /**\n * An additional resource to merge with the default resource.\n * @since 1.3.0\n */\n additionalResource?: Resource;\n}\n\n/**\n * Options for creating an OpenTelemetry sink.\n *\n * This is a union type that accepts either:\n * - {@link OpenTelemetrySinkProviderOptions}: Provide your own `loggerProvider`\n * (recommended for production)\n * - {@link OpenTelemetrySinkExporterOptions}: Let the sink create an exporter\n * automatically based on environment variables\n *\n * When no `loggerProvider` is provided, the protocol is determined by:\n * 1. `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL` environment variable\n * 2. `OTEL_EXPORTER_OTLP_PROTOCOL` environment variable\n * 3. Default: `\"http/json\"`\n *\n * @example Using a custom logger provider (recommended)\n * ```typescript\n * import { LoggerProvider, SimpleLogRecordProcessor } from \"@opentelemetry/sdk-logs\";\n * import { OTLPLogExporter } from \"@opentelemetry/exporter-logs-otlp-grpc\";\n *\n * const provider = new LoggerProvider();\n * provider.addLogRecordProcessor(new SimpleLogRecordProcessor(new OTLPLogExporter()));\n *\n * const sink = getOpenTelemetrySink({ loggerProvider: provider });\n * ```\n *\n * @example Using automatic exporter creation\n * ```typescript\n * // Protocol determined by OTEL_EXPORTER_OTLP_PROTOCOL env var\n * const sink = getOpenTelemetrySink({\n * serviceName: \"my-service\",\n * });\n * ```\n */\nexport type OpenTelemetrySinkOptions =\n | OpenTelemetrySinkProviderOptions\n | OpenTelemetrySinkExporterOptions;\n\n/**\n * A no-op logger provider that returns NOOP_LOGGER for all requests.\n * Used when no OTLP endpoint is configured to avoid repeated connection errors.\n */\nconst noopLoggerProvider: ILoggerProvider = {\n getLogger: () => NOOP_LOGGER,\n};\n\n/**\n * Initializes the logger provider asynchronously.\n * This is used when the user doesn't provide a custom logger provider.\n *\n * If no OTLP endpoint is configured (via options or environment variables),\n * returns a noop logger provider to avoid repeated connection errors.\n *\n * @param options The exporter options.\n * @returns A promise that resolves to the initialized logger provider.\n */\nasync function initializeLoggerProvider(\n options: OpenTelemetrySinkExporterOptions,\n): Promise<ILoggerProvider> {\n // If no endpoint is configured, use noop logger provider to avoid\n // repeated transport errors\n if (!hasOtlpEndpoint(options.otlpExporterConfig)) {\n return noopLoggerProvider;\n }\n\n const resource = defaultResource().merge(\n resourceFromAttributes({\n [ATTR_SERVICE_NAME]: options.serviceName ??\n getEnvironmentVariable(\"OTEL_SERVICE_NAME\"),\n })\n .merge(options.additionalResource ?? null),\n );\n const otlpExporter = await createOtlpExporter(options.otlpExporterConfig);\n const loggerProvider = new LoggerProvider({\n resource,\n processors: [\n // @ts-ignore: it works anyway...\n new SimpleLogRecordProcessor(otlpExporter),\n ],\n });\n return loggerProvider;\n}\n\n/**\n * Emits a log record to the OpenTelemetry logger.\n * @param logger The OpenTelemetry logger.\n * @param record The LogTape log record.\n * @param options The sink options.\n */\nfunction emitLogRecord(\n logger: OTLogger,\n record: LogRecord,\n options: OpenTelemetrySinkOptions,\n): void {\n const objectRenderer = options.objectRenderer ?? \"inspect\";\n const exceptionMode = options.exceptionAttributes ?? \"semconv\";\n const { category, level, message, timestamp, properties } = record;\n const severityNumber = mapLevelToSeverityNumber(level);\n const attributes = convertToAttributes(\n properties,\n objectRenderer,\n exceptionMode,\n );\n attributes[\"category\"] = [...category];\n logger.emit(\n {\n severityNumber,\n severityText: level,\n body: typeof options.messageType === \"function\"\n ? convertMessageToCustomBodyFormat(\n message,\n objectRenderer,\n exceptionMode,\n options.messageType,\n )\n : options.messageType === \"array\"\n ? convertMessageToArray(message, objectRenderer, exceptionMode)\n : convertMessageToString(message, objectRenderer, exceptionMode),\n attributes,\n timestamp: new Date(timestamp),\n } satisfies OTLogRecord,\n );\n}\n\n/**\n * An OpenTelemetry sink with async disposal and initialization tracking.\n * @since 1.3.1\n */\nexport interface OpenTelemetrySink extends Sink, AsyncDisposable {\n /**\n * A promise that resolves when the sink's lazy initialization completes.\n * For sinks created with an explicit `loggerProvider`, this resolves\n * immediately. For sinks using automatic exporter creation, this resolves\n * once the OpenTelemetry logger provider is fully initialized.\n *\n * This is useful for:\n * - Ensuring all buffered log records have been sent before shutdown\n * - Testing scenarios where you need to verify emitted records\n * - Waiting for initialization before proceeding with critical operations\n *\n * @since 1.3.1\n */\n readonly ready: Promise<void>;\n}\n\n/**\n * Creates a sink that forwards log records to OpenTelemetry.\n *\n * When a custom `loggerProvider` is provided, it is used directly.\n * Otherwise, the sink will lazily initialize a logger provider on the first\n * log record, using the protocol determined by environment variables.\n *\n * @param options Options for creating the sink.\n * @returns The sink.\n */\nexport function getOpenTelemetrySink(\n options: OpenTelemetrySinkOptions = {},\n): OpenTelemetrySink {\n if (options.diagnostics) {\n diag.setLogger(new DiagLoggerAdaptor(), DiagLogLevel.DEBUG);\n }\n\n // If loggerProvider is provided, use the synchronous path\n if (options.loggerProvider != null) {\n const loggerProvider = options.loggerProvider;\n const logger = loggerProvider.getLogger(metadata.name, metadata.version);\n const shutdown = loggerProvider.shutdown?.bind(loggerProvider);\n const sink: OpenTelemetrySink = Object.assign(\n (record: LogRecord) => {\n const { category } = record;\n if (\n category[0] === \"logtape\" && category[1] === \"meta\" &&\n category[2] === \"otel\"\n ) {\n return;\n }\n emitLogRecord(logger, record, options);\n },\n {\n ready: Promise.resolve(),\n async [Symbol.asyncDispose](): Promise<void> {\n if (shutdown != null) await shutdown();\n },\n },\n );\n return sink;\n }\n\n // Lazy initialization for automatic exporter creation\n let loggerProvider: ILoggerProvider | null = null;\n let logger: OTLogger | null = null;\n let initPromise: Promise<void> | null = null;\n let initError: Error | null = null;\n // Buffer for log records that arrive during initialization\n let pendingRecords: LogRecord[] = [];\n\n const sink: OpenTelemetrySink = Object.assign(\n (record: LogRecord) => {\n const { category } = record;\n if (\n category[0] === \"logtape\" && category[1] === \"meta\" &&\n category[2] === \"otel\"\n ) {\n return;\n }\n\n // If already initialized, emit the log\n if (logger != null) {\n emitLogRecord(logger, record, options);\n return;\n }\n\n // If initialization failed, skip silently\n if (initError != null) {\n return;\n }\n\n // Buffer the record for later emission\n pendingRecords.push(record);\n\n // Start initialization if not already started\n if (initPromise == null) {\n initPromise = initializeLoggerProvider(options)\n .then((provider) => {\n loggerProvider = provider;\n logger = provider.getLogger(metadata.name, metadata.version);\n // Emit all buffered records\n for (const pendingRecord of pendingRecords) {\n emitLogRecord(logger, pendingRecord, options);\n }\n pendingRecords = [];\n })\n .catch((error) => {\n initError = error;\n pendingRecords = [];\n // Log initialization error to console as a fallback\n // deno-lint-ignore no-console\n console.error(\"Failed to initialize OpenTelemetry logger:\", error);\n });\n }\n },\n {\n get ready(): Promise<void> {\n return initPromise ?? Promise.resolve();\n },\n async [Symbol.asyncDispose](): Promise<void> {\n // Wait for initialization to complete if in progress\n if (initPromise != null) {\n try {\n await initPromise;\n } catch {\n // Initialization failed, nothing to shut down\n return;\n }\n }\n if (loggerProvider?.shutdown != null) {\n await loggerProvider.shutdown();\n }\n },\n },\n );\n\n return sink;\n}\n\nfunction mapLevelToSeverityNumber(level: string): number {\n switch (level) {\n case \"trace\":\n return SeverityNumber.TRACE;\n case \"debug\":\n return SeverityNumber.DEBUG;\n case \"info\":\n return SeverityNumber.INFO;\n case \"warning\":\n return SeverityNumber.WARN;\n case \"error\":\n return SeverityNumber.ERROR;\n case \"fatal\":\n return SeverityNumber.FATAL;\n default:\n return SeverityNumber.UNSPECIFIED;\n }\n}\n\nfunction convertToAttributes(\n properties: Record<string, unknown>,\n objectRenderer: ObjectRenderer,\n exceptionMode: ExceptionAttributeMode,\n): Record<string, AnyValue> {\n const attributes: Record<string, AnyValue> = {};\n for (const [name, value] of Object.entries(properties)) {\n if (value == null) continue;\n\n // Special handling for Error objects based on exceptionAttributes option\n if (value instanceof Error && exceptionMode === \"semconv\") {\n // Follow OpenTelemetry semantic conventions for exceptions\n attributes[\"exception.type\"] = value.name;\n attributes[\"exception.message\"] = value.message;\n if (typeof value.stack === \"string\") {\n attributes[\"exception.stacktrace\"] = value.stack;\n }\n continue;\n }\n\n if (Array.isArray(value)) {\n let t = null;\n for (const v of value) {\n if (v == null) continue;\n if (t != null && typeof v !== t) {\n attributes[name] = value.map((v) =>\n convertToString(v, objectRenderer, exceptionMode)\n );\n break;\n }\n t = typeof v;\n }\n attributes[name] = value;\n } else if (\n typeof value === \"string\" || typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n // Preserve primitive types as-is\n attributes[name] = value;\n } else {\n const encoded = convertToString(value, objectRenderer, exceptionMode);\n if (encoded == null) continue;\n attributes[name] = encoded;\n }\n }\n return attributes;\n}\n\nfunction serializeValue(value: unknown): unknown {\n if (value instanceof Error) {\n const serialized: Record<string, unknown> = {\n name: value.name,\n message: value.message,\n };\n\n if (typeof value.stack === \"string\") {\n serialized.stack = value.stack;\n }\n\n const cause = (value as { cause?: unknown }).cause;\n if (cause !== undefined) {\n serialized.cause = serializeValue(cause);\n }\n\n if (\n typeof AggregateError !== \"undefined\" &&\n value instanceof AggregateError\n ) {\n serialized.errors = value.errors.map(serializeValue);\n }\n\n for (const key of Object.keys(value)) {\n if (!(key in serialized)) {\n serialized[key] = serializeValue(\n (value as unknown as Record<string, unknown>)[key],\n );\n }\n }\n\n return serialized;\n }\n\n if (Array.isArray(value)) {\n return value.map(serializeValue);\n }\n\n if (value !== null && typeof value === \"object\") {\n const serialized: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n serialized[key] = serializeValue(val);\n }\n return serialized;\n }\n\n return value;\n}\n\nfunction convertToString(\n value: unknown,\n objectRenderer: ObjectRenderer,\n exceptionMode: ExceptionAttributeMode,\n): string | null | undefined {\n if (value === null || value === undefined || typeof value === \"string\") {\n return value;\n }\n if (objectRenderer === \"inspect\") return inspect(value);\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return value.toString();\n } else if (value instanceof Date) return value.toISOString();\n else if (\n value instanceof Error &&\n (exceptionMode === \"raw\" || exceptionMode === \"semconv\")\n ) {\n // In message bodies, serialize Error objects with serializeValue for \"raw\" and \"semconv\" modes\n // (semantic conventions only apply to Error objects in properties, not message bodies)\n // When exceptionMode is false, treat Error as a regular object (JSON.stringify)\n return JSON.stringify(serializeValue(value));\n } else return JSON.stringify(value);\n}\n\nfunction convertMessageToArray(\n message: readonly unknown[],\n objectRenderer: ObjectRenderer,\n exceptionMode: ExceptionAttributeMode,\n): AnyValue {\n const body: (string | null | undefined)[] = [];\n for (let i = 0; i < message.length; i += 2) {\n const msg = message[i] as string;\n body.push(msg);\n if (message.length <= i + 1) break;\n const val = message[i + 1];\n body.push(convertToString(val, objectRenderer, exceptionMode));\n }\n return body;\n}\n\nfunction convertMessageToString(\n message: readonly unknown[],\n objectRenderer: ObjectRenderer,\n exceptionMode: ExceptionAttributeMode,\n): AnyValue {\n let body = \"\";\n for (let i = 0; i < message.length; i += 2) {\n const msg = message[i] as string;\n body += msg;\n if (message.length <= i + 1) break;\n const val = message[i + 1];\n const extra = convertToString(val, objectRenderer, exceptionMode);\n body += extra ?? JSON.stringify(extra);\n }\n return body;\n}\n\nfunction convertMessageToCustomBodyFormat(\n message: readonly unknown[],\n objectRenderer: ObjectRenderer,\n exceptionMode: ExceptionAttributeMode,\n bodyFormatter: BodyFormatter,\n): AnyValue {\n const body = message.map((msg) =>\n convertToString(msg, objectRenderer, exceptionMode)\n );\n return bodyFormatter(body);\n}\n\n/**\n * A platform-specific inspect function. In Deno, this is {@link Deno.inspect},\n * and in Node.js/Bun it is {@link util.inspect}. If neither is available, it\n * falls back to {@link JSON.stringify}.\n *\n * @param value The value to inspect.\n * @returns The string representation of the value.\n */\nconst inspect: (value: unknown) => string =\n // @ts-ignore: Deno global\n \"Deno\" in globalThis && \"inspect\" in globalThis.Deno &&\n // @ts-ignore: Deno global\n typeof globalThis.Deno.inspect === \"function\"\n // @ts-ignore: Deno global\n ? globalThis.Deno.inspect\n // @ts-ignore: Node.js global\n : \"util\" in globalThis && \"inspect\" in globalThis.util &&\n // @ts-ignore: Node.js global\n globalThis.util.inspect === \"function\"\n // @ts-ignore: Node.js global\n ? globalThis.util.inspect\n : JSON.stringify;\n\nclass DiagLoggerAdaptor implements DiagLogger {\n logger: Logger;\n\n constructor() {\n this.logger = getLogger([\"logtape\", \"meta\", \"otel\"]);\n }\n\n #escape(msg: string): string {\n return msg.replaceAll(\"{\", \"{{\").replaceAll(\"}\", \"}}\");\n }\n\n error(msg: string, ...values: unknown[]): void {\n this.logger.error(`${this.#escape(msg)}: {values}`, { values });\n }\n\n warn(msg: string, ...values: unknown[]): void {\n this.logger.warn(`${this.#escape(msg)}: {values}`, { values });\n }\n\n info(msg: string, ...values: unknown[]): void {\n this.logger.info(`${this.#escape(msg)}: {values}`, { values });\n }\n\n debug(msg: string, ...values: unknown[]): void {\n this.logger.debug(`${this.#escape(msg)}: {values}`, { values });\n }\n\n verbose(msg: string, ...values: unknown[]): void {\n this.logger.debug(`${this.#escape(msg)}: {values}`, { values });\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logtape/otel",
3
- "version": "1.4.0-dev.465+a3cb852e",
3
+ "version": "1.4.0-dev.466+6520471a",
4
4
  "description": "LogTape OpenTelemetry sink",
5
5
  "keywords": [
6
6
  "LogTape",
@@ -45,7 +45,7 @@
45
45
  "dist/"
46
46
  ],
47
47
  "peerDependencies": {
48
- "@logtape/logtape": "^1.4.0-dev.465+a3cb852e"
48
+ "@logtape/logtape": "^1.4.0-dev.466+6520471a"
49
49
  },
50
50
  "dependencies": {
51
51
  "@opentelemetry/api": "^1.9.0",