@@ -3,6 +3,10 @@ import { Attributes } from "@opentelemetry/api";
3
3
export const NULL_SENTINEL = "$@null((" ;
4
4
export const CIRCULAR_REFERENCE_SENTINEL = "$@circular((" ;
5
5
6
+ function escapeKey ( key : string ) : string {
7
+ return key . replace ( / \. / g, '\\.' ) ;
8
+ }
9
+
6
10
export function flattenAttributes (
7
11
obj : Record < string , unknown > | Array < unknown > | string | boolean | number | null | undefined ,
8
12
prefix ?: string ,
@@ -53,7 +57,8 @@ export function flattenAttributes(
53
57
54
58
55
59
for ( const [ key , value ] of Object . entries ( obj ) ) {
56
- const newPrefix = `${ prefix ? `${ prefix } .` : "" } ${ Array . isArray ( obj ) ? `[${ key } ]` : key } ` ;
60
+ const escapedKey = escapeKey ( key ) ;
61
+ const newPrefix = `${ prefix ? `${ prefix } .` : "" } ${ Array . isArray ( obj ) ? `[${ escapedKey } ]` : escapedKey } ` ;
57
62
if ( Array . isArray ( value ) ) {
58
63
for ( let i = 0 ; i < value . length ; i ++ ) {
59
64
if ( typeof value [ i ] === "object" && value [ i ] !== null ) {
@@ -86,6 +91,10 @@ function isRecord(value: unknown): value is Record<string, unknown> {
86
91
return value !== null && typeof value === "object" && ! Array . isArray ( value ) ;
87
92
}
88
93
94
+ function unescapeKey ( key : string ) : string {
95
+ return key . replace ( / \\ \. / g, '.' ) ;
96
+ }
97
+
89
98
export function unflattenAttributes (
90
99
obj : Attributes
91
100
) : Record < string , unknown > | string | number | boolean | null | undefined {
@@ -109,8 +118,10 @@ export function unflattenAttributes(
109
118
const result : Record < string , unknown > = { } ;
110
119
111
120
for ( const [ key , value ] of Object . entries ( obj ) ) {
112
- const parts = key . split ( "." ) . reduce (
113
- ( acc , part ) => {
121
+ const parts = key
122
+ . split ( / (?< ! \\ ) \. / ) // Split by unescaped dots
123
+ . map ( unescapeKey ) // Unescape keys
124
+ . reduce ( ( acc , part ) => {
114
125
if ( part . startsWith ( "[" ) && part . endsWith ( "]" ) ) {
115
126
// Handle array indices more precisely
116
127
const match = part . match ( / ^ \[ ( \d + ) \] $ / ) ;
0 commit comments