newrelic 8.6.0 → 8.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/NEWS.md CHANGED
@@ -1,19 +1,129 @@
1
- ### v8.6.0 (2021-11-17)
2
-
1
+ ### v8.8.0 (2022-02-23)
2
+
3
+ * Updated AWS metadata capture to utilize IMDSv2.
4
+
5
+ * Fixed link to discuss.newrelic.com in README
6
+
7
+ * Updated minimum Node version warning to output current Node version from process.
8
+
9
+ * Bumped `@newrelic/native-metrics` to ^7.1.1.
10
+
11
+ * Added `Nextjs` to a framework constant within the webframework-shim.
12
+
13
+ * Updated shim to pass active segment to inContext callback.
14
+
15
+ * Bumped `@grpc/grpc-js` to ^1.5.5.
16
+
17
+ * Bumped `@grpc/proto-loader` to ^0.6.9.
18
+
19
+ * Bumped `@newrelic/superagent` to ^5.1.0.
20
+
21
+ * Bumped `@newrelic/koa` to ^6.1.0.
22
+
23
+ * Bumped `async` to ^3.2.3.
24
+
25
+ * Resolved several npm audit warnings for dev deps.
26
+
27
+ * Fixed Post Release workflow by properly configuring git credentials so it can push API docs to branch
28
+ * Added `set -e` in publish docs script to exit on possible failures
29
+ * Removed redundant `npm ci` in publish API docs script
30
+
31
+ * Added ability to ignore certain PRs in `bin/pending-prs.js` report to slack
32
+
33
+ * Updated README to include `@newrelic/pino-enricher` as an external module.
34
+
35
+ * Fixed documentation in a sample of the Datastore Instrumentation for Node.js.
36
+
37
+ * Added a new `mongo:5` container to `npm run sevices` to test mongodb driver >=4.2.0.
38
+
39
+ * Fixed conditions in post release workflow to function when triggered via successful release and manual invoked.
40
+
41
+ * Updated method for retrieving agent version from repository by using `cat package.json | jq .version`
42
+
43
+ * Fixed minor formatting and spelling issues in `create-docs-pr.js`.
44
+
45
+ * Fixed an issue with the docs PR script that assumed `\n` in the NEWS.md file when extract version and release date
46
+
47
+ ### v8.7.1 (2022-01-18)
48
+
49
+ * Bumped @newrelic/aws-sdk to ^4.1.1.
50
+
51
+ * Upgraded `@newrelic/test-utilities` to ^6.3.0.
52
+
53
+ Includes `helpers.getShim` so sub packages properly execute.
54
+
55
+ * Resolved dependabot and certain npm audit warnings.
56
+
57
+ * Automation and CI improvements:
58
+ * Added a script to be used by agent developers to add a PR to `docs-website` after the release of agent.
59
+ * Changed the trigger for post release jobs.
60
+ * Updated the `create-release-tag` script to pass in workflows to check before creating tag.
61
+ * Fixed `create-release-tag` to properly filter out all async workflow run checks
62
+ * Updated agent release to pass in a different list of workflows vs the default
63
+ * Fixed release creation reusable workflow by passing in repo to `bin/create-release-tag.js` and `bin/create-github-release.js`.
64
+ * Added `workflow_dispatch` to Agent Post Release workflow for manual testing.
65
+ * Added a reusable workflow to create a release tag, publish to NPM and publish a GitHub release.
66
+ * Updated agent release workflow to reference reusable workflow.
67
+ * Added a new workflow to update RPM and publish API docs on a published release event type.
68
+
69
+
70
+ ### v8.7.0 (2022-01-04)
71
+
72
+ * Updated `onResolved` instrumentation hook to only be called the first time we see a specific module filepath resolved.
73
+
74
+ * Removed `tracer.segment` in place of direct usage of context manager.
75
+
76
+ * Fixed an issue where multiple calls to `instrumentLoadedModule` resulted in re-instrumenting the same module.
77
+
78
+ * Fixed issue where `instrumentLoadedModule` would return `true` even if the instrumentation handler indicated it did not apply instrumentation.
79
+
80
+ * Added support metrics for tracking when instrumentation was applied per module.
81
+
82
+ * `Supportability/Features/Instrumentation/OnResolved/<module-name>`
83
+ * `Supportability/Features/Instrumentation/OnResolved/<module-name>/Version/<major version>`
84
+ * `Supportability/Features/Instrumentation/OnRequire/<module-name>`
85
+ * `Supportability/Features/Instrumentation/OnRequire/<module-name>/Version/<major version>`
86
+
87
+ * Fixed issue where expected status code ranges would not be parsed until ignored status codes were also defined.
88
+
89
+ * Added an input `changelog_file` to pass in name of changelog. This defaults to `NEWS.md` but some repos use `CHANGELOG.md`
90
+
91
+ * Abstracted `bin/prepare-release.js` to work against other repositories.
92
+
93
+ * Added reusable prepare-release workflow that can be referenced in all other newrelic Node.js repositories.
94
+
95
+ * Updated pending PRs workflow to check all repos the team owns.
96
+
97
+ * Changed the event type from `pull_request` to `pull_request_target` to allow for auto assign of PRs to the Node.js Engineering Board
98
+
99
+ * Fixed add to board workflow to properly pass repository secrets into reusable board workflow.
100
+
101
+ * Changes token used to post issues to org level project board
102
+
103
+ * Runs versioned tests for external modules against tests defined in the external repository instead of tests published in npm modules.
104
+
105
+ * Added a reusable workflow to automatically add issues to the Node.js Engineering Board when created.
106
+
107
+ * Added CI job to update system configurations with new agent version on release.
108
+
109
+ * Moved `methods.js` under bluebird versioned test folder.
110
+
111
+ ### v8.6.0 (2021-11-17)
112
+
3
113
  * Added `onResolved` instrumentation hook to apply instrumentation prior to module load.
4
114
 
5
- This hook fires after the module filepath has been resolved just prior to the module being loaded by the CommonJS module loader.
6
-
7
- * Fixed issue where `recordConsume` was not binding consumer if it was a promise
8
-
9
- * Pinned mongo versioned tests to `<4.2.0` until we can address https://github.com/newrelic/node-newrelic/issues/982
10
-
11
- * Introduced a context management API to be used in place of manually calling tracer.segment get/set.
12
-
13
- ### v8.5.2 (2021-11-09)
14
-
15
- * Fixed issue where unhandled promise rejections were not getting logged as errors in a lambda execution
16
-
115
+ This hook fires after the module filepath has been resolved just prior to the module being loaded by the CommonJS module loader.
116
+
117
+ * Fixed issue where `recordConsume` was not binding consumer if it was a promise
118
+
119
+ * Pinned mongo versioned tests to `<4.2.0` until we can address https://github.com/newrelic/node-newrelic/issues/982
120
+
121
+ * Introduced a context management API to be used in place of manually calling tracer.segment get/set.
122
+
123
+ ### v8.5.2 (2021-11-09)
124
+
125
+ * Fixed issue where unhandled promise rejections were not getting logged as errors in a lambda execution
126
+
17
127
  ### v8.5.1 (2021-11-03)
18
128
 
19
129
  * Fixed bug where failure to retrieve CPU/Memory details for certain Linux distros could result in a crash.
package/README.md CHANGED
@@ -67,7 +67,8 @@ For more information on getting started, [check the Node.js docs](https://docs.n
67
67
  There are several modules that can be installed and configured to accompany the Node.js agent:
68
68
 
69
69
  * [@newrelic/apollo-server-plugin](https://github.com/newrelic/newrelic-node-apollo-server-plugin): New Relic's official Apollo Server plugin for use with the Node.js agent.
70
- * [@newrelic/winston-enricher](https://github.com/newrelic/newrelic-winston-logenricher-node): Provides distributed trace and span information output as JSON-formatted log messages. This is most commonly used with the New Relic Logs product.
70
+ * [@newrelic/winston-enricher](https://github.com/newrelic/newrelic-node-log-extensions/tree/main/packages/winston-log-enricher): Provides distributed trace and span information output as JSON-formatted log messages in Winston. This is most commonly used with the New Relic Logs product.
71
+ * [@newrelic/pino-enricher](https://github.com/newrelic/newrelic-node-log-extensions/tree/main/packages/pino-log-enricher): Provides distributed trace and span information output as JSON-formatted log messages in Pino. This is most commonly used with the New Relic Logs product.
71
72
  * [@newrelic/mysql](https://github.com/newrelic/node-newrelic-mysql)(**Experimental**): Standalone instrumentation for [mysql2](https://github.com/sidorares/node-mysql2#readme) and [mysql2/promise](https://github.com/sidorares/node-mysql2/blob/master/documentation/Promise-Wrapper.md) as well as the same instrumentation for [mysql](https://github.com/mysqljs/mysql#readme) within the Node.js agent.
72
73
 
73
74
  There are several modules included within the Node.js agent to add more instrumentation for 3rd party modules:
@@ -152,7 +153,7 @@ If the issue has been confirmed as a bug or is a feature request, please file a
152
153
  **Support Channels**
153
154
 
154
155
  * [New Relic Documentation](https://docs.newrelic.com/docs/agents/nodejs-agent/getting-started/introduction-new-relic-nodejs): Comprehensive guidance for using our platform
155
- * [New Relic Community](https://discuss.newrelic.com/c/support-products-agents/node-js-agent/): The best place to engage in troubleshooting questions
156
+ * [New Relic Community](https://discuss.newrelic.com/tags/c/telemetry-data-platform/agents/nodeagent): The best place to engage in troubleshooting questions
156
157
  * [New Relic Developer](https://developer.newrelic.com/): Resources for building a custom observability applications
157
158
  * [New Relic University](https://learn.newrelic.com/): A range of online training for New Relic users of every level
158
159
  * [New Relic Technical Support](https://support.newrelic.com/) 24/7/365 ticketed support. Read more about our [Technical Support Offerings](https://docs.newrelic.com/docs/licenses/license-information/general-usage-licenses/support-plan).
@@ -86,7 +86,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
86
86
 
87
87
  ### @grpc/grpc-js
88
88
 
89
- This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.3.7](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/tree/v1.3.7)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/blob/v1.3.7/LICENSE):
89
+ This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.5.5](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/tree/v1.5.5)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/blob/v1.5.5/LICENSE):
90
90
 
91
91
  ```
92
92
  Apache License
@@ -295,7 +295,7 @@ This product includes source derived from [@grpc/grpc-js](https://github.com/grp
295
295
 
296
296
  ### @grpc/proto-loader
297
297
 
298
- This product includes source derived from [@grpc/proto-loader](https://github.com/grpc/grpc-node) ([v0.5.6](https://github.com/grpc/grpc-node/tree/v0.5.6)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/blob/v0.5.6/LICENSE):
298
+ This product includes source derived from [@grpc/proto-loader](https://github.com/grpc/grpc-node) ([v0.6.9](https://github.com/grpc/grpc-node/tree/v0.6.9)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/blob/v0.6.9/LICENSE):
299
299
 
300
300
  ```
301
301
  Apache License
@@ -504,7 +504,7 @@ This product includes source derived from [@grpc/proto-loader](https://github.co
504
504
 
505
505
  ### @newrelic/aws-sdk
506
506
 
507
- This product includes source derived from [@newrelic/aws-sdk](https://github.com/newrelic/node-newrelic-aws-sdk) ([v4.0.1](https://github.com/newrelic/node-newrelic-aws-sdk/tree/v4.0.1)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-aws-sdk/blob/v4.0.1/LICENSE):
507
+ This product includes source derived from [@newrelic/aws-sdk](https://github.com/newrelic/node-newrelic-aws-sdk) ([v4.1.1](https://github.com/newrelic/node-newrelic-aws-sdk/tree/v4.1.1)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-aws-sdk/blob/v4.1.1/LICENSE):
508
508
 
509
509
  ```
510
510
  Apache License
@@ -712,7 +712,7 @@ This product includes source derived from [@newrelic/aws-sdk](https://github.com
712
712
 
713
713
  ### @newrelic/koa
714
714
 
715
- This product includes source derived from [@newrelic/koa](https://github.com/newrelic/node-newrelic-koa) ([v6.0.1](https://github.com/newrelic/node-newrelic-koa/tree/v6.0.1)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-koa/blob/v6.0.1/LICENSE):
715
+ This product includes source derived from [@newrelic/koa](https://github.com/newrelic/node-newrelic-koa) ([v6.1.0](https://github.com/newrelic/node-newrelic-koa/tree/v6.1.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-koa/blob/v6.1.0/LICENSE):
716
716
 
717
717
  ```
718
718
  Apache License
@@ -921,7 +921,7 @@ Apache License
921
921
 
922
922
  ### @newrelic/superagent
923
923
 
924
- This product includes source derived from [@newrelic/superagent](https://github.com/newrelic/node-newrelic-superagent) ([v5.0.1](https://github.com/newrelic/node-newrelic-superagent/tree/v5.0.1)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-superagent/blob/v5.0.1/LICENSE):
924
+ This product includes source derived from [@newrelic/superagent](https://github.com/newrelic/node-newrelic-superagent) ([v5.1.0](https://github.com/newrelic/node-newrelic-superagent/tree/v5.1.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-superagent/blob/v5.1.0/LICENSE):
925
925
 
926
926
  ```
927
927
  Apache License
@@ -1159,7 +1159,7 @@ THE SOFTWARE.
1159
1159
 
1160
1160
  ### async
1161
1161
 
1162
- This product includes source derived from [async](https://github.com/caolan/async) ([v3.2.1](https://github.com/caolan/async/tree/v3.2.1)), distributed under the [MIT License](https://github.com/caolan/async/blob/v3.2.1/LICENSE):
1162
+ This product includes source derived from [async](https://github.com/caolan/async) ([v3.2.3](https://github.com/caolan/async/tree/v3.2.3)), distributed under the [MIT License](https://github.com/caolan/async/blob/v3.2.3/LICENSE):
1163
1163
 
1164
1164
  ```
1165
1165
  Copyright (c) 2010-2018 Caolan McMahon
@@ -1770,7 +1770,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
1770
1770
 
1771
1771
  ### @newrelic/test-utilities
1772
1772
 
1773
- This product includes source derived from [@newrelic/test-utilities](https://github.com/newrelic/node-test-utilities) ([v6.1.1](https://github.com/newrelic/node-test-utilities/tree/v6.1.1)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-test-utilities/blob/v6.1.1/LICENSE):
1773
+ This product includes source derived from [@newrelic/test-utilities](https://github.com/newrelic/node-test-utilities) ([v6.3.0](https://github.com/newrelic/node-test-utilities/tree/v6.3.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-test-utilities/blob/v6.3.0/LICENSE):
1774
1774
 
1775
1775
  ```
1776
1776
  Apache License
@@ -2531,7 +2531,7 @@ SOFTWARE.
2531
2531
 
2532
2532
  ### jsdoc
2533
2533
 
2534
- This product includes source derived from [jsdoc](https://github.com/jsdoc/jsdoc) ([v3.6.7](https://github.com/jsdoc/jsdoc/tree/v3.6.7)), distributed under the [Apache-2.0 License](https://github.com/jsdoc/jsdoc/blob/v3.6.7/LICENSE.md):
2534
+ This product includes source derived from [jsdoc](https://github.com/jsdoc/jsdoc) ([v3.6.10](https://github.com/jsdoc/jsdoc/tree/v3.6.10)), distributed under the [Apache-2.0 License](https://github.com/jsdoc/jsdoc/blob/v3.6.10/LICENSE.md):
2535
2535
 
2536
2536
  ```
2537
2537
  # License
@@ -3292,7 +3292,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3292
3292
 
3293
3293
  ### tap
3294
3294
 
3295
- This product includes source derived from [tap](https://github.com/tapjs/node-tap) ([v15.0.10](https://github.com/tapjs/node-tap/tree/v15.0.10)), distributed under the [ISC License](https://github.com/tapjs/node-tap/blob/v15.0.10/LICENSE):
3295
+ This product includes source derived from [tap](https://github.com/tapjs/node-tap) ([v15.1.6](https://github.com/tapjs/node-tap/tree/v15.1.6)), distributed under the [ISC License](https://github.com/tapjs/node-tap/blob/v15.1.6/LICENSE):
3296
3296
 
3297
3297
  ```
3298
3298
  The ISC License
@@ -3377,7 +3377,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3377
3377
 
3378
3378
  ### @newrelic/native-metrics
3379
3379
 
3380
- This product includes source derived from [@newrelic/native-metrics](https://github.com/newrelic/node-native-metrics) ([v7.0.1](https://github.com/newrelic/node-native-metrics/tree/v7.0.1)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-native-metrics/blob/v7.0.1/LICENSE):
3380
+ This product includes source derived from [@newrelic/native-metrics](https://github.com/newrelic/node-native-metrics) ([v7.1.1](https://github.com/newrelic/node-native-metrics/tree/v7.1.1)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-native-metrics/blob/v7.1.1/LICENSE):
3381
3381
 
3382
3382
  ```
3383
3383
  Apache License
package/api.js CHANGED
@@ -14,7 +14,6 @@ const hashes = require('./lib/util/hashes')
14
14
  const properties = require('./lib/util/properties')
15
15
  const stringify = require('json-stringify-safe')
16
16
  const shimmer = require('./lib/shimmer')
17
- const shims = require('./lib/shim')
18
17
  const isValidType = require('./lib/util/attribute-types')
19
18
  const TransactionShim = require('./lib/shim/transaction-shim')
20
19
  const TransactionHandle = require('./lib/transaction/handle')
@@ -1332,34 +1331,16 @@ API.prototype.instrumentLoadedModule = function instrumentLoadedModule(moduleNam
1332
1331
  NAMES.SUPPORTABILITY.API + '/instrumentLoadedModule'
1333
1332
  )
1334
1333
  metric.incrementCallCount()
1335
- try {
1336
- const instrumentationName = shimmer.getInstrumentationNameFromModuleName(moduleName)
1337
- if (!shimmer.registeredInstrumentations[instrumentationName]) {
1338
- logger.warn("No instrumentation registered for '%s'.", instrumentationName)
1339
- return false
1340
- }
1341
-
1342
- const instrumentation = shimmer.registeredInstrumentations[instrumentationName]
1343
- if (!instrumentation.onRequire) {
1344
- logger.warn("No onRequire function registered for '%s'.", instrumentationName)
1345
- return false
1346
- }
1347
1334
 
1335
+ try {
1348
1336
  const resolvedName = require.resolve(moduleName)
1349
1337
 
1350
- const shim = shims.createShimFromType(
1351
- instrumentation.type,
1352
- this.agent,
1353
- moduleName,
1354
- resolvedName
1355
- )
1356
-
1357
- instrumentation.onRequire(shim, module, moduleName)
1358
-
1359
- return true
1338
+ return shimmer.instrumentPostLoad(this.agent, module, moduleName, resolvedName)
1360
1339
  } catch (error) {
1361
1340
  logger.error('instrumentLoadedModule encountered an error, module not instrumented: %s', error)
1362
1341
  }
1342
+
1343
+ return false
1363
1344
  }
1364
1345
 
1365
1346
  /**
package/index.js CHANGED
@@ -45,10 +45,9 @@ function initialize() {
45
45
  logger.debug('Process was running %s seconds before agent was loaded.', preAgentTime)
46
46
 
47
47
  if (!psemver.satisfies(pkgJSON.engines.node)) {
48
- // TODO: Update this message when Node v12 is deprecated.
49
48
  message =
50
- 'New Relic for Node.js requires a version of Node equal to or\n' +
51
- 'greater than 12.0.0. Not starting!'
49
+ `New Relic for Node.js requires a version of Node ${pkgJSON.engines.node}. \n` +
50
+ `Please upgrade from your current Node version: ${process.version}. Not starting!`
52
51
 
53
52
  logger.error(message)
54
53
  throw new Error(message)
@@ -229,6 +229,7 @@ Config.prototype.mergeServerConfig = mergeServerConfig
229
229
  * recognized, unsupported, and unknown parameters.
230
230
  *
231
231
  * @param {object} json The config blob sent by New Relic.
232
+ * @param recursion
232
233
  */
233
234
  Config.prototype.onConnect = function onConnect(json, recursion) {
234
235
  json = json || Object.create(null)
@@ -865,7 +866,7 @@ Config.prototype.checkAsyncHookStatus = function checkAsyncHookStatus() {
865
866
  * I wanted to cache the DisplayHost, but if I attached the variable to the config object,
866
867
  * it sends the extra variable to New Relic, which is not desired.
867
868
  *
868
- * @return {string} display host name
869
+ * @returns {string} display host name
869
870
  */
870
871
  Config.prototype.getDisplayHost = getDisplayHost
871
872
 
@@ -903,7 +904,7 @@ function getDisplayHost() {
903
904
  * I wanted to cache the Hostname, but if I attached the variable to the config object,
904
905
  * it sends the extra variable to New Relic, which is not desired.
905
906
  *
906
- * @return {string} host name
907
+ * @returns {string} host name
907
908
  */
908
909
  Config.prototype.getHostnameSafe = getHostnameSafe
909
910
 
@@ -980,6 +981,7 @@ Config.prototype.applications = function applications() {
980
981
  *
981
982
  * @param {object} external The configuration being loaded.
982
983
  * @param {object} internal Whichever chunk of the config being overridden.
984
+ * @param arbitrary
983
985
  */
984
986
  Config.prototype._fromPassed = function _fromPassed(external, internal, arbitrary) {
985
987
  if (!external) {
@@ -1065,6 +1067,8 @@ Config.prototype._featureFlagsFromEnv = function _featureFlagsFromEnv() {
1065
1067
  * need to set this yourself.
1066
1068
  * @param object data The current level of the configuration object. Should
1067
1069
  * never need to set this yourself.
1070
+ * @param metadata
1071
+ * @param data
1068
1072
  */
1069
1073
  Config.prototype._fromEnvironment = function _fromEnvironment(metadata, data) {
1070
1074
  if (!metadata) {
@@ -1122,7 +1126,6 @@ Config.prototype._fromEnvironment = function _fromEnvironment(metadata, data) {
1122
1126
  * environment variable.
1123
1127
  *
1124
1128
  * @param {*} inputConfig configuration passed to the Config constructor
1125
- *
1126
1129
  * @returns {boolean}
1127
1130
  */
1128
1131
  Config.prototype._loggingManuallySet = function _loggingManuallySet(inputConfig) {
@@ -1137,7 +1140,6 @@ Config.prototype._loggingManuallySet = function _loggingManuallySet(inputConfig)
1137
1140
  * file or enveironment variable
1138
1141
  *
1139
1142
  * @param {*} inputConfig configuration pass to the Config constructor
1140
- *
1141
1143
  * @returns {boolean}
1142
1144
  */
1143
1145
  Config.prototype._nativeMetricsManuallySet = function _nativeMetricsManuallySet(inputConfig) {
@@ -1156,7 +1158,6 @@ Config.prototype._nativeMetricsManuallySet = function _nativeMetricsManuallySet(
1156
1158
  * environment variable.
1157
1159
  *
1158
1160
  * @param {*} inputConfig configuration passed to the Config constructor
1159
- *
1160
1161
  * @returns {boolean}
1161
1162
  */
1162
1163
  Config.prototype._DTManuallySet = function _DTManuallySet(inputConfig) {
@@ -1173,6 +1174,7 @@ Config.prototype._DTManuallySet = function _DTManuallySet(inputConfig) {
1173
1174
  * - disables cross_application_tracer.enabled if set
1174
1175
  * - defaults logging to disabled
1175
1176
  * - verifies data specific to running DT is defined either in config file of env vars
1177
+ *
1176
1178
  * @param {*} inputConfig configuration passed to the Config constructor
1177
1179
  */
1178
1180
  Config.prototype._enforceServerless = function _enforceServerless(inputConfig) {
@@ -1282,7 +1284,7 @@ Config.prototype._canonicalize = function _canonicalize() {
1282
1284
  }
1283
1285
 
1284
1286
  const expectedCodes = this.error_collector && this.error_collector.expected_status_codes
1285
- if (statusCodes) {
1287
+ if (expectedCodes) {
1286
1288
  this.error_collector.expected_status_codes = _parseCodes(expectedCodes)
1287
1289
  }
1288
1290
 
@@ -1410,7 +1412,6 @@ Config.prototype._applyHighSecurity = function _applyHighSecurity() {
1410
1412
  *
1411
1413
  * @param {Agent} agent
1412
1414
  * @param {object} policies
1413
- *
1414
1415
  * @returns {CollectorResponse} The result of the processing, with the known
1415
1416
  * policies as the response payload.
1416
1417
  */
@@ -1540,7 +1541,7 @@ function redactValue(value) {
1540
1541
  * Get a JSONifiable object containing all settings we want to report to the
1541
1542
  * collector and store in the environment_values table.
1542
1543
  *
1543
- * @return Object containing simple key-value pairs of settings
1544
+ * @returns Object containing simple key-value pairs of settings
1544
1545
  */
1545
1546
  Config.prototype.publicSettings = function publicSettings() {
1546
1547
  let settings = Object.create(null)
@@ -1683,6 +1684,8 @@ function initialize(config) {
1683
1684
 
1684
1685
  /**
1685
1686
  * This helper function creates an empty configuration object
1687
+ *
1688
+ * @param config
1686
1689
  */
1687
1690
  function createNewConfigObject(config) {
1688
1691
  config = new Config(Object.create(null))
@@ -252,7 +252,11 @@ const INFINITE_TRACING = {
252
252
  }
253
253
 
254
254
  const FEATURES = {
255
- CERTIFICATES: SUPPORTABILITY.FEATURES + '/Certificates'
255
+ CERTIFICATES: SUPPORTABILITY.FEATURES + '/Certificates',
256
+ INSTRUMENTATION: {
257
+ ON_RESOLVED: SUPPORTABILITY.FEATURES + '/Instrumentation/OnResolved',
258
+ ON_REQUIRE: SUPPORTABILITY.FEATURES + '/Instrumentation/OnRequire'
259
+ }
256
260
  }
257
261
 
258
262
  module.exports = {
package/lib/shim/shim.js CHANGED
@@ -1307,7 +1307,7 @@ function applySegment(func, segment, full, context, args, inContextCB) {
1307
1307
  }
1308
1308
 
1309
1309
  if (typeof inContextCB === 'function') {
1310
- inContextCB()
1310
+ inContextCB(segment)
1311
1311
  }
1312
1312
 
1313
1313
  try {
@@ -29,10 +29,11 @@ const FRAMEWORK_NAMES = {
29
29
  CONNECT: 'Connect',
30
30
  DIRECTOR: 'Director',
31
31
  EXPRESS: 'Expressjs',
32
+ FASTIFY: 'Fastify',
32
33
  HAPI: 'Hapi',
33
34
  KOA: 'Koa',
34
- RESTIFY: 'Restify',
35
- FASTIFY: 'Fastify'
35
+ NEXT: 'Nextjs',
36
+ RESTIFY: 'Restify'
36
37
  }
37
38
 
38
39
  const MIDDLEWARE_TYPE_DETAILS = {
@@ -64,24 +65,19 @@ const TRANSACTION_INFO_KEY = '__NR_transactionInfo'
64
65
  * Constructs a shim associated with the given agent instance, specialized for
65
66
  * instrumenting web frameworks.
66
67
  *
67
- * @constructor
68
- * @extends TransactionShim
68
+ * @class
69
+ * @augments TransactionShim
69
70
  * @classdesc
70
71
  * A helper class for wrapping web framework modules.
71
- *
72
72
  * @param {Agent} agent
73
73
  * The agent this shim will use.
74
- *
75
74
  * @param {string} moduleName
76
75
  * The name of the module being instrumented.
77
- *
78
76
  * @param {string} resolvedName
79
77
  * The full path to the loaded module.
80
- *
81
78
  * @param {string} [frameworkId]
82
79
  * The name of the web framework being instrumented. If available, use one of
83
80
  * the values from {@link WebFrameworkShim.FRAMEWORK_NAMES}.
84
- *
85
81
  * @see TransactionShim
86
82
  * @see WebFrameworkShim.FRAMEWORK_NAMES
87
83
  */
@@ -130,123 +126,93 @@ WebFrameworkShim.prototype.captureUrlParams = captureUrlParams
130
126
 
131
127
  /**
132
128
  * @callback RouteParserFunction
133
- *
134
129
  * @summary
135
130
  * Called whenever new middleware are mounted using the instrumented framework,
136
131
  * this method should pull out a representation of the mounted path.
137
- *
138
132
  * @param {WebFrameworkShim} shim
139
133
  * The shim in use for this instrumentation.
140
- *
141
- * @param {function} fn
134
+ * @param {Function} fn
142
135
  * The function which received this route string/RegExp.
143
- *
144
136
  * @param {string} fnName
145
137
  * The name of the function to which this route was given.
146
- *
147
138
  * @param {string|RegExp} route
148
139
  * The route that was given to the function.
149
- *
150
- * @return {string|RegExp} The mount point from the given route.
140
+ * @returns {string|RegExp} The mount point from the given route.
151
141
  */
152
142
 
153
143
  /**
154
144
  * @callback RouteRequestFunction
155
- *
156
145
  * @summary
157
146
  * Extracts the request object from the arguments to the middleware function.
158
- *
159
147
  * @param {WebFrameworkShim} shim - The shim used for instrumentation.
160
- * @param {function} fn - The middleware function.
148
+ * @param {Function} fn - The middleware function.
161
149
  * @param {string} fnName - The name of the middleware function.
162
150
  * @param {Array} args - The arguments to the middleware function.
163
- *
164
- * @return {Object} The request object.
151
+ * @returns {object} The request object.
165
152
  */
166
153
 
167
154
  /**
168
155
  * @callback RouteNextFunction
169
- *
170
156
  * @summary
171
157
  * Used to wrap functions that users can call to continue to the next middleware.
172
- *
173
158
  * @param {WebFrameworkShim} shim - The shim used for instrumentation.
174
- * @param {function} fn - The middleware function.
159
+ * @param {Function} fn - The middleware function.
175
160
  * @param {string} fnName - The name of the middleware function.
176
161
  * @param {Array} args - The arguments to the middleware function.
177
162
  * @param {NextWrapperFunction} wrap - A function to wrap an individual next function.
178
- *
179
- * @return {Object} The request object.
163
+ * @returns {object} The request object.
180
164
  */
181
165
 
182
166
  /**
183
167
  * @callback RouteParameterFunction
184
- *
185
168
  * @summary
186
169
  * Extracts the route parameters from the arguments to the middleware function.
187
- *
188
170
  * @param {WebFrameworkShim} shim - The shim used for instrumentation.
189
- * @param {function} fn - The middleware function.
171
+ * @param {Function} fn - The middleware function.
190
172
  * @param {string} fnName - The name of the middleware function.
191
173
  * @param {Array} args - The arguments to the middleware function.
192
- *
193
- * @return {Object} A map of route parameter names to values.
174
+ * @returns {object} A map of route parameter names to values.
194
175
  */
195
176
 
196
177
  /**
197
178
  * @callback MiddlewareWrapperFunction
198
- *
199
179
  * @summary
200
180
  * Called for each middleware passed to a mounting method. Should perform the
201
181
  * wrapping of the middleware.
202
- *
203
182
  * @param {WebFrameworkShim} shim
204
183
  * The shim used for instrumentation.
205
- *
206
- * @param {function} middleware
184
+ * @param {Function} middleware
207
185
  * The middleware function to wrap.
208
- *
209
186
  * @param {string} fnName
210
187
  * The name of the middleware function.
211
- *
212
188
  * @param {string} [route=null]
213
189
  * The route the middleware is mounted on if one was found.
214
- *
215
190
  * @see WebFrameworkShim#recordMiddleware
216
191
  * @see WebFrameworkShim#recordParamware
217
192
  */
218
193
 
219
194
  /**
220
195
  * @interface MiddlewareSpec
221
- *
222
196
  * @description
223
197
  * Describes the interface for middleware functions with this instrumentation.
224
- *
225
198
  * @property {number|RouteRequestFunction} [req=shim.FIRST]
226
199
  * Indicates which argument to the middleware is the request object. It can also be
227
200
  * a function to extract the request object from the middleware arguments.
228
- *
229
201
  * @property {number} [res=shim.SECOND]
230
202
  * Indicates which argument to the middleware is the response object.
231
- *
232
203
  * @property {number|RouteNextFunction} [next=shim.THIRD]
233
204
  * Indicates which argument to the middleware function is the callback. When it is
234
205
  * a function, it will be called with the arguments of the middleware and a function
235
206
  * for wrapping calls that represent continuation from the current middleware.
236
- *
237
207
  * @property {string} [name]
238
208
  * The name to use for this middleware. Defaults to `middleware.name`.
239
- *
240
209
  * @property {RouteParameterFunction} [params]
241
210
  * A function to extract the route parameters from the middleware arguments.
242
211
  * Defaults to using `req.params`.
243
- *
244
212
  * @property {string} [type='MIDDLEWARE']
245
- *
246
- * @property {string|function} [route=null]
213
+ * @property {string | Function} [route=null]
247
214
  * Route/path used for naming segments and transaction name candidates. If a function,
248
215
  * will be invoked just before segment creation with middleware invocation.
249
- *
250
216
  * @property {boolean} [appendPath=true]
251
217
  * Indicates that the path associated with the middleware should be appended
252
218
  * and popped from the stack of name candidates.
@@ -254,31 +220,25 @@ WebFrameworkShim.prototype.captureUrlParams = captureUrlParams
254
220
 
255
221
  /**
256
222
  * @interface MiddlewareMounterSpec
257
- *
258
223
  * @description
259
224
  * Describes the arguments provided to mounting methods (e.g. `app.post()`).
260
- *
261
225
  * @property {number|string} [route=null]
262
226
  * Tells which argument may be the mounting path for the other arguments. If
263
227
  * the indicated argument is a function it is assumed the route was not provided
264
228
  * and the indicated argument is a middleware function. If a string is provided
265
229
  * it will be used as the mounting path.
266
- *
267
230
  * @property {MiddlewareWrapperFunction} [wrapper]
268
231
  * A function to call for each middleware function passed to the mounter.
269
232
  */
270
233
 
271
234
  /**
272
235
  * @interface RenderSpec
273
- * @extends RecorderSpec
274
- *
236
+ * @augments RecorderSpec
275
237
  * @description
276
238
  * Describes the interface for render methods.
277
- *
278
239
  * @property {number} [view=shim.FIRST]
279
240
  * Identifies which argument is the name of the view being rendered. Defaults
280
241
  * to {@link Shim#ARG_INDEXES shim.FIRST}.
281
- *
282
242
  * @see SegmentSpec
283
243
  * @see RecorderSpec
284
244
  */
@@ -292,7 +252,6 @@ WebFrameworkShim.prototype.captureUrlParams = captureUrlParams
292
252
  * - `setRouteParser(parser)`
293
253
  *
294
254
  * @memberof WebFrameworkShim.prototype
295
- *
296
255
  * @param {RouteParserFunction} parser - The parser function to use.
297
256
  */
298
257
  function setRouteParser(parser) {
@@ -310,10 +269,8 @@ function setRouteParser(parser) {
310
269
  * This should be the first thing the instrumentation does.
311
270
  *
312
271
  * @memberof WebFrameworkShim.prototype
313
- *
314
272
  * @param {WebFrameworkShim.FRAMEWORK_NAMES|string} framework
315
273
  * The name of the framework.
316
- *
317
274
  * @see WebFrameworkShim.FRAMEWORK_NAMES
318
275
  */
319
276
  function setFramework(framework) {
@@ -332,7 +289,6 @@ function setFramework(framework) {
332
289
  * Sets the URI path to be used for naming the transaction currently in scope.
333
290
  *
334
291
  * @memberof WebFrameworkShim.prototype
335
- *
336
292
  * @param {string} uri - The URI path to use for the transaction.
337
293
  */
338
294
  function setTransactionUri(uri) {
@@ -351,18 +307,14 @@ function setTransactionUri(uri) {
351
307
  * - `recordRender(func [, spec])`
352
308
  *
353
309
  * @memberof WebFrameworkShim.prototype
354
- *
355
- * @param {Object|Function} nodule
310
+ * @param {object | Function} nodule
356
311
  * The source for the properties to wrap, or a single function to wrap.
357
- *
358
312
  * @param {string|Array.<string>} [properties]
359
313
  * One or more properties to wrap. If omitted, the `nodule` parameter is
360
314
  * assumed to be the function to wrap.
361
- *
362
315
  * @param {RenderSpec} [spec]
363
316
  * The spec for wrapping the render method.
364
- *
365
- * @return {Object|Function} The first parameter to this function, after
317
+ * @returns {object | Function} The first parameter to this function, after
366
318
  * wrapping it or its properties.
367
319
  */
368
320
  function recordRender(nodule, properties, spec) {
@@ -407,20 +359,15 @@ function recordRender(nodule, properties, spec) {
407
359
  * - `wrapMiddlewareMounter(func [, spec])`
408
360
  *
409
361
  * @memberof WebFrameworkShim.prototype
410
- *
411
- * @param {Object|Function} nodule
362
+ * @param {object | Function} nodule
412
363
  * The source for the properties to wrap, or a single function to wrap.
413
- *
414
364
  * @param {string|Array.<string>} [properties]
415
365
  * One or more properties to wrap. If omitted, the `nodule` parameter is
416
366
  * assumed to be the function to wrap.
417
- *
418
367
  * @param {MiddlewareMounterSpec} [spec]
419
368
  * Spec describing the parameters for this middleware mount point.
420
- *
421
- * @return {Object|Function} The first parameter to this function, after
369
+ * @returns {object | Function} The first parameter to this function, after
422
370
  * wrapping it or its properties.
423
- *
424
371
  * @see WebFrameworkShim#recordMiddleware
425
372
  */
426
373
  function wrapMiddlewareMounter(nodule, properties, spec) {
@@ -470,6 +417,10 @@ function wrapMiddlewareMounter(nodule, properties, spec) {
470
417
  }
471
418
 
472
419
  _wrapMiddlewares.call(this, routeIdx, args)
420
+ /**
421
+ * @param _routeIdx
422
+ * @param middlewares
423
+ */
473
424
  function _wrapMiddlewares(_routeIdx, middlewares) {
474
425
  for (let i = 0; i < middlewares.length; ++i) {
475
426
  // If this argument is the route argument skip it.
@@ -512,20 +463,15 @@ function wrapMiddlewareMounter(nodule, properties, spec) {
512
463
  * - `recordMiddleware(func [, spec])`
513
464
  *
514
465
  * @memberof WebFrameworkShim.prototype
515
- *
516
- * @param {Object|Function} nodule
466
+ * @param {object | Function} nodule
517
467
  * The source for the properties to wrap, or a single function to wrap.
518
- *
519
468
  * @param {string|Array.<string>} [properties]
520
469
  * One or more properties to wrap. If omitted, the `nodule` parameter is
521
470
  * assumed to be the function to wrap.
522
- *
523
471
  * @param {MiddlewareSpec} [spec]
524
472
  * The spec for wrapping the middleware.
525
- *
526
- * @return {Object|Function} The first parameter to this function, after
473
+ * @returns {object | Function} The first parameter to this function, after
527
474
  * wrapping it or its properties.
528
- *
529
475
  * @see WebFrameworkShim#wrapMiddlewareMounter
530
476
  */
531
477
  function recordMiddleware(nodule, properties, spec) {
@@ -560,18 +506,14 @@ function recordMiddleware(nodule, properties, spec) {
560
506
  * processing as possible.
561
507
  *
562
508
  * @memberof WebFrameworkShim.prototype
563
- *
564
- * @param {Object|Function} nodule
509
+ * @param {object | Function} nodule
565
510
  * The source for the properties to wrap, or a single function to wrap.
566
- *
567
511
  * @param {string|Array.<string>} [properties]
568
512
  * One or more properties to wrap. If omitted, the `nodule` parameter is
569
513
  * assumed to be the function to wrap.
570
- *
571
514
  * @param {MiddlewareSpec} [spec]
572
515
  * The spec for wrapping the middleware.
573
- *
574
- * @return {Object|Function} The first parameter to this function, after
516
+ * @returns {object | Function} The first parameter to this function, after
575
517
  * wrapping it or its properties.
576
518
  */
577
519
  function recordParamware(nodule, properties, spec) {
@@ -610,10 +552,8 @@ function recordParamware(nodule, properties, spec) {
610
552
  * caught by the user.
611
553
  *
612
554
  * @memberof WebFrameworkShim.prototype
613
- *
614
555
  * @param {Request} req - The request which caused the error.
615
556
  * @param {*?} err - The error which has occurred.
616
- *
617
557
  * @see WebFrameworkShim#errorHandled
618
558
  * @see WebFrameworkShim#setErrorPredicate
619
559
  */
@@ -628,10 +568,8 @@ function noticeError(req, err) {
628
568
  * Indicates that the given error has been handled for this request.
629
569
  *
630
570
  * @memberof WebFrameworkShim.prototype
631
- *
632
571
  * @param {Request} req - The request which caused the error.
633
572
  * @param {*} err - The error which has been handled.
634
- *
635
573
  * @see WebFrameworkShim#noticeError
636
574
  * @see WebFrameworkShim#setErrorPredicate
637
575
  */
@@ -647,11 +585,9 @@ function errorHandled(req, err) {
647
585
  * an error.
648
586
  *
649
587
  * @memberof WebFrameworkShim.prototype
650
- *
651
588
  * @param {function(object): bool} pred
652
589
  * Function which should return true if the object passed to it is considered
653
590
  * an error.
654
- *
655
591
  * @see WebFrameworkShim#noticeError
656
592
  * @see WebFrameworkShim#errorHandled
657
593
  */
@@ -663,7 +599,6 @@ function setErrorPredicate(pred) {
663
599
  * Marks the current path as a potential responder.
664
600
  *
665
601
  * @memberof WebFrameworkShim.prototype
666
- *
667
602
  * @param {Request} req - The request which caused the error.
668
603
  */
669
604
  function savePossibleTransactionName(req) {
@@ -678,7 +613,6 @@ function savePossibleTransactionName(req) {
678
613
  * responded.
679
614
  *
680
615
  * @memberof WebFrameworkShim.prototype
681
- *
682
616
  * @param {function(args, object): bool} pred
683
617
  * Function which should return true if the object passed to it is considered
684
618
  * a response.
@@ -691,8 +625,7 @@ function setResponsePredicate(pred) {
691
625
  * Capture URL parameters from a request object as attributes of the current segment.
692
626
  *
693
627
  * @memberof WebFrameworkShim.prototype
694
- *
695
- * @param {Object} params
628
+ * @param {object} params
696
629
  * An object with key-value pairs.
697
630
  */
698
631
  function captureUrlParams(params) {
@@ -708,19 +641,14 @@ function captureUrlParams(params) {
708
641
  * Default route parser function if one is not provided.
709
642
  *
710
643
  * @private
711
- *
712
644
  * @param {WebFrameworkShim} shim
713
645
  * The shim in use for this instrumentation.
714
- *
715
- * @param {function} fn
646
+ * @param {Function} fn
716
647
  * The function which received this route string/RegExp.
717
- *
718
648
  * @param {string} fnName
719
649
  * The name of the function to which this route was given.
720
- *
721
650
  * @param {string|RegExp} route
722
651
  * The route that was given to the function.
723
- *
724
652
  * @see RouteParserFunction
725
653
  */
726
654
  function _defaultRouteParser(shim, fn, fnName, route) {
@@ -737,8 +665,7 @@ function _defaultRouteParser(shim, fn, fnName, route) {
737
665
  * Default error predicate just returns true.
738
666
  *
739
667
  * @private
740
- *
741
- * @return {bool} True. Always.
668
+ * @returns {bool} True. Always.
742
669
  */
743
670
  function _defaultErrorPredicate() {
744
671
  return true
@@ -748,8 +675,7 @@ function _defaultErrorPredicate() {
748
675
  * Default response predicate just returns false.
749
676
  *
750
677
  * @private
751
- *
752
- * @return {bool} False. Always.
678
+ * @returns {bool} False. Always.
753
679
  */
754
680
  function _defaultResponsePredicate() {
755
681
  return false
@@ -759,19 +685,18 @@ function _defaultResponsePredicate() {
759
685
  * Wraps the given function in a middleware recorder function.
760
686
  *
761
687
  * @private
762
- *
763
688
  * @param {WebFrameworkShim} shim
764
689
  * The shim used for this instrumentation.
765
- *
766
- * @param {function} middleware
690
+ * @param {Function} middleware
767
691
  * The middleware function to record.
768
- *
769
692
  * @param {MiddlewareSpec} spec
770
693
  * The spec describing the middleware.
771
- *
772
- * @return {function} The middleware function wrapped in a recorder.
694
+ * @returns {Function} The middleware function wrapped in a recorder.
773
695
  */
774
696
  function _recordMiddleware(shim, middleware, spec) {
697
+ /**
698
+ *
699
+ */
775
700
  function getRoute() {
776
701
  let route = spec.route || '/'
777
702
 
@@ -797,6 +722,9 @@ function _recordMiddleware(shim, middleware, spec) {
797
722
  metricName = shim._metrics.MIDDLEWARE + metricName + name
798
723
  }
799
724
 
725
+ /**
726
+ * @param route
727
+ */
800
728
  function getSegmentName(route) {
801
729
  let segmentName = metricName
802
730
  if (typeDetails.path) {
@@ -817,6 +745,12 @@ function _recordMiddleware(shim, middleware, spec) {
817
745
  )
818
746
 
819
747
  // TODO: let's please break these out
748
+ /**
749
+ * @param shim
750
+ * @param fn
751
+ * @param fnName
752
+ * @param args
753
+ */
820
754
  function middlewareWithCallbackRecorder(shim, fn, fnName, args) {
821
755
  const route = getRoute()
822
756
 
@@ -909,6 +843,12 @@ function _recordMiddleware(shim, middleware, spec) {
909
843
  }
910
844
  }
911
845
 
846
+ /**
847
+ * @param shim
848
+ * @param fn
849
+ * @param fnName
850
+ * @param args
851
+ */
912
852
  function middlewareWithPromiseRecorder(shim, fn, fnName, args) {
913
853
  const route = getRoute()
914
854
 
@@ -1007,6 +947,10 @@ function _recordMiddleware(shim, middleware, spec) {
1007
947
  }
1008
948
  }
1009
949
 
950
+ /**
951
+ * @param shim
952
+ * @param req
953
+ */
1010
954
  function _makeGetReq(shim, req) {
1011
955
  return function getReqFromArgs(shim, fn, name, args) {
1012
956
  const reqIdx = shim.normalizeIndex(args.length, req)
@@ -1018,6 +962,10 @@ function _makeGetReq(shim, req) {
1018
962
  }
1019
963
  }
1020
964
 
965
+ /**
966
+ * @param nextDetails
967
+ * @param txInfo
968
+ */
1021
969
  function _makeNextBinder(nextDetails, txInfo) {
1022
970
  return function bindNext(shim, fn, _name, segment, args) {
1023
971
  if (!segment) {
@@ -1029,6 +977,11 @@ function _makeNextBinder(nextDetails, txInfo) {
1029
977
 
1030
978
  // Called from outside to wrap functions that could be called to continue
1031
979
  // to the next middleware
980
+ /**
981
+ * @param nodule
982
+ * @param property
983
+ * @param isFinal
984
+ */
1032
985
  function nextWrapper(nodule, property, isFinal) {
1033
986
  shim.wrap(nodule, property, function wrapper(shim, original) {
1034
987
  const parentSegment = segment || shim.getSegment()
@@ -1077,11 +1030,9 @@ function _makeNextBinder(nextDetails, txInfo) {
1077
1030
  * available.
1078
1031
  *
1079
1032
  * @private
1080
- *
1081
1033
  * @param {WebFrameworkShim} shim - The shim used for this instrumentation.
1082
1034
  * @param {http.IncomingMessage} req - The incoming request object.
1083
- *
1084
- * @return {object?} The transaction information if available, otherwise null.
1035
+ * @returns {object?} The transaction information if available, otherwise null.
1085
1036
  */
1086
1037
  function _getTransactionInfo(shim, req) {
1087
1038
  try {
@@ -1096,8 +1047,8 @@ function _getTransactionInfo(shim, req) {
1096
1047
  * Creates a recorder for middleware metrics.
1097
1048
  *
1098
1049
  * @private
1099
- *
1100
- *
1050
+ * @param shim
1051
+ * @param metricName
1101
1052
  * @param {string} path - The mounting path of the middleware.
1102
1053
  * @param {Segment} segment - The segment generated for this middleware.
1103
1054
  * @param {string} scope - The scope of the metric to record.
@@ -1119,13 +1070,10 @@ function _makeMiddlewareRecorder(shim, metricName) {
1119
1070
  * Adds the given error to the transaction information if it is actually an error.
1120
1071
  *
1121
1072
  * @private
1122
- *
1123
1073
  * @param {WebFrameworkShim} shim
1124
1074
  * The shim used for this web framework.
1125
- *
1126
1075
  * @param {TransactionInfo} txInfo
1127
1076
  * The transaction context information for the request.
1128
- *
1129
1077
  * @param {*} err
1130
1078
  * The error to notice.
1131
1079
  */
@@ -1138,14 +1086,11 @@ function _noticeError(shim, txInfo, err) {
1138
1086
  * Determines if the given object is an error according to the shim.
1139
1087
  *
1140
1088
  * @private
1141
- *
1142
1089
  * @param {WebFrameworkShim} shim
1143
1090
  * The shim used for this web framework.
1144
- *
1145
1091
  * @param {?*} err
1146
1092
  * The object to check for error-ness.
1147
- *
1148
- * @return {bool} True if the given object is an error according to the shim.
1093
+ * @returns {bool} True if the given object is an error according to the shim.
1149
1094
  */
1150
1095
  function _isError(shim, err) {
1151
1096
  return err && shim._errorPredicate(err)
@@ -1155,11 +1100,9 @@ function _isError(shim, err) {
1155
1100
  * Copy the keys expected from source to destination.
1156
1101
  *
1157
1102
  * @private
1158
- *
1159
- * @param {Object} destination
1103
+ * @param {object} destination
1160
1104
  * The spec object receiving the expected values
1161
- *
1162
- * @param {Object} source
1105
+ * @param {object} source
1163
1106
  * The spec object the values are coming from
1164
1107
  */
1165
1108
  function _copyExpectedSpecParameters(destination, source) {
package/lib/shimmer.js CHANGED
@@ -6,12 +6,15 @@
6
6
  'use strict'
7
7
 
8
8
  const path = require('path')
9
+ const semver = require('semver')
9
10
  const fs = require('./util/unwrapped-core').fs
10
11
  const logger = require('./logger').child({ component: 'shimmer' })
11
12
  const INSTRUMENTATIONS = require('./instrumentations')()
12
13
  const properties = require('./util/properties')
13
14
  const shims = require('./shim')
14
15
 
16
+ const NAMES = require('./metrics/names')
17
+
15
18
  const MODULE_TYPE = shims.constants.MODULE_TYPE
16
19
 
17
20
  const CORE_INSTRUMENTATION = {
@@ -286,9 +289,13 @@ const shimmer = (module.exports = {
286
289
  // This is triggered by the load call, so record the path that has been seen so
287
290
  // we can examine it after the load call has returned.
288
291
  const resolvedFilepath = resolve.apply(this, arguments)
289
- filepathMap[file] = resolvedFilepath
290
292
 
291
- _onResolveFileName(agent, file, resolvedFilepath)
293
+ // Only fire the first time we see a specific module resolved
294
+ if (filepathMap[file] !== resolvedFilepath) {
295
+ filepathMap[file] = resolvedFilepath
296
+
297
+ _onResolveFileName(agent, file, resolvedFilepath)
298
+ }
292
299
 
293
300
  return resolvedFilepath
294
301
  }
@@ -458,6 +465,14 @@ const shimmer = (module.exports = {
458
465
  instrumentation = moduleName
459
466
  }
460
467
  return instrumentation
468
+ },
469
+
470
+ instrumentPostLoad(agent, module, moduleName, resolvedName) {
471
+ const result = _postLoad(agent, module, moduleName, resolvedName)
472
+ // This is to not break the public API
473
+ // previously it would just call instrumentation
474
+ // and not check the result
475
+ return !!result.__NR_instrumented
461
476
  }
462
477
  })
463
478
 
@@ -502,6 +517,7 @@ function instrumentPostLoad(agent, nodule, moduleName, resolvedName) {
502
517
  const shim = shims.createShimFromType(instrumentation.type, agent, moduleName, resolvedName)
503
518
 
504
519
  applyDebugState(shim, nodule)
520
+ trackInstrumentationUsage(agent, shim, moduleName, NAMES.FEATURES.INSTRUMENTATION.ON_REQUIRE)
505
521
 
506
522
  try {
507
523
  if (instrumentation.onRequire(shim, nodule, moduleName) !== false) {
@@ -597,6 +613,8 @@ function _instrumentOnResolved(agent, moduleName, resolvedFilepath) {
597
613
 
598
614
  const shim = shims.createShimFromType(instrumentation.type, agent, moduleName, resolvedFilepath)
599
615
 
616
+ trackInstrumentationUsage(agent, shim, moduleName, NAMES.FEATURES.INSTRUMENTATION.ON_RESOLVED)
617
+
600
618
  try {
601
619
  instrumentation.onResolved(shim, moduleName, resolvedFilepath)
602
620
  } catch (instrumentationError) {
@@ -644,3 +662,45 @@ function hasValidRegisterOptions(opts) {
644
662
 
645
663
  return true
646
664
  }
665
+
666
+ /**
667
+ * Adds metrics to indicate instrumentation was used for a particular module and
668
+ * what major version the module was at, if possible.
669
+ *
670
+ * @param {*} agent The agent instance.
671
+ * @param {*} shim The instance of the shim used to instrument the module.
672
+ * @param {string} moduleName The name of the required module.
673
+ * @param {string} metricPrefix Support metric prefix to prepend to the metrics. Will indicate onRequire or onResolved
674
+ * from NAMES.FEATURES.INSTRUMENTATION.
675
+ */
676
+ function trackInstrumentationUsage(agent, shim, moduleName, metricPrefix) {
677
+ try {
678
+ const version = tryGetVersion(shim)
679
+ const instrumentationMetricName = `${metricPrefix}/${moduleName}`
680
+
681
+ agent.metrics.getOrCreateMetric(instrumentationMetricName).incrementCallCount()
682
+
683
+ if (version) {
684
+ const majorVersion = semver.major(version)
685
+ const versionMetricName = `${instrumentationMetricName}/Version/${majorVersion}`
686
+
687
+ agent.metrics.getOrCreateMetric(versionMetricName).incrementCallCount()
688
+ }
689
+ } catch (error) {
690
+ logger.debug('Unable to track instrumentation usage for: ', moduleName, error)
691
+ }
692
+ }
693
+
694
+ function tryGetVersion(shim) {
695
+ // Global module (i.e. domain) or finding root failed
696
+ if (shim._moduleRoot === '.') {
697
+ return
698
+ }
699
+
700
+ const packageInfo = shim.require('./package.json')
701
+ if (!packageInfo) {
702
+ return
703
+ }
704
+
705
+ return packageInfo.version
706
+ }
@@ -45,16 +45,6 @@ Tracer.prototype.wrapFunctionFirst = wrapFunctionFirst
45
45
  Tracer.prototype.wrapSyncFunction = wrapSyncFunction
46
46
  Tracer.prototype.wrapCallback = wrapCallback
47
47
 
48
- Object.defineProperty(Tracer.prototype, 'segment', {
49
- get: function segmentGetter() {
50
- return this._contextManager.getContext()
51
- },
52
- set: function segmentSetter(segment) {
53
- this._contextManager.setContext(segment)
54
- return segment
55
- }
56
- })
57
-
58
48
  function getTransaction() {
59
49
  const currentSegment = this._contextManager.getContext()
60
50
  if (currentSegment && currentSegment.transaction && currentSegment.transaction.isActive()) {
@@ -69,6 +59,7 @@ function getSegment() {
69
59
  return this._contextManager.getContext()
70
60
  }
71
61
 
62
+ // TODO: Remove/replace external uses to tracer.getSpanContext()
72
63
  function getSpanContext() {
73
64
  const currentSegment = this.getSegment()
74
65
  return currentSegment && currentSegment.getSpanContext()
@@ -9,6 +9,7 @@ const logger = require('../logger.js').child({ component: 'aws-info' })
9
9
  const common = require('./common')
10
10
  const NAMES = require('../metrics/names.js')
11
11
  let results = null
12
+ const INSTANCE_HOST = '169.254.169.254'
12
13
 
13
14
  module.exports = fetchAWSInfo
14
15
  module.exports.clearCache = function clearAWSCache() {
@@ -24,27 +25,45 @@ function fetchAWSInfo(agent, callback) {
24
25
  return setImmediate(callback, null, results)
25
26
  }
26
27
 
27
- const instanceHost = '169.254.169.254'
28
- const apiVersion = '2016-09-02'
29
- const endpoint = 'dynamic/instance-identity/document'
30
- const url = 'http://' + instanceHost + '/' + apiVersion + '/' + endpoint
31
- common.request(url, agent, function getMetadata(err, data) {
28
+ const authTokenOpts = {
29
+ headers: { 'X-aws-ec2-metadata-token-ttl-seconds': '21600' },
30
+ host: INSTANCE_HOST,
31
+ method: 'PUT',
32
+ path: '/latest/api/token',
33
+ timeout: 500
34
+ }
35
+ common.request(authTokenOpts, agent, function getAuthToken(err, authToken) {
32
36
  if (err) {
37
+ logger.debug('Failed to get AWS auth token.')
33
38
  return callback(err)
34
39
  }
35
40
 
36
- try {
37
- data = JSON.parse(data)
38
- } catch (e) {
39
- logger.debug(e, 'Failed to parse AWS metadata.')
40
- data = null
41
+ const metadataOpts = {
42
+ headers: { 'X-aws-ec2-metadata-token': authToken },
43
+ host: INSTANCE_HOST,
44
+ method: 'GET',
45
+ path: '/2016-09-02/dynamic/instance-identity/document',
46
+ timeout: 500
41
47
  }
42
48
 
43
- results = common.getKeys(data, ['availabilityZone', 'instanceId', 'instanceType'])
44
- if (results == null) {
45
- logger.debug('AWS metadata was invalid.')
46
- agent.metrics.getOrCreateMetric(NAMES.UTILIZATION.AWS_ERROR).incrementCallCount()
47
- }
48
- callback(null, results)
49
+ common.request(metadataOpts, agent, function getMetadata(metaErr, data) {
50
+ if (metaErr) {
51
+ return callback(metaErr)
52
+ }
53
+
54
+ try {
55
+ data = JSON.parse(data)
56
+ } catch (e) {
57
+ logger.debug(e, 'Failed to parse AWS metadata.')
58
+ data = null
59
+ }
60
+
61
+ results = common.getKeys(data, ['availabilityZone', 'instanceId', 'instanceType'])
62
+ if (results == null) {
63
+ logger.debug('AWS metadata was invalid.')
64
+ agent.metrics.getOrCreateMetric(NAMES.UTILIZATION.AWS_ERROR).incrementCallCount()
65
+ }
66
+ callback(null, results)
67
+ })
49
68
  })
50
69
  }
@@ -65,6 +65,12 @@ exports.request = function request(opts, agent, cb) {
65
65
 
66
66
  opts.timeout = opts.timeout || 1000
67
67
 
68
+ // This can make more that GET requests if you pass in an object
69
+ // Node.js just pass this method into ClientRequest which accepts
70
+ // any valid HTTP Method
71
+ // see: https://github.com/nodejs/node/blob/master/lib/http.js#L106
72
+ // Technically this wouldn't work for a PUT/POST with a body
73
+ // but works fine in all cases where this is being used.
68
74
  const req = http.get(opts, function awsRequest(res) {
69
75
  res.pipe(concat(respond))
70
76
  function respond(data) {
@@ -89,9 +95,7 @@ exports.request = function request(opts, agent, cb) {
89
95
  }
90
96
  })
91
97
 
92
- req.setTimeout(1000, function requestTimeout() {
93
- req.abort()
94
- })
98
+ req.on('timeout', abortRequest)
95
99
 
96
100
  req.on('error', function requestError(err) {
97
101
  if (err.code === 'ECONNRESET') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newrelic",
3
- "version": "8.6.0",
3
+ "version": "8.8.0",
4
4
  "author": "New Relic Node.js agent team <nodejs@newrelic.com>",
5
5
  "license": "Apache-2.0",
6
6
  "contributors": [
@@ -136,7 +136,7 @@
136
136
  "prepare-test": "npm run ca-gen && npm run ssl && npm run docker-env",
137
137
  "lint": "eslint ./*.js lib test bin examples",
138
138
  "lint:fix": "eslint --fix, ./*.js lib test bin examples",
139
- "public-docs": "npm ci && jsdoc -c ./jsdoc-conf.json --tutorials examples/shim api.js lib/shim/ lib/transaction/handle.js && cp examples/shim/*.png out/",
139
+ "public-docs": "jsdoc -c ./jsdoc-conf.json --tutorials examples/shim api.js lib/shim/ lib/transaction/handle.js && cp examples/shim/*.png out/",
140
140
  "publish-docs": "./bin/publish-docs.sh",
141
141
  "services": "./bin/docker-services.sh",
142
142
  "smoke": "npm run ssl && time tap test/smoke/**/**/*.tap.js --timeout=180 --no-coverage",
@@ -148,23 +148,24 @@
148
148
  "update-cross-agent-tests": "./bin/update-cats.sh",
149
149
  "versioned-tests": "./bin/run-versioned-tests.sh",
150
150
  "update-changelog-version": "node ./bin/update-changelog-version",
151
+ "checkout-external-versioned": "node ./test/versioned-external/checkout-external-tests.js",
151
152
  "versioned": "npm run versioned:npm7",
152
- "versioned:major": "npm run prepare-test && VERSIONED_MODE=--major NPM7=1 time ./bin/run-versioned-tests.sh",
153
- "versioned:npm6": "npm run prepare-test && time ./bin/run-versioned-tests.sh",
154
- "versioned:npm7": "npm run prepare-test && NPM7=1 time ./bin/run-versioned-tests.sh",
153
+ "versioned:major": "npm run checkout-external-versioned && npm run prepare-test && VERSIONED_MODE=--major NPM7=1 time ./bin/run-versioned-tests.sh",
154
+ "versioned:npm6": "npm run checkout-external-versioned && npm run prepare-test && time ./bin/run-versioned-tests.sh",
155
+ "versioned:npm7": "npm run checkout-external-versioned && npm run prepare-test && NPM7=1 time ./bin/run-versioned-tests.sh",
155
156
  "prepare": "husky install"
156
157
  },
157
158
  "bin": {
158
159
  "newrelic-naming-rules": "./bin/test-naming-rules.js"
159
160
  },
160
161
  "dependencies": {
161
- "@grpc/grpc-js": "^1.2.11",
162
- "@grpc/proto-loader": "^0.5.6",
163
- "@newrelic/aws-sdk": "^4.0.1",
164
- "@newrelic/koa": "^6.0.1",
165
- "@newrelic/superagent": "^5.0.1",
162
+ "@grpc/grpc-js": "^1.5.5",
163
+ "@grpc/proto-loader": "^0.6.9",
164
+ "@newrelic/aws-sdk": "^4.1.1",
165
+ "@newrelic/koa": "^6.1.0",
166
+ "@newrelic/superagent": "^5.1.0",
166
167
  "@tyriar/fibonacci-heap": "^2.0.7",
167
- "async": "^3.2.0",
168
+ "async": "^3.2.3",
168
169
  "concat-stream": "^2.0.0",
169
170
  "https-proxy-agent": "^5.0.0",
170
171
  "json-stringify-safe": "^5.0.0",
@@ -172,13 +173,13 @@
172
173
  "semver": "^5.3.0"
173
174
  },
174
175
  "optionalDependencies": {
175
- "@newrelic/native-metrics": "^7.0.1"
176
+ "@newrelic/native-metrics": "^7.1.1"
176
177
  },
177
178
  "devDependencies": {
178
179
  "@newrelic/eslint-config": "^0.0.3",
179
180
  "@newrelic/newrelic-oss-cli": "^0.1.2",
180
181
  "@newrelic/proxy": "^2.0.0",
181
- "@newrelic/test-utilities": "^6.1.1",
182
+ "@newrelic/test-utilities": "^6.3.0",
182
183
  "@octokit/rest": "^18.0.15",
183
184
  "@slack/bolt": "^3.7.0",
184
185
  "ajv": "^6.12.6",