newrelic 12.6.1 → 12.7.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,24 @@
1
+ ### v12.7.0 (2024-11-11)
2
+
3
+ #### Features
4
+
5
+ * Added `cloud.resource_id` attribute to dynamo spans ([#2701](https://github.com/newrelic/node-newrelic/pull/2701)) ([904f41b](https://github.com/newrelic/node-newrelic/commit/904f41b26637394a24aa13f31ff94b100ae6d090))
6
+ * Enhance Proxy Request Handling to Display Actual External URLs ([#2698](https://github.com/newrelic/node-newrelic/pull/2698)) ([3ef7bbe](https://github.com/newrelic/node-newrelic/commit/3ef7bbe595860234c021a02235e6fd0615da5f69))
7
+ * Thanks for the contribution @mstarzec386
8
+
9
+ #### Documentation
10
+
11
+ * Updated compatibility report ([#2712](https://github.com/newrelic/node-newrelic/pull/2712)) ([82f0e98](https://github.com/newrelic/node-newrelic/commit/82f0e9806c88d14cba2e0cdf47593e036107bd7d)) ([#2699](https://github.com/newrelic/node-newrelic/pull/2699)) ([4432c42](https://github.com/newrelic/node-newrelic/commit/4432c4215d68cc79333ee3828f1ecd55476c63d8))
12
+
13
+ #### Miscellaneous chores
14
+
15
+ * Added a benchmark script for our sql parser ([#2708](https://github.com/newrelic/node-newrelic/pull/2708)) ([9b6de68](https://github.com/newrelic/node-newrelic/commit/9b6de6852747230b87a9873faffba6e5b39669f3))
16
+ * Updated express-esm, generic-pool, grpc, & grpc-esm tests to node:test ([#2702](https://github.com/newrelic/node-newrelic/pull/2702)) ([a229bbf](https://github.com/newrelic/node-newrelic/commit/a229bbf0dd92c43fb2da077d8dce831b84c0c972))
17
+
18
+ #### Tests
19
+
20
+ * Migrated `mysql` and `mysql2` versioned tests to `node:test` ([#2711](https://github.com/newrelic/node-newrelic/pull/2711)) ([fc767e0](https://github.com/newrelic/node-newrelic/commit/fc767e08d8b546d14c53c07bc2cfe65f3fb55368))
21
+
1
22
  ### v12.6.1 (2024-11-07)
2
23
 
3
24
  #### Features
@@ -72,21 +72,66 @@ function dynamoMiddleware(shim, config, next, context) {
72
72
  }
73
73
  }
74
74
 
75
- const dynamoMiddlewareConfig = {
76
- middleware: dynamoMiddleware,
77
- init(shim) {
78
- shim.setDatastore(shim.DYNAMODB)
79
- return true
80
- },
81
- type: InstrumentationDescriptor.TYPE_DATASTORE,
82
- config: {
83
- name: 'NewRelicDynamoMiddleware',
84
- step: 'initialize',
85
- priority: 'high',
86
- override: true
75
+ /**
76
+ * Wraps the deserialize middleware step to add the
77
+ * cloud.resource_id segment attributes for the AWS command
78
+ *
79
+ * @param {Shim} shim
80
+ * @param {Object} config AWS command configuration
81
+ * @param {function} next next function in middleware chain
82
+ * @returns {function}
83
+ */
84
+ function resourceIdMiddlerware(shim, config, next) {
85
+ return async function wrappedResourceIdMiddlerware(args) {
86
+ let region
87
+ try {
88
+ region = await config.region()
89
+ const segment = shim.getSegment()
90
+
91
+ const accountId = shim.agent.config.cloud.aws.account_id
92
+
93
+ if (accountId) {
94
+ const attributes = segment.getAttributes()
95
+ segment.addAttribute(
96
+ 'cloud.resource_id',
97
+ `arn:aws:dynamodb:${region}:${accountId}:table/${attributes.collection}`
98
+ )
99
+ }
100
+ } catch (err) {
101
+ shim.logger.debug(err, 'Failed to add AWS cloud resource id to segment')
102
+ }
103
+
104
+ return next(args)
87
105
  }
88
106
  }
89
107
 
108
+ const dynamoMiddlewareConfig = [
109
+ {
110
+ middleware: dynamoMiddleware,
111
+ init(shim) {
112
+ shim.setDatastore(shim.DYNAMODB)
113
+ return true
114
+ },
115
+ type: InstrumentationDescriptor.TYPE_DATASTORE,
116
+ config: {
117
+ name: 'NewRelicDynamoMiddleware',
118
+ step: 'initialize',
119
+ priority: 'high',
120
+ override: true
121
+ }
122
+ },
123
+ {
124
+ middleware: resourceIdMiddlerware,
125
+ type: InstrumentationDescriptor.TYPE_GENERIC,
126
+ config: {
127
+ name: 'NewRelicCloudResource',
128
+ step: 'deserialize',
129
+ priority: 'low',
130
+ override: true
131
+ }
132
+ }
133
+ ]
134
+
90
135
  module.exports = {
91
136
  dynamoMiddlewareConfig
92
137
  }
@@ -17,8 +17,8 @@ const middlewareByClient = {
17
17
  BedrockRuntime: [...middlewareConfig, bedrockMiddlewareConfig],
18
18
  SNS: [...middlewareConfig, snsMiddlewareConfig],
19
19
  SQS: [...middlewareConfig, sqsMiddlewareConfig],
20
- DynamoDB: [...middlewareConfig, dynamoMiddlewareConfig],
21
- DynamoDBDocument: [...middlewareConfig, dynamoMiddlewareConfig]
20
+ DynamoDB: [...middlewareConfig, ...dynamoMiddlewareConfig],
21
+ DynamoDBDocument: [...middlewareConfig, ...dynamoMiddlewareConfig]
22
22
  }
23
23
 
24
24
  module.exports = function instrumentSmithyClient(shim, smithyClientExport) {
@@ -15,6 +15,7 @@ const copy = require('../../util/copy')
15
15
  const symbols = require('../../symbols')
16
16
  const http = require('http')
17
17
  const synthetics = require('../../synthetics')
18
+ const { URL } = require('node:url')
18
19
 
19
20
  const NAMES = require('../../metrics/names')
20
21
  const DEFAULT_HOST = 'localhost'
@@ -93,6 +94,27 @@ function extractHostPort(opts) {
93
94
  return { host, hostname, port }
94
95
  }
95
96
 
97
+ /**
98
+ * Extracts the host, hostname, and port from HTTP request options when using a proxy
99
+ *
100
+ * @param {object} opts HTTP request options
101
+ * @returns {object|null} { host, hostname, port } if proxy request is detected, or null otherwise.
102
+ */
103
+ function extractHostPortViaProxy(opts) {
104
+ const pathname = opts.pathname || opts.path
105
+
106
+ if (pathname && (pathname.startsWith('https://') || pathname.startsWith('http://'))) {
107
+ const url = new URL(pathname)
108
+ return {
109
+ host: url.host,
110
+ hostname: url.hostname,
111
+ port: url.port || url.protocol === 'https:' ? '443' : '80'
112
+ }
113
+ }
114
+
115
+ return null
116
+ }
117
+
96
118
  /**
97
119
  * Instruments an outbound HTTP request.
98
120
  *
@@ -103,7 +125,9 @@ function extractHostPort(opts) {
103
125
  */
104
126
  module.exports = function instrumentOutbound(agent, opts, makeRequest) {
105
127
  opts = parseOpts(opts)
106
- const { host, hostname, port } = extractHostPort(opts)
128
+
129
+ const viaProxy = extractHostPortViaProxy(opts)
130
+ const { host, hostname, port } = viaProxy ? viaProxy : extractHostPort(opts)
107
131
 
108
132
  if (!hostname || port < 1) {
109
133
  logger.warn('Invalid host name (%s) or port (%s) for outbound request.', hostname, port)
@@ -127,7 +127,7 @@ function wrapResponse(shim, response) {
127
127
  if (!shim.isFunction(cb)) {
128
128
  ++cbIdx
129
129
  cb = function defaultRenderCB(err, str) {
130
- // https://github.com/expressjs/express/blob/4.x/lib/response.js#L961-L962
130
+ // https://github.com/expressjs/express/blob/4.x/lib/response.js#L961-L962
131
131
  if (err) {
132
132
  return res.req.next(err)
133
133
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newrelic",
3
- "version": "12.6.1",
3
+ "version": "12.7.0",
4
4
  "author": "New Relic Node.js agent team <nodejs@newrelic.com>",
5
5
  "license": "Apache-2.0",
6
6
  "contributors": [