newrelic 12.1.0 → 12.2.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,44 @@
1
+ ### v12.2.0 (2024-08-19)
2
+
3
+ #### Features
4
+
5
+ * Added instrumentation support for Express 5 beta ([#2476](https://github.com/newrelic/node-newrelic/pull/2476)) ([06a4c2f](https://github.com/newrelic/node-newrelic/commit/06a4c2f9d62f7313fd246b4eed7f9f04f8b6345b))
6
+ * This will be experimental until `express@5.0.0` is generally available
7
+
8
+ #### Bug fixes
9
+
10
+ * Updated `koa` instrumentation to properly get the matched route name and to handle changes in `@koa/router@13.0.0` ([#2486](https://github.com/newrelic/node-newrelic/pull/2486)) ([0c2ee2f](https://github.com/newrelic/node-newrelic/commit/0c2ee2fd1698972de35a0ad2685e626a074125ed))
11
+
12
+ #### Documentation
13
+
14
+ * Removed reference to `@newrelic/next` in README ([#2479](https://github.com/newrelic/node-newrelic/pull/2479)) ([8740539](https://github.com/newrelic/node-newrelic/commit/8740539c4004e421e5f26d0c92216bcffb93c9cc))
15
+ * Updated compatibility report ([#2487](https://github.com/newrelic/node-newrelic/pull/2487)) ([c0a5e64](https://github.com/newrelic/node-newrelic/commit/c0a5e646773c365897a908daf034881703dbd1df))
16
+
17
+ #### Miscellaneous chores
18
+
19
+ * Reverted to upstream `require-in-the-middle` ([#2473](https://github.com/newrelic/node-newrelic/pull/2473)) ([9bbc41c](https://github.com/newrelic/node-newrelic/commit/9bbc41c5be479af56d5aa0c87291d2fec607e9e4))
20
+ * Updated aggregators unit tests to node:test ([#2481](https://github.com/newrelic/node-newrelic/pull/2481)) ([fd2d76f](https://github.com/newrelic/node-newrelic/commit/fd2d76fb2f6e8debc165700f932d57a02c3d3956))
21
+
22
+ ### v12.1.1 (2024-08-15)
23
+
24
+ #### Bug fixes
25
+
26
+ * Updated `amqplib` instrumentation to properly parse host/port from connect ([#2461](https://github.com/newrelic/node-newrelic/pull/2461)) ([91636a8](https://github.com/newrelic/node-newrelic/commit/91636a8e9702ba4ad1bf9b3941432ea65a3920fe))
27
+ * Updated `redis` instrumentation to parse host/port when a url is not provided ([#2463](https://github.com/newrelic/node-newrelic/pull/2463)) ([2b67623](https://github.com/newrelic/node-newrelic/commit/2b67623afef5fb132105c7f5b1d72e23b6d56dc1))
28
+ * Updated the `kafkajs` node metrics to remove `/Named` from the name ([#2458](https://github.com/newrelic/node-newrelic/pull/2458)) ([37ce113](https://github.com/newrelic/node-newrelic/commit/37ce1137a91c2efa85541cf6ec252a759e5f48ea))
29
+
30
+ #### Code refactoring
31
+
32
+ * Updated pino instrumentation to separate the wrapping of asJson into its own function ([#2464](https://github.com/newrelic/node-newrelic/pull/2464)) ([81fdde1](https://github.com/newrelic/node-newrelic/commit/81fdde1e35b5643ff141db1309ca58d7f6176cd5))
33
+
34
+ #### Documentation
35
+
36
+ * Updated compatibility report ([#2460](https://github.com/newrelic/node-newrelic/pull/2460)) ([a4570e9](https://github.com/newrelic/node-newrelic/commit/a4570e93298d10f4464570b75867634b95a61e89))
37
+
38
+ #### Miscellaneous chores
39
+
40
+ * Removed limit on superagent versioned testing ([#2456](https://github.com/newrelic/node-newrelic/pull/2456)) ([b4b6a6b](https://github.com/newrelic/node-newrelic/commit/b4b6a6b2eca8bd47d17f8b265344b4596c8226b3))
41
+
1
42
  ### v12.1.0 (2024-08-12)
2
43
 
3
44
  #### Bug fixes
package/README.md CHANGED
@@ -152,7 +152,6 @@ For more information on getting started, [check the Node.js docs](https://docs.n
152
152
  There are modules that can be installed and configured to accompany the Node.js agent:
153
153
 
154
154
  * [@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.
155
- * [@newrelic/next](https://github.com/newrelic/newrelic-node-nextjs): Provides instrumentation for the [Next.js](https://github.com/vercel/next.js/) npm package.
156
155
 
157
156
  There are modules included within the Node.js agent to add more instrumentation for 3rd party modules:
158
157
 
@@ -26,6 +26,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
26
26
  * [json-stringify-safe](#json-stringify-safe)
27
27
  * [module-details-from-path](#module-details-from-path)
28
28
  * [readable-stream](#readable-stream)
29
+ * [require-in-the-middle](#require-in-the-middle)
29
30
  * [semver](#semver)
30
31
  * [winston-transport](#winston-transport)
31
32
 
@@ -541,7 +542,7 @@ SOFTWARE.
541
542
 
542
543
  ### @newrelic/security-agent
543
544
 
544
- This product includes source derived from [@newrelic/security-agent](https://github.com/newrelic/csec-node-agent) ([v1.4.0](https://github.com/newrelic/csec-node-agent/tree/v1.4.0)), distributed under the [UNKNOWN License](https://github.com/newrelic/csec-node-agent/blob/v1.4.0/LICENSE):
545
+ This product includes source derived from [@newrelic/security-agent](https://github.com/newrelic/csec-node-agent) ([v1.5.0](https://github.com/newrelic/csec-node-agent/tree/v1.5.0)), distributed under the [UNKNOWN License](https://github.com/newrelic/csec-node-agent/blob/v1.5.0/LICENSE):
545
546
 
546
547
  ```
547
548
  ## New Relic Software License v1.0
@@ -676,7 +677,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
676
677
 
677
678
  ### import-in-the-middle
678
679
 
679
- This product includes source derived from [import-in-the-middle](https://github.com/nodejs/import-in-the-middle) ([v1.9.1](https://github.com/nodejs/import-in-the-middle/tree/v1.9.1)), distributed under the [Apache-2.0 License](https://github.com/nodejs/import-in-the-middle/blob/v1.9.1/LICENSE):
680
+ This product includes source derived from [import-in-the-middle](https://github.com/nodejs/import-in-the-middle) ([v1.11.0](https://github.com/nodejs/import-in-the-middle/tree/v1.11.0)), distributed under the [Apache-2.0 License](https://github.com/nodejs/import-in-the-middle/blob/v1.11.0/LICENSE):
680
681
 
681
682
  ```
682
683
  Apache License
@@ -1018,6 +1019,36 @@ IN THE SOFTWARE.
1018
1019
 
1019
1020
  ```
1020
1021
 
1022
+ ### require-in-the-middle
1023
+
1024
+ This product includes source derived from [require-in-the-middle](https://github.com/elastic/require-in-the-middle) ([v7.4.0](https://github.com/elastic/require-in-the-middle/tree/v7.4.0)), distributed under the [MIT License](https://github.com/elastic/require-in-the-middle/blob/v7.4.0/LICENSE):
1025
+
1026
+ ```
1027
+ The MIT License (MIT)
1028
+
1029
+ Copyright (c) 2016-2019, Thomas Watson Steen
1030
+ Copyright (c) 2019-2023, Elasticsearch B.V.
1031
+
1032
+ Permission is hereby granted, free of charge, to any person obtaining a copy
1033
+ of this software and associated documentation files (the "Software"), to deal
1034
+ in the Software without restriction, including without limitation the rights
1035
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1036
+ copies of the Software, and to permit persons to whom the Software is
1037
+ furnished to do so, subject to the following conditions:
1038
+
1039
+ The above copyright notice and this permission notice shall be included in all
1040
+ copies or substantial portions of the Software.
1041
+
1042
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1043
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1044
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1045
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1046
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1047
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1048
+ SOFTWARE.
1049
+
1050
+ ```
1051
+
1021
1052
  ### semver
1022
1053
 
1023
1054
  This product includes source derived from [semver](https://github.com/npm/node-semver) ([v7.6.3](https://github.com/npm/node-semver/tree/v7.6.3)), distributed under the [ISC License](https://github.com/npm/node-semver/blob/v7.6.3/LICENSE):
@@ -1076,7 +1107,7 @@ SOFTWARE.
1076
1107
 
1077
1108
  ### @aws-sdk/client-s3
1078
1109
 
1079
- This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.616.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.616.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.616.0/LICENSE):
1110
+ This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.631.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.631.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.631.0/LICENSE):
1080
1111
 
1081
1112
  ```
1082
1113
  Apache License
@@ -1285,7 +1316,7 @@ This product includes source derived from [@aws-sdk/client-s3](https://github.co
1285
1316
 
1286
1317
  ### @aws-sdk/s3-request-presigner
1287
1318
 
1288
- This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.616.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.616.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.616.0/LICENSE):
1319
+ This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.631.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.631.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.631.0/LICENSE):
1289
1320
 
1290
1321
  ```
1291
1322
  Apache License
@@ -2179,7 +2210,7 @@ THE SOFTWARE.
2179
2210
 
2180
2211
  ### @slack/bolt
2181
2212
 
2182
- This product includes source derived from [@slack/bolt](https://github.com/slackapi/bolt) ([v3.19.0](https://github.com/slackapi/bolt/tree/v3.19.0)), distributed under the [MIT License](https://github.com/slackapi/bolt/blob/v3.19.0/LICENSE):
2213
+ This product includes source derived from [@slack/bolt](https://github.com/slackapi/bolt) ([v3.21.0](https://github.com/slackapi/bolt/tree/v3.21.0)), distributed under the [MIT License](https://github.com/slackapi/bolt/blob/v3.21.0/LICENSE):
2183
2214
 
2184
2215
  ```
2185
2216
  The MIT License (MIT)
@@ -2683,7 +2714,7 @@ THE SOFTWARE.
2683
2714
 
2684
2715
  ### aws-sdk
2685
2716
 
2686
- This product includes source derived from [aws-sdk](https://github.com/aws/aws-sdk-js) ([v2.1659.0](https://github.com/aws/aws-sdk-js/tree/v2.1659.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js/blob/v2.1659.0/LICENSE.txt):
2717
+ This product includes source derived from [aws-sdk](https://github.com/aws/aws-sdk-js) ([v2.1675.0](https://github.com/aws/aws-sdk-js/tree/v2.1675.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js/blob/v2.1675.0/LICENSE.txt):
2687
2718
 
2688
2719
  ```
2689
2720
 
@@ -3111,7 +3142,7 @@ THE SOFTWARE.
3111
3142
 
3112
3143
  ### eslint-plugin-jsdoc
3113
3144
 
3114
- This product includes source derived from [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) ([v48.8.0](https://github.com/gajus/eslint-plugin-jsdoc/tree/v48.8.0)), distributed under the [BSD-3-Clause License](https://github.com/gajus/eslint-plugin-jsdoc/blob/v48.8.0/LICENSE):
3145
+ This product includes source derived from [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) ([v48.11.0](https://github.com/gajus/eslint-plugin-jsdoc/tree/v48.11.0)), distributed under the [BSD-3-Clause License](https://github.com/gajus/eslint-plugin-jsdoc/blob/v48.11.0/LICENSE):
3115
3146
 
3116
3147
  ```
3117
3148
  Copyright (c) 2018, Gajus Kuizinas (http://gajus.com/)
@@ -4189,7 +4220,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4189
4220
 
4190
4221
  ### @contrast/fn-inspect
4191
4222
 
4192
- This product includes source derived from [@contrast/fn-inspect](https://github.com/Contrast-Security-Inc/node-fn-inspect) ([v4.2.0](https://github.com/Contrast-Security-Inc/node-fn-inspect/tree/v4.2.0)), distributed under the [MIT License](https://github.com/Contrast-Security-Inc/node-fn-inspect/blob/v4.2.0/LICENSE):
4223
+ This product includes source derived from [@contrast/fn-inspect](https://github.com/Contrast-Security-Inc/node-fn-inspect) ([v4.3.0](https://github.com/Contrast-Security-Inc/node-fn-inspect/tree/v4.3.0)), distributed under the [MIT License](https://github.com/Contrast-Security-Inc/node-fn-inspect/blob/v4.3.0/LICENSE):
4193
4224
 
4194
4225
  ```
4195
4226
  Copyright 2022 Contrast Security, Inc
@@ -4215,7 +4246,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4215
4246
 
4216
4247
  ### @newrelic/native-metrics
4217
4248
 
4218
- This product includes source derived from [@newrelic/native-metrics](https://github.com/newrelic/node-native-metrics) ([v10.2.0](https://github.com/newrelic/node-native-metrics/tree/v10.2.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-native-metrics/blob/v10.2.0/LICENSE):
4249
+ This product includes source derived from [@newrelic/native-metrics](https://github.com/newrelic/node-native-metrics) ([v11.0.0](https://github.com/newrelic/node-native-metrics/tree/v11.0.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/node-native-metrics/blob/v11.0.0/LICENSE):
4219
4250
 
4220
4251
  ```
4221
4252
  Apache License
@@ -104,8 +104,9 @@ function getRedisParams(clientOpts) {
104
104
  }
105
105
 
106
106
  return new DatastoreParameters({
107
- host: clientOpts?.socket?.host || 'localhost',
108
- port_path_or_id: clientOpts?.socket?.path || clientOpts?.socket?.port || '6379',
107
+ host: clientOpts?.host || clientOpts?.socket?.host || 'localhost',
108
+ port_path_or_id:
109
+ clientOpts?.port || clientOpts?.socket?.path || clientOpts?.socket?.port || '6379',
109
110
  database_name: clientOpts?.database || 0
110
111
  })
111
112
  }
@@ -9,10 +9,10 @@ const {
9
9
  OperationSpec,
10
10
  params: { DatastoreParameters }
11
11
  } = require('../../shim/specs')
12
- const url = require('url')
13
12
  const wrapModel = require('./channel-model')
14
- const { setCallback } = require('./utils')
13
+ const { setCallback, parseConnectionArgs } = require('./utils')
15
14
  const wrapChannel = require('./channel')
15
+ const { amqpConnection } = require('../../symbols')
16
16
 
17
17
  module.exports.instrumentPromiseAPI = instrumentChannelAPI
18
18
  module.exports.instrumentCallbackAPI = instrumentCallbackAPI
@@ -73,31 +73,52 @@ function instrumentAMQP(shim, amqp, promiseMode) {
73
73
  /**
74
74
  *
75
75
  * Instruments the connect method
76
+ * We have to both wrap and record because
77
+ * we need the host/port for all subsequent calls on the model/channel
78
+ * but record only completes in an active transaction
76
79
  *
77
80
  * @param {Shim} shim instance of shim
78
81
  * @param {object} amqp amqplib object
79
82
  * @param {boolean} promiseMode is this promise based?
80
83
  */
81
84
  function wrapConnect(shim, amqp, promiseMode) {
82
- shim.record(amqp, 'connect', function recordConnect(shim, connect, name, args) {
83
- let [connArgs] = args
84
- const params = new DatastoreParameters()
85
+ shim.wrap(amqp, 'connect', function wrapConnect(shim, connect) {
86
+ return function wrappedConnect() {
87
+ const args = shim.argsToArray.apply(shim, arguments)
88
+ const [connArgs] = args
89
+ const params = parseConnectionArgs({ shim, connArgs })
90
+ const cb = args[args.length - 1]
91
+ if (!promiseMode) {
92
+ args[args.length - 1] = function wrappedCallback() {
93
+ const cbArgs = shim.argsToArray.apply(shim, arguments)
94
+ const [, c] = cbArgs
95
+ c.connection[amqpConnection] = params
96
+ return cb.apply(this, cbArgs)
97
+ }
98
+ }
85
99
 
86
- if (shim.isString(connArgs)) {
87
- connArgs = url.parse(connArgs)
88
- params.host = connArgs.hostname
89
- if (connArgs.port) {
90
- params.port = connArgs.port
100
+ const result = connect.apply(this, args)
101
+ if (promiseMode) {
102
+ return result.then((c) => {
103
+ c.connection[amqpConnection] = params
104
+ return c
105
+ })
91
106
  }
107
+ return result
92
108
  }
109
+ })
93
110
 
111
+ shim.record(amqp, 'connect', function recordConnect(shim, connect, name, args) {
112
+ const [connArgs] = args
113
+ const params = parseConnectionArgs({ shim, connArgs })
94
114
  return new OperationSpec({
95
115
  name: 'amqplib.connect',
96
116
  callback: setCallback(shim, promiseMode),
97
117
  promise: promiseMode,
98
- parameters: params,
99
- stream: null,
100
- recorder: null
118
+ parameters: new DatastoreParameters({
119
+ host: params.host,
120
+ port_path_or_id: params.port
121
+ })
101
122
  })
102
123
  })
103
124
  }
@@ -5,6 +5,7 @@
5
5
 
6
6
  'use strict'
7
7
  const { MessageSpec, MessageSubscribeSpec, RecorderSpec } = require('../../shim/specs')
8
+ const { amqpConnection } = require('../../symbols')
8
9
  const CHANNEL_METHODS = [
9
10
  'close',
10
11
  'open',
@@ -22,13 +23,7 @@ const CHANNEL_METHODS = [
22
23
  'prefetch',
23
24
  'recover'
24
25
  ]
25
- const {
26
- describeMessage,
27
- setCallback,
28
- parseConnect,
29
- getParametersFromMessage,
30
- TEMP_RE
31
- } = require('./utils')
26
+ const { describeMessage, setCallback, getParametersFromMessage, TEMP_RE } = require('./utils')
32
27
 
33
28
  /**
34
29
  *
@@ -89,7 +84,7 @@ function recordPurge({ shim, proto, promiseMode }) {
89
84
 
90
85
  function recordGet({ shim, proto, promiseMode }) {
91
86
  shim.recordConsume(proto, 'get', function wrapGet() {
92
- const { host, port } = parseConnect(this?.connection?.stream)
87
+ const { host, port } = this?.connection?.[amqpConnection] || {}
93
88
  return new MessageSpec({
94
89
  destinationName: shim.FIRST,
95
90
  callback: setCallback(shim, promiseMode),
@@ -115,7 +110,7 @@ function recordGet({ shim, proto, promiseMode }) {
115
110
 
116
111
  function recordConsume({ shim, proto, promiseMode }) {
117
112
  shim.recordSubscribedConsume(proto, 'consume', function consume() {
118
- const { host, port } = parseConnect(this?.connection?.stream)
113
+ const { host, port } = this?.connection?.[amqpConnection] || {}
119
114
  return new MessageSubscribeSpec({
120
115
  name: 'amqplib.Channel#consume',
121
116
  queue: shim.FIRST,
@@ -5,7 +5,8 @@
5
5
 
6
6
  'use strict'
7
7
  const { MessageSpec } = require('../../shim/specs')
8
- const { parseConnect, getParameters, TEMP_RE } = require('./utils')
8
+ const { amqpConnection } = require('../../symbols')
9
+ const { getParameters, TEMP_RE } = require('./utils')
9
10
 
10
11
  /**
11
12
  *
@@ -47,24 +48,26 @@ module.exports = function wrapChannel(shim) {
47
48
  }
48
49
  })
49
50
 
50
- shim.recordProduce(proto, 'sendMessage', function recordSendMessage(shim, fn, n, args) {
51
- const fields = args[0]
52
- if (!fields) {
53
- return null
54
- }
55
- const isDefault = fields.exchange === ''
56
- let exchange = 'Default'
57
- if (!isDefault) {
58
- exchange = TEMP_RE.test(fields.exchange) ? null : fields.exchange
59
- }
60
- const { host, port } = parseConnect(this?.connection?.stream)
51
+ shim.recordProduce(proto, 'sendMessage', recordSendMessage)
52
+ }
53
+
54
+ function recordSendMessage(shim, fn, n, args) {
55
+ const fields = args[0]
56
+ if (!fields) {
57
+ return null
58
+ }
59
+ const isDefault = fields.exchange === ''
60
+ let exchange = 'Default'
61
+ if (!isDefault) {
62
+ exchange = TEMP_RE.test(fields.exchange) ? null : fields.exchange
63
+ }
64
+ const { host, port } = this?.connection?.[amqpConnection] || {}
61
65
 
62
- return new MessageSpec({
63
- destinationName: exchange,
64
- destinationType: shim.EXCHANGE,
65
- routingKey: fields.routingKey,
66
- headers: fields.headers,
67
- parameters: getParameters({ parameters: Object.create(null), fields, host, port })
68
- })
66
+ return new MessageSpec({
67
+ destinationName: exchange,
68
+ destinationType: shim.EXCHANGE,
69
+ routingKey: fields.routingKey,
70
+ headers: fields.headers,
71
+ parameters: getParameters({ parameters: Object.create(null), fields, host, port })
69
72
  })
70
73
  }
@@ -8,7 +8,6 @@ const {
8
8
  MessageSpec,
9
9
  params: { QueueMessageParameters }
10
10
  } = require('../../shim/specs')
11
- const { amqpConnection } = require('../../symbols')
12
11
  const TEMP_RE = /^amq\./
13
12
 
14
13
  /**
@@ -100,25 +99,6 @@ function getParametersFromMessage({ message, host, port }) {
100
99
  return parameters
101
100
  }
102
101
 
103
- /**
104
- * Extracts the host/port from the amqp socket connection.
105
- * Stores on connection as symbol to only parse once.
106
- *
107
- * @param {Socket} socket amqp connection
108
- * @returns {object} {host, port } of connection
109
- */
110
- function parseConnect(socket) {
111
- if (socket[amqpConnection]) {
112
- return socket[amqpConnection]
113
- }
114
- const host = ['127.0.0.1', '::1', '[::1]'].includes(socket?.remoteAddress)
115
- ? 'localhost'
116
- : socket?.remoteAddress
117
- const port = socket?.remotePort
118
- socket[amqpConnection] = { host, port }
119
- return { host, port }
120
- }
121
-
122
102
  /**
123
103
  * Helper to set the appropriate value of the callback property
124
104
  * in the spec. If it's a promise set to null otherwise set it to `shim.LAST`
@@ -131,11 +111,33 @@ function setCallback(shim, promiseMode) {
131
111
  return promiseMode ? null : shim.LAST
132
112
  }
133
113
 
114
+ /**
115
+ * Parses the connection args to return host/port
116
+ *
117
+ * @param {string|object} connArgs connection arguments
118
+ * @returns {object} {host, port }
119
+ */
120
+ function parseConnectionArgs({ shim, connArgs }) {
121
+ const params = {}
122
+ if (shim.isString(connArgs)) {
123
+ connArgs = new URL(connArgs)
124
+ params.host = connArgs.hostname
125
+ if (connArgs.port) {
126
+ params.port = parseInt(connArgs.port, 10)
127
+ }
128
+ } else {
129
+ params.port = connArgs.port || (connArgs.protocol === 'amqp' ? 5672 : 5671)
130
+ params.host = connArgs.hostname
131
+ }
132
+
133
+ return params
134
+ }
135
+
134
136
  module.exports = {
135
137
  describeMessage,
136
138
  getParameters,
137
139
  getParametersFromMessage,
138
- parseConnect,
140
+ parseConnectionArgs,
139
141
  setCallback,
140
142
  TEMP_RE
141
143
  }
@@ -6,7 +6,6 @@
6
6
  'use strict'
7
7
 
8
8
  const { MiddlewareSpec, MiddlewareMounterSpec, RenderSpec } = require('../../lib/shim/specs')
9
- const { MIDDLEWARE_TYPE_NAMES } = require('../../lib/shim/webframework-shim/common')
10
9
 
11
10
  /**
12
11
  * Express middleware generates traces where middleware are considered siblings
@@ -25,18 +24,8 @@ module.exports = function initialize(agent, express, moduleName, shim) {
25
24
  return err !== 'route' && err !== 'router'
26
25
  })
27
26
 
28
- if (express.Router.use) {
29
- wrapExpress4(shim, express)
30
- } else {
31
- wrapExpress3(shim, express)
32
- }
33
- }
34
-
35
- function wrapExpress4(shim, express) {
36
- // Wrap `use` and `route` which are hung off `Router` directly, not on a
37
- // prototype.
38
27
  shim.wrapMiddlewareMounter(
39
- express.Router,
28
+ express.application,
40
29
  'use',
41
30
  new MiddlewareMounterSpec({
42
31
  route: shim.FIRST,
@@ -44,8 +33,13 @@ function wrapExpress4(shim, express) {
44
33
  })
45
34
  )
46
35
 
36
+ wrapExpressRouter(shim, express.Router.use ? express.Router : express.Router.prototype)
37
+ wrapResponse(shim, express.response)
38
+ }
39
+
40
+ function wrapExpressRouter(shim, router) {
47
41
  shim.wrapMiddlewareMounter(
48
- express.application,
42
+ router,
49
43
  'use',
50
44
  new MiddlewareMounterSpec({
51
45
  route: shim.FIRST,
@@ -53,7 +47,7 @@ function wrapExpress4(shim, express) {
53
47
  })
54
48
  )
55
49
 
56
- shim.wrap(express.Router, 'route', function wrapRoute(shim, fn) {
50
+ shim.wrap(router, 'route', function wrapRoute(shim, fn) {
57
51
  if (!shim.isFunction(fn)) {
58
52
  return fn
59
53
  }
@@ -89,7 +83,7 @@ function wrapExpress4(shim, express) {
89
83
  })
90
84
 
91
85
  shim.wrapMiddlewareMounter(
92
- express.Router,
86
+ router,
93
87
  'param',
94
88
  new MiddlewareMounterSpec({
95
89
  route: shim.FIRST,
@@ -105,56 +99,6 @@ function wrapExpress4(shim, express) {
105
99
  }
106
100
  })
107
101
  )
108
-
109
- wrapResponse(shim, express.response)
110
- }
111
-
112
- function wrapExpress3(shim, express) {
113
- // In Express 3 the app returned from `express()` is actually a `connect` app
114
- // which we have no access to before creation. We can not easily wrap the app
115
- // because there are a lot of methods dangling on it that act on the app itself.
116
- // Really we just care about apps being used as `request` event listeners on
117
- // `http.Server` instances so we'll wrap that instead.
118
-
119
- shim.wrapMiddlewareMounter(
120
- express.Router.prototype,
121
- 'param',
122
- new MiddlewareMounterSpec({
123
- route: shim.FIRST,
124
- wrapper: function wrapParamware(shim, middleware, fnName, route) {
125
- return shim.recordParamware(
126
- middleware,
127
- new MiddlewareSpec({
128
- name: route,
129
- req: shim.FIRST,
130
- next: shim.THIRD,
131
- type: MIDDLEWARE_TYPE_NAMES.PARAMWARE
132
- })
133
- )
134
- }
135
- })
136
- )
137
- shim.wrapMiddlewareMounter(
138
- express.Router.prototype,
139
- 'use',
140
- new MiddlewareMounterSpec({
141
- route: shim.FIRST,
142
- wrapper: wrapMiddleware
143
- })
144
- )
145
- shim.wrapMiddlewareMounter(
146
- express.application,
147
- 'use',
148
- new MiddlewareMounterSpec({
149
- route: shim.FIRST,
150
- wrapper: wrapMiddleware
151
- })
152
- )
153
-
154
- // NOTE: Do not wrap application route methods in Express 3, they all just
155
- // forward their arguments to the router.
156
- wrapRouteMethods(shim, express.Router.prototype, shim.FIRST)
157
- wrapResponse(shim, express.response)
158
102
  }
159
103
 
160
104
  function wrapRouteMethods(shim, route, path) {
@@ -11,7 +11,7 @@ function recordLinkingMetrics({ agent, brokers, topic, producer = true }) {
11
11
  const kind = producer === true ? 'Produce' : 'Consume'
12
12
  for (const broker of brokers) {
13
13
  agent.metrics
14
- .getOrCreateMetric(`MessageBroker/Kafka/Nodes/${broker}/${kind}/Named/${topic}`)
14
+ .getOrCreateMetric(`MessageBroker/Kafka/Nodes/${broker}/${kind}/${topic}`)
15
15
  .incrementCallCount()
16
16
  }
17
17
  }
@@ -115,10 +115,8 @@ function wrapMatchedRoute(shim, context) {
115
115
  Object.defineProperty(context, '_matchedRoute', {
116
116
  get: () => context[symbols.koaMatchedRoute],
117
117
  set: (val) => {
118
- const match = getLayerForTransactionName(context)
119
-
120
118
  // match should never be undefined given _matchedRoute was set
121
- if (match) {
119
+ if (val) {
122
120
  const currentSegment = shim.getActiveSegment()
123
121
 
124
122
  // Segment/Transaction may be null, see:
@@ -131,7 +129,7 @@ function wrapMatchedRoute(shim, context) {
131
129
  transaction.nameState.popPath()
132
130
  }
133
131
 
134
- transaction.nameState.appendPath(match.path)
132
+ transaction.nameState.appendPath(val)
135
133
  transaction.nameState.markPath()
136
134
  }
137
135
  }
@@ -169,22 +167,6 @@ function wrapResponseStatus(shim, context) {
169
167
  })
170
168
  }
171
169
 
172
- function getLayerForTransactionName(context) {
173
- // Context.matched might be null
174
- // See https://github.com/newrelic/node-newrelic-koa/pull/29
175
- if (!context.matched) {
176
- return null
177
- }
178
- for (let i = context.matched.length - 1; i >= 0; i--) {
179
- const layer = context.matched[i]
180
- if (layer.opts.end) {
181
- return layer
182
- }
183
- }
184
-
185
- return null
186
- }
187
-
188
170
  function getInheritedPropertyDescriptor(obj, property) {
189
171
  let proto = obj
190
172
  let descriptor = null
@@ -22,8 +22,16 @@ module.exports = [
22
22
  onRequire: cbManagerInstrumentation
23
23
  },
24
24
  {
25
+ // This block is for catching langchain internal imports
26
+ // of the callback manager. See:
27
+ // https://github.com/elastic/require-in-the-middle/pull/88#issuecomment-2124940546
25
28
  type: InstrumentationDescriptor.TYPE_GENERIC,
26
- moduleName: '@langchain/core/dist/runnables/base',
29
+ moduleName: '@langchain/core/dist/callbacks/manager.cjs',
30
+ onRequire: cbManagerInstrumentation
31
+ },
32
+ {
33
+ type: InstrumentationDescriptor.TYPE_GENERIC,
34
+ moduleName: '@langchain/core/runnables',
27
35
  onRequire: runnableInstrumentation
28
36
  },
29
37
  {
@@ -15,7 +15,6 @@ const {
15
15
  } = require('../../util/application-logging')
16
16
  const semver = require('semver')
17
17
 
18
- // eslint-disable-next-line sonarjs/cognitive-complexity
19
18
  module.exports = function instrument(shim, tools) {
20
19
  const pinoVersion = shim.pkgVersion
21
20
 
@@ -35,7 +34,20 @@ module.exports = function instrument(shim, tools) {
35
34
  const metrics = agent.metrics
36
35
  createModuleUsageMetric('pino', metrics)
37
36
 
37
+ wrapAsJson({ shim, tools })
38
+ }
39
+
40
+ /**
41
+ * Wraps `asJson` to properly decorate and forward logs
42
+ *
43
+ * @param {object} params to function
44
+ * @param {Shim} params.shim instance of shim
45
+ * @param {object} params.tools exported `pino/lib/tools`
46
+ */
47
+ function wrapAsJson({ shim, tools }) {
38
48
  const symbols = shim.require('./lib/symbols')
49
+ const { agent } = shim
50
+ const { config, metrics } = agent
39
51
 
40
52
  shim.wrap(tools, 'asJson', function wrapJson(shim, asJson) {
41
53
  /**
@@ -98,16 +110,14 @@ module.exports = function instrument(shim, tools) {
98
110
  * reformats error and assigns NR context data
99
111
  * to log line
100
112
  *
101
- * @param logLine.logLine
102
- * @param {object} logLine log line
103
- * @param {object} metadata NR context data
104
- * @param {string} chindings serialized string of all common log line data
105
- * @param logLine.args
106
- * @param logLine.agent
107
- * @param logLine.chindings
108
- * @param logLine.msg
109
- * @param logLine.level
110
- * @param logLine.logger
113
+ * @param {object} params to function
114
+ * @param {object} params.logLine log line
115
+ * @param {string} params.msg message of log line
116
+ * @param {object} params.agent instance of agent
117
+ * @param {string} params.chindings serialized string of all common log line data
118
+ * @param {string} params.level log level
119
+ * @param {object} params.logger instance of agent logger
120
+ * @returns {function} wrapped log formatter function
111
121
  */
112
122
  function reformatLogLine({ logLine, msg, agent, chindings = '', level, logger }) {
113
123
  const metadata = agent.getLinkingMetadata()
package/lib/shimmer.js CHANGED
@@ -11,7 +11,7 @@ const fs = require('./util/unwrapped-core').fs
11
11
  const logger = require('./logger').child({ component: 'shimmer' })
12
12
  const INSTRUMENTATIONS = require('./instrumentations')()
13
13
  const shims = require('./shim')
14
- const { Hook } = require('@newrelic/ritm')
14
+ const { Hook } = require('require-in-the-middle')
15
15
  const IitmHook = require('import-in-the-middle')
16
16
  const { nrEsmProxy } = require('./symbols')
17
17
  const isAbsolutePath = require('./util/is-absolute-path')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newrelic",
3
- "version": "12.1.0",
3
+ "version": "12.2.0",
4
4
  "author": "New Relic Node.js agent team <nodejs@newrelic.com>",
5
5
  "license": "Apache-2.0",
6
6
  "contributors": [
@@ -197,7 +197,6 @@
197
197
  "dependencies": {
198
198
  "@grpc/grpc-js": "^1.9.4",
199
199
  "@grpc/proto-loader": "^0.7.5",
200
- "@newrelic/ritm": "^7.2.0",
201
200
  "@newrelic/security-agent": "^1.3.0",
202
201
  "@tyriar/fibonacci-heap": "^2.0.7",
203
202
  "concat-stream": "^2.0.0",
@@ -207,6 +206,7 @@
207
206
  "json-stringify-safe": "^5.0.0",
208
207
  "module-details-from-path": "^1.0.3",
209
208
  "readable-stream": "^3.6.1",
209
+ "require-in-the-middle": "^7.4.0",
210
210
  "semver": "^7.5.2",
211
211
  "winston-transport": "^4.5.0"
212
212
  },