Skip to content

core modules imported with require('node:...') are not instrumented #2816

Closed

Description

Instrumentation for the following does not work because node:http is required instead of http.

// node-prefixed-core-modules.js
require('./').start() // elastic-apm-node
const http = require('node:http')
const server = http.createServer((req, res) => {
  req.resume()
  res.statusCode = 200
  res.end('pong')
})
server.listen(3000, () => {
  http.get('http://localhost:3000', res => {
    console.log('CLIENT: res.headers:', res.headers)
    res.resume()
    res.on('end', () => {
      console.log('CLIENT: res "end"')
      server.close()
    })
  })
})

Support for node:-prefixed imports to explicitly mean core modules was added in node v16.0.0 (and maybe in v14.8.0?). See nodejs/node#37246

With require-in-the-middle debug logging:

% DEBUG=require-in-the-middle node foo.js
  require-in-the-middle registering require hook +0ms
  require-in-the-middle processing non-core module require('./system-cpu'): /Users/trentm/el/apm-agent-nodejs/lib/metrics/platforms/generic/system-cpu.js +3ms
  require-in-the-middle processing core module require('os'): os +1ms
  require-in-the-middle ignoring core module not on whitelist: os +0ms
  require-in-the-middle could not parse filename: /Users/trentm/el/apm-agent-nodejs/lib/metrics/platforms/generic/system-cpu.js +1ms
  require-in-the-middle processing non-core module require('node:http'): node:http +3ms
  require-in-the-middle could not parse filename: node:http +0ms
CLIENT: res.headers: {
  date: 'Fri, 08 Jul 2022 21:53:22 GMT',
  connection: 'close',
  'content-length': '4'
}
CLIENT: res "end"

The issue is that require-in-the-middle's isCore fails:

    const filename = Module._resolveFilename(id, this)   // filename = 'node:http'
    const core = isCore(filename)  // core = false

We'll need to update require-in-the-middle to fix this. We should watch out for not separately wrapping require('http') and require('node:http'), so perhaps a good answer would be to normalize the filename. E.g. a first naive stab could just drop the leading node: if any. ... Yup, making this change in require-in-the-middle/index.js works:

    let filename = Module._resolveFilename(id, this)
    if (filename.startsWith('node:')) {
      filename = filename.slice(5)
    }
    const core = isCore(filename)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions