dd-trace
Version:
Datadog APM tracing client for JavaScript
70 lines (58 loc) • 2.03 kB
JavaScript
// Old instrumentation temporarily replaced with compatibility mode only instrumentation.
// See https://github.com/DataDog/dd-trace-js/issues/312
const {
channel,
addHook,
} = require('../helpers/instrument')
const shimmer = require('../../../datadog-shimmer')
const startServerCh = channel('apm:http2:server:request:start')
const errorServerCh = channel('apm:http2:server:request:error')
const emitCh = channel('apm:http2:server:response:emit')
addHook({ name: 'http2' }, http2 => {
shimmer.wrap(http2, 'createSecureServer', wrapCreateServer)
shimmer.wrap(http2, 'createServer', wrapCreateServer)
})
function wrapCreateServer (createServer) {
return function (...args) {
const server = createServer.apply(this, args)
shimmer.wrap(server, 'emit', wrapEmit)
return server
}
}
function wrapResponseEmit (originalEmit, ctx) {
// Named `emit`/arity-1 mirrors the response method so the per-response wrap
// skips its name/length rewrite.
return function emit (eventName) {
ctx.req = this.req
ctx.eventName = eventName
return emitCh.runStores(ctx, originalEmit, this, ...arguments)
}
}
function wrapEmit (originalEmit) {
// Named `emit` mirrors the server method so the one-time wrap skips its name
// rewrite; rest params keep the per-event forwarding allocation-free.
return function emit (...args) {
if (!startServerCh.hasSubscribers) {
return Reflect.apply(originalEmit, this, args)
}
const eventName = args[0]
if (eventName === 'request') {
const req = args[1]
const res = args[2]
res.req = req
const ctx = { req, res }
return startServerCh.runStores(ctx, () => {
shimmer.wrap(res, 'emit', emit => wrapResponseEmit(emit, ctx))
try {
return Reflect.apply(originalEmit, this, args)
} catch (error) {
ctx.error = error
errorServerCh.publish(ctx)
throw error
}
})
}
return Reflect.apply(originalEmit, this, args)
}
}