newrelic 11.23.0 → 11.23.2

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,45 @@
1
+ ### v11.23.2 (2024-07-22)
2
+
3
+ #### Features
4
+
5
+ * Added support for `fs.glob` in Node 22+ ([#2369](https://github.com/newrelic/node-newrelic/pull/2369)) ([1791a4e](https://github.com/newrelic/node-newrelic/commit/1791a4ef4a31e36757c47a9947ef8840fdd995c2))
6
+
7
+ #### Bug fixes
8
+
9
+ * Updated aws-sdk v3 instrumentation to load custom middleware last to properly get the external http span to add `aws.*` attributes ([#2382](https://github.com/newrelic/node-newrelic/pull/2382)) ([751801b](https://github.com/newrelic/node-newrelic/commit/751801be814343c9ddcee3dd7e83f87a1c6786d4))
10
+ * Updated cassandra-driver instrumentation to properly trace promise based executions ([#2351](https://github.com/newrelic/node-newrelic/pull/2351)) ([bab9a8b](https://github.com/newrelic/node-newrelic/commit/bab9a8bab4ab6af8efa70d8559bdcc7ca6f5df32))
11
+
12
+ #### Documentation
13
+
14
+ * Removed examples/api/ ([#2381](https://github.com/newrelic/node-newrelic/pull/2381)) ([fb964de](https://github.com/newrelic/node-newrelic/commit/fb964de863f8989161f9a780f9eddc6e3ec91138))
15
+ * Removed out of date `ROADMAP_Node.md` from root of project ([#2367](https://github.com/newrelic/node-newrelic/pull/2367)) ([4be870c](https://github.com/newrelic/node-newrelic/commit/4be870c758d9b931866ef3e6781d01bf176671a9))
16
+ * Updated compatibility report ([#2345](https://github.com/newrelic/node-newrelic/pull/2345)) ([f08adc3](https://github.com/newrelic/node-newrelic/commit/f08adc3a30bdf3e5d23bd00efeb3b16ac06cd3e5))
17
+
18
+ #### Miscellaneous chores
19
+
20
+ * Always upload status logs in compatibility report CI ([#2341](https://github.com/newrelic/node-newrelic/pull/2341)) ([b3f1ee3](https://github.com/newrelic/node-newrelic/commit/b3f1ee3fe40c38c7484661dfb2e599df4f31003e))
21
+
22
+ #### Tests
23
+
24
+ * Removed `server.start` in grpc tests as it is deprecated and no longer needed ([#2372](https://github.com/newrelic/node-newrelic/pull/2372)) ([d212b15](https://github.com/newrelic/node-newrelic/commit/d212b15c929ebca22881f3d41a8d7f99033847a8))
25
+ * Updated benchmark test results to output result files ([#2350](https://github.com/newrelic/node-newrelic/pull/2350)) ([1b51a68](https://github.com/newrelic/node-newrelic/commit/1b51a68200dae14b865a6db06d62655a25a62c2d))
26
+
27
+ #### Continuous integration
28
+
29
+ * Added benchmark test GitHub Action ([#2366](https://github.com/newrelic/node-newrelic/pull/2366)) ([afd3ab4](https://github.com/newrelic/node-newrelic/commit/afd3ab48611ec8409be1472ebbc63db24cff8e73))
30
+ * Increased the limit of installs from 2 to a bigger number for versioned tests ([#2346](https://github.com/newrelic/node-newrelic/pull/2346)) ([f85a385](https://github.com/newrelic/node-newrelic/commit/f85a38524f1d41e82b2c5085c41d79d1263b63c3))
31
+ * Updated `bin/create-docs-pr` to create an empty array if changelog.json is missing security ([#2348](https://github.com/newrelic/node-newrelic/pull/2348)) ([7d5368c](https://github.com/newrelic/node-newrelic/commit/7d5368ce873affbf2593bd6b1cc32259da852e1d))
32
+
33
+ ### v11.23.1 (2024-07-11)
34
+
35
+ #### Bug fixes
36
+
37
+ * Updated redis v4 instrumentation to work with transactions(multi/exec) ([#2343](https://github.com/newrelic/node-newrelic/pull/2343)) ([39eb842](https://github.com/newrelic/node-newrelic/commit/39eb8421b84f7fe298acf5c9c89de31ee0cc2604))
38
+
39
+ #### Documentation
40
+
41
+ * Updated compatibility report ([#2342](https://github.com/newrelic/node-newrelic/pull/2342)) ([5c9e3e6](https://github.com/newrelic/node-newrelic/commit/5c9e3e6bfa8a388c7dd071ecb0231b069f065645))
42
+
1
43
  ### v11.23.0 (2024-07-10)
2
44
 
3
45
  #### Features
@@ -7,63 +7,78 @@
7
7
 
8
8
  const {
9
9
  OperationSpec,
10
- params: { DatastoreParameters }
10
+ params: { DatastoreParameters },
11
+ ClassWrapSpec
11
12
  } = require('../../shim/specs')
12
- const CLIENT_COMMANDS = ['select', 'quit', 'SELECT', 'QUIT']
13
- const opts = Symbol('clientOptions')
13
+ const { redisClientOpts } = require('../../symbols')
14
14
 
15
15
  module.exports = function initialize(_agent, redis, _moduleName, shim) {
16
16
  shim.setDatastore(shim.REDIS)
17
- const COMMANDS = Object.keys(shim.require('dist/lib/client/commands.js').default)
18
- const CMDS_TO_INSTRUMENT = [...COMMANDS, ...CLIENT_COMMANDS]
19
- shim.wrap(redis, 'createClient', function wrapCreateClient(shim, original) {
20
- return function wrappedCreateClient() {
21
- const client = original.apply(this, arguments)
22
- client[opts] = getRedisParams(client.options)
23
- CMDS_TO_INSTRUMENT.forEach(instrumentClientCommand.bind(null, shim, client))
24
- if (client.options.legacyMode) {
25
- client.v4[opts] = getRedisParams(client.options)
26
- CMDS_TO_INSTRUMENT.forEach(instrumentClientCommand.bind(null, shim, client.v4))
17
+ const commandsQueue = shim.require('dist/lib/client/commands-queue.js')
18
+
19
+ shim.wrapClass(
20
+ commandsQueue,
21
+ 'default',
22
+ new ClassWrapSpec({
23
+ post: function postConstructor(shim) {
24
+ instrumentAddCommand({ shim, commandsQueue: this })
27
25
  }
26
+ })
27
+ )
28
+
29
+ shim.wrap(redis, 'createClient', function wrapCreateClient(_shim, createClient) {
30
+ return function wrappedCreateClient(options) {
31
+ // saving connection opts to shim
32
+ // since the RedisCommandsQueue gets constructed at createClient
33
+ // we can delete the symbol afterwards to ensure the appropriate
34
+ // connection options are for the given RedisCommandsQueue
35
+ shim[redisClientOpts] = getRedisParams(options)
36
+ const client = createClient.apply(this, arguments)
37
+ delete shim[redisClientOpts]
28
38
  return client
29
39
  }
30
40
  })
31
41
  }
32
42
 
33
43
  /**
34
- * Instruments a given command on the client by calling `shim.recordOperation`
44
+ * Instruments a given command when added to the command queue by calling `shim.recordOperation`
35
45
  *
36
- * @param {Shim} shim shim instance
37
- * @param {object} client redis client instance
38
- * @param {string} cmd command to instrument
46
+ * @param {object} params
47
+ * @param {Shim} params.shim shim instance
48
+ * @param {object} params.commandsQueue instance
39
49
  */
40
- function instrumentClientCommand(shim, client, cmd) {
50
+ function instrumentAddCommand({ shim, commandsQueue }) {
41
51
  const { agent } = shim
52
+ const clientOpts = shim[redisClientOpts]
42
53
 
43
- shim.recordOperation(client, cmd, function wrapCommand(_shim, _fn, _fnName, args) {
44
- const [key, value] = args
45
- const parameters = Object.assign({}, client[opts])
46
- // If selecting a database, subsequent commands
47
- // will be using said database, update the clientOptions
48
- // but not the current parameters(feature parity with v3)
49
- if (cmd.toLowerCase() === 'select') {
50
- client[opts].database_name = key
51
- }
52
- if (agent.config.attributes.enabled) {
53
- if (key) {
54
- parameters.key = JSON.stringify(key)
54
+ shim.recordOperation(
55
+ commandsQueue,
56
+ 'addCommand',
57
+ function wrapAddCommand(_shim, _fn, _fnName, args) {
58
+ const [cmd, key, value] = args[0]
59
+ const parameters = Object.assign({}, clientOpts)
60
+ // If selecting a database, subsequent commands
61
+ // will be using said database, update the clientOpts
62
+ // but not the current parameters(feature parity with v3)
63
+ if (cmd.toLowerCase() === 'select') {
64
+ clientOpts.database_name = key
55
65
  }
56
- if (value) {
57
- parameters.value = JSON.stringify(value)
66
+ if (agent.config.attributes.enabled) {
67
+ if (key) {
68
+ parameters.key = JSON.stringify(key)
69
+ }
70
+ if (value) {
71
+ parameters.value = JSON.stringify(value)
72
+ }
58
73
  }
59
- }
60
74
 
61
- return new OperationSpec({
62
- name: (cmd && cmd.toLowerCase()) || 'other',
63
- parameters,
64
- promise: true
65
- })
66
- })
75
+ return new OperationSpec({
76
+ name: (cmd && cmd.toLowerCase()) || 'other',
77
+ parameters,
78
+ promise: true
79
+ })
80
+ }
81
+ )
67
82
  }
68
83
 
69
84
  /**
@@ -73,6 +88,21 @@ function instrumentClientCommand(shim, client, cmd) {
73
88
  * @returns {object} params
74
89
  */
75
90
  function getRedisParams(clientOpts) {
91
+ // need to replicate logic done in RedisClient
92
+ // to parse the url to assign to socket.host/port
93
+ // see: https://github.com/redis/node-redis/blob/5576a0db492cda2cd88e09881bc330aa956dd0f5/packages/client/lib/client/index.ts#L160
94
+ if (clientOpts?.url) {
95
+ const parsedURL = new URL(clientOpts.url)
96
+ clientOpts.socket = { host: parsedURL.hostname }
97
+ if (parsedURL.port) {
98
+ clientOpts.socket.port = parsedURL.port
99
+ }
100
+
101
+ if (parsedURL.pathname) {
102
+ clientOpts.database = parsedURL.pathname.substring(1)
103
+ }
104
+ }
105
+
76
106
  return new DatastoreParameters({
77
107
  host: clientOpts?.socket?.host || 'localhost',
78
108
  port_path_or_id: clientOpts?.socket?.path || clientOpts?.socket?.port || '6379',
@@ -95,6 +95,7 @@ module.exports.middlewareConfig = [
95
95
  config: {
96
96
  name: 'NewRelicDeserialize',
97
97
  step: 'deserialize',
98
+ priority: 'low',
98
99
  override: true
99
100
  }
100
101
  }
@@ -29,7 +29,7 @@ module.exports = function initialize(_agent, cassandra, _moduleName, shim) {
29
29
  ClientProto,
30
30
  ['connect', 'shutdown'],
31
31
  function operationSpec(shim, _fn, name) {
32
- return new OperationSpec({ callback: shim.LAST, name })
32
+ return new OperationSpec({ callback: shim.LAST, name, promise: true })
33
33
  }
34
34
  )
35
35
 
@@ -39,7 +39,8 @@ module.exports = function initialize(_agent, cassandra, _moduleName, shim) {
39
39
  '_execute',
40
40
  new QuerySpec({
41
41
  query: shim.FIRST,
42
- callback: shim.LAST
42
+ callback: shim.LAST,
43
+ promise: true
43
44
  })
44
45
  )
45
46
 
@@ -64,7 +65,8 @@ module.exports = function initialize(_agent, cassandra, _moduleName, shim) {
64
65
  '_innerExecute',
65
66
  new QuerySpec({
66
67
  query: shim.FIRST,
67
- callback: shim.LAST
68
+ callback: shim.LAST,
69
+ promise: true
68
70
  })
69
71
  )
70
72
 
@@ -109,7 +111,8 @@ module.exports = function initialize(_agent, cassandra, _moduleName, shim) {
109
111
  'batch',
110
112
  new QuerySpec({
111
113
  query: findBatchQueryArg,
112
- callback: shim.LAST
114
+ callback: shim.LAST,
115
+ promise: true
113
116
  })
114
117
  )
115
118
  }
@@ -45,6 +45,11 @@ function initialize(agent, fs, moduleName, shim) {
45
45
  'ftruncate'
46
46
  ]
47
47
 
48
+ if (Object.hasOwnProperty.call(fs, 'glob') === true) {
49
+ // The `glob` method was added in Node 22.
50
+ methods.push('glob')
51
+ }
52
+
48
53
  const nonRecordedMethods = ['write', 'read']
49
54
 
50
55
  shim.record(fs, methods, recordFs)
package/lib/symbols.js CHANGED
@@ -27,6 +27,7 @@ module.exports = {
27
27
  langchainRunId: Symbol('runId'),
28
28
  prismaConnection: Symbol('prismaConnection'),
29
29
  prismaModelCall: Symbol('modelCall'),
30
+ redisClientOpts: Symbol('clientOptions'),
30
31
  segment: Symbol('segment'),
31
32
  shim: Symbol('shim'),
32
33
  storeDatabase: Symbol('storeDatabase'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newrelic",
3
- "version": "11.23.0",
3
+ "version": "11.23.2",
4
4
  "author": "New Relic Node.js agent team <nodejs@newrelic.com>",
5
5
  "license": "Apache-2.0",
6
6
  "contributors": [