@@ -25,6 +25,10 @@ import {
2525} from "@opentelemetry/sdk-logs" ;
2626import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions" ;
2727import metadata from "../deno.json" with { type : "json" } ;
28+ // Cross-runtime inspect: Deno.inspect / util.inspect (handles circular
29+ // references); falls back to JSON.stringify in browsers. Resolved via the
30+ // `#util` import map per runtime.
31+ import { inspect } from "#util" ;
2832
2933/**
3034 * Gets an environment variable value across different JavaScript runtimes.
@@ -606,6 +610,7 @@ function convertValueToAnyValue(
606610 value : unknown ,
607611 objectRenderer : ObjectRenderer ,
608612 exceptionMode : ExceptionAttributeMode ,
613+ seenObjects : Set < any > = new Set ( ) ,
609614) : AnyValue | null {
610615 // Handle null/undefined
611616 if ( value == null ) return null ;
@@ -618,6 +623,11 @@ function convertValueToAnyValue(
618623 return value ;
619624 }
620625
626+ if ( seenObjects . has ( value ) ) {
627+ return null ;
628+ }
629+ seenObjects . add ( value ) ;
630+
621631 // Handle arrays - recursively convert elements
622632 if ( Array . isArray ( value ) ) {
623633 // Check if it's a homogeneous array of primitives (OTel spec prefers these)
@@ -654,6 +664,7 @@ function convertValueToAnyValue(
654664 item ,
655665 objectRenderer ,
656666 exceptionMode ,
667+ seenObjects ,
657668 ) ;
658669 // Skip null items but preserve the structure
659670 if ( convertedItem !== null ) {
@@ -677,6 +688,7 @@ function convertValueToAnyValue(
677688 val ,
678689 objectRenderer ,
679690 exceptionMode ,
691+ seenObjects ,
680692 ) ;
681693 if ( convertedVal !== null ) {
682694 converted [ key ] = convertedVal ;
@@ -700,6 +712,7 @@ function convertValueToAnyValue(
700712 val ,
701713 objectRenderer ,
702714 exceptionMode ,
715+ seenObjects ,
703716 ) ;
704717 if ( convertedVal !== null ) {
705718 converted [ key ] = convertedVal ;
@@ -869,29 +882,6 @@ function convertMessageToCustomBodyFormat(
869882 return bodyFormatter ( body ) ;
870883}
871884
872- /**
873- * A platform-specific inspect function. In Deno, this is {@link Deno.inspect},
874- * and in Node.js/Bun it is {@link util.inspect}. If neither is available, it
875- * falls back to {@link JSON.stringify}.
876- *
877- * @param value The value to inspect.
878- * @returns The string representation of the value.
879- */
880- const inspect : ( value : unknown ) => string =
881- // @ts -ignore: Deno global
882- "Deno" in globalThis && "inspect" in globalThis . Deno &&
883- // @ts -ignore: Deno global
884- typeof globalThis . Deno . inspect === "function"
885- // @ts -ignore: Deno global
886- ? globalThis . Deno . inspect
887- // @ts -ignore: Node.js global
888- : "util" in globalThis && "inspect" in globalThis . util &&
889- // @ts -ignore: Node.js global
890- globalThis . util . inspect === "function"
891- // @ts -ignore: Node.js global
892- ? globalThis . util . inspect
893- : JSON . stringify ;
894-
895885class DiagLoggerAdaptor implements DiagLogger {
896886 logger : Logger ;
897887
0 commit comments