newrelic 13.6.3 → 13.6.5
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 +24 -0
- package/lib/instrumentation/aws-sdk/v3/bedrock.js +5 -0
- package/lib/subscribers/amqplib/connect.js +5 -2
- package/lib/subscribers/base.js +4 -2
- package/lib/subscribers/express/base.js +26 -0
- package/lib/subscribers/express/param.js +4 -4
- package/lib/subscribers/express/route.js +4 -4
- package/lib/subscribers/express/use.js +4 -4
- package/lib/subscribers/message-consumer.js +20 -2
- package/lib/subscribers/middleware-wrapper.js +15 -2
- package/lib/subscribers/middleware.js +2 -2
- package/package.json +1 -1
package/NEWS.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
### v13.6.5 (2025-11-17)
|
|
2
|
+
|
|
3
|
+
#### Bug fixes
|
|
4
|
+
|
|
5
|
+
* Updated express instrumentation to ignore error when the `next` handler passes `route` or `router` ([#3513](https://github.com/newrelic/node-newrelic/pull/3513)) ([724b218](https://github.com/newrelic/node-newrelic/commit/724b218174bddcf2ecf8cffc317bbfad1f0012eb))
|
|
6
|
+
* Updated MessageConsumerSubscriber to wait for consumer callback to end when it is a promise ([#3510](https://github.com/newrelic/node-newrelic/pull/3510)) ([45667a0](https://github.com/newrelic/node-newrelic/commit/45667a0ce2aaaf57a5e7a8acc8f0feea31e6152f))
|
|
7
|
+
|
|
8
|
+
#### Documentation
|
|
9
|
+
|
|
10
|
+
* Updated compatibility report ([#3498](https://github.com/newrelic/node-newrelic/pull/3498)) ([ef41b38](https://github.com/newrelic/node-newrelic/commit/ef41b3851b2096035d5b7b655d5243a9aeb699c8))
|
|
11
|
+
|
|
12
|
+
#### Tests
|
|
13
|
+
|
|
14
|
+
* Updated aws sdk v3 s3 test to no longer test DeleteBucketCommand ([#3512](https://github.com/newrelic/node-newrelic/pull/3512)) ([df27448](https://github.com/newrelic/node-newrelic/commit/df274484e0e657fd9c38452e500450878fc24ee4))
|
|
15
|
+
|
|
16
|
+
### v13.6.4 (2025-11-13)
|
|
17
|
+
|
|
18
|
+
#### Bug fixes
|
|
19
|
+
|
|
20
|
+
* Updated `MessageConsumerSubscriber` to end transaction created for a given message consumption ([#3503](https://github.com/newrelic/node-newrelic/pull/3503)) ([ba30818](https://github.com/newrelic/node-newrelic/commit/ba308184e5cb4f916aec53963cce0caa9149efbe))
|
|
21
|
+
* Updated `MessageProducerSubscriber` to properly set the sampled flag on `traceparent` ([#3505](https://github.com/newrelic/node-newrelic/pull/3505)) ([0b1a9a8](https://github.com/newrelic/node-newrelic/commit/0b1a9a80b81e0f4388d421f17176eab386d04cbc))
|
|
22
|
+
* Updated the bedrock middleware to be registered with a `high` priority to ensure payload is properly deserialized ([#3500](https://github.com/newrelic/node-newrelic/pull/3500)) ([63e531b](https://github.com/newrelic/node-newrelic/commit/63e531bf50d600d92556b3785725dd38145f3491))
|
|
23
|
+
|
|
1
24
|
### v13.6.3 (2025-11-11)
|
|
2
25
|
|
|
3
26
|
#### Bug fixes
|
|
@@ -8040,3 +8063,4 @@ Special thanks to Ryan Copley (@RyanCopley) for the contribution.
|
|
|
8040
8063
|
|
|
8041
8064
|
|
|
8042
8065
|
|
|
8066
|
+
|
|
@@ -392,6 +392,11 @@ module.exports.bedrockMiddlewareConfig = {
|
|
|
392
392
|
config: {
|
|
393
393
|
name: 'NewRelicBedrockMiddleware',
|
|
394
394
|
step: 'deserialize',
|
|
395
|
+
// force high priority to ensure we wrap before any other
|
|
396
|
+
// middleware and then our `after` hook will be the result of
|
|
397
|
+
// any other middleware registered on the deserialize step
|
|
398
|
+
// See: https://github.com/aws/aws-sdk-js-v3/issues/7490
|
|
399
|
+
priority: 'high',
|
|
395
400
|
override: true
|
|
396
401
|
}
|
|
397
402
|
}
|
|
@@ -9,8 +9,11 @@ const isString = require('#agentlib/util/is-string.js')
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* This subscriber is two-fold:
|
|
12
|
-
* 1.
|
|
13
|
-
*
|
|
12
|
+
* 1. Capture the connection arguments and assign to symbol on connection to be
|
|
13
|
+
* used for all other amqplib subscribers.
|
|
14
|
+
* 2. Create a segment for the connect. Note this will attempt to create a segment
|
|
15
|
+
* but the base subscriber will decide if it is created or not, otherwise it'll
|
|
16
|
+
* return the current context.
|
|
14
17
|
*/
|
|
15
18
|
class ConnectSubscriber extends Subscriber {
|
|
16
19
|
constructor({ agent, logger }) {
|
package/lib/subscribers/base.js
CHANGED
|
@@ -114,7 +114,9 @@ class Subscriber {
|
|
|
114
114
|
asyncStart.runStores(context, () => {
|
|
115
115
|
try {
|
|
116
116
|
if (callback) {
|
|
117
|
-
|
|
117
|
+
const cbResult = Reflect.apply(callback, this, arguments)
|
|
118
|
+
context.cbResult = cbResult
|
|
119
|
+
return cbResult
|
|
118
120
|
}
|
|
119
121
|
} finally {
|
|
120
122
|
asyncEnd.publish(context)
|
|
@@ -363,7 +365,7 @@ class Subscriber {
|
|
|
363
365
|
if (distributedTracingEnabled) {
|
|
364
366
|
// we have to pass in traceId, segment id, and hard code traceFlags to 1
|
|
365
367
|
// because we're inserting headers right before the original function is bound.
|
|
366
|
-
const traceFlags = tx.
|
|
368
|
+
const traceFlags = tx.isSampled() === true ? 1 : 0
|
|
367
369
|
tx.insertDistributedTraceHeaders(headers, null, { traceId: tx.traceId, spanId: ctx?.segment?.id, traceFlags })
|
|
368
370
|
} else {
|
|
369
371
|
cat.addCatHeaders(this.config, tx, headers, useMqNames)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const MiddlewareSubscriber = require('../middleware')
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Special error handler to ignore if the error passed to next handler
|
|
10
|
+
* is 'route' or 'router', which are used by Express internally to
|
|
11
|
+
* skip out of a route or router.
|
|
12
|
+
*
|
|
13
|
+
* @param {*} err - The error passed to the next handler
|
|
14
|
+
* @returns {boolean} - returns true if error exists and not equal to a string or `route` or `router`
|
|
15
|
+
*/
|
|
16
|
+
function errorHandler(err) {
|
|
17
|
+
return err && err !== 'route' && err !== 'router'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class ExpressSubscriber extends MiddlewareSubscriber {
|
|
21
|
+
constructor({ agent, logger, packageName = 'express', channelName }) {
|
|
22
|
+
super({ agent, logger, packageName, channelName, system: 'Expressjs', errorHandler })
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = ExpressSubscriber
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const ExpressSubscriber = require('./base')
|
|
9
9
|
|
|
10
|
-
class ExpressParamSubscriber extends
|
|
11
|
-
constructor({ agent, logger, packageName
|
|
12
|
-
super({ agent, logger, packageName, channelName: 'nr_param'
|
|
10
|
+
class ExpressParamSubscriber extends ExpressSubscriber {
|
|
11
|
+
constructor({ agent, logger, packageName }) {
|
|
12
|
+
super({ agent, logger, packageName, channelName: 'nr_param' })
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
handler(data) {
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
const MiddlewareSubscriber = require('../middleware')
|
|
9
8
|
const methods = ['all', 'delete', 'get', 'head', 'post', 'put', 'patch']
|
|
9
|
+
const ExpressSubscriber = require('./base')
|
|
10
10
|
|
|
11
|
-
class ExpressRouteSubscriber extends
|
|
12
|
-
constructor({ agent, logger, packageName
|
|
13
|
-
super({ agent, logger, packageName, channelName: 'nr_route'
|
|
11
|
+
class ExpressRouteSubscriber extends ExpressSubscriber {
|
|
12
|
+
constructor({ agent, logger, packageName }) {
|
|
13
|
+
super({ agent, logger, packageName, channelName: 'nr_route' })
|
|
14
14
|
this.events = ['end']
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const ExpressSubscriber = require('./base')
|
|
9
9
|
|
|
10
|
-
class ExpressUseSubscriber extends
|
|
11
|
-
constructor({ agent, logger, packageName
|
|
12
|
-
super({ agent, logger, packageName, channelName: 'nr_use'
|
|
10
|
+
class ExpressUseSubscriber extends ExpressSubscriber {
|
|
11
|
+
constructor({ agent, logger, packageName }) {
|
|
12
|
+
super({ agent, logger, packageName, channelName: 'nr_use' })
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
handler(data) {
|
|
@@ -65,6 +65,25 @@ class MessageConsumerSubscriber extends Subscriber {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Checks the result of the message handler.
|
|
70
|
+
* If it's a promise, waits for it to resolve before ending transaction.
|
|
71
|
+
* This ensures that the transaction stays active until the promise resolves.
|
|
72
|
+
* @param {object} data the data associated with the `asyncEnd` event
|
|
73
|
+
*/
|
|
74
|
+
asyncEnd(data) {
|
|
75
|
+
const ctx = this.agent.tracer.getContext()
|
|
76
|
+
const result = data.cbResult
|
|
77
|
+
if (typeof result?.then === 'function') {
|
|
78
|
+
const prom = Promise.resolve(result)
|
|
79
|
+
prom.finally(() => {
|
|
80
|
+
ctx?.transaction?.end()
|
|
81
|
+
})
|
|
82
|
+
} else {
|
|
83
|
+
ctx?.transaction?.end()
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
68
87
|
enable() {
|
|
69
88
|
super.enable()
|
|
70
89
|
this.channel.asyncStart.bindStore(this.store, (data) => {
|
|
@@ -83,9 +102,8 @@ class MessageConsumerSubscriber extends Subscriber {
|
|
|
83
102
|
/**
|
|
84
103
|
* Used to create a transaction for every consumption callback.
|
|
85
104
|
*
|
|
86
|
-
* @param {object} data event passed to asyncStart handler
|
|
87
105
|
*/
|
|
88
|
-
asyncStart(
|
|
106
|
+
asyncStart() {
|
|
89
107
|
const ctx = this.agent.tracer.getContext()
|
|
90
108
|
const tx = ctx?.transaction
|
|
91
109
|
tx.setPartialName(this.name)
|
|
@@ -19,6 +19,17 @@ function getFunctionName(handler) {
|
|
|
19
19
|
return handler.name === '' ? '<anonymous>' : handler.name
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Default error handler for determining if error should stored with transaction.
|
|
24
|
+
* Note: Based on previous shim instrumentation only Express, Restify, and Hapi have
|
|
25
|
+
* a different handler.
|
|
26
|
+
* @param {Error} err error passed to done handler
|
|
27
|
+
* @returns {boolean} returns true if error exists
|
|
28
|
+
*/
|
|
29
|
+
function defaultErrorHandler(err) {
|
|
30
|
+
return err
|
|
31
|
+
}
|
|
32
|
+
|
|
22
33
|
/**
|
|
23
34
|
* The baseline parameters available to the middleware wrapper
|
|
24
35
|
*
|
|
@@ -26,6 +37,7 @@ function getFunctionName(handler) {
|
|
|
26
37
|
* @property {object} agent A New Relic Node.js agent instance.
|
|
27
38
|
* @property {object} logger An agent logger instance.
|
|
28
39
|
* @property {string} system handling the instrumentation(i.e - Fastify, Expressjs, Hapi, etc)
|
|
40
|
+
* @property {Function} [errorHandler] optional function to determine if error should be recorded
|
|
29
41
|
*/
|
|
30
42
|
|
|
31
43
|
/**
|
|
@@ -36,13 +48,14 @@ function getFunctionName(handler) {
|
|
|
36
48
|
* @property {string} prefix formatted prefix to name segments/timeslice metrics
|
|
37
49
|
*/
|
|
38
50
|
class MiddlewareWrapper {
|
|
39
|
-
constructor({ agent, logger, system }) {
|
|
51
|
+
constructor({ agent, logger, system, errorHandler }) {
|
|
40
52
|
this.agent = agent
|
|
41
53
|
this.logger = logger
|
|
42
54
|
this.system = system
|
|
43
55
|
this.config = agent.config
|
|
44
56
|
this.prefix = `Nodejs/Middleware/${this.system}`
|
|
45
57
|
this.agent.environment.setFramework(system)
|
|
58
|
+
this.isError = errorHandler ?? defaultErrorHandler
|
|
46
59
|
}
|
|
47
60
|
|
|
48
61
|
/**
|
|
@@ -180,7 +193,7 @@ class MiddlewareWrapper {
|
|
|
180
193
|
if (isSync) {
|
|
181
194
|
function wrappedDone(...doneArgs) {
|
|
182
195
|
const [err] = doneArgs
|
|
183
|
-
if (err) {
|
|
196
|
+
if (self.isError(err)) {
|
|
184
197
|
self.storeError(txInfo, err)
|
|
185
198
|
// route has been completed, pop from path
|
|
186
199
|
// to allow other handlers to name it more accurately
|
|
@@ -8,12 +8,12 @@ const Subscriber = require('./base')
|
|
|
8
8
|
const MiddlewareWrapper = require('./middleware-wrapper')
|
|
9
9
|
|
|
10
10
|
class MiddlewareSubscriber extends Subscriber {
|
|
11
|
-
constructor({ agent, logger, packageName, channelName, system }) {
|
|
11
|
+
constructor({ agent, logger, packageName, channelName, system, errorHandler }) {
|
|
12
12
|
super({ agent, logger, packageName, channelName })
|
|
13
13
|
// this is because the handler simply wraps a function
|
|
14
14
|
// that is executed later when a request is made
|
|
15
15
|
this.requireActiveTx = false
|
|
16
|
-
this.wrapper = new MiddlewareWrapper({ agent, logger, system })
|
|
16
|
+
this.wrapper = new MiddlewareWrapper({ agent, logger, system, errorHandler })
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|