Skip to content

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

@trentm

Description

@trentm

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)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions