From 9084f08f5339d18d39a8c4ed530fd72c86daca05 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Fri, 29 Oct 2021 09:00:55 -0700 Subject: [PATCH] fix: wrap 'fs.realpath.native' when configured with asyncHooks=false (#2403) Before this `fs.realpath.native` would be undefined after wrapping of `fs.realpath`. Fixes: #2401 --- CHANGELOG.asciidoc | 4 ++++ lib/instrumentation/patch-async.js | 9 ++++++++ test/instrumentation/fs.test.js | 33 ++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 test/instrumentation/fs.test.js diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 22b19ca050..7d320b52e8 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -39,6 +39,10 @@ Notes: [float] ===== Bug fixes +* Wrap `fs.realpath.native` when configured with `asyncHooks=false`. This + fixes using that function (which was undefined before this fix) and a + crash when importing fs-extra@10. ({issues}2401[#2401]) + * A significant change was made to internal run context tracking (a.k.a. async context tracking). There are no configuration changes or API changes for custom instrumentation. ({pull}2181[#2181]) diff --git a/lib/instrumentation/patch-async.js b/lib/instrumentation/patch-async.js index d14392b2df..ebf3fddf27 100644 --- a/lib/instrumentation/patch-async.js +++ b/lib/instrumentation/patch-async.js @@ -249,6 +249,11 @@ module.exports = function (ins) { if (dns.resolveNaptr) wrap(dns, 'resolveNaptr', activator) var fs = require('fs') + var wrappedFsRealpathNative + if (fs.realpath.native) { + wrappedFsRealpathNative = wrap(fs.realpath, 'native', activator) + } + massWrap( fs, [ @@ -287,6 +292,10 @@ module.exports = function (ins) { activator ) + if (wrappedFsRealpathNative) { + fs.realpath.native = wrappedFsRealpathNative + } + // only wrap lchown and lchmod on systems that have them. if (fs.lchown) wrap(fs, 'lchown', activator) // eslint-disable-line node/no-deprecated-api if (fs.lchmod) wrap(fs, 'lchmod', activator) // eslint-disable-line node/no-deprecated-api diff --git a/test/instrumentation/fs.test.js b/test/instrumentation/fs.test.js new file mode 100644 index 0000000000..6f8588caa7 --- /dev/null +++ b/test/instrumentation/fs.test.js @@ -0,0 +1,33 @@ +'use strict' + +// Some testing of run-context tracking through 'fs' methods. + +const apm = require('../..').start({ + serviceName: 'test-fs', + captureExceptions: false, + metricsInterval: '0s', + centralConfig: false, + cloudProvider: 'none', + disableSend: true, + asyncHooks: false +}) + +const fs = require('fs') + +const tape = require('tape') + +if (typeof fs.realpath.native === 'function') { + // Before https://github.com/elastic/apm-agent-nodejs/issues/2401 this test + // would crash with asyncHooks=false + tape.test('fs.realpath.native', function (t) { + var trans = apm.startTransaction('t0') + var span = apm.startSpan('s1') + fs.realpath.native(__filename, function (err, resolvedPath) { + t.error(err, 'no error from fs.realpath.native') + t.equal(apm.currentSpan, span, 'apm.currentSpan is as expected') + span.end() + trans.end() + t.end() + }) + }) +}