@logtape/otel 2.4.0-dev.858 → 2.4.0-dev.865

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,19 +1,40 @@
1
1
 
2
2
  //#region deno.json
3
3
  var name = "@logtape/otel";
4
- var version = "2.4.0-dev.858+602e54c4";
4
+ var version = "2.4.0-dev.865+57354081";
5
5
  var license = "MIT";
6
6
  var exports$1 = { ".": "./src/mod.ts" };
7
+ var imports = { "#util": "src/util.deno.ts" };
7
8
  var tasks = {
8
9
  "build": "pnpm build",
9
- "test": "deno test --allow-net --allow-env"
10
+ "test": "deno test",
11
+ "test:node": {
12
+ "dependencies": ["build"],
13
+ "command": "node --experimental-transform-types --test"
14
+ },
15
+ "test:bun": {
16
+ "dependencies": ["build"],
17
+ "command": "bun test"
18
+ },
19
+ "test-all": { "dependencies": [
20
+ "test",
21
+ "test:node",
22
+ "test:bun"
23
+ ] }
10
24
  };
25
+ var exclude = [
26
+ "dist/",
27
+ "npm/",
28
+ "node_modules/"
29
+ ];
11
30
  var deno_default = {
12
31
  name,
13
32
  version,
14
33
  license,
15
34
  exports: exports$1,
16
- tasks
35
+ imports,
36
+ tasks,
37
+ exclude
17
38
  };
18
39
 
19
40
  //#endregion
package/dist/deno.js CHANGED
@@ -1,18 +1,39 @@
1
1
  //#region deno.json
2
2
  var name = "@logtape/otel";
3
- var version = "2.4.0-dev.858+602e54c4";
3
+ var version = "2.4.0-dev.865+57354081";
4
4
  var license = "MIT";
5
5
  var exports = { ".": "./src/mod.ts" };
6
+ var imports = { "#util": "src/util.deno.ts" };
6
7
  var tasks = {
7
8
  "build": "pnpm build",
8
- "test": "deno test --allow-net --allow-env"
9
+ "test": "deno test",
10
+ "test:node": {
11
+ "dependencies": ["build"],
12
+ "command": "node --experimental-transform-types --test"
13
+ },
14
+ "test:bun": {
15
+ "dependencies": ["build"],
16
+ "command": "bun test"
17
+ },
18
+ "test-all": { "dependencies": [
19
+ "test",
20
+ "test:node",
21
+ "test:bun"
22
+ ] }
9
23
  };
24
+ var exclude = [
25
+ "dist/",
26
+ "npm/",
27
+ "node_modules/"
28
+ ];
10
29
  var deno_default = {
11
30
  name,
12
31
  version,
13
32
  license,
14
33
  exports,
15
- tasks
34
+ imports,
35
+ tasks,
36
+ exclude
16
37
  };
17
38
 
18
39
  //#endregion
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\": \"2.4.0-dev.858+602e54c4\",\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\": \"2.4.0-dev.865+57354081\",\n \"license\": \"MIT\",\n \"exports\": {\n \".\": \"./src/mod.ts\"\n },\n \"imports\": {\n \"#util\": \"src/util.deno.ts\"\n },\n \"tasks\": {\n \"build\": \"pnpm build\",\n \"test\": \"deno test\",\n \"test:node\": {\n \"dependencies\": [\n \"build\"\n ],\n \"command\": \"node --experimental-transform-types --test\"\n },\n \"test:bun\": {\n \"dependencies\": [\n \"build\"\n ],\n \"command\": \"bun test\"\n },\n \"test-all\": {\n \"dependencies\": [\n \"test\",\n \"test:node\",\n \"test:bun\"\n ]\n }\n },\n \"exclude\": [\n \"dist/\",\n \"npm/\",\n \"node_modules/\"\n ]\n}\n"],"mappings":";WACU;cACG;cACA;cACA,EACT,KAAK,eACN;cACU,EACT,SAAS,mBACV;YACQ;CACP,SAAS;CACT,QAAQ;CACR,aAAa;EACX,gBAAgB,CACd,OACD;EACD,WAAW;CACZ;CACD,YAAY;EACV,gBAAgB,CACd,OACD;EACD,WAAW;CACZ;CACD,YAAY,EACV,gBAAgB;EACd;EACA;EACA;CACD,EACF;AACF;cACU;CACT;CACA;CACA;AACD;mBArCH;;;;;;;;AAsCC"}
package/dist/mod.cjs CHANGED
@@ -6,6 +6,7 @@ const __opentelemetry_api_logs = require_rolldown_runtime.__toESM(require("@open
6
6
  const __opentelemetry_resources = require_rolldown_runtime.__toESM(require("@opentelemetry/resources"));
7
7
  const __opentelemetry_sdk_logs = require_rolldown_runtime.__toESM(require("@opentelemetry/sdk-logs"));
8
8
  const __opentelemetry_semantic_conventions = require_rolldown_runtime.__toESM(require("@opentelemetry/semantic-conventions"));
9
+ const __util = require_rolldown_runtime.__toESM(require("#util"));
9
10
 
10
11
  //#region src/mod.ts
11
12
  /**
@@ -217,9 +218,11 @@ function mapLevelToSeverityNumber(level) {
217
218
  * @param exceptionMode How to handle Error objects
218
219
  * @returns An AnyValue or null if the value should be skipped
219
220
  */
220
- function convertValueToAnyValue(value, objectRenderer, exceptionMode) {
221
+ function convertValueToAnyValue(value, objectRenderer, exceptionMode, seenObjects = /* @__PURE__ */ new Set()) {
221
222
  if (value == null) return null;
222
223
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
224
+ if (seenObjects.has(value)) return null;
225
+ seenObjects.add(value);
223
226
  if (Array.isArray(value)) {
224
227
  let primitiveType = null;
225
228
  let isHomogeneous = true;
@@ -239,7 +242,7 @@ function convertValueToAnyValue(value, objectRenderer, exceptionMode) {
239
242
  if (isHomogeneous && primitiveType !== null) return value;
240
243
  const converted = [];
241
244
  for (const item of value) {
242
- const convertedItem = convertValueToAnyValue(item, objectRenderer, exceptionMode);
245
+ const convertedItem = convertValueToAnyValue(item, objectRenderer, exceptionMode, seenObjects);
243
246
  if (convertedItem !== null) converted.push(convertedItem);
244
247
  }
245
248
  return converted;
@@ -249,7 +252,7 @@ function convertValueToAnyValue(value, objectRenderer, exceptionMode) {
249
252
  const errorObj = serializeValue(value);
250
253
  const converted = {};
251
254
  for (const [key, val] of Object.entries(errorObj)) {
252
- const convertedVal = convertValueToAnyValue(val, objectRenderer, exceptionMode);
255
+ const convertedVal = convertValueToAnyValue(val, objectRenderer, exceptionMode, seenObjects);
253
256
  if (convertedVal !== null) converted[key] = convertedVal;
254
257
  }
255
258
  return converted;
@@ -260,12 +263,12 @@ function convertValueToAnyValue(value, objectRenderer, exceptionMode) {
260
263
  if (isPlainObject) {
261
264
  const converted = {};
262
265
  for (const [key, val] of Object.entries(value)) {
263
- const convertedVal = convertValueToAnyValue(val, objectRenderer, exceptionMode);
266
+ const convertedVal = convertValueToAnyValue(val, objectRenderer, exceptionMode, seenObjects);
264
267
  if (convertedVal !== null) converted[key] = convertedVal;
265
268
  }
266
269
  return converted;
267
270
  }
268
- if (objectRenderer === "inspect") return inspect(value);
271
+ if (objectRenderer === "inspect") return (0, __util.inspect)(value);
269
272
  return JSON.stringify(value);
270
273
  }
271
274
  return String(value);
@@ -308,7 +311,7 @@ function serializeValue(value) {
308
311
  }
309
312
  function convertToString(value, objectRenderer, exceptionMode) {
310
313
  if (value === null || value === void 0 || typeof value === "string") return value;
311
- if (objectRenderer === "inspect") return inspect(value);
314
+ if (objectRenderer === "inspect") return (0, __util.inspect)(value);
312
315
  if (typeof value === "number" || typeof value === "boolean") return value.toString();
313
316
  else if (value instanceof Date) return value.toISOString();
314
317
  else if (value instanceof Error && (exceptionMode === "raw" || exceptionMode === "semconv")) return JSON.stringify(serializeValue(value));
@@ -341,15 +344,6 @@ function convertMessageToCustomBodyFormat(message, objectRenderer, exceptionMode
341
344
  const body = message.map((msg) => convertToString(msg, objectRenderer, exceptionMode));
342
345
  return bodyFormatter(body);
343
346
  }
344
- /**
345
- * A platform-specific inspect function. In Deno, this is {@link Deno.inspect},
346
- * and in Node.js/Bun it is {@link util.inspect}. If neither is available, it
347
- * falls back to {@link JSON.stringify}.
348
- *
349
- * @param value The value to inspect.
350
- * @returns The string representation of the value.
351
- */
352
- const inspect = "Deno" in globalThis && "inspect" in globalThis.Deno && typeof globalThis.Deno.inspect === "function" ? globalThis.Deno.inspect : "util" in globalThis && "inspect" in globalThis.util && globalThis.util.inspect === "function" ? globalThis.util.inspect : JSON.stringify;
353
347
  var DiagLoggerAdaptor = class {
354
348
  logger;
355
349
  constructor() {
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAgByD;KA6JpD,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"}
1
+ {"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAgByD;KAiKpD,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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAgByD;KA6JpD,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"}
1
+ {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAgByD;KAiKpD,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
@@ -5,6 +5,7 @@ import { NOOP_LOGGER, SeverityNumber } from "@opentelemetry/api-logs";
5
5
  import { defaultResource, resourceFromAttributes } from "@opentelemetry/resources";
6
6
  import { LoggerProvider as LoggerProvider$1, SimpleLogRecordProcessor } from "@opentelemetry/sdk-logs";
7
7
  import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
8
+ import { inspect } from "#util";
8
9
 
9
10
  //#region src/mod.ts
10
11
  /**
@@ -216,9 +217,11 @@ function mapLevelToSeverityNumber(level) {
216
217
  * @param exceptionMode How to handle Error objects
217
218
  * @returns An AnyValue or null if the value should be skipped
218
219
  */
219
- function convertValueToAnyValue(value, objectRenderer, exceptionMode) {
220
+ function convertValueToAnyValue(value, objectRenderer, exceptionMode, seenObjects = /* @__PURE__ */ new Set()) {
220
221
  if (value == null) return null;
221
222
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
223
+ if (seenObjects.has(value)) return null;
224
+ seenObjects.add(value);
222
225
  if (Array.isArray(value)) {
223
226
  let primitiveType = null;
224
227
  let isHomogeneous = true;
@@ -238,7 +241,7 @@ function convertValueToAnyValue(value, objectRenderer, exceptionMode) {
238
241
  if (isHomogeneous && primitiveType !== null) return value;
239
242
  const converted = [];
240
243
  for (const item of value) {
241
- const convertedItem = convertValueToAnyValue(item, objectRenderer, exceptionMode);
244
+ const convertedItem = convertValueToAnyValue(item, objectRenderer, exceptionMode, seenObjects);
242
245
  if (convertedItem !== null) converted.push(convertedItem);
243
246
  }
244
247
  return converted;
@@ -248,7 +251,7 @@ function convertValueToAnyValue(value, objectRenderer, exceptionMode) {
248
251
  const errorObj = serializeValue(value);
249
252
  const converted = {};
250
253
  for (const [key, val] of Object.entries(errorObj)) {
251
- const convertedVal = convertValueToAnyValue(val, objectRenderer, exceptionMode);
254
+ const convertedVal = convertValueToAnyValue(val, objectRenderer, exceptionMode, seenObjects);
252
255
  if (convertedVal !== null) converted[key] = convertedVal;
253
256
  }
254
257
  return converted;
@@ -259,7 +262,7 @@ function convertValueToAnyValue(value, objectRenderer, exceptionMode) {
259
262
  if (isPlainObject) {
260
263
  const converted = {};
261
264
  for (const [key, val] of Object.entries(value)) {
262
- const convertedVal = convertValueToAnyValue(val, objectRenderer, exceptionMode);
265
+ const convertedVal = convertValueToAnyValue(val, objectRenderer, exceptionMode, seenObjects);
263
266
  if (convertedVal !== null) converted[key] = convertedVal;
264
267
  }
265
268
  return converted;
@@ -340,15 +343,6 @@ function convertMessageToCustomBodyFormat(message, objectRenderer, exceptionMode
340
343
  const body = message.map((msg) => convertToString(msg, objectRenderer, exceptionMode));
341
344
  return bodyFormatter(body);
342
345
  }
343
- /**
344
- * A platform-specific inspect function. In Deno, this is {@link Deno.inspect},
345
- * and in Node.js/Bun it is {@link util.inspect}. If neither is available, it
346
- * falls back to {@link JSON.stringify}.
347
- *
348
- * @param value The value to inspect.
349
- * @returns The string representation of the value.
350
- */
351
- const inspect = "Deno" in globalThis && "inspect" in globalThis.Deno && typeof globalThis.Deno.inspect === "function" ? globalThis.Deno.inspect : "util" in globalThis && "inspect" in globalThis.util && globalThis.util.inspect === "function" ? globalThis.util.inspect : JSON.stringify;
352
346
  var DiagLoggerAdaptor = class {
353
347
  logger;
354
348
  constructor() {
package/dist/mod.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.js","names":["name: string","config?: OTLPExporterNodeConfigBase","specifier: string","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","value: unknown","objectRenderer: ObjectRenderer","exceptionMode: ExceptionAttributeMode","primitiveType: string | null","converted: AnyValue[]","converted: Record<string, AnyValue>","properties: Record<string, unknown>","attributes: Record<string, AnyValue>","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// Indirect import wrapper prevents bundlers from statically analyzing the\n// specifier and including Node.js-only packages in browser bundles.\n// - Vite/Rollup: a variable specifier defeats static analysis; /* @vite-ignore\n// */ suppresses the resulting \"cannot be analyzed\" warning.\n// - Webpack: /* webpackIgnore: true */ disables bundling of this import.\n// deno-lint-ignore no-explicit-any\nconst _importModule = (specifier: string): Promise<any> =>\n import(/* @vite-ignore */ /* webpackIgnore: true */ specifier);\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 _importModule(\n \"@opentelemetry/exporter-logs-otlp-grpc\",\n );\n return new OTLPLogExporter(config);\n }\n case \"http/protobuf\": {\n const { OTLPLogExporter } = await _importModule(\n \"@opentelemetry/exporter-logs-otlp-proto\",\n );\n return new OTLPLogExporter(config);\n }\n case \"http/json\":\n default: {\n const { OTLPLogExporter } = await _importModule(\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 2.0.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 2.0.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\n/**\n * Converts a JavaScript value to an OpenTelemetry AnyValue.\n * This function recursively handles nested objects and arrays while preserving\n * their structure according to the OpenTelemetry specification.\n *\n * @param value The value to convert\n * @param objectRenderer How to render objects that can't be converted directly\n * @param exceptionMode How to handle Error objects\n * @returns An AnyValue or null if the value should be skipped\n */\nfunction convertValueToAnyValue(\n value: unknown,\n objectRenderer: ObjectRenderer,\n exceptionMode: ExceptionAttributeMode,\n): AnyValue | null {\n // Handle null/undefined\n if (value == null) return null;\n\n // Preserve primitives as-is\n if (\n typeof value === \"string\" || typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n\n // Handle arrays - recursively convert elements\n if (Array.isArray(value)) {\n // Check if it's a homogeneous array of primitives (OTel spec prefers these)\n let primitiveType: string | null = null;\n let isHomogeneous = true;\n\n for (const item of value) {\n if (item == null) continue;\n const itemType = typeof item;\n if (\n itemType !== \"string\" && itemType !== \"number\" &&\n itemType !== \"boolean\"\n ) {\n isHomogeneous = false;\n break;\n }\n if (primitiveType === null) {\n primitiveType = itemType;\n } else if (primitiveType !== itemType) {\n isHomogeneous = false;\n break;\n }\n }\n\n // If homogeneous array of primitives, return as-is\n if (isHomogeneous && primitiveType !== null) {\n return value as AnyValue;\n }\n\n // Otherwise, recursively convert each element to AnyValue\n const converted: AnyValue[] = [];\n for (const item of value) {\n const convertedItem = convertValueToAnyValue(\n item,\n objectRenderer,\n exceptionMode,\n );\n // Skip null items but preserve the structure\n if (convertedItem !== null) {\n converted.push(convertedItem);\n }\n }\n return converted;\n }\n\n // Handle Date objects - convert to ISO string\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n // Handle Error objects - serialize to structured object\n if (value instanceof Error) {\n const errorObj = serializeValue(value) as Record<string, unknown>;\n const converted: Record<string, AnyValue> = {};\n for (const [key, val] of Object.entries(errorObj)) {\n const convertedVal = convertValueToAnyValue(\n val,\n objectRenderer,\n exceptionMode,\n );\n if (convertedVal !== null) {\n converted[key] = convertedVal;\n }\n }\n return converted;\n }\n\n // Handle plain objects - recursively convert to map<string, AnyValue>\n if (typeof value === \"object\") {\n // Check if it's a plain object (not a special class instance)\n const proto = Object.getPrototypeOf(value);\n const isPlainObject = proto === Object.prototype || proto === null;\n\n if (isPlainObject) {\n const converted: Record<string, AnyValue> = {};\n for (\n const [key, val] of Object.entries(value as Record<string, unknown>)\n ) {\n const convertedVal = convertValueToAnyValue(\n val,\n objectRenderer,\n exceptionMode,\n );\n if (convertedVal !== null) {\n converted[key] = convertedVal;\n }\n }\n return converted;\n }\n\n // For non-plain objects (class instances, etc.), fall back to string representation\n if (objectRenderer === \"inspect\") {\n return inspect(value);\n }\n return JSON.stringify(value);\n }\n\n // Fallback for other types\n return String(value);\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 // Use the new recursive converter\n const convertedValue = convertValueToAnyValue(\n value,\n objectRenderer,\n exceptionMode,\n );\n if (convertedValue !== null) {\n attributes[name] = convertedValue;\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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"}
1
+ {"version":3,"file":"mod.js","names":["name: string","config?: OTLPExporterNodeConfigBase","specifier: string","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","value: unknown","objectRenderer: ObjectRenderer","exceptionMode: ExceptionAttributeMode","seenObjects: Set<unknown>","primitiveType: string | null","converted: AnyValue[]","converted: Record<string, AnyValue>","properties: Record<string, unknown>","attributes: Record<string, AnyValue>","serialized: Record<string, unknown>","message: readonly unknown[]","body: (string | null | undefined)[]","bodyFormatter: BodyFormatter","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// Cross-runtime inspect: Deno.inspect / util.inspect (handles circular\n// references); falls back to JSON.stringify in browsers. Resolved via the\n// `#util` import map per runtime.\nimport { inspect } from \"#util\";\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// Indirect import wrapper prevents bundlers from statically analyzing the\n// specifier and including Node.js-only packages in browser bundles.\n// - Vite/Rollup: a variable specifier defeats static analysis; /* @vite-ignore\n// */ suppresses the resulting \"cannot be analyzed\" warning.\n// - Webpack: /* webpackIgnore: true */ disables bundling of this import.\n// deno-lint-ignore no-explicit-any\nconst _importModule = (specifier: string): Promise<any> =>\n import(/* @vite-ignore */ /* webpackIgnore: true */ specifier);\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 _importModule(\n \"@opentelemetry/exporter-logs-otlp-grpc\",\n );\n return new OTLPLogExporter(config);\n }\n case \"http/protobuf\": {\n const { OTLPLogExporter } = await _importModule(\n \"@opentelemetry/exporter-logs-otlp-proto\",\n );\n return new OTLPLogExporter(config);\n }\n case \"http/json\":\n default: {\n const { OTLPLogExporter } = await _importModule(\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 2.0.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 2.0.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\n/**\n * Converts a JavaScript value to an OpenTelemetry AnyValue.\n * This function recursively handles nested objects and arrays while preserving\n * their structure according to the OpenTelemetry specification.\n *\n * @param value The value to convert\n * @param objectRenderer How to render objects that can't be converted directly\n * @param exceptionMode How to handle Error objects\n * @returns An AnyValue or null if the value should be skipped\n */\nfunction convertValueToAnyValue(\n value: unknown,\n objectRenderer: ObjectRenderer,\n exceptionMode: ExceptionAttributeMode,\n seenObjects: Set<unknown> = new Set(),\n): AnyValue | null {\n // Handle null/undefined\n if (value == null) return null;\n\n // Preserve primitives as-is\n if (\n typeof value === \"string\" || typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n\n if (seenObjects.has(value)) {\n return null;\n }\n seenObjects.add(value);\n\n // Handle arrays - recursively convert elements\n if (Array.isArray(value)) {\n // Check if it's a homogeneous array of primitives (OTel spec prefers these)\n let primitiveType: string | null = null;\n let isHomogeneous = true;\n\n for (const item of value) {\n if (item == null) continue;\n const itemType = typeof item;\n if (\n itemType !== \"string\" && itemType !== \"number\" &&\n itemType !== \"boolean\"\n ) {\n isHomogeneous = false;\n break;\n }\n if (primitiveType === null) {\n primitiveType = itemType;\n } else if (primitiveType !== itemType) {\n isHomogeneous = false;\n break;\n }\n }\n\n // If homogeneous array of primitives, return as-is\n if (isHomogeneous && primitiveType !== null) {\n return value as AnyValue;\n }\n\n // Otherwise, recursively convert each element to AnyValue\n const converted: AnyValue[] = [];\n for (const item of value) {\n const convertedItem = convertValueToAnyValue(\n item,\n objectRenderer,\n exceptionMode,\n seenObjects,\n );\n // Skip null items but preserve the structure\n if (convertedItem !== null) {\n converted.push(convertedItem);\n }\n }\n return converted;\n }\n\n // Handle Date objects - convert to ISO string\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n // Handle Error objects - serialize to structured object\n if (value instanceof Error) {\n const errorObj = serializeValue(value) as Record<string, unknown>;\n const converted: Record<string, AnyValue> = {};\n for (const [key, val] of Object.entries(errorObj)) {\n const convertedVal = convertValueToAnyValue(\n val,\n objectRenderer,\n exceptionMode,\n seenObjects,\n );\n if (convertedVal !== null) {\n converted[key] = convertedVal;\n }\n }\n return converted;\n }\n\n // Handle plain objects - recursively convert to map<string, AnyValue>\n if (typeof value === \"object\") {\n // Check if it's a plain object (not a special class instance)\n const proto = Object.getPrototypeOf(value);\n const isPlainObject = proto === Object.prototype || proto === null;\n\n if (isPlainObject) {\n const converted: Record<string, AnyValue> = {};\n for (\n const [key, val] of Object.entries(value as Record<string, unknown>)\n ) {\n const convertedVal = convertValueToAnyValue(\n val,\n objectRenderer,\n exceptionMode,\n seenObjects,\n );\n if (convertedVal !== null) {\n converted[key] = convertedVal;\n }\n }\n return converted;\n }\n\n // For non-plain objects (class instances, etc.), fall back to string representation\n if (objectRenderer === \"inspect\") {\n return inspect(value);\n }\n return JSON.stringify(value);\n }\n\n // Fallback for other types\n return String(value);\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 // Use the new recursive converter\n const convertedValue = convertValueToAnyValue(\n value,\n objectRenderer,\n exceptionMode,\n );\n if (convertedValue !== null) {\n attributes[name] = convertedValue;\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\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/dist/util.cjs ADDED
@@ -0,0 +1,9 @@
1
+
2
+ //#region src/util.ts
3
+ function inspect(obj, options) {
4
+ const indent = options?.compact === true ? void 0 : 2;
5
+ return JSON.stringify(obj, null, indent);
6
+ }
7
+
8
+ //#endregion
9
+ exports.inspect = inspect;
@@ -0,0 +1,12 @@
1
+ //#region src/util.d.ts
2
+ interface InspectOptions {
3
+ colors?: boolean;
4
+ depth?: number | null;
5
+ compact?: boolean;
6
+ [key: string]: unknown;
7
+ }
8
+ declare function inspect(obj: unknown, options?: InspectOptions): string;
9
+ //# sourceMappingURL=util.d.ts.map
10
+ //#endregion
11
+ export { InspectOptions, inspect };
12
+ //# sourceMappingURL=util.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.cts","names":[],"sources":["../src/util.ts"],"sourcesContent":[],"mappings":";UAAiB,cAAA;EAAA,MAAA,CAAA,EAAA,OAAA;EAOD,KAAA,CAAA,EAAA,MAAO,GAAA,IAAyB;;;;iBAAhC,OAAA,yBAAgC"}
package/dist/util.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ //#region src/util.d.ts
2
+ interface InspectOptions {
3
+ colors?: boolean;
4
+ depth?: number | null;
5
+ compact?: boolean;
6
+ [key: string]: unknown;
7
+ }
8
+ declare function inspect(obj: unknown, options?: InspectOptions): string;
9
+ //# sourceMappingURL=util.d.ts.map
10
+ //#endregion
11
+ export { InspectOptions, inspect };
12
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","names":[],"sources":["../src/util.ts"],"sourcesContent":[],"mappings":";UAAiB,cAAA;EAAA,MAAA,CAAA,EAAA,OAAA;EAOD,KAAA,CAAA,EAAA,MAAO,GAAA,IAAyB;;;;iBAAhC,OAAA,yBAAgC"}
@@ -0,0 +1,16 @@
1
+
2
+ //#region src/util.deno.ts
3
+ function inspect(obj, options) {
4
+ if ("Deno" in globalThis) return Deno.inspect(obj, {
5
+ colors: options?.colors,
6
+ depth: options?.depth ?? void 0,
7
+ compact: options?.compact ?? true
8
+ });
9
+ else {
10
+ const indent = options?.compact === true ? void 0 : 2;
11
+ return JSON.stringify(obj, null, indent);
12
+ }
13
+ }
14
+
15
+ //#endregion
16
+ exports.inspect = inspect;
@@ -0,0 +1,12 @@
1
+ //#region src/util.deno.d.ts
2
+ interface InspectOptions {
3
+ colors?: boolean;
4
+ depth?: number | null;
5
+ compact?: boolean;
6
+ [key: string]: unknown;
7
+ }
8
+ declare function inspect(obj: unknown, options?: InspectOptions): string;
9
+ //# sourceMappingURL=util.deno.d.ts.map
10
+ //#endregion
11
+ export { InspectOptions, inspect };
12
+ //# sourceMappingURL=util.deno.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.deno.d.cts","names":[],"sources":["../src/util.deno.ts"],"sourcesContent":[],"mappings":";UAAiB,cAAA;EAAA,MAAA,CAAA,EAAA,OAAA;EAOD,KAAA,CAAA,EAAA,MAAO,GAAA,IAAyB;;;;iBAAhC,OAAA,yBAAgC"}
@@ -0,0 +1,12 @@
1
+ //#region src/util.deno.d.ts
2
+ interface InspectOptions {
3
+ colors?: boolean;
4
+ depth?: number | null;
5
+ compact?: boolean;
6
+ [key: string]: unknown;
7
+ }
8
+ declare function inspect(obj: unknown, options?: InspectOptions): string;
9
+ //# sourceMappingURL=util.deno.d.ts.map
10
+ //#endregion
11
+ export { InspectOptions, inspect };
12
+ //# sourceMappingURL=util.deno.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.deno.d.ts","names":[],"sources":["../src/util.deno.ts"],"sourcesContent":[],"mappings":";UAAiB,cAAA;EAAA,MAAA,CAAA,EAAA,OAAA;EAOD,KAAA,CAAA,EAAA,MAAO,GAAA,IAAyB;;;;iBAAhC,OAAA,yBAAgC"}
@@ -0,0 +1,16 @@
1
+ //#region src/util.deno.ts
2
+ function inspect(obj, options) {
3
+ if ("Deno" in globalThis) return Deno.inspect(obj, {
4
+ colors: options?.colors,
5
+ depth: options?.depth ?? void 0,
6
+ compact: options?.compact ?? true
7
+ });
8
+ else {
9
+ const indent = options?.compact === true ? void 0 : 2;
10
+ return JSON.stringify(obj, null, indent);
11
+ }
12
+ }
13
+
14
+ //#endregion
15
+ export { inspect };
16
+ //# sourceMappingURL=util.deno.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.deno.js","names":["obj: unknown","options?: InspectOptions"],"sources":["../src/util.deno.ts"],"sourcesContent":["export interface InspectOptions {\n colors?: boolean;\n depth?: number | null;\n compact?: boolean;\n [key: string]: unknown;\n}\n\nexport function inspect(obj: unknown, options?: InspectOptions): string {\n if (\"Deno\" in globalThis) {\n return Deno.inspect(obj, {\n colors: options?.colors,\n depth: options?.depth ?? undefined,\n compact: options?.compact ?? true,\n });\n } else {\n const indent = options?.compact === true ? undefined : 2;\n return JSON.stringify(obj, null, indent);\n }\n}\n"],"mappings":";AAOA,SAAgB,QAAQA,KAAcC,SAAkC;AACtE,KAAI,UAAU,WACZ,QAAO,KAAK,QAAQ,KAAK;EACvB,QAAQ,SAAS;EACjB,OAAO,SAAS;EAChB,SAAS,SAAS,WAAW;CAC9B,EAAC;MACG;EACL,MAAM,SAAS,SAAS,YAAY,gBAAmB;AACvD,SAAO,KAAK,UAAU,KAAK,MAAM,OAAO;CACzC;AACF"}
package/dist/util.js ADDED
@@ -0,0 +1,9 @@
1
+ //#region src/util.ts
2
+ function inspect(obj, options) {
3
+ const indent = options?.compact === true ? void 0 : 2;
4
+ return JSON.stringify(obj, null, indent);
5
+ }
6
+
7
+ //#endregion
8
+ export { inspect };
9
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","names":["obj: unknown","options?: InspectOptions"],"sources":["../src/util.ts"],"sourcesContent":["export interface InspectOptions {\n colors?: boolean;\n depth?: number | null;\n compact?: boolean;\n [key: string]: unknown;\n}\n\nexport function inspect(obj: unknown, options?: InspectOptions): string {\n const indent = options?.compact === true ? undefined : 2;\n return JSON.stringify(obj, null, indent);\n}\n"],"mappings":";AAOA,SAAgB,QAAQA,KAAcC,SAAkC;CACtE,MAAM,SAAS,SAAS,YAAY,gBAAmB;AACvD,QAAO,KAAK,UAAU,KAAK,MAAM,OAAO;AACzC"}
@@ -0,0 +1,10 @@
1
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const node_util = require_rolldown_runtime.__toESM(require("node:util"));
3
+
4
+ //#region src/util.node.ts
5
+ function inspect(obj, options) {
6
+ return node_util.default.inspect(obj, options);
7
+ }
8
+
9
+ //#endregion
10
+ exports.inspect = inspect;
@@ -0,0 +1,12 @@
1
+ //#region src/util.node.d.ts
2
+ interface InspectOptions {
3
+ colors?: boolean;
4
+ depth?: number | null;
5
+ compact?: boolean;
6
+ [key: string]: unknown;
7
+ }
8
+ declare function inspect(obj: unknown, options?: InspectOptions): string;
9
+ //# sourceMappingURL=util.node.d.ts.map
10
+ //#endregion
11
+ export { InspectOptions, inspect };
12
+ //# sourceMappingURL=util.node.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.node.d.cts","names":[],"sources":["../src/util.node.ts"],"sourcesContent":[],"mappings":";UAEiB,cAAA;EAAA,MAAA,CAAA,EAAA,OAAA;EAOD,KAAA,CAAA,EAAA,MAAO,GAAA,IAAyB;;;;iBAAhC,OAAA,yBAAgC"}
@@ -0,0 +1,12 @@
1
+ //#region src/util.node.d.ts
2
+ interface InspectOptions {
3
+ colors?: boolean;
4
+ depth?: number | null;
5
+ compact?: boolean;
6
+ [key: string]: unknown;
7
+ }
8
+ declare function inspect(obj: unknown, options?: InspectOptions): string;
9
+ //# sourceMappingURL=util.node.d.ts.map
10
+ //#endregion
11
+ export { InspectOptions, inspect };
12
+ //# sourceMappingURL=util.node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.node.d.ts","names":[],"sources":["../src/util.node.ts"],"sourcesContent":[],"mappings":";UAEiB,cAAA;EAAA,MAAA,CAAA,EAAA,OAAA;EAOD,KAAA,CAAA,EAAA,MAAO,GAAA,IAAyB;;;;iBAAhC,OAAA,yBAAgC"}
@@ -0,0 +1,10 @@
1
+ import util from "node:util";
2
+
3
+ //#region src/util.node.ts
4
+ function inspect(obj, options) {
5
+ return util.inspect(obj, options);
6
+ }
7
+
8
+ //#endregion
9
+ export { inspect };
10
+ //# sourceMappingURL=util.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.node.js","names":["obj: unknown","options?: InspectOptions"],"sources":["../src/util.node.ts"],"sourcesContent":["import util from \"node:util\";\n\nexport interface InspectOptions {\n colors?: boolean;\n depth?: number | null;\n compact?: boolean;\n [key: string]: unknown;\n}\n\nexport function inspect(obj: unknown, options?: InspectOptions): string {\n return util.inspect(obj, options);\n}\n"],"mappings":";;;AASA,SAAgB,QAAQA,KAAcC,SAAkC;AACtE,QAAO,KAAK,QAAQ,KAAK,QAAQ;AAClC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logtape/otel",
3
- "version": "2.4.0-dev.858+602e54c4",
3
+ "version": "2.4.0-dev.865+57354081",
4
4
  "description": "LogTape OpenTelemetry sink",
5
5
  "keywords": [
6
6
  "LogTape",
@@ -40,12 +40,36 @@
40
40
  },
41
41
  "./package.json": "./package.json"
42
42
  },
43
+ "imports": {
44
+ "#util": {
45
+ "types": {
46
+ "import": "./dist/util.d.ts",
47
+ "require": "./dist/util.d.cts"
48
+ },
49
+ "browser": {
50
+ "import": "./dist/util.js",
51
+ "require": "./dist/util.cjs"
52
+ },
53
+ "node": {
54
+ "import": "./dist/util.node.js",
55
+ "require": "./dist/util.node.cjs"
56
+ },
57
+ "bun": {
58
+ "import": "./dist/util.node.js",
59
+ "require": "./dist/util.node.cjs"
60
+ },
61
+ "deno": "./dist/util.deno.js",
62
+ "import": "./dist/util.js",
63
+ "require": "./dist/util.cjs",
64
+ "default": "./dist/util.js"
65
+ }
66
+ },
43
67
  "sideEffects": false,
44
68
  "files": [
45
69
  "dist/"
46
70
  ],
47
71
  "peerDependencies": {
48
- "@logtape/logtape": "^2.4.0-dev.858+602e54c4"
72
+ "@logtape/logtape": "^2.4.0-dev.865+57354081"
49
73
  },
50
74
  "dependencies": {
51
75
  "@opentelemetry/api": "^1.9.0",