newrelic 12.21.0 → 12.23.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 +60 -0
- package/THIRD_PARTY_NOTICES.md +54 -6
- package/index.js +3 -3
- package/lib/agent.js +8 -0
- package/lib/config/default.js +35 -1
- package/lib/config/index.js +36 -22
- package/lib/instrumentation/@hapi/hapi.js +6 -10
- package/lib/instrumentation/@hapi/vision.js +3 -3
- package/lib/instrumentation/amqplib/amqplib.js +2 -4
- package/lib/instrumentation/amqplib/channel.js +3 -4
- package/lib/instrumentation/bunyan.js +1 -2
- package/lib/instrumentation/cassandra-driver.js +1 -3
- package/lib/instrumentation/core/child_process.js +1 -2
- package/lib/instrumentation/core/fs.js +2 -3
- package/lib/instrumentation/core/inspector.js +1 -2
- package/lib/instrumentation/core/net.js +2 -3
- package/lib/instrumentation/core/zlib.js +2 -3
- package/lib/instrumentation/fastify.js +4 -6
- package/lib/instrumentation/grpc-js/grpc.js +3 -8
- package/lib/instrumentation/kafkajs/consumer.js +2 -4
- package/lib/instrumentation/kafkajs/producer.js +1 -2
- package/lib/instrumentation/koa/router-instrumentation.js +2 -2
- package/lib/instrumentation/openai.js +120 -7
- package/lib/instrumentation/pino/pino.js +2 -2
- package/lib/instrumentation/winston.js +3 -6
- package/lib/llm-events/aws-bedrock/bedrock-command.js +1 -9
- package/lib/llm-events/aws-bedrock/bedrock-response.js +2 -7
- package/lib/llm-events/aws-bedrock/chat-completion-message.js +1 -1
- package/lib/llm-events/openai/chat-completion-message.js +17 -5
- package/lib/llm-events/openai/chat-completion-summary.js +13 -3
- package/lib/otel/metrics/bootstrap-metrics.js +117 -0
- package/lib/otel/metrics/proxying-exporter.js +75 -0
- package/lib/otel/setup.js +1 -1
- package/lib/otel/transformation-rules.json +0 -33
- package/lib/serverless/aws-lambda.js +6 -6
- package/lib/shim/message-shim/subscribe-consume.js +2 -5
- package/lib/shim/promise-shim.js +6 -4
- package/lib/shim/shim.js +12 -11
- package/lib/shim/webframework-shim/middleware-mounter.js +1 -3
- package/lib/spans/helpers.js +63 -1
- package/lib/spans/span-event-aggregator.js +6 -3
- package/lib/spans/span-event.js +10 -4
- package/lib/spans/streaming-span-event-aggregator.js +6 -2
- package/lib/spans/streaming-span-event.js +10 -4
- package/lib/util/code-level-metrics.js +1 -1
- package/lib/w3c/tracestate.js +5 -0
- package/package.json +4 -3
- package/lib/otel/bootstrap-metrics.js +0 -58
package/NEWS.md
CHANGED
|
@@ -1,3 +1,63 @@
|
|
|
1
|
+
### v12.23.0 (2025-06-30)
|
|
2
|
+
|
|
3
|
+
#### Features
|
|
4
|
+
|
|
5
|
+
* Added ability to report only on entry and exit spans ([#3184](https://github.com/newrelic/node-newrelic/pull/3184)) ([1f909d3](https://github.com/newrelic/node-newrelic/commit/1f909d389f790733c8787a9db8b0ee71c26bb5ed))
|
|
6
|
+
* Added Node.js 24 support ([#3080](https://github.com/newrelic/node-newrelic/pull/3080)) ([a538c2a](https://github.com/newrelic/node-newrelic/commit/a538c2a5e23b96be40fa3c014e60b912f695423e))
|
|
7
|
+
|
|
8
|
+
#### Documentation
|
|
9
|
+
|
|
10
|
+
* Updated compatibility report ([#3186](https://github.com/newrelic/node-newrelic/pull/3186)) ([5498c15](https://github.com/newrelic/node-newrelic/commit/5498c15bb6cf3329fe50595da46ab4f2b1385170))
|
|
11
|
+
|
|
12
|
+
#### Miscellaneous chores
|
|
13
|
+
|
|
14
|
+
* Fix issues on Node 24 ([#3181](https://github.com/newrelic/node-newrelic/pull/3181)) ([24832df](https://github.com/newrelic/node-newrelic/commit/24832df2984df960a4e44375525a8127a00a637c))
|
|
15
|
+
* Removed force labels on main CI workflow ([#3183](https://github.com/newrelic/node-newrelic/pull/3183)) ([3aaee17](https://github.com/newrelic/node-newrelic/commit/3aaee17586f817ae1a2ab0573570a740bd6397ef))
|
|
16
|
+
* Updated undici tests to unblock CI ([#3185](https://github.com/newrelic/node-newrelic/pull/3185)) ([08261eb](https://github.com/newrelic/node-newrelic/commit/08261ebcdbafdb625a451f4ccec9b0cba7641cc2))
|
|
17
|
+
|
|
18
|
+
#### Continuous integration
|
|
19
|
+
|
|
20
|
+
* Fixed the name of todo colum in add to board reusable workflow ([#3178](https://github.com/newrelic/node-newrelic/pull/3178)) ([f216e0c](https://github.com/newrelic/node-newrelic/commit/f216e0c48adf0291bfa38b3edbb04c9dcc96f92c))
|
|
21
|
+
|
|
22
|
+
### v12.22.0 (2025-06-24)
|
|
23
|
+
|
|
24
|
+
#### Features
|
|
25
|
+
|
|
26
|
+
* Added `openai` v5 streaming support ([#3148](https://github.com/newrelic/node-newrelic/pull/3148)) ([6e90d41](https://github.com/newrelic/node-newrelic/commit/6e90d41756929bf69b82e190dc39792f97ec6d92))
|
|
27
|
+
* Added support for `openai.responses.create` api ([#3139](https://github.com/newrelic/node-newrelic/pull/3139)) ([a1204b2](https://github.com/newrelic/node-newrelic/commit/a1204b2484f3307eac74e7a370be2fc38061c358))
|
|
28
|
+
|
|
29
|
+
#### Bug fixes
|
|
30
|
+
|
|
31
|
+
* Fixed error logging for undefined tracestate header ([#3170](https://github.com/newrelic/node-newrelic/pull/3170)) ([3c915f5](https://github.com/newrelic/node-newrelic/commit/3c915f5a631b609daa6b87f3018e458945077f65))
|
|
32
|
+
|
|
33
|
+
#### Code refactoring
|
|
34
|
+
|
|
35
|
+
* Updated transformation rules to remove the bespoke rule to appease `@google-cloud/pubsub` < 5.1.0 ([#3151](https://github.com/newrelic/node-newrelic/pull/3151)) ([2d9b4b4](https://github.com/newrelic/node-newrelic/commit/2d9b4b4642e856622175adcfd2e31fa4cdfa7a3a))
|
|
36
|
+
|
|
37
|
+
#### Documentation
|
|
38
|
+
|
|
39
|
+
* Gemini compatibility ([#3134](https://github.com/newrelic/node-newrelic/pull/3134)) ([bbdc531](https://github.com/newrelic/node-newrelic/commit/bbdc531ac59aad7b53f1a98306b6857927b87237))
|
|
40
|
+
* Updated compatibility report ([#3171](https://github.com/newrelic/node-newrelic/pull/3171)) ([f3361e4](https://github.com/newrelic/node-newrelic/commit/f3361e421d67a0015719c3ae91bed64e5d38f317))
|
|
41
|
+
|
|
42
|
+
#### Miscellaneous chores
|
|
43
|
+
|
|
44
|
+
* Added logging of used New Relic environment variables ([#3145](https://github.com/newrelic/node-newrelic/pull/3145)) ([1a9d9f5](https://github.com/newrelic/node-newrelic/commit/1a9d9f53ddce7f373a7ff868b363feacf10e3bd8))
|
|
45
|
+
* Added supportability metrics to OTEL metrics API ([#3164](https://github.com/newrelic/node-newrelic/pull/3164)) ([5312db0](https://github.com/newrelic/node-newrelic/commit/5312db0f7c0b4260dd39691e246625380ea2ed12))
|
|
46
|
+
* Fixed formatting in Slack PR titles ([#3167](https://github.com/newrelic/node-newrelic/pull/3167)) ([847859f](https://github.com/newrelic/node-newrelic/commit/847859f8ece852d4fa511039d2131573d4b1392b))
|
|
47
|
+
* Improved output of pending prs script ([#3160](https://github.com/newrelic/node-newrelic/pull/3160)) ([9bafd77](https://github.com/newrelic/node-newrelic/commit/9bafd7758fc63d7fb5106fe0a28aaa5a626bdf3d))
|
|
48
|
+
* Improved setup of OpenTelemetry metrics API ([#3138](https://github.com/newrelic/node-newrelic/pull/3138)) ([e91592d](https://github.com/newrelic/node-newrelic/commit/e91592d8365a3e2543228526d6959751da7ea5aa))
|
|
49
|
+
* Pinned google/genai to <1.5.0 ([#3154](https://github.com/newrelic/node-newrelic/pull/3154)) ([04b9bde](https://github.com/newrelic/node-newrelic/commit/04b9bdef417d6ce9e9148c9489bbfc28081d5e84))
|
|
50
|
+
* Removed discontinued Bedrock models ([#3158](https://github.com/newrelic/node-newrelic/pull/3158)) ([2c79a31](https://github.com/newrelic/node-newrelic/commit/2c79a312daf31f51f8a270facf1c3a125700e987))
|
|
51
|
+
* Removed usage of `shim.argsToArray` in favor of rest parameters ([#3141](https://github.com/newrelic/node-newrelic/pull/3141)) ([b144d71](https://github.com/newrelic/node-newrelic/commit/b144d712f6e75265dc4be6f82a2fc3977ac1c640))
|
|
52
|
+
* Tweaked nestjs test manifest ([#3152](https://github.com/newrelic/node-newrelic/pull/3152)) ([51b82aa](https://github.com/newrelic/node-newrelic/commit/51b82aa28279e0d5ac8be5f4e6a4274532c76a22))
|
|
53
|
+
|
|
54
|
+
#### Tests
|
|
55
|
+
|
|
56
|
+
* Added JSDoc annotation for benchmark interface ([#3127](https://github.com/newrelic/node-newrelic/pull/3127)) ([77e7e0a](https://github.com/newrelic/node-newrelic/commit/77e7e0a27f719ce14d31636e46600ec7ff881b13))
|
|
57
|
+
* fixed test assertion for langchain openai ([#3169](https://github.com/newrelic/node-newrelic/pull/3169)) ([29ec912](https://github.com/newrelic/node-newrelic/commit/29ec9122fdf9347875b884efa6f6fba9cb32303e))
|
|
58
|
+
* Skips running nest 11+ on node 18 due to dropping support ([#3149](https://github.com/newrelic/node-newrelic/pull/3149)) ([961975b](https://github.com/newrelic/node-newrelic/commit/961975baeb74e46c0e60d96cbd49fb421acd0dfd))
|
|
59
|
+
* unpinned google genai tests ([#3168](https://github.com/newrelic/node-newrelic/pull/3168)) ([cfa7114](https://github.com/newrelic/node-newrelic/commit/cfa71142ba7fb9861a1e7ab835276e7c651b9993))
|
|
60
|
+
|
|
1
61
|
### v12.21.0 (2025-06-04)
|
|
2
62
|
|
|
3
63
|
#### Features
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -72,6 +72,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
|
|
|
72
72
|
* [lint-staged](#lint-staged)
|
|
73
73
|
* [lockfile-lint](#lockfile-lint)
|
|
74
74
|
* [nock](#nock)
|
|
75
|
+
* [protobufjs](#protobufjs)
|
|
75
76
|
* [proxyquire](#proxyquire)
|
|
76
77
|
* [rimraf](#rimraf)
|
|
77
78
|
* [self-cert](#self-cert)
|
|
@@ -94,7 +95,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
|
|
|
94
95
|
|
|
95
96
|
### @grpc/grpc-js
|
|
96
97
|
|
|
97
|
-
This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.13.
|
|
98
|
+
This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.13.4](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/tree/v1.13.4)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js/blob/v1.13.4/LICENSE):
|
|
98
99
|
|
|
99
100
|
```
|
|
100
101
|
Apache License
|
|
@@ -1901,7 +1902,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
1901
1902
|
|
|
1902
1903
|
### import-in-the-middle
|
|
1903
1904
|
|
|
1904
|
-
This product includes source derived from [import-in-the-middle](https://github.com/nodejs/import-in-the-middle) ([v1.
|
|
1905
|
+
This product includes source derived from [import-in-the-middle](https://github.com/nodejs/import-in-the-middle) ([v1.14.0](https://github.com/nodejs/import-in-the-middle/tree/v1.14.0)), distributed under the [Apache-2.0 License](https://github.com/nodejs/import-in-the-middle/blob/v1.14.0/LICENSE):
|
|
1905
1906
|
|
|
1906
1907
|
```
|
|
1907
1908
|
Apache License
|
|
@@ -2332,7 +2333,7 @@ SOFTWARE.
|
|
|
2332
2333
|
|
|
2333
2334
|
### @aws-sdk/client-s3
|
|
2334
2335
|
|
|
2335
|
-
This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.
|
|
2336
|
+
This product includes source derived from [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3) ([v3.821.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.821.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.821.0/LICENSE):
|
|
2336
2337
|
|
|
2337
2338
|
```
|
|
2338
2339
|
Apache License
|
|
@@ -2541,7 +2542,7 @@ This product includes source derived from [@aws-sdk/client-s3](https://github.co
|
|
|
2541
2542
|
|
|
2542
2543
|
### @aws-sdk/s3-request-presigner
|
|
2543
2544
|
|
|
2544
|
-
This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.
|
|
2545
|
+
This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.821.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.821.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.821.0/LICENSE):
|
|
2545
2546
|
|
|
2546
2547
|
```
|
|
2547
2548
|
Apache License
|
|
@@ -4369,7 +4370,7 @@ SOFTWARE.
|
|
|
4369
4370
|
|
|
4370
4371
|
### eslint-plugin-jsdoc
|
|
4371
4372
|
|
|
4372
|
-
This product includes source derived from [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) ([v50.
|
|
4373
|
+
This product includes source derived from [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) ([v50.7.1](https://github.com/gajus/eslint-plugin-jsdoc/tree/v50.7.1)), distributed under the [BSD-3-Clause License](https://github.com/gajus/eslint-plugin-jsdoc/blob/v50.7.1/LICENSE):
|
|
4373
4374
|
|
|
4374
4375
|
```
|
|
4375
4376
|
Copyright (c) 2018, Gajus Kuizinas (http://gajus.com/)
|
|
@@ -4401,7 +4402,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
4401
4402
|
|
|
4402
4403
|
### eslint
|
|
4403
4404
|
|
|
4404
|
-
This product includes source derived from [eslint](https://github.com/eslint/eslint) ([v9.
|
|
4405
|
+
This product includes source derived from [eslint](https://github.com/eslint/eslint) ([v9.28.0](https://github.com/eslint/eslint/tree/v9.28.0)), distributed under the [MIT License](https://github.com/eslint/eslint/blob/v9.28.0/LICENSE):
|
|
4405
4406
|
|
|
4406
4407
|
```
|
|
4407
4408
|
Copyright OpenJS Foundation and other contributors, <www.openjsf.org>
|
|
@@ -5012,6 +5013,53 @@ SOFTWARE.
|
|
|
5012
5013
|
|
|
5013
5014
|
```
|
|
5014
5015
|
|
|
5016
|
+
### protobufjs
|
|
5017
|
+
|
|
5018
|
+
This product includes source derived from [protobufjs](https://github.com/protobufjs/protobuf.js) ([v7.5.3](https://github.com/protobufjs/protobuf.js/tree/v7.5.3)), distributed under the [BSD-3-Clause License](https://github.com/protobufjs/protobuf.js/blob/v7.5.3/LICENSE):
|
|
5019
|
+
|
|
5020
|
+
```
|
|
5021
|
+
This license applies to all parts of protobuf.js except those files
|
|
5022
|
+
either explicitly including or referencing a different license or
|
|
5023
|
+
located in a directory containing a different LICENSE file.
|
|
5024
|
+
|
|
5025
|
+
---
|
|
5026
|
+
|
|
5027
|
+
Copyright (c) 2016, Daniel Wirtz All rights reserved.
|
|
5028
|
+
|
|
5029
|
+
Redistribution and use in source and binary forms, with or without
|
|
5030
|
+
modification, are permitted provided that the following conditions are
|
|
5031
|
+
met:
|
|
5032
|
+
|
|
5033
|
+
* Redistributions of source code must retain the above copyright
|
|
5034
|
+
notice, this list of conditions and the following disclaimer.
|
|
5035
|
+
* Redistributions in binary form must reproduce the above copyright
|
|
5036
|
+
notice, this list of conditions and the following disclaimer in the
|
|
5037
|
+
documentation and/or other materials provided with the distribution.
|
|
5038
|
+
* Neither the name of its author, nor the names of its contributors
|
|
5039
|
+
may be used to endorse or promote products derived from this software
|
|
5040
|
+
without specific prior written permission.
|
|
5041
|
+
|
|
5042
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
5043
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
5044
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
5045
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
5046
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
5047
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
5048
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
5049
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
5050
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
5051
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
5052
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
5053
|
+
|
|
5054
|
+
---
|
|
5055
|
+
|
|
5056
|
+
Code generated by the command line utilities is owned by the owner
|
|
5057
|
+
of the input file used when generating it. This code is not
|
|
5058
|
+
standalone and requires a support library to be linked with it. This
|
|
5059
|
+
support library is itself covered by the above license.
|
|
5060
|
+
|
|
5061
|
+
```
|
|
5062
|
+
|
|
5015
5063
|
### proxyquire
|
|
5016
5064
|
|
|
5017
5065
|
This product includes source derived from [proxyquire](https://github.com/thlorenz/proxyquire) ([v1.8.0](https://github.com/thlorenz/proxyquire/tree/v1.8.0)), distributed under the [MIT License](https://github.com/thlorenz/proxyquire/blob/v1.8.0/LICENSE):
|
package/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
const HealthReporter = require('./lib/health-reporter')
|
|
8
|
+
const HealthReporter = require('./lib/health-reporter.js')
|
|
9
9
|
|
|
10
10
|
// Record opening times before loading any other files.
|
|
11
11
|
const preAgentTime = process.uptime()
|
|
@@ -64,8 +64,8 @@ function initialize() {
|
|
|
64
64
|
throw new Error(message)
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
// TODO: Update this check when Node
|
|
68
|
-
if (psemver.satisfies('>=
|
|
67
|
+
// TODO: Update this check when Node v26 support is added
|
|
68
|
+
if (psemver.satisfies('>=25.0.0')) {
|
|
69
69
|
logger.warn(
|
|
70
70
|
'New Relic for Node.js %s has not been tested on Node.js %s. Please ' +
|
|
71
71
|
'update the agent or downgrade your version of Node.js',
|
package/lib/agent.js
CHANGED
|
@@ -104,6 +104,14 @@ const DEFAULT_HARVEST_INTERVAL_MS = 60000
|
|
|
104
104
|
* @event Agent#harvestStarted
|
|
105
105
|
*/
|
|
106
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Indicates that the OpenTelemetry metrics API client has been fully
|
|
109
|
+
* configured and is ready to send metrics to New Relic. This happens
|
|
110
|
+
* subsequent to the {@link Agent#started} event.
|
|
111
|
+
*
|
|
112
|
+
* @event Agent#otelMetricsBootstrapped
|
|
113
|
+
*/
|
|
114
|
+
|
|
107
115
|
/**
|
|
108
116
|
* Indicates that the agent state has entered the "started" state. That is,
|
|
109
117
|
* the agent has finished bootstrapping and is collecting and sending data.
|
package/lib/config/default.js
CHANGED
|
@@ -1120,6 +1120,19 @@ defaultConfig.definition = () => ({
|
|
|
1120
1120
|
default: false
|
|
1121
1121
|
},
|
|
1122
1122
|
|
|
1123
|
+
/**
|
|
1124
|
+
* Controls whether the agent will generate spans for in-process actions.
|
|
1125
|
+
* When disabled, this will only create spans for entry and exit spans.
|
|
1126
|
+
* entry spans - initial actions for web servers and messsage queue consumption.
|
|
1127
|
+
* exit spans - all outgoing calls to external services(external and database calls)
|
|
1128
|
+
*/
|
|
1129
|
+
in_process_spans: {
|
|
1130
|
+
enabled: {
|
|
1131
|
+
formatter: boolean,
|
|
1132
|
+
default: true
|
|
1133
|
+
}
|
|
1134
|
+
},
|
|
1135
|
+
|
|
1123
1136
|
sampler: {
|
|
1124
1137
|
/**
|
|
1125
1138
|
* When set to `always_on`, the sampled flag in the `traceparent` header
|
|
@@ -1706,7 +1719,28 @@ defaultConfig.definition = () => ({
|
|
|
1706
1719
|
* application entity that is instrumented by the New Relic agent.
|
|
1707
1720
|
*/
|
|
1708
1721
|
metrics: {
|
|
1709
|
-
enabled: { default: false, formatter: boolean }
|
|
1722
|
+
enabled: { default: false, formatter: boolean },
|
|
1723
|
+
|
|
1724
|
+
/**
|
|
1725
|
+
* `exportInterval` defines the number of milliseconds between each
|
|
1726
|
+
* attempt to ship metrics to New Relic. This value must be equal to
|
|
1727
|
+
* or greater than the value of `exportTimeout`.
|
|
1728
|
+
*/
|
|
1729
|
+
exportInterval: {
|
|
1730
|
+
default: 60_000,
|
|
1731
|
+
formatter: int
|
|
1732
|
+
},
|
|
1733
|
+
|
|
1734
|
+
/**
|
|
1735
|
+
* `exportTimeout` defines the number of milliseconds an export operation
|
|
1736
|
+
* is allowed in order to successfully complete. If the timeout is
|
|
1737
|
+
* exceeded, it will be reported via the OpenTelemetry diagnostics
|
|
1738
|
+
* API.
|
|
1739
|
+
*/
|
|
1740
|
+
exportTimeout: {
|
|
1741
|
+
default: 30_000,
|
|
1742
|
+
formatter: int
|
|
1743
|
+
}
|
|
1710
1744
|
}
|
|
1711
1745
|
}
|
|
1712
1746
|
})
|
package/lib/config/index.js
CHANGED
|
@@ -1143,6 +1143,13 @@ function setFromEnv({ config, key, envVar, formatter, paths }) {
|
|
|
1143
1143
|
const setting = process.env[envVar]
|
|
1144
1144
|
if (setting) {
|
|
1145
1145
|
const formattedSetting = formatter ? formatter(setting, logger) : setting
|
|
1146
|
+
// `setting` _should_ be a string when reading from the actual process
|
|
1147
|
+
// environment. But we have tests that construct an environment with
|
|
1148
|
+
// non-string values. So we need to convert them before accessing.
|
|
1149
|
+
const prefix = setting.toString().at(0)
|
|
1150
|
+
const suffix = setting.toString().at(-1)
|
|
1151
|
+
const redacted = prefix + '*'.repeat(setting.length) + suffix
|
|
1152
|
+
logger.trace({ env: { [envVar]: redacted } }, 'setting value from environment variable')
|
|
1146
1153
|
setNestedKey(config, [...paths, key], formattedSetting)
|
|
1147
1154
|
}
|
|
1148
1155
|
}
|
|
@@ -1162,31 +1169,36 @@ Config.prototype._fromEnvironment = function _fromEnvironment(
|
|
|
1162
1169
|
objectKeys = 1
|
|
1163
1170
|
) {
|
|
1164
1171
|
let keysSeen = 0
|
|
1165
|
-
|
|
1172
|
+
for (const [key, value] of Object.entries(data)) {
|
|
1166
1173
|
const type = typeof value
|
|
1167
|
-
keysSeen
|
|
1174
|
+
keysSeen += 1
|
|
1175
|
+
|
|
1176
|
+
if (type !== 'string' && type !== 'object') {
|
|
1177
|
+
continue
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1168
1180
|
if (type === 'string') {
|
|
1169
1181
|
const envVar = deriveEnvVar(key, paths)
|
|
1170
1182
|
setFromEnv({ config, key, envVar, paths })
|
|
1171
|
-
|
|
1172
|
-
if (Object.prototype.hasOwnProperty.call(value, 'env')) {
|
|
1173
|
-
setFromEnv({
|
|
1174
|
-
config,
|
|
1175
|
-
key,
|
|
1176
|
-
envVar: value.env,
|
|
1177
|
-
paths,
|
|
1178
|
-
formatter: value.formatter
|
|
1179
|
-
})
|
|
1180
|
-
} else if (Object.prototype.hasOwnProperty.call(value, 'default')) {
|
|
1181
|
-
const envVar = deriveEnvVar(key, paths)
|
|
1182
|
-
setFromEnv({ config, key, envVar, formatter: value.formatter, paths })
|
|
1183
|
-
} else {
|
|
1184
|
-
paths.push(key)
|
|
1185
|
-
const { length } = Object.keys(value)
|
|
1186
|
-
this._fromEnvironment(config, value, paths, length)
|
|
1187
|
-
}
|
|
1183
|
+
continue
|
|
1188
1184
|
}
|
|
1189
|
-
|
|
1185
|
+
|
|
1186
|
+
if (Object.prototype.hasOwnProperty.call(value, 'env') === true) {
|
|
1187
|
+
const envVar = value.env
|
|
1188
|
+
setFromEnv({ config, key, paths, envVar, formatter: value.formatter })
|
|
1189
|
+
continue
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
if (Object.prototype.hasOwnProperty.call(value, 'default') === true) {
|
|
1193
|
+
const envVar = deriveEnvVar(key, paths)
|
|
1194
|
+
setFromEnv({ config, key, paths, envVar, formatter: value.formatter })
|
|
1195
|
+
continue
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
paths.push(key)
|
|
1199
|
+
const { length } = Object.keys(value)
|
|
1200
|
+
this._fromEnvironment(config, value, paths, length)
|
|
1201
|
+
}
|
|
1190
1202
|
|
|
1191
1203
|
// we have traversed every key in current object leaf node, remove wrapping key
|
|
1192
1204
|
// to properly derive env vars of future leaf nodes
|
|
@@ -1738,16 +1750,18 @@ Config.prototype._warnDeprecations = function _warnDeprecations() {
|
|
|
1738
1750
|
* configuration file settings.
|
|
1739
1751
|
*
|
|
1740
1752
|
* @param {object} config Optional configuration to be used in place of a config file.
|
|
1753
|
+
* @param root0
|
|
1754
|
+
* @param root0.loggerInstance
|
|
1741
1755
|
* @returns {object} instantiated configuration object
|
|
1742
1756
|
*/
|
|
1743
|
-
function initialize(config) {
|
|
1757
|
+
function initialize(config, { loggerInstance } = {}) {
|
|
1744
1758
|
/**
|
|
1745
1759
|
* When the logger is required here, it bootstraps itself and then
|
|
1746
1760
|
* injects itself into this module's closure via setLogger on the
|
|
1747
1761
|
* instance of the logger it creates. Logs are queued until config
|
|
1748
1762
|
* has been loaded to apply logging settings to bootstrapping logs
|
|
1749
1763
|
*/
|
|
1750
|
-
logger = require('../logger')
|
|
1764
|
+
logger = loggerInstance ?? require('../logger')
|
|
1751
1765
|
|
|
1752
1766
|
if (config) {
|
|
1753
1767
|
return new Config(config)
|
|
@@ -72,16 +72,14 @@ function serverPostConstructor(shim) {
|
|
|
72
72
|
|
|
73
73
|
function wrapProtoDecorate(shim, proto) {
|
|
74
74
|
shim.wrap(proto, 'decorate', function wrapDecorate(shim, original) {
|
|
75
|
-
return function wrappedDecorate(
|
|
75
|
+
return function wrappedDecorate(...args) {
|
|
76
|
+
const [type] = args
|
|
76
77
|
// server.decorate also accepts 'request', 'toolkit', 'server' types,
|
|
77
78
|
// but we're only concerned with 'handler'
|
|
78
79
|
if (type !== 'handler') {
|
|
79
|
-
return original.apply(this,
|
|
80
|
+
return original.apply(this, args)
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
// Convert arguments to usable array
|
|
83
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
84
|
-
|
|
85
83
|
// Wrap the third server.decorate arg, the user-defined handler
|
|
86
84
|
shim.wrap(args, shim.THIRD, function wrapHandler(shim, fn) {
|
|
87
85
|
if (typeof fn !== 'function') {
|
|
@@ -108,9 +106,7 @@ function wrapProtoDecorate(shim, proto) {
|
|
|
108
106
|
|
|
109
107
|
function wrapProtoRoute(shim, proto) {
|
|
110
108
|
shim.wrap(proto, 'route', function wrapRoute(shim, original) {
|
|
111
|
-
return function wrappedRoute() {
|
|
112
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
113
|
-
|
|
109
|
+
return function wrappedRoute(...args) {
|
|
114
110
|
if (!shim.isObject(args[0])) {
|
|
115
111
|
return original.apply(this, args)
|
|
116
112
|
}
|
|
@@ -171,8 +167,8 @@ function _wrapRouteHandler(shim, container, path) {
|
|
|
171
167
|
|
|
172
168
|
function wrapProtoExt(shim, proto) {
|
|
173
169
|
shim.wrap(proto, 'ext', function wrapExt(shim, original) {
|
|
174
|
-
return function wrappedExt(
|
|
175
|
-
const
|
|
170
|
+
return function wrappedExt(...args) {
|
|
171
|
+
const [event, method] = args
|
|
176
172
|
|
|
177
173
|
if (shim.isArray(event)) {
|
|
178
174
|
for (let i = 0; i < event.length; i++) {
|
|
@@ -31,12 +31,12 @@ module.exports = function initialize(agent, vision, moduleName, shim) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
function wrapDecorate(shim, decorate) {
|
|
34
|
-
return function wrappedDecorate(
|
|
34
|
+
return function wrappedDecorate(...args) {
|
|
35
|
+
const [type, name, handler] = args
|
|
35
36
|
if (type !== 'toolkit' || name !== 'view') {
|
|
36
|
-
return decorate.apply(this,
|
|
37
|
+
return decorate.apply(this, args)
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
40
40
|
args[2] = shim.recordRender(handler, new RenderSpec({ promise: true }))
|
|
41
41
|
|
|
42
42
|
return decorate.apply(this, args)
|
|
@@ -83,14 +83,12 @@ function instrumentAMQP(shim, amqp, promiseMode) {
|
|
|
83
83
|
*/
|
|
84
84
|
function wrapConnect(shim, amqp, promiseMode) {
|
|
85
85
|
shim.wrap(amqp, 'connect', function wrapConnect(shim, connect) {
|
|
86
|
-
return function wrappedConnect() {
|
|
87
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
86
|
+
return function wrappedConnect(...args) {
|
|
88
87
|
const [connArgs] = args
|
|
89
88
|
const params = parseConnectionArgs({ shim, connArgs })
|
|
90
89
|
const cb = args[args.length - 1]
|
|
91
90
|
if (!promiseMode) {
|
|
92
|
-
args[args.length - 1] = function wrappedCallback() {
|
|
93
|
-
const cbArgs = shim.argsToArray.apply(shim, arguments)
|
|
91
|
+
args[args.length - 1] = function wrappedCallback(...cbArgs) {
|
|
94
92
|
const [, c] = cbArgs
|
|
95
93
|
c.connection[amqpConnection] = params
|
|
96
94
|
return cb.apply(this, cbArgs)
|
|
@@ -33,16 +33,15 @@ module.exports = function wrapChannel(shim) {
|
|
|
33
33
|
return fn
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
return function wrappedSendOrEnqueue() {
|
|
36
|
+
return function wrappedSendOrEnqueue(...args) {
|
|
37
37
|
const segment = shim.getSegment()
|
|
38
|
-
const cb =
|
|
38
|
+
const cb = args[args.length - 1]
|
|
39
39
|
if (!shim.isFunction(cb) || !segment) {
|
|
40
40
|
shim.logger.debug({ cb: !!cb, segment: !!segment }, 'Not binding sendOrEnqueue callback')
|
|
41
|
-
return fn.apply(this,
|
|
41
|
+
return fn.apply(this, args)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
shim.logger.trace('Binding sendOrEnqueue callback to %s', segment.name)
|
|
45
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
46
45
|
args[args.length - 1] = shim.bindSegment(cb, segment)
|
|
47
46
|
return fn.apply(this, args)
|
|
48
47
|
}
|
|
@@ -82,8 +82,7 @@ module.exports = function instrument(agent, bunyan, _, shim) {
|
|
|
82
82
|
|
|
83
83
|
if (metricsEnabled || localDecoratingEnabled) {
|
|
84
84
|
shim.wrap(bunyan.prototype, '_emit', function wrapEmit(_shim, emit) {
|
|
85
|
-
return function wrappedEmit() {
|
|
86
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
85
|
+
return function wrappedEmit(...args) {
|
|
87
86
|
const rec = args[0]
|
|
88
87
|
|
|
89
88
|
if (metricsEnabled) {
|
|
@@ -71,12 +71,10 @@ module.exports = function initialize(_agent, cassandra, _moduleName, shim) {
|
|
|
71
71
|
)
|
|
72
72
|
|
|
73
73
|
shim.wrap(RequestExecutionProto, 'start', function wrapStart(shim, start) {
|
|
74
|
-
return function wrappedStart() {
|
|
74
|
+
return function wrappedStart(...args) {
|
|
75
75
|
const parent = shim.getSegment()
|
|
76
76
|
const self = this
|
|
77
77
|
|
|
78
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
79
|
-
|
|
80
78
|
/**
|
|
81
79
|
* In older versions of cassandra-driver, we can't rely on RequestExecution._sendOnConnection,
|
|
82
80
|
* so instead we use the callback passed to RequestExecution.start as a sort of hook point,
|
|
@@ -29,8 +29,7 @@ function initialize(agent, childProcess, moduleName, shim) {
|
|
|
29
29
|
|
|
30
30
|
function wrapChildProcessClass(shim, childProcessClass) {
|
|
31
31
|
shim.wrap(childProcessClass.prototype, 'on', function wrapChildProcessClassOn(shim, fn) {
|
|
32
|
-
return function wrappedChildProcessOn() {
|
|
33
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
32
|
+
return function wrappedChildProcessOn(...args) {
|
|
34
33
|
const cbIndex = args.length - 1
|
|
35
34
|
|
|
36
35
|
const originalListener = args[cbIndex]
|
|
@@ -66,13 +66,12 @@ function initialize(agent, fs, moduleName, shim) {
|
|
|
66
66
|
})
|
|
67
67
|
|
|
68
68
|
shim.wrap(fs, nonRecordedMethods, function wrapNonRecordedFs(shim, fn) {
|
|
69
|
-
return function wrappedNonRecordedFs() {
|
|
69
|
+
return function wrappedNonRecordedFs(...args) {
|
|
70
70
|
// these are called in tight loops so opting out early
|
|
71
71
|
if (!shim.getActiveSegment()) {
|
|
72
|
-
return fn.apply(this,
|
|
72
|
+
return fn.apply(this, args)
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
76
75
|
const cbIndex = args.length - 1
|
|
77
76
|
|
|
78
77
|
shim.bindSegment(args, cbIndex)
|
|
@@ -14,8 +14,7 @@ function initialize(agent, inspector, name, shim) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
shim.wrap(sessionProto, 'post', function wrapPost(shim, fn) {
|
|
17
|
-
return function wrappedPost() {
|
|
18
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
17
|
+
return function wrappedPost(...args) {
|
|
19
18
|
shim.bindCallbackSegment(null, args, shim.LAST)
|
|
20
19
|
return fn.apply(this, args)
|
|
21
20
|
}
|
|
@@ -24,12 +24,11 @@ module.exports = function initialize(agent, net, moduleName, shim) {
|
|
|
24
24
|
const serverProto = net.Server.prototype
|
|
25
25
|
|
|
26
26
|
shim.wrap(serverProto, ['listen', 'close'], function wrapNoRecord(shim, fn) {
|
|
27
|
-
return function wrappedNoRecord() {
|
|
27
|
+
return function wrappedNoRecord(...args) {
|
|
28
28
|
if (!shim.getActiveSegment()) {
|
|
29
|
-
return fn.apply(this,
|
|
29
|
+
return fn.apply(this, args)
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
33
32
|
const cbIndex = args.length - 1
|
|
34
33
|
|
|
35
34
|
shim.bindSegment(args, cbIndex)
|
|
@@ -32,12 +32,11 @@ function initialize(agent, zlib, moduleName, shim) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
function wrapNoSegment(shim, fn) {
|
|
35
|
-
return function wrappedZLibNoSegment() {
|
|
35
|
+
return function wrappedZLibNoSegment(...args) {
|
|
36
36
|
if (!shim.getActiveSegment()) {
|
|
37
|
-
return fn.apply(this,
|
|
37
|
+
return fn.apply(this, args)
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
41
40
|
const cbIndex = args.length - 1
|
|
42
41
|
|
|
43
42
|
shim.bindSegment(args, cbIndex)
|
|
@@ -68,8 +68,7 @@ const setupRouteHandler = (shim, fastify) => {
|
|
|
68
68
|
})
|
|
69
69
|
|
|
70
70
|
shim.wrap(fastify, 'addHook', function addWrapHook(shim, fn) {
|
|
71
|
-
return function wrappedAddHook() {
|
|
72
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
71
|
+
return function wrappedAddHook(...args) {
|
|
73
72
|
const hookName = args[0]
|
|
74
73
|
if (REQUEST_HOOKS.includes(hookName)) {
|
|
75
74
|
const middlewareFunction = args[1]
|
|
@@ -122,13 +121,12 @@ function setupMiddlewareHandlers(shim, fastify, isv3Plus) {
|
|
|
122
121
|
// This style is accomplished leveraging decorators. Both middie (which was built-in in v2)
|
|
123
122
|
// and fastify-express mount a 'use' function for mounting middleware.
|
|
124
123
|
shim.wrap(fastify, 'decorate', function wrapDecorate(shim, fn) {
|
|
125
|
-
return function wrappedDecorate() {
|
|
126
|
-
const name =
|
|
124
|
+
return function wrappedDecorate(...args) {
|
|
125
|
+
const name = args[0]
|
|
127
126
|
if (name !== 'use') {
|
|
128
|
-
return fn.apply(this,
|
|
127
|
+
return fn.apply(this, args)
|
|
129
128
|
}
|
|
130
129
|
|
|
131
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
132
130
|
args[1] = shim.wrapMiddlewareMounter(args[1], mounterSpec)
|
|
133
131
|
|
|
134
132
|
return fn.apply(this, args)
|
|
@@ -63,9 +63,7 @@ function wrapStart(shim, original) {
|
|
|
63
63
|
|
|
64
64
|
return shim.applySegment(callStart, segment, true, this, arguments)
|
|
65
65
|
|
|
66
|
-
function callStart() {
|
|
67
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
68
|
-
|
|
66
|
+
function callStart(...args) {
|
|
69
67
|
const originalMetadata = args[0]
|
|
70
68
|
const nrMetadata = originalMetadata.clone()
|
|
71
69
|
|
|
@@ -138,9 +136,7 @@ function wrapStart(shim, original) {
|
|
|
138
136
|
function wrapRegister(shim, original) {
|
|
139
137
|
const constants = shim.require('./build/src/constants')
|
|
140
138
|
|
|
141
|
-
return function wrappedRegister() {
|
|
142
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
143
|
-
|
|
139
|
+
return function wrappedRegister(...args) {
|
|
144
140
|
const name = args[0]
|
|
145
141
|
const handler = args[1]
|
|
146
142
|
const type = args[args.length - 1]
|
|
@@ -219,8 +215,7 @@ function wrapRegister(shim, original) {
|
|
|
219
215
|
const config = agent.config
|
|
220
216
|
if (!shim.isWrapped(stream.call.callEventTracker, 'onCallEnd')) {
|
|
221
217
|
shim.wrap(stream.call.callEventTracker, 'onCallEnd', function onCallEnd(shim, orig) {
|
|
222
|
-
return function wrappedOnCallEnd() {
|
|
223
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
218
|
+
return function wrappedOnCallEnd(...args) {
|
|
224
219
|
const [{ code: statusCode }] = args
|
|
225
220
|
transaction.trace.attributes.addAttribute(DESTINATION, 'response.status', statusCode)
|
|
226
221
|
if (shouldTrackError(statusCode, config)) {
|
|
@@ -24,8 +24,7 @@ const SEGMENT_PREFIX = 'kafkajs.Kafka.consumer#'
|
|
|
24
24
|
module.exports = wrapConsumer
|
|
25
25
|
|
|
26
26
|
function wrapConsumer(shim, orig) {
|
|
27
|
-
return function wrappedConsumer() {
|
|
28
|
-
const args = shim.argsToArray.apply(shim, arguments)
|
|
27
|
+
return function wrappedConsumer(...args) {
|
|
29
28
|
const consumer = orig.apply(this, args)
|
|
30
29
|
consumer[kafkaCtx] = this[kafkaCtx]
|
|
31
30
|
|
|
@@ -58,8 +57,7 @@ function wrapConsumer(shim, orig) {
|
|
|
58
57
|
|
|
59
58
|
function wrapRun(shim, fn) {
|
|
60
59
|
const agent = shim.agent
|
|
61
|
-
return function wrappedRun() {
|
|
62
|
-
const runArgs = shim.argsToArray.apply(shim, arguments)
|
|
60
|
+
return function wrappedRun(...runArgs) {
|
|
63
61
|
const brokers = this[kafkaCtx].brokers
|
|
64
62
|
if (runArgs?.[0]?.eachBatch) {
|
|
65
63
|
runArgs[0].eachBatch = shim.wrap(
|
|
@@ -14,8 +14,7 @@ const { kafkaCtx } = require('../../symbols')
|
|
|
14
14
|
module.exports = nrProducerWrapper
|
|
15
15
|
|
|
16
16
|
function nrProducerWrapper(shim, orig) {
|
|
17
|
-
return function nrProducer() {
|
|
18
|
-
const params = shim.argsToArray.apply(shim, arguments)
|
|
17
|
+
return function nrProducer(...params) {
|
|
19
18
|
const producer = orig.apply(this, params)
|
|
20
19
|
producer[kafkaCtx] = this[kafkaCtx]
|
|
21
20
|
|