newrelic 7.1.2 → 7.3.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 +97 -0
- package/THIRD_PARTY_NOTICES.md +33 -2
- package/bin/test-naming-rules.js +4 -4
- package/index.js +4 -2
- package/lib/agent.js +4 -0
- package/lib/collector/api.js +45 -18
- package/lib/collector/facts.js +22 -8
- package/lib/collector/http-agents.js +20 -7
- package/lib/collector/remote-method.js +32 -9
- package/lib/config/index.js +48 -39
- package/lib/feature_flags.js +6 -2
- package/lib/grpc/connection.js +39 -15
- package/lib/instrumentation/core/async_hooks.js +101 -14
- package/lib/instrumentation/core/http.js +5 -0
- package/lib/instrumentation/core/timers.js +6 -1
- package/lib/metrics/names.js +7 -1
- package/lib/shim/shim.js +6 -1
- package/lib/spans/create-span-event-aggregator.js +1 -0
- package/lib/spans/span-event.js +6 -3
- package/lib/spans/streaming-span-event.js +6 -3
- package/lib/transaction/index.js +36 -0
- package/newrelic.js +1 -1
- package/package.json +19 -7
- package/CONTRIBUTING.md +0 -135
- package/Migration Guide.md +0 -271
- package/ROADMAP_Node.md +0 -24
- package/SECURITY.md +0 -5
- package/THIRD_PARTY_NOTICES_ADDENDUM.md +0 -213
- package/bin/ca-gen.js +0 -91
- package/bin/cassandra-setup.sh +0 -11
- package/bin/check-workflow-run.js +0 -74
- package/bin/clean.sh +0 -18
- package/bin/compare-bench-results.js +0 -172
- package/bin/create-release.js +0 -74
- package/bin/docker-env-vars.sh +0 -15
- package/bin/docker-services.sh +0 -49
- package/bin/generate-release-notes.js +0 -126
- package/bin/github.js +0 -119
- package/bin/publish-docs.sh +0 -16
- package/bin/run-bench.js +0 -137
- package/bin/run-versioned-tests.sh +0 -32
- package/bin/smoke.sh +0 -8
- package/bin/ssl.sh +0 -87
- package/bin/travis-install-gcc5.sh +0 -13
- package/bin/travis-install-mongo.sh +0 -16
- package/bin/travis-node.sh +0 -57
- package/bin/travis-setup.sh +0 -52
- package/bin/update-ca-bundle.sh +0 -20
- package/bin/update-cats.sh +0 -8
- package/bin/update-changelog-version.js +0 -68
- package/jsdoc-conf.json +0 -18
- package/third_party_manifest.json +0 -619
package/NEWS.md
CHANGED
|
@@ -1,3 +1,100 @@
|
|
|
1
|
+
### v7.3.0 (2021-04-06)
|
|
2
|
+
|
|
3
|
+
* Added new feature-flag 'new_promise_tracking' which enables cleaning up of segment references on native promise resolve instead of destroy. Includes usage of async-await. This can be enabled via `feature_flag: { new_promise_tracking: true }` in the config file or `NEW_RELIC_FEATURE_FLAG_NEW_PROMISE_TRACKING=1` in your ENV vars.
|
|
4
|
+
|
|
5
|
+
Applications with heavy promise usage or high-throughput applications with some promise usage should see moderate to high reduction in memory usage and may see a slight reduction in CPU usage. A bump in throughput may also be noticed in some cases. Results will vary by application.
|
|
6
|
+
|
|
7
|
+
If you are experiencing high overhead levels with your promise usage and the agent attached, we recommend testing your application with 'new_promise_tracking' set to true to see if overhead is reduced. You'll also want to verify your data is still being captured correctly in case it falls into a known or unknown limitation of this approach. **NOTE: chaining of promise continuations onto an already resolved promise across an async hop (scheduled timer) will result in state-loss with this new functionality turned on. This is a less-common use-case but worth considering with your applications.**
|
|
8
|
+
|
|
9
|
+
* Fixed memory leak introduced when Infinite Tracing is enabled.
|
|
10
|
+
|
|
11
|
+
When Infinite Tracing endpoints reconnected they would instantiate a new gRPC client prior to calling `client.recordSpan()`. It appears several objects created by grpc-js (`ChannelImplementation` and child objects, promises, etc.) are held in memory indefinitely due to scheduled timers even when the client is no-longer referenced and the associated stream closed. We now avoid this situation by only creating the client once and then reusing it to establish new stream connections.
|
|
12
|
+
|
|
13
|
+
### v7.2.1 (2021-03-29)
|
|
14
|
+
|
|
15
|
+
* Dev-only sub-dependency bump of 'y18n' to clear npm audit warnings.
|
|
16
|
+
|
|
17
|
+
* Bumped @grpc/grpc-js to ^1.2.11.
|
|
18
|
+
|
|
19
|
+
* Bumped @grpc/proto-loader to ^0.5.6.
|
|
20
|
+
|
|
21
|
+
* Agent no longer propagates segments for promises via async-hooks when the transaction associated with the parentSegment has ended.
|
|
22
|
+
|
|
23
|
+
This change reduces the amount of context tracking work needed for certain rare edge-case scenarios involving promises.
|
|
24
|
+
|
|
25
|
+
* Fixed issue where capturing axios request errors could result in a memory leak.
|
|
26
|
+
|
|
27
|
+
The agent now clears error references on transaction end, which are not used for later processing. Errors returned from 'axios' requests contain a reference to the request object which deeper down has a handle to a promise in `handleRequestError`. The TraceSegment associated with that promise has a handle to the transaction, which through the error capture ultimately kept the promise in memory and prevented it from being destroyed to free-up the TraceSegment from the segment map. This change also has the benefit of freeing up some memory early for transactions held onto for transaction traces.
|
|
28
|
+
|
|
29
|
+
* Added active transaction check to `wrappedResEnd` to prevent unecessary work for ended transactions in the case of multiple `Response.prototype.end()` invocations.
|
|
30
|
+
|
|
31
|
+
### v7.2.0 (2021-03-23)
|
|
32
|
+
|
|
33
|
+
* Added feature flag to allow disabling of certificate bundle usage.
|
|
34
|
+
|
|
35
|
+
**Deprecation Warning:** The certificate bundle included by New Relic will be disabled by default and then fully removed in later major versions. We recommend testing with the certificate_bundle feature flag set to `false` to determine if you will need to modify your environment or setup your own appropriate bundle. Example configuration: `feature_flag: { certificate_bundle: false }`.
|
|
36
|
+
|
|
37
|
+
* The `NEW_RELIC_NO_CONFIG_FILE` environment variable is no longer needed to run the agent without a configuration file.
|
|
38
|
+
|
|
39
|
+
* If a configuration file is used with agent configuration environment variables, the environment variables will override the corresponding configuration file settings.
|
|
40
|
+
|
|
41
|
+
* Fixed bug where applications with multiple names on a dynamically named host (UUID like) would have instances consolidated, losing per-host breakdowns.
|
|
42
|
+
|
|
43
|
+
Removed 'host' from agent 'identifier' override to prevent server safety mechanism from kicking in. Host will still be used to identify unique agent instances, so was unnecessary to include as part of the identifier. This also resulted in additional processing overhead on the back-end. The identifier override is still kept in place with multiple application names to continue to allow uniquely identifying instances on the same host with multiple application names where the first name may be identical. For example `app_name['myName', 'unique1']` and `app_name['myName', 'unique2']`. These names would consolidate down into a single instance on the same host without the identifier override.
|
|
44
|
+
|
|
45
|
+
* Fixed bug where truncated http (external) or datastore segments would generate generic spans instead of appropriate http or datastore spans.
|
|
46
|
+
|
|
47
|
+
* Set distributed tracing to enabled in the `newrelic.js` template configuration file supplied with the agent.
|
|
48
|
+
|
|
49
|
+
* Added module root to shim.require() logging to aid debugging.
|
|
50
|
+
|
|
51
|
+
* Migrated from .npmignore to 'files' list in package.json to control which files are packaged.
|
|
52
|
+
|
|
53
|
+
Thank you to @JamesPeiris for the initial nudge via PR to move in this direction.
|
|
54
|
+
|
|
55
|
+
* Converted remaining collector unit tests to use tap API.
|
|
56
|
+
|
|
57
|
+
* Added linting to scripts in /bin folder.
|
|
58
|
+
|
|
59
|
+
Linting rules added are slightly more permissive than production rules and allow full ecma 8.
|
|
60
|
+
|
|
61
|
+
* Added new developer documentation to /docs folder.
|
|
62
|
+
|
|
63
|
+
This information is ported over from private GHE wiki used prior to going open source. S/O @astorm for original versions of the function wrapping and module instrumentation docs.
|
|
64
|
+
|
|
65
|
+
### v7.1.3 (2021-03-09)
|
|
66
|
+
|
|
67
|
+
* Bumped @grpc/grpc-js to ^1.2.7.
|
|
68
|
+
|
|
69
|
+
* Removed index-bad-config test which tested a no-longer possible use-case.
|
|
70
|
+
|
|
71
|
+
* Removed license-key test logic from serverless-harvest test.
|
|
72
|
+
|
|
73
|
+
Serverless mode does not require a license key as data transfer is handled by the integration.
|
|
74
|
+
|
|
75
|
+
* Added support metric to be able to track usage of cert bundle via usage of custom certificates.
|
|
76
|
+
|
|
77
|
+
* Removed requirement to configure application name when running in AWS Lambda (serverless mode).
|
|
78
|
+
|
|
79
|
+
Application name is not currently leveraged by New Relic for Lambda invocations. The agent now defaults the application name in serverless mode to remove the requirement of end-user configuration while handling cases if it were to be leveraged in the future.
|
|
80
|
+
|
|
81
|
+
* Stopped binding/propagating segments via `setImmediate` for ended transactions.
|
|
82
|
+
|
|
83
|
+
* Fixed bug where agent would attempt to call the 'preconnect' endpoint on the redirect host returned by the previous 'preconnect' call when reconnecting to the New Relic servers.
|
|
84
|
+
|
|
85
|
+
The 'preconnect' calls will now always use the original agent configuration value. Subsequent endpoints (connect, harvest endpoints, etc.) will continue to leverage the new redirect host value returned by 'preconnect.' The original config values are no-longer overridden.
|
|
86
|
+
|
|
87
|
+
* Fixed issue where a call to `transaction.acceptDistributedTraceHeaders` would throw an error when the `headers` parameter is a string.
|
|
88
|
+
|
|
89
|
+
* Improved clarity of logging between 'no log file' or disabled agent startup issues.
|
|
90
|
+
|
|
91
|
+
* Logs no-config file error to initialized logger (stdout) in addition to existing console.error() logging.
|
|
92
|
+
* Adds specific message to no config file separate from being disabled.
|
|
93
|
+
|
|
94
|
+
* Removed aws-sdk versioned test filtering.
|
|
95
|
+
|
|
96
|
+
* Removed unused Travis CI scripts.
|
|
97
|
+
|
|
1
98
|
### v7.1.2 (2021-02-24)
|
|
2
99
|
|
|
3
100
|
* Fixed bug where the agent failed to reconnect to Infinite Tracing gRPC streams on Status OK at higher log levels.
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -41,6 +41,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
|
|
|
41
41
|
* [benchmark](#benchmark)
|
|
42
42
|
* [bluebird](#bluebird)
|
|
43
43
|
* [chai](#chai)
|
|
44
|
+
* [commander](#commander)
|
|
44
45
|
* [eslint](#eslint)
|
|
45
46
|
* [express](#express)
|
|
46
47
|
* [fastify](#fastify)
|
|
@@ -74,7 +75,7 @@ code, the source code can be found at [https://github.com/newrelic/node-newrelic
|
|
|
74
75
|
|
|
75
76
|
### @grpc/grpc-js
|
|
76
77
|
|
|
77
|
-
This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.2.
|
|
78
|
+
This product includes source derived from [@grpc/grpc-js](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) ([v1.2.11](https://github.com/grpc/grpc-node/tree/%40grpc/grpc-js%401.2.11/packages/grpc-js)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/blob/%40grpc/grpc-js%401.2.11/packages/grpc-js/LICENSE):
|
|
78
79
|
|
|
79
80
|
```
|
|
80
81
|
Apache License
|
|
@@ -283,7 +284,7 @@ This product includes source derived from [@grpc/grpc-js](https://github.com/grp
|
|
|
283
284
|
|
|
284
285
|
### @grpc/proto-loader
|
|
285
286
|
|
|
286
|
-
This product includes source derived from [@grpc/proto-loader](https://github.com/grpc/grpc-node) ([v0.5.
|
|
287
|
+
This product includes source derived from [@grpc/proto-loader](https://github.com/grpc/grpc-node) ([v0.5.6](https://github.com/grpc/grpc-node/tree/%40grpc/proto-loader%400.5.6/packages/proto-loader)), distributed under the [Apache-2.0 License](https://github.com/grpc/grpc-node/blob/%40grpc/proto-loader%400.5.6/packages/proto-loader/LICENSE):
|
|
287
288
|
|
|
288
289
|
```
|
|
289
290
|
Apache License
|
|
@@ -1924,6 +1925,36 @@ SOFTWARE.
|
|
|
1924
1925
|
|
|
1925
1926
|
```
|
|
1926
1927
|
|
|
1928
|
+
### commander
|
|
1929
|
+
|
|
1930
|
+
This product includes source derived from [commander](https://github.com/tj/commander.js) ([v7.0.0](https://github.com/tj/commander.js/tree/v7.0.0)), distributed under the [MIT License](https://github.com/tj/commander.js/blob/v7.0.0/LICENSE):
|
|
1931
|
+
|
|
1932
|
+
```
|
|
1933
|
+
(The MIT License)
|
|
1934
|
+
|
|
1935
|
+
Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
|
|
1936
|
+
|
|
1937
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
1938
|
+
a copy of this software and associated documentation files (the
|
|
1939
|
+
'Software'), to deal in the Software without restriction, including
|
|
1940
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
1941
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
1942
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
1943
|
+
the following conditions:
|
|
1944
|
+
|
|
1945
|
+
The above copyright notice and this permission notice shall be
|
|
1946
|
+
included in all copies or substantial portions of the Software.
|
|
1947
|
+
|
|
1948
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
1949
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
1950
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
1951
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
1952
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
1953
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
1954
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
1955
|
+
|
|
1956
|
+
```
|
|
1957
|
+
|
|
1927
1958
|
### eslint
|
|
1928
1959
|
|
|
1929
1960
|
This product includes source derived from [eslint](https://github.com/eslint/eslint) ([v6.8.0](https://github.com/eslint/eslint/tree/v6.8.0)), distributed under the [MIT License](https://github.com/eslint/eslint/blob/v6.8.0/LICENSE):
|
package/bin/test-naming-rules.js
CHANGED
|
@@ -15,13 +15,13 @@ var urltils = require('../lib/util/urltils')
|
|
|
15
15
|
var MetricNormalizer = require('../lib/metrics/normalizer')
|
|
16
16
|
|
|
17
17
|
var cwd = process.cwd()
|
|
18
|
-
var
|
|
18
|
+
var options = null
|
|
19
19
|
if (arrayContainsAny(process.argv, '-h', '-?', '--help')) {
|
|
20
20
|
printHelp()
|
|
21
21
|
} else if (process.argv.length === 3) {
|
|
22
|
-
|
|
22
|
+
options = {rules: null, urls: path.resolve(cwd, process.argv[2])}
|
|
23
23
|
} else if (process.argv.length === 4) {
|
|
24
|
-
|
|
24
|
+
options = {
|
|
25
25
|
rules: path.resolve(cwd, process.argv[2]),
|
|
26
26
|
urls: path.resolve(cwd, process.argv[3])
|
|
27
27
|
}
|
|
@@ -29,7 +29,7 @@ if (arrayContainsAny(process.argv, '-h', '-?', '--help')) {
|
|
|
29
29
|
printHelp()
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
run(
|
|
32
|
+
run(options)
|
|
33
33
|
|
|
34
34
|
function printHelp() {
|
|
35
35
|
console.log('Usage:')
|
package/index.js
CHANGED
|
@@ -76,8 +76,10 @@ function initialize() {
|
|
|
76
76
|
// just pipes to stdout.
|
|
77
77
|
logger = require('./lib/logger')
|
|
78
78
|
|
|
79
|
-
if (!config
|
|
80
|
-
logger.info('
|
|
79
|
+
if (!config) {
|
|
80
|
+
logger.info('No configuration detected. Not starting.')
|
|
81
|
+
} else if (!config.agent_enabled) {
|
|
82
|
+
logger.info('Module disabled in configuration. Not starting.')
|
|
81
83
|
} else {
|
|
82
84
|
agent = createAgent(config)
|
|
83
85
|
addStartupSupportabilities(agent)
|
package/lib/agent.js
CHANGED
|
@@ -458,6 +458,10 @@ Agent.prototype.onConnect = function onConnect() {
|
|
|
458
458
|
this.spanEventAggregator.reconfigure(this.config)
|
|
459
459
|
this.transactionEventAggregator.reconfigure(this.config)
|
|
460
460
|
this.customEventAggregator.reconfigure(this.config)
|
|
461
|
+
|
|
462
|
+
if (this.config.certificates && this.config.certificates.length > 0) {
|
|
463
|
+
this.metrics.getOrCreateMetric(NAMES.FEATURES.CERTIFICATES).incrementCallCount()
|
|
464
|
+
}
|
|
461
465
|
}
|
|
462
466
|
|
|
463
467
|
/**
|
package/lib/collector/api.js
CHANGED
|
@@ -12,6 +12,8 @@ const RemoteMethod = require('./remote-method')
|
|
|
12
12
|
|
|
13
13
|
const NAMES = require('../metrics/names')
|
|
14
14
|
|
|
15
|
+
const DEFAULT_PORT = 443
|
|
16
|
+
|
|
15
17
|
// just to make clear what's going on
|
|
16
18
|
const TO_MILLIS = 1e3
|
|
17
19
|
|
|
@@ -54,22 +56,41 @@ function CollectorAPI(agent) {
|
|
|
54
56
|
this._agent = agent
|
|
55
57
|
this._reqHeadersMap = null
|
|
56
58
|
|
|
59
|
+
const initialEndpoint = {
|
|
60
|
+
host: agent.config.host,
|
|
61
|
+
port: agent.config.port
|
|
62
|
+
}
|
|
63
|
+
|
|
57
64
|
/* RemoteMethods can be reused and have little per-object state, so why not
|
|
58
65
|
* save some GC time?
|
|
59
66
|
*/
|
|
60
67
|
this._methods = {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
settings: new RemoteMethod('agent_settings', agent.config),
|
|
64
|
-
errors: new RemoteMethod('error_data', agent.config),
|
|
65
|
-
metrics: new RemoteMethod('metric_data', agent.config),
|
|
66
|
-
traces: new RemoteMethod('transaction_sample_data', agent.config),
|
|
67
|
-
shutdown: new RemoteMethod('shutdown', agent.config),
|
|
68
|
-
events: new RemoteMethod('analytic_event_data', agent.config),
|
|
69
|
-
customEvents: new RemoteMethod('custom_event_data', agent.config),
|
|
70
|
-
queryData: new RemoteMethod('sql_trace_data', agent.config),
|
|
71
|
-
errorEvents: new RemoteMethod('error_event_data', agent.config),
|
|
72
|
-
spanEvents: new RemoteMethod('span_event_data', agent.config)
|
|
68
|
+
preconnect: new RemoteMethod('preconnect', agent.config, initialEndpoint),
|
|
69
|
+
connect: new RemoteMethod('connect', agent.config, initialEndpoint),
|
|
70
|
+
settings: new RemoteMethod('agent_settings', agent.config, initialEndpoint),
|
|
71
|
+
errors: new RemoteMethod('error_data', agent.config, initialEndpoint),
|
|
72
|
+
metrics: new RemoteMethod('metric_data', agent.config, initialEndpoint),
|
|
73
|
+
traces: new RemoteMethod('transaction_sample_data', agent.config, initialEndpoint),
|
|
74
|
+
shutdown: new RemoteMethod('shutdown', agent.config, initialEndpoint),
|
|
75
|
+
events: new RemoteMethod('analytic_event_data', agent.config, initialEndpoint),
|
|
76
|
+
customEvents: new RemoteMethod('custom_event_data', agent.config, initialEndpoint),
|
|
77
|
+
queryData: new RemoteMethod('sql_trace_data', agent.config, initialEndpoint),
|
|
78
|
+
errorEvents: new RemoteMethod('error_event_data', agent.config, initialEndpoint),
|
|
79
|
+
spanEvents: new RemoteMethod('span_event_data', agent.config, initialEndpoint)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Updates all methods except preconnect w/ new host/port pairs sent down from server
|
|
85
|
+
* during preconnect (via redirect_host). Preconnect does not update.
|
|
86
|
+
*/
|
|
87
|
+
CollectorAPI.prototype._updateEndpoints = function _updateEndpoints(endpoint) {
|
|
88
|
+
logger.trace('Updating endpoints to: ', endpoint)
|
|
89
|
+
for (const [key, remoteMethod] of Object.entries(this._methods)) {
|
|
90
|
+
// Preconnect should always use configured options, not updates from server.
|
|
91
|
+
if (key !== 'preconnect') {
|
|
92
|
+
remoteMethod.updateEndpoint(endpoint)
|
|
93
|
+
}
|
|
73
94
|
}
|
|
74
95
|
}
|
|
75
96
|
|
|
@@ -160,7 +181,7 @@ CollectorAPI.prototype._login = function _login(callback) {
|
|
|
160
181
|
|
|
161
182
|
const payload = [preconnectData]
|
|
162
183
|
|
|
163
|
-
methods.
|
|
184
|
+
methods.preconnect.invoke(payload, onPreConnect)
|
|
164
185
|
|
|
165
186
|
function onPreConnect(error, response) {
|
|
166
187
|
if (error || !SUCCESS.has(response.status)) {
|
|
@@ -188,8 +209,13 @@ CollectorAPI.prototype._login = function _login(callback) {
|
|
|
188
209
|
res.redirect_host
|
|
189
210
|
)
|
|
190
211
|
|
|
191
|
-
|
|
192
|
-
|
|
212
|
+
const [host, port] = parts
|
|
213
|
+
const newEndpoint = {
|
|
214
|
+
host: host,
|
|
215
|
+
port: port || DEFAULT_PORT
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
self._updateEndpoints(newEndpoint)
|
|
193
219
|
}
|
|
194
220
|
}
|
|
195
221
|
|
|
@@ -226,7 +252,7 @@ CollectorAPI.prototype._connect = function _connect(env, callback) {
|
|
|
226
252
|
const methods = this._methods
|
|
227
253
|
const agent = this._agent
|
|
228
254
|
|
|
229
|
-
methods.
|
|
255
|
+
methods.connect.invoke(env, onConnect)
|
|
230
256
|
|
|
231
257
|
function onConnect(error, res) {
|
|
232
258
|
if (error || !SUCCESS.has(res.status)) {
|
|
@@ -239,10 +265,11 @@ CollectorAPI.prototype._connect = function _connect(env, callback) {
|
|
|
239
265
|
}
|
|
240
266
|
|
|
241
267
|
agent.setState('connected')
|
|
268
|
+
|
|
242
269
|
logger.info(
|
|
243
270
|
'Connected to %s:%d with agent run ID %s.',
|
|
244
|
-
|
|
245
|
-
|
|
271
|
+
methods.connect.endpoint.host,
|
|
272
|
+
methods.connect.endpoint.port,
|
|
246
273
|
config.agent_run_id
|
|
247
274
|
)
|
|
248
275
|
|
package/lib/collector/facts.js
CHANGED
|
@@ -64,14 +64,7 @@ function facts(agent, callback) {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
// or for the first transaction, add the `port` for the server too.
|
|
69
|
-
// NOTE: The concat is necessary to prevent sort from happening in-place.
|
|
70
|
-
results.identifier = [
|
|
71
|
-
'nodejs',
|
|
72
|
-
results.host,
|
|
73
|
-
results.app_name.concat([]).sort().join(',')
|
|
74
|
-
].join(':')
|
|
67
|
+
results.identifier = getIdentifierOverride(results.app_name)
|
|
75
68
|
|
|
76
69
|
const ipAddresses = getAllIPAddresses()
|
|
77
70
|
if (ipAddresses.length) {
|
|
@@ -112,3 +105,24 @@ function getAllIPAddresses() {
|
|
|
112
105
|
return addresses
|
|
113
106
|
}, [])
|
|
114
107
|
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Creates an identifier override to support customers who have multiple agents on the
|
|
111
|
+
* same host with the first app name that is identical.
|
|
112
|
+
* https://github.com/newrelic/node-newrelic/commit/c0901e6807a50ac3969d79ab48c31c8e0232a6b5#r18254962
|
|
113
|
+
* https://source.datanerd.us/collector-collective/connect-service/blob/1470c21109393a5b43c8788da88a37f41a300b98/src/main/java/com/nr/collector/methods/Connect.java#L1424-L1431
|
|
114
|
+
*
|
|
115
|
+
* IMPORTANT: we do not include host as it has negative consequences and is unnecessary.
|
|
116
|
+
* On the server, the host will still be used as part of the key to determine if two agent
|
|
117
|
+
* connections are the same real agent or a separate one.
|
|
118
|
+
* https://github.com/newrelic/node-newrelic/issues/654
|
|
119
|
+
*/
|
|
120
|
+
function getIdentifierOverride(appNames) {
|
|
121
|
+
const identifier = [
|
|
122
|
+
'nodejs',
|
|
123
|
+
// NOTE: The concat is necessary to prevent sort from happening in-place.
|
|
124
|
+
appNames.concat([]).sort().join(',')
|
|
125
|
+
].join(':')
|
|
126
|
+
|
|
127
|
+
return identifier
|
|
128
|
+
}
|
|
@@ -103,14 +103,27 @@ function proxyOptions(config) {
|
|
|
103
103
|
proxy_url: proxy_url
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
// merge user certificates with built-in certs
|
|
107
|
-
|
|
108
106
|
if (config.certificates && config.certificates.length > 0) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
)
|
|
113
|
-
|
|
107
|
+
opts.certificates = config.certificates
|
|
108
|
+
|
|
109
|
+
// merge user certificates with built-in certs
|
|
110
|
+
if (config.feature_flag.certificate_bundle) {
|
|
111
|
+
logger.info(
|
|
112
|
+
'Using a proxy with a special cert. This enables our cert bundle which, combined ' +
|
|
113
|
+
'with some versions of node, exacerbates a leak in node core TLS.'
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
const certWarningMessage = [
|
|
117
|
+
'Deprecation Warning: The certificate bundle included by New Relic will be ',
|
|
118
|
+
'disabled by default and then fully removed in later major versions. We recommend ',
|
|
119
|
+
'testing with the certificate_bundle feature flag set to `false` to determine if ',
|
|
120
|
+
'you will need to modify your environment or setup your own appropriate bundle. ',
|
|
121
|
+
'Example configuration: feature_flag: { certificate_bundle: false }.'
|
|
122
|
+
].join('')
|
|
123
|
+
logger.warnOnce('CERT_WARNING', certWarningMessage)
|
|
124
|
+
|
|
125
|
+
opts.certificates = config.certificates.concat(certificates)
|
|
126
|
+
}
|
|
114
127
|
}
|
|
115
128
|
|
|
116
129
|
return opts
|
|
@@ -29,15 +29,24 @@ const USER_AGENT_FORMAT = 'NewRelic-NodeAgent/%s (nodejs %s %s-%s)'
|
|
|
29
29
|
const ENCODING_HEADER = 'CONTENT-ENCODING'
|
|
30
30
|
const DEFAULT_ENCODING = 'identity'
|
|
31
31
|
|
|
32
|
-
function RemoteMethod(name, config) {
|
|
32
|
+
function RemoteMethod(name, config, endpoint) {
|
|
33
33
|
if (!name) {
|
|
34
34
|
throw new TypeError('Must include name of method to invoke on collector.')
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
this.name = name
|
|
38
38
|
this._config = config
|
|
39
|
-
|
|
40
39
|
this._protocolVersion = 17
|
|
40
|
+
|
|
41
|
+
this.endpoint = endpoint
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
RemoteMethod.prototype.updateEndpoint = function updateEndpoint(endpoint) {
|
|
45
|
+
if (!endpoint) {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
this.endpoint = endpoint
|
|
41
50
|
}
|
|
42
51
|
|
|
43
52
|
RemoteMethod.prototype.serialize = function serialize(payload, callback) {
|
|
@@ -88,8 +97,8 @@ RemoteMethod.prototype.invoke = function invoke(payload, nrHeaders, callback) {
|
|
|
88
97
|
RemoteMethod.prototype._post = function _post(data, nrHeaders, callback) {
|
|
89
98
|
var method = this
|
|
90
99
|
var options = {
|
|
91
|
-
port: this.
|
|
92
|
-
host: this.
|
|
100
|
+
port: this.endpoint.port,
|
|
101
|
+
host: this.endpoint.host,
|
|
93
102
|
compressed: this._shouldCompress(data),
|
|
94
103
|
path: this._path(),
|
|
95
104
|
onError: callback,
|
|
@@ -254,10 +263,24 @@ RemoteMethod.prototype._request = function _request(options) {
|
|
|
254
263
|
request = https.request(requestOptions)
|
|
255
264
|
} else {
|
|
256
265
|
if (this._config.certificates && this._config.certificates.length > 0) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
)
|
|
260
|
-
|
|
266
|
+
requestOptions.ca = this._config.certificates
|
|
267
|
+
|
|
268
|
+
if (this._config.feature_flag.certificate_bundle) {
|
|
269
|
+
logger.debug(
|
|
270
|
+
'Adding custom certificate to the cert bundle.'
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
const certWarningMessage = [
|
|
274
|
+
'Deprecation Warning: The certificate bundle included by New Relic will be ',
|
|
275
|
+
'disabled by default and then fully removed in later major versions. We recommend ',
|
|
276
|
+
'testing with the certificate_bundle feature flag set to `false` to determine if ',
|
|
277
|
+
'you will need to modify your environment or setup your own appropriate bundle. ',
|
|
278
|
+
'Example configuration: feature_flag: { certificate_bundle: false }.'
|
|
279
|
+
].join('')
|
|
280
|
+
logger.warnOnce('CERT_WARNING', certWarningMessage)
|
|
281
|
+
|
|
282
|
+
requestOptions.ca = this._config.certificates.concat(certificates)
|
|
283
|
+
}
|
|
261
284
|
}
|
|
262
285
|
request = https.request(requestOptions)
|
|
263
286
|
}
|
|
@@ -317,7 +340,7 @@ RemoteMethod.prototype._headers = function _headers(options) {
|
|
|
317
340
|
|
|
318
341
|
var headers = {
|
|
319
342
|
// select the virtual host on the server end
|
|
320
|
-
'Host': this.
|
|
343
|
+
'Host': this.endpoint.host,
|
|
321
344
|
'User-Agent': agent,
|
|
322
345
|
'Connection': 'Keep-Alive',
|
|
323
346
|
'Content-Length': byteLength(options.body),
|
package/lib/config/index.js
CHANGED
|
@@ -1098,6 +1098,8 @@ Config.prototype._fromEnvironment = function _fromEnvironment(metadata, data) {
|
|
|
1098
1098
|
if (typeof node === 'string') {
|
|
1099
1099
|
var setting = process.env[node]
|
|
1100
1100
|
if (setting) {
|
|
1101
|
+
logger.debug(`${node} environment variable set.`)
|
|
1102
|
+
|
|
1101
1103
|
if (ENV.LIST_VARS.has(node)) {
|
|
1102
1104
|
let split = ENV.LIST_VARS_CUSTOM_DELIMITERS[node] || /,/
|
|
1103
1105
|
data[value] = setting.split(split).map(function trimVal(k) {
|
|
@@ -1188,6 +1190,20 @@ Config.prototype._DTManuallySet = function _DTManuallySet(inputConfig) {
|
|
|
1188
1190
|
*/
|
|
1189
1191
|
Config.prototype._enforceServerless = function _enforceServerless(inputConfig) {
|
|
1190
1192
|
if (this.serverless_mode.enabled) {
|
|
1193
|
+
// Application name is not currently leveraged by our Lambda product (March 2021).
|
|
1194
|
+
// Defaulting the name removes burden on customers to set while avoiding
|
|
1195
|
+
// breaking should it be used in the future.
|
|
1196
|
+
if (!this.app_name || this.app_name.length === 0) {
|
|
1197
|
+
const namingSource = process.env.AWS_LAMBDA_FUNCTION_NAME
|
|
1198
|
+
? 'process.env.AWS_LAMBDA_FUNCTION_NAME'
|
|
1199
|
+
: 'DEFAULT'
|
|
1200
|
+
|
|
1201
|
+
const name = process.env.AWS_LAMBDA_FUNCTION_NAME || 'Serverless Application'
|
|
1202
|
+
this.app_name = [name]
|
|
1203
|
+
|
|
1204
|
+
logger.info('Auto-naming serverless application to [\'%s\'] from: %s', name, namingSource)
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1191
1207
|
// Explicitly disable old CAT in serverless_mode
|
|
1192
1208
|
if (this.cross_application_tracer.enabled) {
|
|
1193
1209
|
this.cross_application_tracer.enabled = false
|
|
@@ -1602,11 +1618,9 @@ Config.prototype.getAggregatorConfig = function getAggregatorConfig(method) {
|
|
|
1602
1618
|
* 5. If this module is installed as a dependency, the directory above the
|
|
1603
1619
|
* node_modules folder in which newrelic is installed.
|
|
1604
1620
|
*
|
|
1605
|
-
*
|
|
1606
|
-
*
|
|
1607
|
-
*
|
|
1608
|
-
* necessary, as well as a complete enumeration of the other available
|
|
1609
|
-
* variables.
|
|
1621
|
+
* When node process environment varaibles and a config file are used,
|
|
1622
|
+
* the environment variables will override their corresponding
|
|
1623
|
+
* configuration file settings.
|
|
1610
1624
|
*
|
|
1611
1625
|
* @param {object} config Optional configuration to be used in place of a
|
|
1612
1626
|
* config file.
|
|
@@ -1622,15 +1636,22 @@ function initialize(config) {
|
|
|
1622
1636
|
if (config) return new Config(config)
|
|
1623
1637
|
|
|
1624
1638
|
if (isTruthular(process.env.NEW_RELIC_NO_CONFIG_FILE)) {
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
return config
|
|
1639
|
+
logger.info('NEW_RELIC_NO_CONFIG_FILE set, deferring to environment variables.')
|
|
1640
|
+
|
|
1641
|
+
return createNewConfigObject(config)
|
|
1628
1642
|
}
|
|
1629
1643
|
|
|
1630
1644
|
var filepath = _findConfigFile()
|
|
1631
1645
|
if (!filepath) {
|
|
1632
|
-
|
|
1633
|
-
|
|
1646
|
+
logger.info(['Unable to find configuration file.',
|
|
1647
|
+
'If a configuration file is desired (common for non-containerized environments),',
|
|
1648
|
+
`a base configuration file can be copied from ${BASE_CONFIG_PATH}`,
|
|
1649
|
+
'and renamed to "newrelic.js" in the directory from which you will start',
|
|
1650
|
+
'your application.',
|
|
1651
|
+
'Attempting to start agent using environment variables.'
|
|
1652
|
+
].join(' '))
|
|
1653
|
+
|
|
1654
|
+
return createNewConfigObject(config)
|
|
1634
1655
|
}
|
|
1635
1656
|
|
|
1636
1657
|
var userConf
|
|
@@ -1639,12 +1660,16 @@ function initialize(config) {
|
|
|
1639
1660
|
} catch (error) {
|
|
1640
1661
|
logger.error(error)
|
|
1641
1662
|
|
|
1642
|
-
|
|
1643
|
-
`Unable to read configuration file "${filepath}".`,
|
|
1644
|
-
|
|
1645
|
-
'
|
|
1646
|
-
'
|
|
1647
|
-
].join('
|
|
1663
|
+
logger.warn([
|
|
1664
|
+
`Unable to read existing configuration file "${filepath}".`,
|
|
1665
|
+
'To allow reading of the file (if desired),',
|
|
1666
|
+
'please ensure the application has read access and the file is exporting valid JSON.',
|
|
1667
|
+
'Attempting to start agent using enviornment variables.'
|
|
1668
|
+
].join(' '))
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
if (!userConf) {
|
|
1672
|
+
return createNewConfigObject(config)
|
|
1648
1673
|
}
|
|
1649
1674
|
|
|
1650
1675
|
config = new Config(userConf)
|
|
@@ -1656,29 +1681,13 @@ function initialize(config) {
|
|
|
1656
1681
|
return config
|
|
1657
1682
|
}
|
|
1658
1683
|
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
)
|
|
1667
|
-
|
|
1668
|
-
let locations = mainpath
|
|
1669
|
-
if (mainpath !== altpath) {
|
|
1670
|
-
locations += ' or\n' + altpath
|
|
1671
|
-
}
|
|
1672
|
-
|
|
1673
|
-
/* eslint-disable no-console */
|
|
1674
|
-
console.error([
|
|
1675
|
-
'Unable to find New Relic module configuration. A base configuration file',
|
|
1676
|
-
`can be copied from ${BASE_CONFIG_PATH}`,
|
|
1677
|
-
`and put at ${locations}.`,
|
|
1678
|
-
'If you are not using file-based configuration, please set the environment',
|
|
1679
|
-
'variable `NEW_RELIC_NO_CONFIG_FILE=true`.'
|
|
1680
|
-
].join('\n'))
|
|
1681
|
-
/* eslint-enable no-console */
|
|
1684
|
+
/**
|
|
1685
|
+
* This helper function creates an empty configuration object
|
|
1686
|
+
*/
|
|
1687
|
+
function createNewConfigObject(config) {
|
|
1688
|
+
config = new Config(Object.create(null))
|
|
1689
|
+
if (config.newrelic_home) delete config.newrelic_home
|
|
1690
|
+
return config
|
|
1682
1691
|
}
|
|
1683
1692
|
|
|
1684
1693
|
/**
|
package/lib/feature_flags.js
CHANGED
|
@@ -9,10 +9,14 @@
|
|
|
9
9
|
exports.prerelease = {
|
|
10
10
|
express5: false,
|
|
11
11
|
await_support: true,
|
|
12
|
-
serverless_mode: true,
|
|
12
|
+
serverless_mode: true, // TODO: Move to released & remove code checks next Major.
|
|
13
13
|
promise_segments: false,
|
|
14
14
|
reverse_naming_rules: false,
|
|
15
|
-
fastify_instrumentation: false
|
|
15
|
+
fastify_instrumentation: false,
|
|
16
|
+
// Starts by defaulting true as introducing for deprecation/removal purposes.
|
|
17
|
+
// Will eventually set false prior full removal of feature.
|
|
18
|
+
certificate_bundle: true,
|
|
19
|
+
new_promise_tracking: false
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
// flags that are no longer used for released features
|