Skip to content

Commit

Permalink
feat: instrument core modules imported with require('node:...') (elas…
Browse files Browse the repository at this point in the history
…tic#2868)

Starting in node v14.18.0, support for identifying core node modules
with the 'node:'-prefix was added:
https://nodejs.org/api/modules.html#core-modules

Closes: elastic#2816
  • Loading branch information
trentm authored and fpm-peter committed Aug 20, 2024
1 parent e7eb0b1 commit 4edfb98
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 25 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,27 @@ Notes:
[[release-notes-3.x]]
=== Node.js Agent version 3.x
==== Unreleased
[float]
===== Breaking changes
[float]
===== Features
- Support instrumenting core modules when require'd with the optional
https://nodejs.org/api/modules.html#core-modules['node:'-prefix].
For example `require('node:http')` will now be instrumented.
({issues}2816[#2816])
[float]
===== Bug fixes
[float]
===== Chores
[[release-notes-3.38.0]]
==== 3.38.0 2022/08/11
Expand Down
49 changes: 26 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"lint:license-files": "./dev-utils/gen-notice.sh --lint . # requires node >=16",
"coverage": "COVERAGE=true ./test/script/run_tests.sh",
"test": "./test/script/run_tests.sh",
"test:deps": "dependency-check start.js index.js 'lib/**/*.js' 'test/**/*.js' --no-dev -i async_hooks -i perf_hooks -i parseurl",
"test:deps": "dependency-check start.js index.js 'lib/**/*.js' 'test/**/*.js' --no-dev -i async_hooks -i perf_hooks -i parseurl -i node:http",
"test:tav": "tav --quiet",
"test:docs": "./test/script/docker/run_docs.sh",
"test:types": "tsc --project test/types/tsconfig.json && tsc --project test/types/transpile/tsconfig.json && node test/types/transpile/index.js && tsc --project test/types/transpile-default/tsconfig.json && node test/types/transpile-default/index.js",
Expand Down Expand Up @@ -106,7 +106,7 @@
"original-url": "^1.2.3",
"pino": "^6.11.2",
"relative-microtime": "^2.0.0",
"require-in-the-middle": "^5.0.3",
"require-in-the-middle": "^5.2.0",
"semver": "^6.3.0",
"set-cookie-serde": "^1.0.0",
"shallow-clone-shim": "^2.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and other contributors where applicable.
* Licensed under the BSD 2-Clause License; you may not use this file except in
* compliance with the BSD 2-Clause License.
*/

'use strict'

// Test that instrumentation of core modules works when required with the
// 'node:' prefix.

const { CapturingTransport } = require('../../../_capturing_transport')

const apm = require('../../../..').start({
serviceName: 'test-node-prefixed-http-require',
captureExceptions: false,
metricsInterval: 0,
centralConfig: false,
cloudProvider: 'none',
transport () {
return new CapturingTransport()
}
})

try {
var http = require('node:http')
} catch (_requireErr) {
console.log(`# SKIP node ${process.version} doesn't support require('node:...')`)
process.exit()
}

const test = require('tape')
const { findObjInArray } = require('../../../_utils')

test('node:http instrumentation works', function (t) {
var server = http.createServer(function (req, res) {
res.end('pong')
})

server.listen(function onListen () {
const aTrans = apm.startTransaction('aTrans', 'manual')
const port = server.address().port
const url = 'http://localhost:' + port
http.get(url, function (res) {
res.resume()
res.on('end', function () {
aTrans.end()
server.close()
apm.flush(() => {
const aTrans_ = findObjInArray(apm._transport.transactions, 'name', 'aTrans')
const httpClientSpan = findObjInArray(apm._transport.spans, 'name', `GET localhost:${port}`)
const httpServerTrans = findObjInArray(apm._transport.transactions, 'type', 'request')
t.ok(aTrans_ && httpClientSpan && httpServerTrans, 'received the expected trace objs')
t.equal(httpClientSpan.parent_id, aTrans_.id, 'http client span is a child of the manual trans')
t.equal(httpServerTrans.parent_id, httpClientSpan.id, 'http server trans is a child of the http client span')
t.end()
})
})
})
})
})

0 comments on commit 4edfb98

Please sign in to comment.