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 +17 -0
- package/THIRD_PARTY_NOTICES.md +4 -4
- package/lib/instrumentation/{mysql.js → mysql/mysql.js} +21 -14
- package/lib/instrumentation/mysql/nr-hooks.js +25 -0
- package/lib/instrumentations.js +1 -1
- package/lib/sampler.js +2 -21
- package/lib/serverless/aws-lambda.js +2 -3
- package/lib/shim/shim.js +2 -13
- package/package.json +3 -3
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.
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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) ([
|
|
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('
|
|
9
|
-
const properties = require('
|
|
8
|
+
const dbutils = require('../../db/utils')
|
|
9
|
+
const properties = require('../../util/properties')
|
|
10
10
|
|
|
11
|
-
|
|
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 (
|
|
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 (
|
|
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 &&
|
|
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
|
|
110
|
-
if (!
|
|
116
|
+
function wrapQueryable(shim, queryable, isPoolQuery) {
|
|
117
|
+
if (!queryable || !queryable.query || shim.isWrapped(queryable.query)) {
|
|
111
118
|
shim.logger.debug(
|
|
112
119
|
{
|
|
113
|
-
|
|
114
|
-
query: !!(
|
|
115
|
-
isWrapped: !!(
|
|
120
|
+
queryable: !!queryable,
|
|
121
|
+
query: !!(queryable && queryable.query),
|
|
122
|
+
isWrapped: !!(queryable && shim.isWrapped(queryable.query))
|
|
116
123
|
},
|
|
117
|
-
'Not
|
|
124
|
+
'Not wrapping queryable'
|
|
118
125
|
)
|
|
119
126
|
return false
|
|
120
127
|
}
|
|
121
128
|
|
|
122
|
-
const proto = Object.getPrototypeOf(
|
|
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 (
|
|
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
|
+
]
|
package/lib/instrumentations.js
CHANGED
|
@@ -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': {
|
|
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
|
|
199
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1750
|
-
|
|
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.
|
|
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": "^
|
|
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.
|
|
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",
|