newrelic 8.9.1 → 8.10.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,3 +1,20 @@
1
+ ### v8.10.0 (2022-04-18)
2
+
3
+ * Added instrumentation for `mysql2/promise`.
4
+ * This previously only existed in our standalone `@newrelic/mysql`, but now gives feature partiy between the two.
5
+
6
+ * Removed unused native CPU metric sampler. This logic was no longer getting touched if running Node.js > 6.1.0.
7
+
8
+ * Fixed promise interceptor from re-throwing errors.
9
+
10
+ * Added transaction naming documentation ported from a discussion forum post: https://discuss.newrelic.com/t/relic-solution-the-philosophy-of-naming-your-node-agent-transactions/.
11
+
12
+ * Added `promises.tap.js` to mysql2 versioned tests.
13
+
14
+ * Updated @newrelic/test-utilities to latest.
15
+ * Removed unused test file in restify versioned tests.
16
+ * Added `--strict` flag to versioned test runner to properly fail CI runs when test files are not included.
17
+
1
18
  ### v8.9.1 (2022-03-22)
2
19
 
3
20
  * Fixed `shim.wrapReturn` to call `Reflect.construct` in construct Proxy trap. Also including `newTarget` to work with inherited classes.
@@ -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.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):
715
+ This product includes source derived from [@newrelic/koa](https://github.com/newrelic/node-newrelic-koa) ([v6.1.1](https://github.com/newrelic/node-newrelic-koa/tree/v6.1.1)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-newrelic-koa/blob/v6.1.1/LICENSE):
716
716
 
717
717
  ```
718
718
  Apache License
@@ -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.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):
1773
+ This product includes source derived from [@newrelic/test-utilities](https://github.com/newrelic/node-test-utilities) ([v6.5.2](https://github.com/newrelic/node-test-utilities/tree/v6.5.2)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-test-utilities/blob/v6.5.2/LICENSE):
1774
1774
 
1775
1775
  ```
1776
1776
  Apache License
@@ -2456,7 +2456,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
2456
2456
 
2457
2457
  ### glob
2458
2458
 
2459
- This product includes source derived from [glob](https://github.com/isaacs/node-glob) ([v7.1.7](https://github.com/isaacs/node-glob/tree/v7.1.7)), distributed under the [ISC License](https://github.com/isaacs/node-glob/blob/v7.1.7/LICENSE):
2459
+ This product includes source derived from [glob](https://github.com/isaacs/node-glob) ([v7.2.0](https://github.com/isaacs/node-glob/tree/v7.2.0)), distributed under the [ISC License](https://github.com/isaacs/node-glob/blob/v7.2.0/LICENSE):
2460
2460
 
2461
2461
  ```
2462
2462
  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.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):
3380
+ This product includes source derived from [@newrelic/native-metrics](https://github.com/newrelic/node-native-metrics) ([v8.0.0](https://github.com/newrelic/node-native-metrics/tree/v8.0.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-native-metrics/blob/v8.0.0/LICENSE):
3381
3381
 
3382
3382
  ```
3383
3383
  Apache License
@@ -5,17 +5,17 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- const dbutils = require('../db/utils')
9
- const properties = require('../util/properties')
8
+ const dbutils = require('../../db/utils')
9
+ const properties = require('../../util/properties')
10
10
 
11
- module.exports = function initialize(agent, mysql, moduleName, shim) {
11
+ exports.callbackInitialize = function callbackInitialize(shim, mysql) {
12
12
  shim.setDatastore(shim.MYSQL)
13
13
  shim.__wrappedPoolConnection = false
14
14
 
15
15
  shim.wrapReturn(mysql, 'createConnection', wrapCreateConnection)
16
16
  function wrapCreateConnection(shim, fn, fnName, connection) {
17
17
  shim.logger.debug('Wrapping Connection#query')
18
- if (wrapQueriable(shim, connection, false)) {
18
+ if (wrapQueryable(shim, connection, false)) {
19
19
  const connProto = Object.getPrototypeOf(connection)
20
20
  shim.setInternalProperty(connProto, '__NR_storeDatabase', true)
21
21
  shim.unwrap(mysql, 'createConnection')
@@ -25,7 +25,7 @@ module.exports = function initialize(agent, mysql, moduleName, shim) {
25
25
  shim.wrapReturn(mysql, 'createPool', wrapCreatePool)
26
26
  function wrapCreatePool(shim, fn, fnName, pool) {
27
27
  shim.logger.debug('Wrapping Pool#query and Pool#getConnection')
28
- if (wrapQueriable(shim, pool, true) && wrapGetConnection(shim, pool)) {
28
+ if (wrapQueryable(shim, pool, true) && wrapGetConnection(shim, pool)) {
29
29
  shim.unwrap(mysql, 'createPool')
30
30
  }
31
31
  }
@@ -48,6 +48,13 @@ module.exports = function initialize(agent, mysql, moduleName, shim) {
48
48
  }
49
49
  }
50
50
 
51
+ exports.promiseInitialize = function promiseInitialize(shim) {
52
+ const callbackAPI = shim.require('./index')
53
+ if (callbackAPI && !shim.isWrapped(callbackAPI.createConnection)) {
54
+ exports.callbackInitialize(shim, callbackAPI)
55
+ }
56
+ }
57
+
51
58
  function wrapGetConnection(shim, connectable) {
52
59
  if (!connectable || !connectable.getConnection || shim.isWrapped(connectable.getConnection)) {
53
60
  shim.logger.trace(
@@ -91,7 +98,7 @@ function wrapGetConnectionCallback(shim, cb) {
91
98
  return function wrappedGetConnectionCallback(err, conn) {
92
99
  try {
93
100
  shim.logger.debug('Wrapping PoolConnection#query')
94
- if (!err && wrapQueriable(shim, conn, false)) {
101
+ if (!err && wrapQueryable(shim, conn, false)) {
95
102
  // Leave getConnection wrapped in order to maintain TX state, but we can
96
103
  // simplify the wrapping of its callback in future calls.
97
104
  shim.__wrappedPoolConnection = true
@@ -106,20 +113,20 @@ function wrapGetConnectionCallback(shim, cb) {
106
113
  }
107
114
  }
108
115
 
109
- function wrapQueriable(shim, queriable, isPoolQuery) {
110
- if (!queriable || !queriable.query || shim.isWrapped(queriable.query)) {
116
+ function wrapQueryable(shim, queryable, isPoolQuery) {
117
+ if (!queryable || !queryable.query || shim.isWrapped(queryable.query)) {
111
118
  shim.logger.debug(
112
119
  {
113
- queriable: !!queriable,
114
- query: !!(queriable && queriable.query),
115
- isWrapped: !!(queriable && shim.isWrapped(queriable.query))
120
+ queryable: !!queryable,
121
+ query: !!(queryable && queryable.query),
122
+ isWrapped: !!(queryable && shim.isWrapped(queryable.query))
116
123
  },
117
- 'Not wrappying queriable'
124
+ 'Not wrapping queryable'
118
125
  )
119
126
  return false
120
127
  }
121
128
 
122
- const proto = Object.getPrototypeOf(queriable)
129
+ const proto = Object.getPrototypeOf(queryable)
123
130
 
124
131
  let describe
125
132
  if (isPoolQuery) {
@@ -131,7 +138,7 @@ function wrapQueriable(shim, queriable, isPoolQuery) {
131
138
 
132
139
  shim.recordQuery(proto, 'query', describe)
133
140
 
134
- if (queriable.execute) {
141
+ if (queryable.execute) {
135
142
  shim.recordQuery(proto, 'execute', describe)
136
143
  }
137
144
 
@@ -0,0 +1,25 @@
1
+ /*
2
+ * Copyright 2022 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ 'use strict'
7
+ const instrumentation = require('./mysql')
8
+
9
+ /**
10
+ * We only need to register the instrumentation once for both mysql and mysql2
11
+ * because there is some 🪄 in shimmer
12
+ * See: https://github.com/newrelic/node-newrelic/blob/main/lib/shimmer.js#L459
13
+ */
14
+ module.exports = [
15
+ {
16
+ type: 'datastore',
17
+ moduleName: 'mysql',
18
+ onRequire: instrumentation.callbackInitialize
19
+ },
20
+ {
21
+ type: 'datastore',
22
+ moduleName: 'mysql2/promise',
23
+ onRequire: instrumentation.promiseInitialize
24
+ }
25
+ ]
@@ -25,7 +25,7 @@ module.exports = function instrumentations() {
25
25
  'koa': { module: '@newrelic/koa' },
26
26
  'memcached': { type: MODULE_TYPE.DATASTORE },
27
27
  'mongodb': { type: MODULE_TYPE.DATASTORE },
28
- 'mysql': { type: MODULE_TYPE.DATASTORE },
28
+ 'mysql': { module: './instrumentation/mysql' },
29
29
  'pg': { type: MODULE_TYPE.DATASTORE },
30
30
  'q': { type: null },
31
31
  'redis': { type: MODULE_TYPE.DATASTORE },
package/lib/sampler.js CHANGED
@@ -109,17 +109,6 @@ function sampleCpu(agent) {
109
109
  }
110
110
  }
111
111
 
112
- function sampleCpuNative(agent, nativeMetrics) {
113
- const recordCPU = generateCPUMetricRecorder(agent)
114
- nativeMetrics.on('usage', function collectResourceUsage(usage) {
115
- recordCPU(usage.diff.ru_utime / MILLIS, usage.diff.ru_stime / MILLIS)
116
- })
117
-
118
- return function cpuSampler() {
119
- // NOOP?
120
- }
121
- }
122
-
123
112
  function sampleLoop(agent, nativeMetrics) {
124
113
  return function loopSampler() {
125
114
  // Convert from microseconds to seconds
@@ -195,16 +184,8 @@ module.exports = {
195
184
  }
196
185
  }
197
186
 
198
- // Add CPU sampling using the built-in data if available, otherwise pulling
199
- // from the native module.
200
- if (process.cpuUsage) {
201
- // introduced in 6.1.0
202
- samplers.push(new Sampler(sampleCpu(agent), SAMPLE_INTERVAL))
203
- } else if (this.nativeMetrics && this.nativeMetrics.usageEnabled) {
204
- samplers.push(new Sampler(sampleCpuNative(agent, this.nativeMetrics), SAMPLE_INTERVAL))
205
- } else {
206
- logger.debug('Not adding CPU metric sampler.')
207
- }
187
+ // Add CPU sampling using the built-in data (introduced in 6.1.0)
188
+ samplers.push(new Sampler(sampleCpu(agent), SAMPLE_INTERVAL))
208
189
 
209
190
  this.state = 'running'
210
191
  },
@@ -199,20 +199,19 @@ class AwsLambda {
199
199
  // we need to store the error in uncaughtException
200
200
  // otherwise the transaction will end before they are captured
201
201
  function lambdaInterceptPromise(prom, resultProcessor, cb) {
202
- return prom.then(
202
+ prom.then(
203
203
  function onThen(arg) {
204
204
  if (resultProcessor) {
205
205
  resultProcessor(arg)
206
206
  }
207
207
  cb()
208
- return arg
209
208
  },
210
209
  function onCatch(err) {
211
210
  uncaughtException = err
212
211
  cb()
213
- throw err // This is not our error, just rethrowing the promise rejection.
214
212
  }
215
213
  )
214
+ return prom
216
215
  }
217
216
 
218
217
  function wrapCallbackAndCaptureError(transaction, txnEnder, cb, processResult) {
package/lib/shim/shim.js CHANGED
@@ -1746,19 +1746,8 @@ function shimRequire(filePath) {
1746
1746
  * @returns {Promise} A new promise to replace the original one.
1747
1747
  */
1748
1748
  function interceptPromise(prom, cb) {
1749
- if (this.isFunction(prom.finally)) {
1750
- return prom.finally(cb)
1751
- }
1752
- return prom.then(
1753
- function onThen(arg) {
1754
- cb()
1755
- return arg
1756
- },
1757
- function onCatch(err) {
1758
- cb()
1759
- throw err // This is not our error, just rethrowing the promise rejection.
1760
- }
1761
- )
1749
+ prom.then(cb, cb)
1750
+ return prom
1762
1751
  }
1763
1752
 
1764
1753
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newrelic",
3
- "version": "8.9.1",
3
+ "version": "8.10.0",
4
4
  "author": "New Relic Node.js agent team <nodejs@newrelic.com>",
5
5
  "license": "Apache-2.0",
6
6
  "contributors": [
@@ -173,13 +173,13 @@
173
173
  "semver": "^5.3.0"
174
174
  },
175
175
  "optionalDependencies": {
176
- "@newrelic/native-metrics": "^7.1.1"
176
+ "@newrelic/native-metrics": "^8.0.0"
177
177
  },
178
178
  "devDependencies": {
179
179
  "@newrelic/eslint-config": "^0.0.3",
180
180
  "@newrelic/newrelic-oss-cli": "^0.1.2",
181
181
  "@newrelic/proxy": "^2.0.0",
182
- "@newrelic/test-utilities": "^6.3.0",
182
+ "@newrelic/test-utilities": "^6.5.2",
183
183
  "@octokit/rest": "^18.0.15",
184
184
  "@slack/bolt": "^3.7.0",
185
185
  "ajv": "^6.12.6",