Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DEBUG-2972] Add initial support for Code Origin for Spans (Fastify entry spans only) #4449

Merged
merged 11 commits into from
Oct 14, 2024
2 changes: 2 additions & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
/packages/dd-trace/test/appsec/ @DataDog/asm-js

/integration-tests/debugger/ @DataDog/dd-trace-js @DataDog/debugger
/packages/datadog-code-origin/ @DataDog/dd-trace-js @DataDog/debugger
/packages/datadog-plugin-*/**/code_origin.* @DataDog/dd-trace-js @DataDog/debugger
/packages/dd-trace/src/debugger/ @DataDog/dd-trace-js @DataDog/debugger
/packages/dd-trace/test/debugger/ @DataDog/dd-trace-js @DataDog/debugger

Expand Down
38 changes: 38 additions & 0 deletions packages/datadog-code-origin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict'

const { getUserLandFrames } = require('../dd-trace/src/plugins/util/stacktrace')

const limit = Number(process.env._DD_CODE_ORIGIN_MAX_USER_FRAMES) || 8

module.exports = {
entryTag,
exitTag
}

function entryTag (topOfStackFunc) {
return tag('entry', topOfStackFunc)
}

function exitTag (topOfStackFunc) {
return tag('exit', topOfStackFunc)
}

function tag (type, topOfStackFunc) {
const frames = getUserLandFrames(topOfStackFunc, limit)
const tags = {
'_dd.code_origin.type': type
}
for (let i = 0; i < frames.length; i++) {
const frame = frames[i]
tags[`_dd.code_origin.frames.${i}.file`] = frame.file
tags[`_dd.code_origin.frames.${i}.line`] = String(frame.line)
tags[`_dd.code_origin.frames.${i}.column`] = String(frame.column)
if (frame.method) {
tags[`_dd.code_origin.frames.${i}.method`] = frame.method
}
if (frame.type) {
tags[`_dd.code_origin.frames.${i}.type`] = frame.type
}
}
return tags
}
13 changes: 12 additions & 1 deletion packages/datadog-instrumentations/src/fastify.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const { addHook, channel, AsyncResource } = require('./helpers/instrument')

const errorChannel = channel('apm:fastify:middleware:error')
const handleChannel = channel('apm:fastify:request:handle')
const routeAddedChannel = channel('apm:fastify:route:added')

const parsingResources = new WeakMap()

Expand All @@ -16,6 +17,7 @@ function wrapFastify (fastify, hasParsingEvents) {

if (!app || typeof app.addHook !== 'function') return app

app.addHook('onRoute', onRoute)
app.addHook('onRequest', onRequest)
app.addHook('preHandler', preHandler)

Expand Down Expand Up @@ -86,8 +88,9 @@ function onRequest (request, reply, done) {

const req = getReq(request)
const res = getRes(reply)
const routeConfig = getRouteConfig(request)

handleChannel.publish({ req, res })
handleChannel.publish({ req, res, routeConfig })

return done()
}
Expand Down Expand Up @@ -142,6 +145,10 @@ function getRes (reply) {
return reply && (reply.raw || reply.res || reply)
}

function getRouteConfig (request) {
return request?.routeOptions?.config
}

function publishError (error, req) {
if (error) {
errorChannel.publish({ error, req })
Expand All @@ -150,6 +157,10 @@ function publishError (error, req) {
return error
}

function onRoute (routeOptions) {
routeAddedChannel.publish({ routeOptions, onRoute })
}

addHook({ name: 'fastify', versions: ['>=3'] }, fastify => {
const wrapped = shimmer.wrapFunction(fastify, fastify => wrapFastify(fastify, true))

Expand Down
2 changes: 1 addition & 1 deletion packages/datadog-instrumentations/src/mocha/common.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { addHook, channel } = require('../helpers/instrument')
const shimmer = require('../../../datadog-shimmer')
const { getCallSites } = require('../../../dd-trace/src/plugins/util/test')
const { getCallSites } = require('../../../dd-trace/src/plugins/util/stacktrace')
const { testToStartLine } = require('./utils')

const parameterizedTestCh = channel('ci:mocha:test:parameterize')
Expand Down
31 changes: 31 additions & 0 deletions packages/datadog-plugin-fastify/src/code_origin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict'

const { entryTag } = require('../../datadog-code-origin')
const Plugin = require('../../dd-trace/src/plugins/plugin')
const web = require('../../dd-trace/src/plugins/util/web')

const kCodeOriginForSpansTagsSym = Symbol('datadog.codeOriginForSpansTags')

class FastifyCodeOriginForSpansPlugin extends Plugin {
static get id () {
return 'fastify'
}

constructor (...args) {
super(...args)

this.addSub('apm:fastify:request:handle', ({ req, routeConfig }) => {
const tags = routeConfig?.[kCodeOriginForSpansTagsSym]
if (!tags) return
const context = web.getContext(req)
context.span?.addTags(tags)
})

this.addSub('apm:fastify:route:added', ({ routeOptions, onRoute }) => {
if (!routeOptions.config) routeOptions.config = {}
routeOptions.config[kCodeOriginForSpansTagsSym] = entryTag(onRoute)
})
}
}

module.exports = FastifyCodeOriginForSpansPlugin
22 changes: 10 additions & 12 deletions packages/datadog-plugin-fastify/src/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
'use strict'

const RouterPlugin = require('../../datadog-plugin-router/src')
const FastifyTracingPlugin = require('./tracing')
const FastifyCodeOriginForSpansPlugin = require('./code_origin')
const CompositePlugin = require('../../dd-trace/src/plugins/composite')

class FastifyPlugin extends RouterPlugin {
static get id () {
return 'fastify'
}

constructor (...args) {
super(...args)

this.addSub('apm:fastify:request:handle', ({ req }) => {
this.setFramework(req, 'fastify', this.config)
})
class FastifyPlugin extends CompositePlugin {
static get id () { return 'fastify' }
static get plugins () {
return {
tracing: FastifyTracingPlugin,
codeOriginForSpans: FastifyCodeOriginForSpansPlugin
}
}
}

Expand Down
19 changes: 19 additions & 0 deletions packages/datadog-plugin-fastify/src/tracing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict'

const RouterPlugin = require('../../datadog-plugin-router/src')

class FastifyTracingPlugin extends RouterPlugin {
static get id () {
return 'fastify'
}

constructor (...args) {
super(...args)

this.addSub('apm:fastify:request:handle', ({ req }) => {
this.setFramework(req, 'fastify', this.config)
})
}
}

module.exports = FastifyTracingPlugin
Loading
Loading