Skip to content

Commit

Permalink
[DI] Drop snapshot if JSON payload is too large
Browse files Browse the repository at this point in the history
The log track has a 1MB limit of the JSON payload. The client is not
notified if the payload is too large, but it is simply never indexed.

This is a very crude approach. In the future a more sophsticated
algorithm will be implemented that reduces the size of the snapshot
instead of removing it completely.
  • Loading branch information
watson committed Oct 28, 2024
1 parent 24e846e commit 87e143e
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
23 changes: 23 additions & 0 deletions integration-tests/debugger/snapshot-pruning.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict'

const { assert } = require('chai')
const { setup } = require('./utils')

describe('Dynamic Instrumentation', function () {
const t = setup()

describe('input messages', function () {
describe('with snapshot', function () {
beforeEach(t.triggerBreakpoint)

it('should prune snapshot if payload is too large', function (done) {
t.agent.on('debugger-input', ({ payload }) => {
assert.isBelow(Buffer.byteLength(JSON.stringify(payload)), 1024 * 1024) // 1MB
done()
})

t.agent.addRemoteConfig(t.generateRemoteConfig({ captureSnapshot: true }))
})
})
})
})
41 changes: 41 additions & 0 deletions integration-tests/debugger/target-app/snapshot-pruning.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict'

require('dd-trace/init')

const { randomBytes } = require('crypto')
const Fastify = require('fastify')

const fastify = Fastify()

const TARGET_SIZE = 1024 * 1024 // 1MB
const LARGE_STRING = randomBytes(1024).toString('hex')

fastify.get('/:name', function handler (request) {
// eslint-disable-next-line no-unused-vars
const obj = generateObjectWithJSONSizeLargerThan1MB()

return { hello: request.params.name } // BREAKPOINT
})

fastify.listen({ port: process.env.APP_PORT }, (err) => {
if (err) {
fastify.log.error(err)
process.exit(1)
}
process.send({ port: process.env.APP_PORT })
})

function generateObjectWithJSONSizeLargerThan1MB () {
const obj = {}
let i = 0

while (++i) {
if (i % 100 === 0) {
const size = JSON.stringify(obj).length
if (size > TARGET_SIZE) break
}
obj[i] = LARGE_STRING
}

return obj
}
12 changes: 11 additions & 1 deletion packages/dd-trace/src/debugger/devtools_client/send.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const { GIT_COMMIT_SHA, GIT_REPOSITORY_URL } = require('../../plugins/util/tags'

module.exports = send

const MAX_PAYLOAD_SIZE = 1024 * 1024 // 1MB

const ddsource = 'dd_debugger'
const hostname = getHostname()
const service = config.service
Expand Down Expand Up @@ -37,5 +39,13 @@ function send (message, logger, snapshot, cb) {
'debugger.snapshot': snapshot
}

request(JSON.stringify(payload), opts, cb)
let json = JSON.stringify(payload)

if (Buffer.byteLength(json) > MAX_PAYLOAD_SIZE) {
// TODO: This is a very crude way to handle large payloads. Proper pruning will be implemented later (DEBUG-2624)
delete payload['debugger.snapshot']
json = JSON.stringify(payload)
}

request(json, opts, cb)
}

0 comments on commit 87e143e

Please sign in to comment.