Skip to content

Commit

Permalink
send meta_struct properties as byte array
Browse files Browse the repository at this point in the history
  • Loading branch information
uurien committed May 24, 2024
1 parent 95b5a41 commit c6e1c64
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 24 deletions.
39 changes: 36 additions & 3 deletions packages/dd-trace/src/encode/0.4.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class AgentEncoder {
this._encodeMap(bytes, span.metrics)
if (span.meta_struct) {
this._encodeString(bytes, 'meta_struct')
this._encodeObject(bytes, span.meta_struct)
this._encodeMetaStruct(bytes, span.meta_struct)
}
}
}
Expand Down Expand Up @@ -271,12 +271,45 @@ class AgentEncoder {
}
}

_encodeMetaStruct (bytes, value) {
const keys = Array.isArray(value) ? [] : Object.keys(value)
const validKeys = keys.filter(key =>
typeof value[key] === 'string' ||
typeof value[key] === 'number' ||
(value[key] !== null && typeof value[key] === 'object'))

this._encodeMapPrefix(bytes, validKeys.length)

for (const key of validKeys) {
this._encodeString(bytes, key)
this._encodeObjectAsByteArray(bytes, value[key])
}
}

_encodeObjectAsByteArray (bytes, value) {
const prefixLength = 5
const offset = bytes.length

bytes.reserve(prefixLength)
bytes.length += prefixLength

this._encodeObject(bytes, value)

// we should do it after encoding the object to know the real length
const length = bytes.length - offset - prefixLength
bytes.buffer[offset] = 0xc6
bytes.buffer[offset + 1] = length >> 24
bytes.buffer[offset + 2] = length >> 16
bytes.buffer[offset + 3] = length >> 8
bytes.buffer[offset + 4] = length
}

_encodeObject (bytes, value, circularReferencesDetector = new Set()) {
circularReferencesDetector.add(value)
if (Array.isArray(value)) {
return this._encodeObjectAsArray(bytes, value, circularReferencesDetector)
this._encodeObjectAsArray(bytes, value, circularReferencesDetector)
} else if (value !== null && typeof value === 'object') {
return this._encodeObjectAsMap(bytes, value, circularReferencesDetector)
this._encodeObjectAsMap(bytes, value, circularReferencesDetector)
} else if (typeof value === 'string' || typeof value === 'number') {
this._encodeValue(bytes, value)
}
Expand Down
35 changes: 14 additions & 21 deletions packages/dd-trace/test/encode/0.4.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,31 +249,21 @@ describe('encode', () => {

const decoded = msgpack.decode(buffer, { codec })
const trace = decoded[0]
expect(trace[0].meta_struct).to.deep.equal(metaStruct)
})

it('should encode meta_struct with simple array of simple values', () => {
const metaStruct = ['one', 2, 'three', 4, 5, 'six']
data[0].meta_struct = metaStruct
encoder.encode(data)

const buffer = encoder.makePayload()

const decoded = msgpack.decode(buffer, { codec })
const trace = decoded[0]
expect(trace[0].meta_struct).to.deep.equal(metaStruct)
expect(msgpack.decode(trace[0].meta_struct.foo)).to.be.equal(metaStruct.foo)
expect(msgpack.decode(trace[0].meta_struct.baz)).to.be.equal(metaStruct.baz)
})

it('should encode meta_struct with array of objects', () => {
const metaStruct = [{ foo: 'bar' }, { baz: 123 }]
it('should ignore array in meta_struct', () => {
const metaStruct = ['one', 2, 'three', 4, 5, 'six']
data[0].meta_struct = metaStruct
encoder.encode(data)

const buffer = encoder.makePayload()

const decoded = msgpack.decode(buffer, { codec })
const trace = decoded[0]
expect(trace[0].meta_struct).to.deep.equal(metaStruct)
expect(trace[0].meta_struct).to.deep.equal({})
})

it('should encode meta_struct with empty object and array', () => {
Expand All @@ -288,7 +278,8 @@ describe('encode', () => {

const decoded = msgpack.decode(buffer, { codec })
const trace = decoded[0]
expect(trace[0].meta_struct).to.deep.equal(metaStruct)
expect(msgpack.decode(trace[0].meta_struct.foo)).to.deep.equal(metaStruct.foo)
expect(msgpack.decode(trace[0].meta_struct.bar)).to.deep.equal(metaStruct.bar)
})

it('should encode meta_struct with possible real use case', () => {
Expand Down Expand Up @@ -342,7 +333,7 @@ describe('encode', () => {

const decoded = msgpack.decode(buffer, { codec })
const trace = decoded[0]
expect(trace[0].meta_struct).to.deep.equal(metaStruct)
expect(msgpack.decode(trace[0].meta_struct['_dd.stack'])).to.deep.equal(metaStruct['_dd.stack'])
})

it('should encode meta_struct ignoring circular references in objects', () => {
Expand Down Expand Up @@ -373,7 +364,7 @@ describe('encode', () => {
}
}
}
expect(trace[0].meta_struct).to.deep.equal(expectedMetaStruct)
expect(msgpack.decode(trace[0].meta_struct.foo)).to.deep.equal(expectedMetaStruct.foo)
})

it('should encode meta_struct ignoring circular references in arrays', () => {
Expand All @@ -398,7 +389,7 @@ describe('encode', () => {
bar: 'baz'
}]
}
expect(trace[0].meta_struct).to.deep.equal(expectedMetaStruct)
expect(msgpack.decode(trace[0].meta_struct.foo)).to.deep.equal(expectedMetaStruct.foo)
})

it('should encode meta_struct ignoring undefined properties', () => {
Expand All @@ -418,7 +409,8 @@ describe('encode', () => {
const expectedMetaStruct = {
foo: 'bar'
}
expect(trace[0].meta_struct).to.deep.equal(expectedMetaStruct)
expect(msgpack.decode(trace[0].meta_struct.foo)).to.deep.equal(expectedMetaStruct.foo)
expect(trace[0].meta_struct.undefinedProperty).to.be.undefined
})

it('should encode meta_struct ignoring null properties', () => {
Expand All @@ -438,7 +430,8 @@ describe('encode', () => {
const expectedMetaStruct = {
foo: 'bar'
}
expect(trace[0].meta_struct).to.deep.equal(expectedMetaStruct)
expect(msgpack.decode(trace[0].meta_struct.foo)).to.deep.equal(expectedMetaStruct.foo)
expect(trace[0].meta_struct.nullProperty).to.be.undefined
})

it('should not encode null meta_struct', () => {
Expand Down

0 comments on commit c6e1c64

Please sign in to comment.