newrelic 12.4.0 → 12.5.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,22 @@
1
+ ### v12.5.0 (2024-09-12)
2
+
3
+ #### Features
4
+
5
+ * Added utilization info for ECS ([#2565](https://github.com/newrelic/node-newrelic/pull/2565)) ([6f92073](https://github.com/newrelic/node-newrelic/commit/6f92073a6c01124d8ab1b54d06c176a36fbc3441))
6
+
7
+ #### Bug fixes
8
+
9
+ * Ensured README displays for Azure site extension ([#2564](https://github.com/newrelic/node-newrelic/pull/2564)) ([a30aed5](https://github.com/newrelic/node-newrelic/commit/a30aed5cf31c0c89678618e51215063562331848))
10
+
11
+ #### Documentation
12
+
13
+ * Updated compatibility report ([#2562](https://github.com/newrelic/node-newrelic/pull/2562)) ([8f7aebe](https://github.com/newrelic/node-newrelic/commit/8f7aebe7e4274ce45cfe961537a09b34077b3aa0))
14
+
15
+ #### Tests
16
+
17
+ * Convert `metric` and `metrics-recorder` tests to `node:test` ([#2552](https://github.com/newrelic/node-newrelic/pull/2552)) ([7ae4af4](https://github.com/newrelic/node-newrelic/commit/7ae4af4c8adfabadd3c865bd2fdd0e8ba5317eef))
18
+ * Updated `serverless` unit tests to `node:test` ([#2549](https://github.com/newrelic/node-newrelic/pull/2549)) ([619f23c](https://github.com/newrelic/node-newrelic/commit/619f23c938bf39c360a6da9a307c178986c70902))
19
+
1
20
  ### v12.4.0 (2024-09-11)
2
21
 
3
22
  #### Features
@@ -34,6 +34,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
34
34
  * [@aws-sdk/client-s3](#aws-sdkclient-s3)
35
35
  * [@aws-sdk/s3-request-presigner](#aws-sdks3-request-presigner)
36
36
  * [@koa/router](#koarouter)
37
+ * [@matteo.collina/tspl](#matteocollinatspl)
37
38
  * [@newrelic/eslint-config](#newreliceslint-config)
38
39
  * [@newrelic/newrelic-oss-cli](#newrelicnewrelic-oss-cli)
39
40
  * [@newrelic/test-utilities](#newrelictest-utilities)
@@ -69,7 +70,6 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
69
70
  * [nock](#nock)
70
71
  * [proxy](#proxy)
71
72
  * [proxyquire](#proxyquire)
72
- * [rfdc](#rfdc)
73
73
  * [rimraf](#rimraf)
74
74
  * [self-cert](#self-cert)
75
75
  * [should](#should)
@@ -1076,7 +1076,7 @@ SOFTWARE.
1076
1076
 
1077
1077
  ### @aws-sdk/client-s3
1078
1078
 
1079
- This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.637.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.637.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.637.0/LICENSE):
1079
+ This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.632.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.632.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.632.0/LICENSE):
1080
1080
 
1081
1081
  ```
1082
1082
  Apache License
@@ -1285,7 +1285,7 @@ This product includes source derived from [@aws-sdk/client-s3](https://github.co
1285
1285
 
1286
1286
  ### @aws-sdk/s3-request-presigner
1287
1287
 
1288
- This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.637.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.637.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.637.0/LICENSE):
1288
+ This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.632.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.632.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.632.0/LICENSE):
1289
1289
 
1290
1290
  ```
1291
1291
  Apache License
@@ -1521,6 +1521,35 @@ THE SOFTWARE.
1521
1521
 
1522
1522
  ```
1523
1523
 
1524
+ ### @matteo.collina/tspl
1525
+
1526
+ This product includes source derived from [@matteo.collina/tspl](https://github.com/mcollina/tspl) ([v0.1.1](https://github.com/mcollina/tspl/tree/v0.1.1)), distributed under the [MIT License](https://github.com/mcollina/tspl/blob/v0.1.1/LICENSE):
1527
+
1528
+ ```
1529
+ MIT License
1530
+
1531
+ Copyright (c) 2023 Matteo Collina
1532
+
1533
+ Permission is hereby granted, free of charge, to any person obtaining a copy
1534
+ of this software and associated documentation files (the "Software"), to deal
1535
+ in the Software without restriction, including without limitation the rights
1536
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1537
+ copies of the Software, and to permit persons to whom the Software is
1538
+ furnished to do so, subject to the following conditions:
1539
+
1540
+ The above copyright notice and this permission notice shall be included in all
1541
+ copies or substantial portions of the Software.
1542
+
1543
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1544
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1545
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1546
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1547
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1548
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1549
+ SOFTWARE.
1550
+
1551
+ ```
1552
+
1524
1553
  ### @newrelic/eslint-config
1525
1554
 
1526
1555
  This product includes source derived from [@newrelic/eslint-config](https://github.com/newrelic/eslint-config-newrelic) ([v0.3.0](https://github.com/newrelic/eslint-config-newrelic/tree/v0.3.0)), distributed under the [Apache-2.0 License](https://github.com/newrelic/eslint-config-newrelic/blob/v0.3.0/LICENSE):
@@ -2656,7 +2685,7 @@ SOFTWARE.
2656
2685
 
2657
2686
  ### async
2658
2687
 
2659
- This product includes source derived from [async](https://github.com/caolan/async) ([v3.2.6](https://github.com/caolan/async/tree/v3.2.6)), distributed under the [MIT License](https://github.com/caolan/async/blob/v3.2.6/LICENSE):
2688
+ This product includes source derived from [async](https://github.com/caolan/async) ([v3.2.5](https://github.com/caolan/async/tree/v3.2.5)), distributed under the [MIT License](https://github.com/caolan/async/blob/v3.2.5/LICENSE):
2660
2689
 
2661
2690
  ```
2662
2691
  Copyright (c) 2010-2018 Caolan McMahon
@@ -2683,7 +2712,7 @@ THE SOFTWARE.
2683
2712
 
2684
2713
  ### aws-sdk
2685
2714
 
2686
- This product includes source derived from [aws-sdk](https://github.com/aws/aws-sdk-js) ([v2.1687.0](https://github.com/aws/aws-sdk-js/tree/v2.1687.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js/blob/v2.1687.0/LICENSE.txt):
2715
+ This product includes source derived from [aws-sdk](https://github.com/aws/aws-sdk-js) ([v2.1677.0](https://github.com/aws/aws-sdk-js/tree/v2.1677.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js/blob/v2.1677.0/LICENSE.txt):
2687
2716
 
2688
2717
  ```
2689
2718
 
@@ -3978,29 +4007,6 @@ OTHER DEALINGS IN THE SOFTWARE.
3978
4007
 
3979
4008
  ```
3980
4009
 
3981
- ### rfdc
3982
-
3983
- This product includes source derived from [rfdc](https://github.com/davidmarkclements/rfdc) ([v1.4.1](https://github.com/davidmarkclements/rfdc/tree/v1.4.1)), distributed under the [MIT License](https://github.com/davidmarkclements/rfdc/blob/v1.4.1/LICENSE):
3984
-
3985
- ```
3986
- Copyright 2019 "David Mark Clements <david.mark.clements@gmail.com>"
3987
-
3988
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
3989
- documentation files (the "Software"), to deal in the Software without restriction, including without limitation
3990
- the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
3991
- to permit persons to whom the Software is furnished to do so, subject to the following conditions:
3992
-
3993
- The above copyright notice and this permission notice shall be included in all copies or substantial portions
3994
- of the Software.
3995
-
3996
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
3997
- TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
3998
- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
3999
- CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4000
- IN THE SOFTWARE.
4001
-
4002
- ```
4003
-
4004
4010
  ### rimraf
4005
4011
 
4006
4012
  This product includes source derived from [rimraf](https://github.com/isaacs/rimraf) ([v2.7.1](https://github.com/isaacs/rimraf/tree/v2.7.1)), distributed under the [ISC License](https://github.com/isaacs/rimraf/blob/v2.7.1/LICENSE):
@@ -204,11 +204,12 @@ const HAPI = {
204
204
 
205
205
  const UTILIZATION = {
206
206
  AWS_ERROR: SUPPORTABILITY.UTILIZATION + '/aws/error',
207
- PCF_ERROR: SUPPORTABILITY.UTILIZATION + '/pcf/error',
208
207
  AZURE_ERROR: SUPPORTABILITY.UTILIZATION + '/azure/error',
209
- GCP_ERROR: SUPPORTABILITY.UTILIZATION + '/gcp/error',
208
+ BOOT_ID_ERROR: SUPPORTABILITY.UTILIZATION + '/boot_id/error',
210
209
  DOCKER_ERROR: SUPPORTABILITY.UTILIZATION + '/docker/error',
211
- BOOT_ID_ERROR: SUPPORTABILITY.UTILIZATION + '/boot_id/error'
210
+ ECS_CONTAINER_ERROR: SUPPORTABILITY.UTILIZATION + '/ecs/container_id/error',
211
+ GCP_ERROR: SUPPORTABILITY.UTILIZATION + '/gcp/error',
212
+ PCF_ERROR: SUPPORTABILITY.UTILIZATION + '/pcf/error'
212
213
  }
213
214
 
214
215
  const CUSTOM_EVENTS = {
@@ -6,7 +6,6 @@
6
6
  'use strict'
7
7
 
8
8
  const fs = require('node:fs')
9
- const http = require('node:http')
10
9
  const log = require('../logger').child({ component: 'docker-info' })
11
10
  const common = require('./common')
12
11
  const NAMES = require('../metrics/names')
@@ -17,12 +16,17 @@ const CGROUPS_V1_PATH = '/proc/self/cgroup'
17
16
  const CGROUPS_V2_PATH = '/proc/self/mountinfo'
18
17
  const BOOT_ID_PROC_FILE = '/proc/sys/kernel/random/boot_id'
19
18
 
20
- module.exports.getVendorInfo = fetchDockerVendorInfo
21
- module.exports.clearVendorCache = function clearDockerVendorCache() {
19
+ module.exports = {
20
+ clearVendorCache: clearDockerVendorCache,
21
+ getBootId,
22
+ getVendorInfo: fetchDockerVendorInfo
23
+ }
24
+
25
+ function clearDockerVendorCache() {
22
26
  vendorInfo = null
23
27
  }
24
28
 
25
- module.exports.getBootId = function getBootId(agent, callback, logger = log) {
29
+ function getBootId(agent, callback, logger = log) {
26
30
  if (!/linux/i.test(os.platform())) {
27
31
  logger.debug('Platform is not a flavor of linux, omitting boot info')
28
32
  return setImmediate(callback, null, null)
@@ -37,76 +41,8 @@ module.exports.getBootId = function getBootId(agent, callback, logger = log) {
37
41
  }
38
42
 
39
43
  logger.debug('Container boot id is not available in cgroups info')
40
-
41
- if (hasAwsContainerApi() === false) {
42
- // We don't seem to have a recognized location for getting the container
43
- // identifier.
44
- logger.debug('Container is not in a recognized ECS container, omitting boot info')
45
- recordBootIdError(agent)
46
- return callback(null, null)
47
- }
48
-
49
- getEcsContainerId({ agent, callback, logger })
50
- })
51
- }
52
-
53
- /**
54
- * Queries the AWS ECS metadata API to get the boot id.
55
- *
56
- * @param {object} params Function parameters.
57
- * @param {object} params.agent Newrelic agent instance.
58
- * @param {Function} params.callback Typical error first callback. The second
59
- * parameter is the boot id as a string.
60
- * @param {object} [params.logger] Internal logger instance.
61
- */
62
- function getEcsContainerId({ agent, callback, logger }) {
63
- const ecsApiUrl =
64
- process.env.ECS_CONTAINER_METADATA_URI_V4 || process.env.ECS_CONTAINER_METADATA_URI
65
- const req = http.request(ecsApiUrl, (res) => {
66
- let body = Buffer.alloc(0)
67
- res.on('data', (chunk) => {
68
- body = Buffer.concat([body, chunk])
69
- })
70
- res.on('end', () => {
71
- try {
72
- const json = body.toString('utf8')
73
- const data = JSON.parse(json)
74
- if (data.DockerId == null) {
75
- logger.debug('Failed to find DockerId in response, omitting boot info')
76
- recordBootIdError(agent)
77
- return callback(null, null)
78
- }
79
- callback(null, data.DockerId)
80
- } catch (error) {
81
- logger.debug('Failed to process ECS API response, omitting boot info: ' + error.message)
82
- recordBootIdError(agent)
83
- callback(null, null)
84
- }
85
- })
86
- })
87
-
88
- req.on('error', () => {
89
- logger.debug('Failed to query ECS endpoint, omitting boot info')
90
- recordBootIdError(agent)
91
44
  callback(null, null)
92
45
  })
93
-
94
- req.end()
95
- }
96
-
97
- /**
98
- * Inspects the running environment to determine if the AWS ECS metadata API
99
- * is available.
100
- *
101
- * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ec2-metadata.html
102
- *
103
- * @returns {boolean}
104
- */
105
- function hasAwsContainerApi() {
106
- if (process.env.ECS_CONTAINER_METADATA_URI_V4 != null) {
107
- return true
108
- }
109
- return process.env.ECS_CONTAINER_METADATA_URI != null
110
46
  }
111
47
 
112
48
  /**
@@ -0,0 +1,112 @@
1
+ /*
2
+ * Copyright 2024 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ 'use strict'
7
+
8
+ const http = require('node:http')
9
+ const NAMES = require('../metrics/names')
10
+
11
+ module.exports = function fetchEcsInfo(
12
+ agent,
13
+ callback,
14
+ {
15
+ logger = require('../logger').child({ component: 'ecs-info' }),
16
+ getEcsContainerId = _getEcsContainerId,
17
+ hasAwsContainerApi = _hasAwsContainerApi,
18
+ recordIdError = _recordIdError
19
+ } = {}
20
+ ) {
21
+ // Per spec, we do not have a `detect_ecs` key. Since ECS is a service of AWS,
22
+ // we rely on the `detect_aws` setting.
23
+ if (!agent.config.utilization || !agent.config.utilization.detect_aws) {
24
+ return setImmediate(callback, null)
25
+ }
26
+
27
+ if (hasAwsContainerApi() === false) {
28
+ logger.debug('ECS API not available, omitting ECS container id info')
29
+ recordIdError(agent)
30
+ return callback(null, null)
31
+ }
32
+
33
+ getEcsContainerId({
34
+ agent,
35
+ logger,
36
+ recordIdError,
37
+ callback: (error, dockerId) => {
38
+ if (error) {
39
+ return callback(error, null)
40
+ }
41
+ if (dockerId === null) {
42
+ // Some error happened where we could not find the id. Skipping.
43
+ return callback(null, null)
44
+ }
45
+ return callback(null, { ecsDockerId: dockerId })
46
+ }
47
+ })
48
+ }
49
+
50
+ /**
51
+ * Queries the AWS ECS metadata API to get the boot id.
52
+ *
53
+ * @param {object} params Function parameters.
54
+ * @param {object} params.agent Newrelic agent instance.
55
+ * @param {Function} params.callback Typical error first callback. The second
56
+ * parameter is the boot id as a string.
57
+ * @param {object} params.logger Internal logger instance.
58
+ * @param {function} params.recordIdError Function to record error metric.
59
+ */
60
+ function _getEcsContainerId({ agent, callback, logger, recordIdError }) {
61
+ const ecsApiUrl =
62
+ process.env.ECS_CONTAINER_METADATA_URI_V4 || process.env.ECS_CONTAINER_METADATA_URI
63
+ const req = http.request(ecsApiUrl, (res) => {
64
+ let body = Buffer.alloc(0)
65
+ res.on('data', (chunk) => {
66
+ body = Buffer.concat([body, chunk])
67
+ })
68
+ res.on('end', () => {
69
+ try {
70
+ const json = body.toString('utf8')
71
+ const data = JSON.parse(json)
72
+ if (data.DockerId == null) {
73
+ logger.debug('Failed to find DockerId in response, omitting boot info')
74
+ recordIdError(agent)
75
+ return callback(null, null)
76
+ }
77
+ callback(null, data.DockerId)
78
+ } catch (error) {
79
+ logger.debug('Failed to process ECS API response, omitting boot info: ' + error.message)
80
+ recordIdError(agent)
81
+ callback(null, null)
82
+ }
83
+ })
84
+ })
85
+
86
+ req.on('error', () => {
87
+ logger.debug('Failed to query ECS endpoint, omitting boot info')
88
+ recordIdError(agent)
89
+ callback(null, null)
90
+ })
91
+
92
+ req.end()
93
+ }
94
+
95
+ /**
96
+ * Inspects the running environment to determine if the AWS ECS metadata API
97
+ * is available.
98
+ *
99
+ * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ec2-metadata.html
100
+ *
101
+ * @returns {boolean}
102
+ */
103
+ function _hasAwsContainerApi() {
104
+ if (process.env.ECS_CONTAINER_METADATA_URI_V4 != null) {
105
+ return true
106
+ }
107
+ return process.env.ECS_CONTAINER_METADATA_URI != null
108
+ }
109
+
110
+ function _recordIdError(agent) {
111
+ agent.metrics.getOrCreateMetric(NAMES.UTILIZATION.ECS_CONTAINER_ERROR).incrementCallCount()
112
+ }
@@ -9,11 +9,12 @@ const logger = require('../logger').child({ component: 'utilization' })
9
9
 
10
10
  const VENDOR_METHODS = {
11
11
  aws: require('./aws-info'),
12
- pcf: require('./pcf-info'),
13
12
  azure: require('./azure-info'),
14
- gcp: require('./gcp-info'),
15
13
  docker: require('./docker-info').getVendorInfo,
16
- kubernetes: require('./kubernetes-info')
14
+ ecs: require('./ecs-info'),
15
+ gcp: require('./gcp-info'),
16
+ kubernetes: require('./kubernetes-info'),
17
+ pcf: require('./pcf-info')
17
18
  }
18
19
  const VENDOR_NAMES = Object.keys(VENDOR_METHODS)
19
20
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newrelic",
3
- "version": "12.4.0",
3
+ "version": "12.5.0",
4
4
  "author": "New Relic Node.js agent team <nodejs@newrelic.com>",
5
5
  "license": "Apache-2.0",
6
6
  "contributors": [
@@ -219,6 +219,7 @@
219
219
  "@aws-sdk/client-s3": "^3.556.0",
220
220
  "@aws-sdk/s3-request-presigner": "^3.556.0",
221
221
  "@koa/router": "^12.0.1",
222
+ "@matteo.collina/tspl": "^0.1.1",
222
223
  "@newrelic/eslint-config": "^0.3.0",
223
224
  "@newrelic/newrelic-oss-cli": "^0.1.2",
224
225
  "@newrelic/test-utilities": "^9.1.0",
@@ -254,7 +255,6 @@
254
255
  "nock": "11.8.0",
255
256
  "proxy": "^2.1.1",
256
257
  "proxyquire": "^1.8.0",
257
- "rfdc": "^1.3.1",
258
258
  "rimraf": "^2.6.3",
259
259
  "self-cert": "^2.0.0",
260
260
  "should": "*",