Skip to content
Draft
9 changes: 8 additions & 1 deletion manifests/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ refs:
- &ref_5_76_0 '>=5.76.0'
- &ref_5_77_0 '>=5.77.0'
- &ref_5_79_0 '>=5.79.0'
- &ref_5_80_0 '>=5.80.0'
tests/:
apm_tracing_e2e/:
test_otel.py:
Expand Down Expand Up @@ -1499,7 +1500,13 @@ tests/:
test_profiling.py:
Test_Profile: *ref_5_16_0 #actual version unknown
test_protobuf.py: missing_feature
test_resource_renaming.py: missing_feature
test_resource_renaming.py:
Test_Resource_Renaming_HTTP_Endpoint_Tag:
'*': *ref_5_80_0
nextjs: missing_feature # Next.js have file based routing, resource renaming is supported if we are not able to get route from insturmantation that we can't reprocude it.
Test_Resource_Renaming_Stats_Aggregation_Keys:
'*': *ref_5_80_0
nextjs: missing_feature
test_sampling_rates.py:
Test_SampleRateFunction: *ref_5_54_0
Test_SamplingDecisionAdded: *ref_5_17_0 # real version unknown
Expand Down
13 changes: 10 additions & 3 deletions tests/test_resource_renaming.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from utils import bug, scenarios, weblog, interfaces, features
from utils import bug, scenarios, weblog, interfaces, features, missing_feature, context
from utils._weblog import HttpResponse


Expand Down Expand Up @@ -36,15 +36,22 @@ def test_http_endpoint_basic(self):
assert get_endpoint_tag(self.r_param_str) == "/resource_renaming/files/{param:str}"
assert get_endpoint_tag(self.r_param_str_2) == "/resource_renaming/files/{param:str}"

def setup_http_endpoint_root(self):
"""Setup requests for root endpoint testing"""
self.r_root = weblog.get("/")

@missing_feature(context.weblog_variant == "fastify", reason="Fasitfy root route is always '/' not empty string")
def test_http_endpoint_root(self):
"""Test that root endpoint is handled correctly"""
assert get_endpoint_tag(self.r_root) == "/"

def setup_http_endpoint_edge_cases(self):
"""Setup requests for edge case testing"""
self.r_root = weblog.get("/")
self.r_long_path = weblog.get("/resource_renaming/a/b/c/d/e/f/g/h/i/j/k/l/m")
self.r_empty_segments = weblog.get("/resource_renaming//double//slash")

def test_http_endpoint_edge_cases(self):
"""Test that edge cases are handled correctly"""
assert get_endpoint_tag(self.r_root) == "/"
assert get_endpoint_tag(self.r_long_path) == "/resource_renaming/a/b/c/d/e/f/g"
assert get_endpoint_tag(self.r_empty_segments) == "/resource_renaming/double/slash"

Expand Down
2 changes: 1 addition & 1 deletion utils/_context/_scenarios/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ class _Scenarios:
"DD_LOGS_INJECTION": "true",
"DD_TRACE_RESOURCE_RENAMING_ENABLED": "true",
"DD_TRACE_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT": "true",
"DD_TRACE_COMPUTE_STATS": "true",
Copy link
Contributor Author

@IlyasShabi IlyasShabi Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DD_TRACE_STATS_COMPUTATION_ENABLED is the right env var for all tracers
@florentinl

"DD_TRACE_STATS_COMPUTATION_ENABLED": "true",
},
appsec_enabled=False,
doc="",
Expand Down
34 changes: 22 additions & 12 deletions utils/build/docker/nodejs/express/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const api = require('@opentelemetry/api')
const iast = require('./iast')
const dsm = require('./dsm')
const di = require('./debugger')
const { OpenFeature } = require('@openfeature/server-sdk')

const { spawnSync } = require('child_process')

Expand Down Expand Up @@ -666,18 +667,6 @@ app.get('/add_event', (req, res) => {

require('./rasp')(app)

const startServer = () => {
return new Promise((resolve) => {
app.listen(7777, '0.0.0.0', () => {
tracer.trace('init.service', () => {})
console.log('listening')
resolve()
})
})
}

// apollo-server does not support Express 5 yet https://github.com/apollographql/apollo-server/issues/7928
const { OpenFeature } = require('@openfeature/server-sdk')
let openFeatureClient = null

// Initialize OpenFeature provider if FFE is enabled
Expand Down Expand Up @@ -724,12 +713,33 @@ app.post('/ffe', async (req, res) => {
}
})

// apollo-server does not support Express 5 yet https://github.com/apollographql/apollo-server/issues/7928
const initGraphQL = () => {
return graphQLEnabled
? require('./graphql')(app)
: Promise.resolve()
}

const startServer = () => {
return new Promise((resolve) => {
const server = http.createServer((req, res) => {
if (req.url.startsWith('/resource_renaming')) {
res.writeHead(200)
res.end('OK')
} else {
// Everything else goes to Express
app(req, res)
}
})

server.listen(7777, '0.0.0.0', () => {
tracer.trace('init.service', () => {})
console.log('listening')
resolve()
})
})
}

initGraphQL()
.then(startServer)
.catch(error => {
Expand Down
30 changes: 25 additions & 5 deletions utils/build/docker/nodejs/express4-typescript/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,29 @@ app.get('/set_cookie', (req: Request, res: Response) => {

require('./rasp')(app)

require('./graphql')(app).then(() => {
app.listen(7777, '0.0.0.0', () => {
tracer.trace('init.service', () => {})
console.log('listening')
const startServer = () => {
return new Promise((resolve) => {
const server = http.createServer((req: http.IncomingMessage, res: http.ServerResponse) => {
if (req.url?.startsWith('/resource_renaming')) {
res.writeHead(200)
res.end('OK')
} else {
// Everything else goes to Express
app(req, res)
}
})

server.listen(7777, '0.0.0.0', () => {
tracer.trace('init.service', () => {})
console.log('listening')
resolve(true)
})
})
}

require('./graphql')(app)
.then(startServer)
.catch((error: Error) => {
console.error('Failed to start server:', error)
process.exit(1)
})
})
21 changes: 20 additions & 1 deletion utils/build/docker/nodejs/fastify/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,31 @@ const tracer = require('dd-trace').init({
})

const { promisify } = require('util')
const fastify = require('fastify')({ logger: true })
const axios = require('axios')
const crypto = require('crypto')
const http = require('http')
const winston = require('winston')

const server = http.createServer()

const fastify = require('fastify')({
logger: true,
serverFactory: (handler) => {
server.on('request', (req, res) => {
if (req.url.startsWith('/resource_renaming')) {
// Handle resource renaming with HTTP server directly
res.writeHead(200)
res.end('OK')
} else {
// Everything else goes to Fastify
handler(req, res)
}
})

return server
}
})

const iast = require('./iast')
const dsm = require('./dsm')
const di = require('./debugger')
Expand Down
Loading