newrelic 8.0.0 → 8.4.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 +5023 -4922
- package/THIRD_PARTY_NOTICES.md +618 -209
- package/api.js +156 -219
- package/bin/test-naming-rules.js +57 -51
- package/bin/tracetractor +0 -1
- package/index.js +7 -14
- package/lib/agent.js +111 -114
- package/lib/aggregators/base-aggregator.js +1 -1
- package/lib/aggregators/event-aggregator.js +6 -6
- package/lib/attributes.js +13 -14
- package/lib/collector/api.js +44 -54
- package/lib/collector/facts.js +68 -66
- package/lib/collector/http-agents.js +36 -32
- package/lib/collector/key-parser.js +1 -1
- package/lib/collector/parse-response.js +1 -2
- package/lib/collector/remote-method.js +69 -61
- package/lib/collector/serverless.js +13 -18
- package/lib/collector/ssl/certificates.js +1056 -1056
- package/lib/config/attribute-filter.js +109 -101
- package/lib/config/default.js +35 -21
- package/lib/config/env.js +17 -12
- package/lib/config/harvest-config-validator.js +1 -1
- package/lib/config/hsm.js +1 -1
- package/lib/config/index.js +240 -234
- package/lib/config/lasp.js +3 -3
- package/lib/config/merge-server-config.js +8 -6
- package/lib/custom-events/custom-event-aggregator.js +1 -1
- package/lib/db/parse-sql.js +13 -16
- package/lib/db/parsed-statement.js +13 -19
- package/lib/db/query-parsers/sql.js +12 -15
- package/lib/db/query-sample.js +16 -12
- package/lib/db/query-trace-aggregator.js +16 -16
- package/lib/db/statement-matcher.js +5 -5
- package/lib/db/utils.js +2 -2
- package/lib/environment.js +210 -175
- package/lib/errors/error-collector.js +20 -33
- package/lib/errors/error-event-aggregator.js +1 -1
- package/lib/errors/error-trace-aggregator.js +3 -4
- package/lib/errors/helper.js +23 -32
- package/lib/errors/index.js +31 -43
- package/lib/feature_flags.js +3 -4
- package/lib/grpc/connection/states.js +6 -6
- package/lib/grpc/connection.js +35 -46
- package/lib/header-attributes.js +55 -59
- package/lib/header-processing.js +1 -1
- package/lib/instrumentation/amqplib.js +34 -43
- package/lib/instrumentation/bluebird.js +63 -22
- package/lib/instrumentation/cassandra-driver.js +8 -4
- package/lib/instrumentation/connect.js +7 -6
- package/lib/instrumentation/core/async_hooks.js +16 -9
- package/lib/instrumentation/core/child_process.js +20 -28
- package/lib/instrumentation/core/crypto.js +1 -7
- package/lib/instrumentation/core/dns.js +3 -7
- package/lib/instrumentation/core/domain.js +4 -10
- package/lib/instrumentation/core/fs.js +22 -37
- package/lib/instrumentation/core/globals.js +4 -8
- package/lib/instrumentation/core/http-outbound.js +20 -114
- package/lib/instrumentation/core/http.js +61 -128
- package/lib/instrumentation/core/inspector.js +7 -11
- package/lib/instrumentation/core/net.js +3 -1
- package/lib/instrumentation/core/timers.js +21 -28
- package/lib/instrumentation/core/zlib.js +3 -11
- package/lib/instrumentation/director.js +4 -4
- package/lib/instrumentation/express.js +12 -10
- package/lib/instrumentation/fastify/spec-builders.js +5 -0
- package/lib/instrumentation/fastify.js +37 -10
- package/lib/instrumentation/generic-pool.js +1 -1
- package/lib/instrumentation/hapi/hapi-17.js +20 -21
- package/lib/instrumentation/hapi/shared.js +1 -1
- package/lib/instrumentation/hapi.js +37 -37
- package/lib/instrumentation/ioredis.js +8 -9
- package/lib/instrumentation/memcached.js +41 -45
- package/lib/instrumentation/mongodb/common.js +221 -0
- package/lib/instrumentation/mongodb/constants.js +87 -0
- package/lib/instrumentation/mongodb/v2-mongo.js +110 -0
- package/lib/instrumentation/mongodb/v3-mongo.js +80 -0
- package/lib/instrumentation/mongodb/v4-mongo.js +90 -0
- package/lib/instrumentation/mongodb.js +20 -312
- package/lib/instrumentation/mysql.js +51 -44
- package/lib/instrumentation/oracle.js +24 -28
- package/lib/instrumentation/pg.js +34 -25
- package/lib/instrumentation/promise.js +65 -62
- package/lib/instrumentation/q.js +2 -2
- package/lib/instrumentation/redis.js +38 -38
- package/lib/instrumentation/restify.js +1 -1
- package/lib/instrumentation/vision.js +4 -4
- package/lib/instrumentation/when.js +12 -4
- package/lib/instrumentations.js +25 -25
- package/lib/logger.js +6 -6
- package/lib/metrics/index.js +50 -30
- package/lib/metrics/mapper.js +15 -15
- package/lib/metrics/metric-aggregator.js +5 -10
- package/lib/metrics/names.js +8 -7
- package/lib/metrics/normalizer/rule.js +14 -15
- package/lib/metrics/normalizer/tx_segment.js +33 -29
- package/lib/metrics/normalizer.js +51 -54
- package/lib/metrics/recorders/custom.js +8 -6
- package/lib/metrics/recorders/distributed-trace.js +3 -18
- package/lib/metrics/recorders/generic.js +6 -5
- package/lib/metrics/recorders/http.js +11 -13
- package/lib/metrics/recorders/http_external.js +8 -10
- package/lib/metrics/recorders/message-transaction.js +7 -18
- package/lib/metrics/recorders/other.js +7 -17
- package/lib/parse-proc-cpuinfo.js +26 -31
- package/lib/parse-proc-meminfo.js +5 -3
- package/lib/prioritized-attributes.js +14 -19
- package/lib/priority-queue.js +11 -11
- package/lib/proxy/grpc.js +1 -1
- package/lib/reservoir.js +12 -6
- package/lib/sampler.js +33 -34
- package/lib/serverless/api-gateway.js +3 -3
- package/lib/serverless/aws-lambda.js +28 -37
- package/lib/shim/conglomerate-shim.js +4 -4
- package/lib/shim/datastore-shim.js +61 -67
- package/lib/shim/index.js +10 -11
- package/lib/shim/message-shim.js +149 -151
- package/lib/shim/promise-shim.js +19 -14
- package/lib/shim/shim.js +131 -125
- package/lib/shim/specs/index.js +21 -22
- package/lib/shim/transaction-shim.js +52 -210
- package/lib/shim/webframework-shim.js +75 -85
- package/lib/shimmer.js +184 -166
- package/lib/spans/create-span-event-aggregator.js +11 -8
- package/lib/spans/span-context.js +4 -10
- package/lib/spans/span-event-aggregator.js +68 -13
- package/lib/spans/span-event.js +6 -8
- package/lib/spans/span-streamer.js +10 -18
- package/lib/spans/streaming-span-attributes.js +1 -1
- package/lib/spans/streaming-span-event-aggregator.js +1 -1
- package/lib/spans/streaming-span-event.js +4 -4
- package/lib/stats/apdex.js +7 -13
- package/lib/stats/index.js +14 -19
- package/lib/system-info.js +29 -25
- package/lib/timer.js +35 -21
- package/lib/transaction/dt-payload.js +1 -1
- package/lib/transaction/handle.js +19 -19
- package/lib/transaction/index.js +133 -151
- package/lib/transaction/name-state.js +18 -19
- package/lib/transaction/trace/aggregator.js +78 -73
- package/lib/transaction/trace/exclusive-time-calculator.js +9 -13
- package/lib/transaction/trace/index.js +37 -35
- package/lib/transaction/trace/segment.js +56 -73
- package/lib/transaction/tracecontext.js +38 -46
- package/lib/transaction/tracer/index.js +130 -91
- package/lib/transaction/transaction-event-aggregator.js +29 -31
- package/lib/uninstrumented.js +11 -12
- package/lib/util/arity.js +2 -2
- package/lib/util/attribute-types.js +1 -5
- package/lib/util/byte-limit.js +4 -5
- package/lib/util/cat.js +270 -33
- package/lib/util/codec.js +10 -6
- package/lib/util/copy.js +2 -2
- package/lib/util/deep-equal.js +51 -21
- package/lib/util/flatten.js +9 -6
- package/lib/util/hashes.js +16 -16
- package/lib/util/label-parser.js +22 -28
- package/lib/util/logger.js +53 -35
- package/lib/util/process-version.js +3 -3
- package/lib/util/properties.js +5 -5
- package/lib/util/sql/obfuscate.js +21 -31
- package/lib/util/stream-sink.js +5 -6
- package/lib/util/unwrapped-core.js +2 -2
- package/lib/util/urltils.js +26 -30
- package/lib/utilization/aws-info.js +8 -9
- package/lib/utilization/azure-info.js +37 -35
- package/lib/utilization/common.js +17 -16
- package/lib/utilization/docker-info.js +14 -16
- package/lib/utilization/gcp-info.js +38 -37
- package/lib/utilization/index.js +5 -5
- package/lib/utilization/kubernetes-info.js +2 -2
- package/lib/utilization/pcf-info.js +12 -12
- package/package.json +23 -6
- package/stub_api.js +16 -14
package/lib/config/index.js
CHANGED
|
@@ -10,7 +10,7 @@ const CollectorResponse = require('../collector/response')
|
|
|
10
10
|
const copy = require('../util/copy')
|
|
11
11
|
const defaultConfig = require('./default').config
|
|
12
12
|
const EventEmitter = require('events').EventEmitter
|
|
13
|
-
const
|
|
13
|
+
const featureFlag = require('../feature_flags')
|
|
14
14
|
const flatten = require('../util/flatten')
|
|
15
15
|
const fs = require('../util/unwrapped-core').fs
|
|
16
16
|
const hashes = require('../util/hashes')
|
|
@@ -29,45 +29,39 @@ const mergeServerConfig = new MergeServerConfig()
|
|
|
29
29
|
const AZURE_APP_NAME = 'APP_POOL_ID'
|
|
30
30
|
const DEFAULT_MAX_PAYLOAD_SIZE_IN_BYTES = 1000000
|
|
31
31
|
const DEFAULT_CONFIG_PATH = require.resolve('./default')
|
|
32
|
-
const SPAN_EVENT_LIMIT = 1000
|
|
33
32
|
const BASE_CONFIG_PATH = require.resolve('../../newrelic')
|
|
34
|
-
const HAS_ARBITRARY_KEYS = new Set([
|
|
35
|
-
'ignore_messages',
|
|
36
|
-
'expected_messages',
|
|
37
|
-
'labels'
|
|
38
|
-
])
|
|
33
|
+
const HAS_ARBITRARY_KEYS = new Set(['ignore_messages', 'expected_messages', 'labels'])
|
|
39
34
|
|
|
40
35
|
const LASP_MAP = require('./lasp').LASP_MAP
|
|
41
36
|
const ENV = require('./env')
|
|
42
37
|
const HSM = require('./hsm')
|
|
38
|
+
const REMOVE_BEFORE_SEND = new Set(['attributeFilter'])
|
|
43
39
|
|
|
44
40
|
const exists = fs.existsSync || path.existsSync
|
|
45
41
|
let logger = null // Lazy-loaded in `initialize`.
|
|
46
42
|
let _configInstance = null
|
|
47
43
|
|
|
48
|
-
const getConfigFileNames = () =>
|
|
49
|
-
process.env.NEW_RELIC_CONFIG_FILENAME,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
: undefined
|
|
63
|
-
].filter(Boolean)
|
|
44
|
+
const getConfigFileNames = () =>
|
|
45
|
+
[process.env.NEW_RELIC_CONFIG_FILENAME, 'newrelic.js', 'newrelic.cjs'].filter(Boolean)
|
|
46
|
+
|
|
47
|
+
const getConfigFileLocations = () =>
|
|
48
|
+
[
|
|
49
|
+
process.env.NEW_RELIC_HOME,
|
|
50
|
+
process.cwd(),
|
|
51
|
+
process.env.HOME,
|
|
52
|
+
path.join(__dirname, '../../../..'), // above node_modules
|
|
53
|
+
// the REPL has no main module
|
|
54
|
+
process.mainModule && process.mainModule.filename
|
|
55
|
+
? path.dirname(process.mainModule.filename)
|
|
56
|
+
: undefined
|
|
57
|
+
].filter(Boolean)
|
|
64
58
|
|
|
65
59
|
function isTruthular(setting) {
|
|
66
60
|
if (setting == null) {
|
|
67
61
|
return false
|
|
68
62
|
}
|
|
69
63
|
|
|
70
|
-
|
|
64
|
+
const normalized = setting.toString().toLowerCase()
|
|
71
65
|
switch (normalized) {
|
|
72
66
|
case 'false':
|
|
73
67
|
case 'f':
|
|
@@ -93,7 +87,7 @@ function fromObjectList(setting) {
|
|
|
93
87
|
|
|
94
88
|
function _findConfigFile() {
|
|
95
89
|
const configFileCandidates = getConfigFileLocations().reduce((files, configPath) => {
|
|
96
|
-
const configFiles = getConfigFileNames().map(filename =>
|
|
90
|
+
const configFiles = getConfigFileNames().map((filename) =>
|
|
97
91
|
path.join(path.resolve(configPath), filename)
|
|
98
92
|
)
|
|
99
93
|
|
|
@@ -117,7 +111,7 @@ function Config(config) {
|
|
|
117
111
|
|
|
118
112
|
// feature flags are mostly private settings for gating unreleased features
|
|
119
113
|
// flags are set in the feature_flags.js file
|
|
120
|
-
this.feature_flag = copy.shallow(
|
|
114
|
+
this.feature_flag = copy.shallow(featureFlag.prerelease)
|
|
121
115
|
|
|
122
116
|
// set by environment
|
|
123
117
|
this.newrelic_home = null
|
|
@@ -160,9 +154,9 @@ function Config(config) {
|
|
|
160
154
|
this.browser_monitoring.loader_version = ''
|
|
161
155
|
|
|
162
156
|
// Settings to play nice with DLPs (see NODE-1044).
|
|
163
|
-
this.compressed_content_encoding = 'deflate'
|
|
164
|
-
this.simple_compression = false
|
|
165
|
-
this.put_for_data_send = false
|
|
157
|
+
this.compressed_content_encoding = 'deflate' // Deflate or gzip
|
|
158
|
+
this.simple_compression = false // Disables subcomponent compression
|
|
159
|
+
this.put_for_data_send = false // Changes http verb for harvest
|
|
166
160
|
|
|
167
161
|
// 3. override defaults with values from the loaded / passed configuration
|
|
168
162
|
this._fromPassed(config)
|
|
@@ -188,7 +182,7 @@ function Config(config) {
|
|
|
188
182
|
analytic_event_data: this.transaction_events.max_samples_stored,
|
|
189
183
|
custom_event_data: this.custom_insights_events.max_samples_stored,
|
|
190
184
|
error_event_data: this.error_collector.max_event_samples_stored,
|
|
191
|
-
span_event_data:
|
|
185
|
+
span_event_data: this.span_events.max_samples_stored
|
|
192
186
|
}
|
|
193
187
|
}
|
|
194
188
|
}
|
|
@@ -201,9 +195,9 @@ function Config(config) {
|
|
|
201
195
|
if (this.security_policies_token) {
|
|
202
196
|
throw new Error(
|
|
203
197
|
'Security Policies and High Security Mode cannot both be present ' +
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
198
|
+
'in the agent configuration. If Security Policies have been set ' +
|
|
199
|
+
'for your account, please ensure the security_policies_token is ' +
|
|
200
|
+
'set but high_security is disabled (default).'
|
|
207
201
|
)
|
|
208
202
|
}
|
|
209
203
|
this._applyHighSecurity()
|
|
@@ -243,17 +237,21 @@ Config.prototype.onConnect = function onConnect(json, recursion) {
|
|
|
243
237
|
this.emit('agent_enabled', false)
|
|
244
238
|
return
|
|
245
239
|
}
|
|
246
|
-
if (Object.keys(json).length === 0)
|
|
240
|
+
if (Object.keys(json).length === 0) {
|
|
241
|
+
return
|
|
242
|
+
}
|
|
247
243
|
|
|
248
244
|
Object.keys(json).forEach(function updateProp(key) {
|
|
249
245
|
this._fromServer(json, key)
|
|
250
246
|
}, this)
|
|
251
247
|
|
|
248
|
+
this._warnDeprecations()
|
|
249
|
+
|
|
252
250
|
this.emit('change', this)
|
|
253
251
|
}
|
|
254
252
|
|
|
255
253
|
Config.prototype._getMostSecure = function getMostSecure(key, currentVal, newVal) {
|
|
256
|
-
|
|
254
|
+
const filter = LASP_MAP[key] && LASP_MAP[key].filter
|
|
257
255
|
if (!this.security_policies_token || !filter) {
|
|
258
256
|
// If we aren't applying something vetted by security policies we
|
|
259
257
|
// just return the new value.
|
|
@@ -299,8 +297,7 @@ Config.prototype._fromServer = function _fromServer(params, key) {
|
|
|
299
297
|
case 'encoding_key':
|
|
300
298
|
this._alwaysUpdateIfChanged(params, key)
|
|
301
299
|
if (this.cross_process_id && this.encoding_key) {
|
|
302
|
-
this.obfuscatedId =
|
|
303
|
-
hashes.obfuscateNameUsingKey(this.cross_process_id, this.encoding_key)
|
|
300
|
+
this.obfuscatedId = hashes.obfuscateNameUsingKey(this.cross_process_id, this.encoding_key)
|
|
304
301
|
}
|
|
305
302
|
break
|
|
306
303
|
|
|
@@ -321,12 +318,7 @@ Config.prototype._fromServer = function _fromServer(params, key) {
|
|
|
321
318
|
|
|
322
319
|
case 'collect_error_events':
|
|
323
320
|
if (params.collect_error_events === false) {
|
|
324
|
-
this._updateNestedIfChanged(
|
|
325
|
-
params,
|
|
326
|
-
this.error_collector,
|
|
327
|
-
key,
|
|
328
|
-
'capture_events'
|
|
329
|
-
)
|
|
321
|
+
this._updateNestedIfChanged(params, this.error_collector, key, 'capture_events')
|
|
330
322
|
}
|
|
331
323
|
break
|
|
332
324
|
|
|
@@ -355,10 +347,7 @@ Config.prototype._fromServer = function _fromServer(params, key) {
|
|
|
355
347
|
this.emit(key, null)
|
|
356
348
|
break
|
|
357
349
|
}
|
|
358
|
-
logger.info(
|
|
359
|
-
'Valid event_harvest_config received. Updating harvest cycles.',
|
|
360
|
-
val
|
|
361
|
-
)
|
|
350
|
+
logger.info('Valid event_harvest_config received. Updating harvest cycles.', val)
|
|
362
351
|
const limits = Object.keys(val.harvest_limits).reduce((acc, k) => {
|
|
363
352
|
const v = val.harvest_limits[k]
|
|
364
353
|
if (harvestConfigValidator.isValidHarvestValue(v)) {
|
|
@@ -406,12 +395,7 @@ Config.prototype._fromServer = function _fromServer(params, key) {
|
|
|
406
395
|
// Browser Monitoring
|
|
407
396
|
//
|
|
408
397
|
case 'browser_monitoring.loader':
|
|
409
|
-
this._updateNestedIfChangedRaw(
|
|
410
|
-
params,
|
|
411
|
-
this.browser_monitoring,
|
|
412
|
-
key,
|
|
413
|
-
'loader'
|
|
414
|
-
)
|
|
398
|
+
this._updateNestedIfChangedRaw(params, this.browser_monitoring, key, 'loader')
|
|
415
399
|
break
|
|
416
400
|
|
|
417
401
|
// these are used by browser_monitoring
|
|
@@ -422,24 +406,14 @@ Config.prototype._fromServer = function _fromServer(params, key) {
|
|
|
422
406
|
case 'error_beacon':
|
|
423
407
|
case 'browser_key':
|
|
424
408
|
case 'js_agent_loader':
|
|
425
|
-
this._updateNestedIfChangedRaw(
|
|
426
|
-
params,
|
|
427
|
-
this.browser_monitoring,
|
|
428
|
-
key,
|
|
429
|
-
key
|
|
430
|
-
)
|
|
409
|
+
this._updateNestedIfChangedRaw(params, this.browser_monitoring, key, key)
|
|
431
410
|
break
|
|
432
411
|
|
|
433
412
|
//
|
|
434
413
|
// Cross Application Tracer
|
|
435
414
|
//
|
|
436
415
|
case 'cross_application_tracer.enabled':
|
|
437
|
-
this._updateNestedIfChanged(
|
|
438
|
-
params,
|
|
439
|
-
this.cross_application_tracer,
|
|
440
|
-
key,
|
|
441
|
-
'enabled'
|
|
442
|
-
)
|
|
416
|
+
this._updateNestedIfChanged(params, this.cross_application_tracer, key, 'enabled')
|
|
443
417
|
break
|
|
444
418
|
//
|
|
445
419
|
// Error Collector
|
|
@@ -530,12 +504,7 @@ Config.prototype._fromServer = function _fromServer(params, key) {
|
|
|
530
504
|
// Transaction Events
|
|
531
505
|
//
|
|
532
506
|
case 'transaction_events.enabled':
|
|
533
|
-
this._updateNestedIfChanged(
|
|
534
|
-
params,
|
|
535
|
-
this.transaction_events,
|
|
536
|
-
key,
|
|
537
|
-
'enabled'
|
|
538
|
-
)
|
|
507
|
+
this._updateNestedIfChanged(params, this.transaction_events, key, 'enabled')
|
|
539
508
|
break
|
|
540
509
|
|
|
541
510
|
//
|
|
@@ -576,6 +545,13 @@ Config.prototype._fromServer = function _fromServer(params, key) {
|
|
|
576
545
|
this.logUnsupported(params, key)
|
|
577
546
|
break
|
|
578
547
|
|
|
548
|
+
// DT span event harvest config limits
|
|
549
|
+
case 'span_event_harvest_config':
|
|
550
|
+
this.span_event_harvest_config = {
|
|
551
|
+
...params[key]
|
|
552
|
+
}
|
|
553
|
+
break
|
|
554
|
+
|
|
579
555
|
// These settings are not allowed from the server.
|
|
580
556
|
case 'attributes.enabled':
|
|
581
557
|
case 'attributes.exclude':
|
|
@@ -610,11 +586,13 @@ Config.prototype._fromServer = function _fromServer(params, key) {
|
|
|
610
586
|
* @param {string} key Value we're looking to set.
|
|
611
587
|
*/
|
|
612
588
|
Config.prototype._alwaysUpdateIfChanged = function _alwaysUpdateIfChanged(json, key) {
|
|
613
|
-
|
|
589
|
+
const value = json[key]
|
|
614
590
|
if (value != null && this[key] !== value) {
|
|
615
591
|
if (Array.isArray(value) && Array.isArray(this[key])) {
|
|
616
592
|
value.forEach(function pushIfNew(element) {
|
|
617
|
-
if (this[key].indexOf(element) === -1)
|
|
593
|
+
if (this[key].indexOf(element) === -1) {
|
|
594
|
+
this[key].push(element)
|
|
595
|
+
}
|
|
618
596
|
}, this)
|
|
619
597
|
} else {
|
|
620
598
|
this[key] = value
|
|
@@ -652,7 +630,7 @@ Config.prototype._updateIfChanged = function _updateIfChanged(json, key) {
|
|
|
652
630
|
*/
|
|
653
631
|
Config.prototype._validateThenUpdateStatusCodes = _validateThenUpdateStatusCodes
|
|
654
632
|
function _validateThenUpdateStatusCodes(remote, local, remoteKey, localKey) {
|
|
655
|
-
|
|
633
|
+
const valueToTest = remote[remoteKey]
|
|
656
634
|
if (!Array.isArray(valueToTest)) {
|
|
657
635
|
logger.warn(
|
|
658
636
|
'Saw SSC (ignore|expect)_status_codes that is not an array, will not merge: %s',
|
|
@@ -663,10 +641,11 @@ function _validateThenUpdateStatusCodes(remote, local, remoteKey, localKey) {
|
|
|
663
641
|
|
|
664
642
|
let valid = true
|
|
665
643
|
valueToTest.forEach(function validateArray(thingToTest) {
|
|
666
|
-
if (!('string' ===
|
|
644
|
+
if (!('string' === typeof thingToTest || 'number' === typeof thingToTest)) {
|
|
667
645
|
logger.warn(
|
|
668
646
|
'Saw SSC (ignore|expect)_status_code that is not a number or string,' +
|
|
669
|
-
|
|
647
|
+
'will not merge: %s',
|
|
648
|
+
thingToTest
|
|
670
649
|
)
|
|
671
650
|
valid = false
|
|
672
651
|
}
|
|
@@ -695,7 +674,7 @@ function _validateThenUpdateStatusCodes(remote, local, remoteKey, localKey) {
|
|
|
695
674
|
Config.prototype._validateThenUpdateErrorClasses = _validateThenUpdateErrorClasses
|
|
696
675
|
|
|
697
676
|
function _validateThenUpdateErrorClasses(remote, local, remoteKey, localKey) {
|
|
698
|
-
|
|
677
|
+
const valueToTest = remote[remoteKey]
|
|
699
678
|
if (!Array.isArray(valueToTest)) {
|
|
700
679
|
logger.warn(
|
|
701
680
|
'Saw SSC (ignore|expect)_classes that is not an array, will not merge: %s',
|
|
@@ -706,8 +685,8 @@ function _validateThenUpdateErrorClasses(remote, local, remoteKey, localKey) {
|
|
|
706
685
|
|
|
707
686
|
let valid = true
|
|
708
687
|
Object.keys(valueToTest).forEach(function validateArray(key) {
|
|
709
|
-
|
|
710
|
-
if ('string' !==
|
|
688
|
+
const thingToTest = valueToTest[key]
|
|
689
|
+
if ('string' !== typeof thingToTest) {
|
|
711
690
|
logger.warn(
|
|
712
691
|
'Saw SSC (ignore|expect)_class that is not a string, will not merge: %s',
|
|
713
692
|
thingToTest
|
|
@@ -739,12 +718,9 @@ function _validateThenUpdateErrorClasses(remote, local, remoteKey, localKey) {
|
|
|
739
718
|
Config.prototype._validateThenUpdateErrorMessages = _validateThenUpdateErrorMessages
|
|
740
719
|
|
|
741
720
|
function _validateThenUpdateErrorMessages(remote, local, remoteKey, localKey) {
|
|
742
|
-
|
|
721
|
+
const valueToTest = remote[remoteKey]
|
|
743
722
|
if (Array.isArray(valueToTest)) {
|
|
744
|
-
logger.warn(
|
|
745
|
-
'Saw SSC (ignore|expect)_message that is an Array, will not merge: %s',
|
|
746
|
-
valueToTest
|
|
747
|
-
)
|
|
723
|
+
logger.warn('Saw SSC (ignore|expect)_message that is an Array, will not merge: %s', valueToTest)
|
|
748
724
|
return
|
|
749
725
|
}
|
|
750
726
|
|
|
@@ -768,12 +744,9 @@ function _validateThenUpdateErrorMessages(remote, local, remoteKey, localKey) {
|
|
|
768
744
|
|
|
769
745
|
let valid = true
|
|
770
746
|
Object.keys(valueToTest).forEach(function validateArray(key) {
|
|
771
|
-
|
|
747
|
+
const arrayToTest = valueToTest[key]
|
|
772
748
|
if (!Array.isArray(arrayToTest)) {
|
|
773
|
-
logger.warn(
|
|
774
|
-
'Saw SSC message array that is not an array, will not merge: %s',
|
|
775
|
-
arrayToTest
|
|
776
|
-
)
|
|
749
|
+
logger.warn('Saw SSC message array that is not an array, will not merge: %s', arrayToTest)
|
|
777
750
|
valid = false
|
|
778
751
|
}
|
|
779
752
|
})
|
|
@@ -822,8 +795,10 @@ function _updateNestedIfChangedRaw(remote, local, remoteKey, localKey) {
|
|
|
822
795
|
* @param {string} key Value we're looking to set.
|
|
823
796
|
*/
|
|
824
797
|
Config.prototype._emitIfSet = function _emitIfSet(json, key) {
|
|
825
|
-
|
|
826
|
-
if (value != null)
|
|
798
|
+
const value = json[key]
|
|
799
|
+
if (value != null) {
|
|
800
|
+
this.emit(key, value)
|
|
801
|
+
}
|
|
827
802
|
}
|
|
828
803
|
|
|
829
804
|
/**
|
|
@@ -834,11 +809,11 @@ Config.prototype._emitIfSet = function _emitIfSet(json, key) {
|
|
|
834
809
|
* @param {string} key Value the agent won't set.
|
|
835
810
|
*/
|
|
836
811
|
Config.prototype.logDisabled = function logDisabled(json, key) {
|
|
837
|
-
|
|
812
|
+
const value = json[key]
|
|
838
813
|
if (value != null) {
|
|
839
814
|
logger.debug(
|
|
840
815
|
'Server-side configuration of %s is currently disabled by local configuration. ' +
|
|
841
|
-
|
|
816
|
+
'(Server sent value of %s.)',
|
|
842
817
|
key,
|
|
843
818
|
value
|
|
844
819
|
)
|
|
@@ -853,11 +828,11 @@ Config.prototype.logDisabled = function logDisabled(json, key) {
|
|
|
853
828
|
* @param {string} key Value the agent doesn't set.
|
|
854
829
|
*/
|
|
855
830
|
Config.prototype.logUnsupported = function logUnsupported(json, key) {
|
|
856
|
-
|
|
831
|
+
const value = json[key]
|
|
857
832
|
if (value !== null && value !== undefined) {
|
|
858
833
|
logger.debug(
|
|
859
834
|
'Server-side configuration of %s is currently not supported by the ' +
|
|
860
|
-
|
|
835
|
+
'Node.js agent. (Server sent value of %s.)',
|
|
861
836
|
key,
|
|
862
837
|
value
|
|
863
838
|
)
|
|
@@ -872,12 +847,8 @@ Config.prototype.logUnsupported = function logUnsupported(json, key) {
|
|
|
872
847
|
* @param {string} key Value the agent knows nothing about.
|
|
873
848
|
*/
|
|
874
849
|
Config.prototype.logUnknown = function logUnknown(json, key) {
|
|
875
|
-
|
|
876
|
-
logger.debug(
|
|
877
|
-
'New Relic sent unknown configuration parameter %s with value %s.',
|
|
878
|
-
key,
|
|
879
|
-
value
|
|
880
|
-
)
|
|
850
|
+
const value = json[key]
|
|
851
|
+
logger.debug('New Relic sent unknown configuration parameter %s with value %s.', key, value)
|
|
881
852
|
}
|
|
882
853
|
|
|
883
854
|
/**
|
|
@@ -903,7 +874,7 @@ Config.prototype.clearDisplayHostCache = function clearDisplayHostCache() {
|
|
|
903
874
|
}
|
|
904
875
|
|
|
905
876
|
function getDisplayHost() {
|
|
906
|
-
|
|
877
|
+
let _displayHost
|
|
907
878
|
this.getDisplayHost = function getCachedDisplayHost() {
|
|
908
879
|
return _displayHost
|
|
909
880
|
}
|
|
@@ -911,8 +882,8 @@ function getDisplayHost() {
|
|
|
911
882
|
_displayHost = this.getHostnameSafe()
|
|
912
883
|
return _displayHost
|
|
913
884
|
}
|
|
914
|
-
|
|
915
|
-
|
|
885
|
+
const stringBuffer = Buffer.from(this.process_host.display_name, 'utf8')
|
|
886
|
+
const numBytes = stringBuffer.length
|
|
916
887
|
|
|
917
888
|
if (numBytes > 255) {
|
|
918
889
|
logger.warn('Custom host display name must be less than 255 bytes')
|
|
@@ -941,16 +912,18 @@ Config.prototype.clearHostnameCache = function clearHostnameCache() {
|
|
|
941
912
|
}
|
|
942
913
|
|
|
943
914
|
Config.prototype.getIPAddresses = function getIPAddresses() {
|
|
944
|
-
|
|
945
|
-
|
|
915
|
+
const addresses = Object.create(null)
|
|
916
|
+
const interfaces = os.networkInterfaces()
|
|
946
917
|
|
|
947
|
-
for (
|
|
948
|
-
if (interfaceKey.match(/^lo/))
|
|
918
|
+
for (const interfaceKey in interfaces) {
|
|
919
|
+
if (interfaceKey.match(/^lo/)) {
|
|
920
|
+
continue
|
|
921
|
+
}
|
|
949
922
|
|
|
950
|
-
|
|
951
|
-
for (
|
|
952
|
-
|
|
953
|
-
|
|
923
|
+
const interfaceDescriptions = interfaces[interfaceKey]
|
|
924
|
+
for (let i = 0; i < interfaceDescriptions.length; i++) {
|
|
925
|
+
const description = interfaceDescriptions[i]
|
|
926
|
+
const family = description.family.toLowerCase()
|
|
954
927
|
addresses[family] = description.address
|
|
955
928
|
}
|
|
956
929
|
}
|
|
@@ -958,7 +931,7 @@ Config.prototype.getIPAddresses = function getIPAddresses() {
|
|
|
958
931
|
}
|
|
959
932
|
|
|
960
933
|
function getHostnameSafe() {
|
|
961
|
-
|
|
934
|
+
let _hostname
|
|
962
935
|
this.getHostnameSafe = function getCachedHostname() {
|
|
963
936
|
return _hostname
|
|
964
937
|
}
|
|
@@ -966,7 +939,7 @@ function getHostnameSafe() {
|
|
|
966
939
|
_hostname = os.hostname()
|
|
967
940
|
return _hostname
|
|
968
941
|
} catch (e) {
|
|
969
|
-
|
|
942
|
+
const addresses = this.getIPAddresses()
|
|
970
943
|
|
|
971
944
|
if (this.process_host.ipv_preference === '6' && addresses.ipv6) {
|
|
972
945
|
_hostname = addresses.ipv6
|
|
@@ -989,7 +962,7 @@ function getHostnameSafe() {
|
|
|
989
962
|
* Ensure that the apps names are always returned as a list.
|
|
990
963
|
*/
|
|
991
964
|
Config.prototype.applications = function applications() {
|
|
992
|
-
|
|
965
|
+
const apps = this.app_name
|
|
993
966
|
|
|
994
967
|
if (Array.isArray(apps) && apps.length > 0) {
|
|
995
968
|
return apps
|
|
@@ -1009,20 +982,27 @@ Config.prototype.applications = function applications() {
|
|
|
1009
982
|
* @param {object} internal Whichever chunk of the config being overridden.
|
|
1010
983
|
*/
|
|
1011
984
|
Config.prototype._fromPassed = function _fromPassed(external, internal, arbitrary) {
|
|
1012
|
-
if (!external)
|
|
1013
|
-
|
|
985
|
+
if (!external) {
|
|
986
|
+
return
|
|
987
|
+
}
|
|
988
|
+
if (!internal) {
|
|
989
|
+
internal = this
|
|
990
|
+
}
|
|
1014
991
|
|
|
1015
992
|
Object.keys(external).forEach(function overwrite(key) {
|
|
1016
993
|
// if it's not in the defaults, it doesn't exist
|
|
1017
|
-
if (!arbitrary && internal[key] === undefined)
|
|
994
|
+
if (!arbitrary && internal[key] === undefined) {
|
|
995
|
+
return
|
|
996
|
+
}
|
|
1018
997
|
|
|
1019
998
|
if (key === 'ssl' && !isTruthular(external.ssl)) {
|
|
1020
999
|
logger.warn('SSL config key can no longer be disabled, not updating.')
|
|
1021
1000
|
return
|
|
1022
1001
|
}
|
|
1023
1002
|
|
|
1003
|
+
let node = null
|
|
1024
1004
|
try {
|
|
1025
|
-
|
|
1005
|
+
node = external[key]
|
|
1026
1006
|
} catch (err) {
|
|
1027
1007
|
logger.warn('Error thrown on access of user config for key: %s', key)
|
|
1028
1008
|
return
|
|
@@ -1030,7 +1010,7 @@ Config.prototype._fromPassed = function _fromPassed(external, internal, arbitrar
|
|
|
1030
1010
|
|
|
1031
1011
|
if (typeof node === 'object' && !Array.isArray(node)) {
|
|
1032
1012
|
// is top level and can have arbitrary keys
|
|
1033
|
-
|
|
1013
|
+
const allowArbitrary = internal === this || HAS_ARBITRARY_KEYS.has(key)
|
|
1034
1014
|
this._fromPassed(node, internal[key], allowArbitrary)
|
|
1035
1015
|
} else {
|
|
1036
1016
|
internal[key] = node
|
|
@@ -1047,11 +1027,17 @@ Config.prototype._fromPassed = function _fromPassed(external, internal, arbitrar
|
|
|
1047
1027
|
* of configuration.
|
|
1048
1028
|
*/
|
|
1049
1029
|
Config.prototype._fromSpecial = function _fromSpecial() {
|
|
1050
|
-
|
|
1051
|
-
if (
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1030
|
+
const name = this.app_name
|
|
1031
|
+
if (
|
|
1032
|
+
name === null ||
|
|
1033
|
+
name === undefined ||
|
|
1034
|
+
name === '' ||
|
|
1035
|
+
(Array.isArray(name) && name.length === 0)
|
|
1036
|
+
) {
|
|
1037
|
+
const azureName = process.env[AZURE_APP_NAME]
|
|
1038
|
+
if (azureName) {
|
|
1039
|
+
this.app_name = azureName.split(',')
|
|
1040
|
+
}
|
|
1055
1041
|
}
|
|
1056
1042
|
}
|
|
1057
1043
|
|
|
@@ -1060,7 +1046,7 @@ Config.prototype._fromSpecial = function _fromSpecial() {
|
|
|
1060
1046
|
* (of the form NEW_RELIC_FEATURE_FLAG_<feature flag name in upper case>).
|
|
1061
1047
|
*/
|
|
1062
1048
|
Config.prototype._featureFlagsFromEnv = function _featureFlagsFromEnv() {
|
|
1063
|
-
const flags = Object.keys(
|
|
1049
|
+
const flags = Object.keys(featureFlag.prerelease).concat(featureFlag.released)
|
|
1064
1050
|
const config = this
|
|
1065
1051
|
flags.forEach(function checkFlag(flag) {
|
|
1066
1052
|
const envVal = process.env['NEW_RELIC_FEATURE_FLAG_' + flag.toUpperCase()]
|
|
@@ -1081,8 +1067,12 @@ Config.prototype._featureFlagsFromEnv = function _featureFlagsFromEnv() {
|
|
|
1081
1067
|
* never need to set this yourself.
|
|
1082
1068
|
*/
|
|
1083
1069
|
Config.prototype._fromEnvironment = function _fromEnvironment(metadata, data) {
|
|
1084
|
-
if (!metadata)
|
|
1085
|
-
|
|
1070
|
+
if (!metadata) {
|
|
1071
|
+
metadata = ENV.ENV_MAPPING
|
|
1072
|
+
}
|
|
1073
|
+
if (!data) {
|
|
1074
|
+
data = this
|
|
1075
|
+
}
|
|
1086
1076
|
|
|
1087
1077
|
Object.keys(metadata).forEach(function applyEnvDefault(value) {
|
|
1088
1078
|
// if it's not in the config, it doesn't exist
|
|
@@ -1090,14 +1080,14 @@ Config.prototype._fromEnvironment = function _fromEnvironment(metadata, data) {
|
|
|
1090
1080
|
return
|
|
1091
1081
|
}
|
|
1092
1082
|
|
|
1093
|
-
|
|
1083
|
+
const node = metadata[value]
|
|
1094
1084
|
if (typeof node === 'string') {
|
|
1095
|
-
|
|
1085
|
+
const setting = process.env[node]
|
|
1096
1086
|
if (setting) {
|
|
1097
1087
|
logger.debug(`${node} environment variable set.`)
|
|
1098
1088
|
|
|
1099
1089
|
if (ENV.LIST_VARS.has(node)) {
|
|
1100
|
-
|
|
1090
|
+
const split = ENV.LIST_VARS_CUSTOM_DELIMITERS[node] || /,/
|
|
1101
1091
|
data[value] = setting.split(split).map(function trimVal(k) {
|
|
1102
1092
|
return k.trim()
|
|
1103
1093
|
})
|
|
@@ -1119,7 +1109,9 @@ Config.prototype._fromEnvironment = function _fromEnvironment(metadata, data) {
|
|
|
1119
1109
|
}
|
|
1120
1110
|
} else {
|
|
1121
1111
|
// don't crash if the mapping has config keys the current config doesn't.
|
|
1122
|
-
if (!data[value])
|
|
1112
|
+
if (!data[value]) {
|
|
1113
|
+
data[value] = Object.create(null)
|
|
1114
|
+
}
|
|
1123
1115
|
this._fromEnvironment(node, data[value])
|
|
1124
1116
|
}
|
|
1125
1117
|
}, this)
|
|
@@ -1137,7 +1129,7 @@ Config.prototype._loggingManuallySet = function _loggingManuallySet(inputConfig)
|
|
|
1137
1129
|
const inputEnabled = inputConfig && inputConfig.logging && inputConfig.logging.enabled
|
|
1138
1130
|
const envEnabled = process.env.NEW_RELIC_LOG_ENABLED
|
|
1139
1131
|
|
|
1140
|
-
return
|
|
1132
|
+
return inputEnabled !== undefined || envEnabled !== undefined
|
|
1141
1133
|
}
|
|
1142
1134
|
|
|
1143
1135
|
/**
|
|
@@ -1148,16 +1140,16 @@ Config.prototype._loggingManuallySet = function _loggingManuallySet(inputConfig)
|
|
|
1148
1140
|
*
|
|
1149
1141
|
* @returns {boolean}
|
|
1150
1142
|
*/
|
|
1151
|
-
Config.prototype._nativeMetricsManuallySet =
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1143
|
+
Config.prototype._nativeMetricsManuallySet = function _nativeMetricsManuallySet(inputConfig) {
|
|
1144
|
+
const inputEnabled =
|
|
1145
|
+
inputConfig &&
|
|
1146
|
+
inputConfig.plugins &&
|
|
1147
|
+
inputConfig.plugins.native_metrics &&
|
|
1148
|
+
inputConfig.plugins.native_metrics.enabled
|
|
1149
|
+
const envEnabled = process.env.NEW_RELIC_NATIVE_METRICS_ENABLED
|
|
1150
|
+
|
|
1151
|
+
return inputEnabled !== undefined || envEnabled !== undefined
|
|
1152
|
+
}
|
|
1161
1153
|
|
|
1162
1154
|
/**
|
|
1163
1155
|
* Returns true if distributed tracing has been manually enabled via configuration file or
|
|
@@ -1168,13 +1160,12 @@ Config.prototype._nativeMetricsManuallySet =
|
|
|
1168
1160
|
* @returns {boolean}
|
|
1169
1161
|
*/
|
|
1170
1162
|
Config.prototype._DTManuallySet = function _DTManuallySet(inputConfig) {
|
|
1171
|
-
const inputEnabled =
|
|
1172
|
-
|
|
1173
|
-
&& inputConfig.distributed_tracing.enabled
|
|
1163
|
+
const inputEnabled =
|
|
1164
|
+
inputConfig && inputConfig.distributed_tracing && inputConfig.distributed_tracing.enabled
|
|
1174
1165
|
|
|
1175
1166
|
const envEnabled = process.env.NEW_RELIC_DISTRIBUTED_TRACING_ENABLED
|
|
1176
1167
|
|
|
1177
|
-
return
|
|
1168
|
+
return inputEnabled !== undefined || envEnabled !== undefined
|
|
1178
1169
|
}
|
|
1179
1170
|
|
|
1180
1171
|
/**
|
|
@@ -1197,7 +1188,7 @@ Config.prototype._enforceServerless = function _enforceServerless(inputConfig) {
|
|
|
1197
1188
|
const name = process.env.AWS_LAMBDA_FUNCTION_NAME || 'Serverless Application'
|
|
1198
1189
|
this.app_name = [name]
|
|
1199
1190
|
|
|
1200
|
-
logger.info(
|
|
1191
|
+
logger.info("Auto-naming serverless application to ['%s'] from: %s", name, namingSource)
|
|
1201
1192
|
}
|
|
1202
1193
|
|
|
1203
1194
|
// Explicitly disable old CAT in serverless_mode
|
|
@@ -1217,26 +1208,25 @@ Config.prototype._enforceServerless = function _enforceServerless(inputConfig) {
|
|
|
1217
1208
|
|
|
1218
1209
|
logger.info(
|
|
1219
1210
|
'Logging is disabled by default when serverless_mode is enabled. ' +
|
|
1220
|
-
|
|
1221
|
-
|
|
1211
|
+
'If desired, enable logging via config file or environment variable and ' +
|
|
1212
|
+
'set filepath to a valid path for current environment, stdout or stderr.'
|
|
1222
1213
|
)
|
|
1223
1214
|
}
|
|
1224
1215
|
|
|
1225
|
-
if (this._nativeMetricsManuallySet(inputConfig) &&
|
|
1226
|
-
this.plugins.native_metrics.enabled) {
|
|
1216
|
+
if (this._nativeMetricsManuallySet(inputConfig) && this.plugins.native_metrics.enabled) {
|
|
1227
1217
|
logger.info(
|
|
1228
1218
|
'Enabling the native-metrics module when in serverless mode may greatly ' +
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1219
|
+
'increase cold-start times. Given the limited benefit of the VM metrics' +
|
|
1220
|
+
'and general lack of control in a serverless environment, we do not ' +
|
|
1221
|
+
'recommend this trade-off.'
|
|
1232
1222
|
)
|
|
1233
1223
|
} else {
|
|
1234
1224
|
this.plugins.native_metrics.enabled = false
|
|
1235
1225
|
|
|
1236
1226
|
logger.info(
|
|
1237
1227
|
'The native-metrics module is disabled by default when serverless_mode ' +
|
|
1238
|
-
|
|
1239
|
-
|
|
1228
|
+
'is enabled. If desired, enable the native-metrics module via config file ' +
|
|
1229
|
+
'or environment variable.'
|
|
1240
1230
|
)
|
|
1241
1231
|
}
|
|
1242
1232
|
|
|
@@ -1248,8 +1238,8 @@ Config.prototype._enforceServerless = function _enforceServerless(inputConfig) {
|
|
|
1248
1238
|
if (this.distributed_tracing.enabled) {
|
|
1249
1239
|
logger.warn(
|
|
1250
1240
|
'Using distributed tracing in serverless mode requires account_id be ' +
|
|
1251
|
-
|
|
1252
|
-
|
|
1241
|
+
'defined, either in your newrelic.js file or via environment variables. ' +
|
|
1242
|
+
'Disabling distributed tracing.'
|
|
1253
1243
|
)
|
|
1254
1244
|
this.distributed_tracing.enabled = false
|
|
1255
1245
|
}
|
|
@@ -1270,8 +1260,9 @@ Config.prototype._enforceServerless = function _enforceServerless(inputConfig) {
|
|
|
1270
1260
|
DT_KEYS.forEach((key) => {
|
|
1271
1261
|
if (this[key]) {
|
|
1272
1262
|
logger.warn(
|
|
1273
|
-
key +
|
|
1274
|
-
|
|
1263
|
+
key +
|
|
1264
|
+
' was configured locally without enabling serverless_mode. ' +
|
|
1265
|
+
'This local value will be ignored and set by the New Relic servers.'
|
|
1275
1266
|
)
|
|
1276
1267
|
this[key] = null
|
|
1277
1268
|
}
|
|
@@ -1285,7 +1276,7 @@ Config.prototype._enforceServerless = function _enforceServerless(inputConfig) {
|
|
|
1285
1276
|
* based on special properties of configuration values should go here as well.
|
|
1286
1277
|
*/
|
|
1287
1278
|
Config.prototype._canonicalize = function _canonicalize() {
|
|
1288
|
-
|
|
1279
|
+
const statusCodes = this.error_collector && this.error_collector.ignore_status_codes
|
|
1289
1280
|
if (statusCodes) {
|
|
1290
1281
|
this.error_collector.ignore_status_codes = _parseCodes(statusCodes)
|
|
1291
1282
|
}
|
|
@@ -1295,17 +1286,17 @@ Config.prototype._canonicalize = function _canonicalize() {
|
|
|
1295
1286
|
this.error_collector.expected_status_codes = _parseCodes(expectedCodes)
|
|
1296
1287
|
}
|
|
1297
1288
|
|
|
1298
|
-
|
|
1289
|
+
const logAliases = {
|
|
1299
1290
|
verbose: 'trace',
|
|
1300
1291
|
debugging: 'debug',
|
|
1301
1292
|
warning: 'warn',
|
|
1302
1293
|
err: 'error'
|
|
1303
1294
|
}
|
|
1304
|
-
|
|
1295
|
+
const level = this.logging.level
|
|
1305
1296
|
this.logging.level = logAliases[level] || level
|
|
1306
1297
|
|
|
1307
1298
|
if (this.host === '') {
|
|
1308
|
-
|
|
1299
|
+
const region = parseKey(this.license_key)
|
|
1309
1300
|
if (region) {
|
|
1310
1301
|
this.host = 'collector.' + region + '.nr-data.net'
|
|
1311
1302
|
} else {
|
|
@@ -1317,8 +1308,8 @@ Config.prototype._canonicalize = function _canonicalize() {
|
|
|
1317
1308
|
logger.warnOnce(
|
|
1318
1309
|
'IgnoreServerConfigurationWarning',
|
|
1319
1310
|
'The local config setting `ignore_server_configuration` has been deprecated ' +
|
|
1320
|
-
|
|
1321
|
-
|
|
1311
|
+
'and removed as of Agent v5. Please review agent documentation or contact ' +
|
|
1312
|
+
'New Relic support.'
|
|
1322
1313
|
)
|
|
1323
1314
|
}
|
|
1324
1315
|
|
|
@@ -1330,16 +1321,17 @@ Config.prototype._canonicalize = function _canonicalize() {
|
|
|
1330
1321
|
function _parseCodes(codes) {
|
|
1331
1322
|
// range does not support negative values
|
|
1332
1323
|
function parseRange(range, parsed) {
|
|
1333
|
-
|
|
1324
|
+
const split = range.split('-')
|
|
1334
1325
|
if (split.length !== 2) {
|
|
1335
1326
|
logger.warn('Failed to parse range %s', range)
|
|
1336
1327
|
return parsed
|
|
1337
1328
|
}
|
|
1338
|
-
if (split[0] === '') {
|
|
1329
|
+
if (split[0] === '') {
|
|
1330
|
+
// catch negative code. ex. -7
|
|
1339
1331
|
return parsed.push(parseInt(range, 10))
|
|
1340
1332
|
}
|
|
1341
|
-
|
|
1342
|
-
|
|
1333
|
+
const lower = parseInt(split[0], 10)
|
|
1334
|
+
const upper = parseInt(split[1], 10)
|
|
1343
1335
|
if (Number.isNaN(lower) || Number.isNaN(upper)) {
|
|
1344
1336
|
logger.warn('Range must contain two numbers %s', range)
|
|
1345
1337
|
return parsed
|
|
@@ -1348,22 +1340,23 @@ function _parseCodes(codes) {
|
|
|
1348
1340
|
logger.warn('Range must start with lower bound %s', range)
|
|
1349
1341
|
} else if (lower < 0 || upper > 1000) {
|
|
1350
1342
|
logger.warn('Range must be between 0 and 1000 %s', range)
|
|
1351
|
-
} else {
|
|
1352
|
-
|
|
1343
|
+
} else {
|
|
1344
|
+
// success
|
|
1345
|
+
for (let i = lower; i <= upper; i++) {
|
|
1353
1346
|
parsed.push(i)
|
|
1354
1347
|
}
|
|
1355
1348
|
}
|
|
1356
1349
|
return parsed
|
|
1357
1350
|
}
|
|
1358
1351
|
|
|
1359
|
-
|
|
1360
|
-
for (
|
|
1361
|
-
|
|
1362
|
-
|
|
1352
|
+
const parsedCodes = []
|
|
1353
|
+
for (let i = 0; i < codes.length; i++) {
|
|
1354
|
+
const code = codes[i]
|
|
1355
|
+
|
|
1363
1356
|
if (typeof code === 'string' && code.indexOf('-') !== -1) {
|
|
1364
1357
|
parseRange(code, parsedCodes)
|
|
1365
1358
|
} else {
|
|
1366
|
-
parsedCode = parseInt(code, 10)
|
|
1359
|
+
const parsedCode = parseInt(code, 10)
|
|
1367
1360
|
if (!Number.isNaN(parsedCode)) {
|
|
1368
1361
|
parsedCodes.push(parsedCode)
|
|
1369
1362
|
} else {
|
|
@@ -1379,7 +1372,7 @@ function _parseCodes(codes) {
|
|
|
1379
1372
|
* them to be correct.
|
|
1380
1373
|
*/
|
|
1381
1374
|
Config.prototype._applyHighSecurity = function _applyHighSecurity() {
|
|
1382
|
-
|
|
1375
|
+
const config = this
|
|
1383
1376
|
checkNode('', this, HSM.HIGH_SECURITY_SETTINGS)
|
|
1384
1377
|
// as a one off, we add a global exclude rule to the list to keep from
|
|
1385
1378
|
// clobbering user defined rules
|
|
@@ -1391,15 +1384,11 @@ Config.prototype._applyHighSecurity = function _applyHighSecurity() {
|
|
|
1391
1384
|
}
|
|
1392
1385
|
|
|
1393
1386
|
function checkKey(base, target, settings, key) {
|
|
1394
|
-
|
|
1387
|
+
const hsValue = settings[key]
|
|
1395
1388
|
|
|
1396
1389
|
if (hsValue && typeof hsValue === 'object' && !(hsValue instanceof Array)) {
|
|
1397
1390
|
if (typeof target[key] !== 'object') {
|
|
1398
|
-
logger.warn(
|
|
1399
|
-
'High Security Mode: %s should be an object, found %s',
|
|
1400
|
-
key,
|
|
1401
|
-
target[key]
|
|
1402
|
-
)
|
|
1391
|
+
logger.warn('High Security Mode: %s should be an object, found %s', key, target[key])
|
|
1403
1392
|
target[key] = Object.create(null)
|
|
1404
1393
|
}
|
|
1405
1394
|
|
|
@@ -1407,12 +1396,7 @@ Config.prototype._applyHighSecurity = function _applyHighSecurity() {
|
|
|
1407
1396
|
}
|
|
1408
1397
|
|
|
1409
1398
|
if (target[key] !== hsValue) {
|
|
1410
|
-
logger.warn(
|
|
1411
|
-
'High Security Mode: %s was set to %s, coercing to %s',
|
|
1412
|
-
key,
|
|
1413
|
-
target[key],
|
|
1414
|
-
hsValue
|
|
1415
|
-
)
|
|
1399
|
+
logger.warn('High Security Mode: %s was set to %s, coercing to %s', key, target[key], hsValue)
|
|
1416
1400
|
target[key] = hsValue
|
|
1417
1401
|
config.emit(base + key, hsValue)
|
|
1418
1402
|
}
|
|
@@ -1431,8 +1415,8 @@ Config.prototype._applyHighSecurity = function _applyHighSecurity() {
|
|
|
1431
1415
|
* policies as the response payload.
|
|
1432
1416
|
*/
|
|
1433
1417
|
Config.prototype.applyLasp = function applyLasp(agent, policies) {
|
|
1434
|
-
|
|
1435
|
-
|
|
1418
|
+
const config = this
|
|
1419
|
+
const keys = Object.keys(policies)
|
|
1436
1420
|
|
|
1437
1421
|
if (!config.security_policies_token) {
|
|
1438
1422
|
if (keys.length) {
|
|
@@ -1444,12 +1428,12 @@ Config.prototype.applyLasp = function applyLasp(agent, policies) {
|
|
|
1444
1428
|
return CollectorResponse.success(null)
|
|
1445
1429
|
}
|
|
1446
1430
|
|
|
1447
|
-
|
|
1448
|
-
|
|
1431
|
+
const missingLASP = []
|
|
1432
|
+
const missingRequired = []
|
|
1449
1433
|
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1434
|
+
const finalPolicies = keys.reduce(function applyPolicy(obj, name) {
|
|
1435
|
+
const policy = policies[name]
|
|
1436
|
+
const localMapping = LASP_MAP[name]
|
|
1453
1437
|
|
|
1454
1438
|
if (!localMapping) {
|
|
1455
1439
|
if (!policy.required) {
|
|
@@ -1459,26 +1443,26 @@ Config.prototype.applyLasp = function applyLasp(agent, policies) {
|
|
|
1459
1443
|
// policy is required but does not exist in agent -- fail
|
|
1460
1444
|
missingRequired.push(name)
|
|
1461
1445
|
} else {
|
|
1462
|
-
|
|
1463
|
-
|
|
1446
|
+
const splitConfigName = localMapping.path.split('.')
|
|
1447
|
+
let settingBlock = config[splitConfigName[0]]
|
|
1464
1448
|
// pull out the configuration subsection that the option lives in
|
|
1465
|
-
for (
|
|
1449
|
+
for (let i = 1; i < splitConfigName.length - 1; ++i) {
|
|
1466
1450
|
settingBlock = settingBlock[splitConfigName[i]]
|
|
1467
1451
|
}
|
|
1468
|
-
|
|
1469
|
-
|
|
1452
|
+
const valueName = splitConfigName[splitConfigName.length - 1]
|
|
1453
|
+
const localVal = settingBlock[valueName]
|
|
1470
1454
|
|
|
1471
1455
|
// Indexes into "allowed values" based on "enabled" setting
|
|
1472
1456
|
// to retrieve proper mapping.
|
|
1473
|
-
|
|
1474
|
-
|
|
1457
|
+
const policyValues = localMapping.allowedValues
|
|
1458
|
+
const policyValue = policyValues[policy.enabled ? 1 : 0]
|
|
1475
1459
|
|
|
1476
1460
|
// get the most secure setting between local config and the policy
|
|
1477
|
-
|
|
1461
|
+
const finalValue = (settingBlock[valueName] = config._getMostSecure(
|
|
1478
1462
|
name,
|
|
1479
1463
|
localVal,
|
|
1480
1464
|
policyValue
|
|
1481
|
-
)
|
|
1465
|
+
))
|
|
1482
1466
|
policy.enabled = policyValues.indexOf(finalValue) === 1
|
|
1483
1467
|
obj[name] = policy
|
|
1484
1468
|
|
|
@@ -1507,11 +1491,14 @@ Config.prototype.applyLasp = function applyLasp(agent, policies) {
|
|
|
1507
1491
|
if (missingLASP.length) {
|
|
1508
1492
|
fatalMessage =
|
|
1509
1493
|
'The agent did not receive one or more security policies that it ' +
|
|
1510
|
-
'expected and will shut down: ' +
|
|
1494
|
+
'expected and will shut down: ' +
|
|
1495
|
+
missingLASP.join(', ') +
|
|
1496
|
+
'.'
|
|
1511
1497
|
} else if (missingRequired.length) {
|
|
1512
1498
|
fatalMessage =
|
|
1513
1499
|
'The agent received one or more required security policies that it ' +
|
|
1514
|
-
'does not recognize and will shut down: ' +
|
|
1500
|
+
'does not recognize and will shut down: ' +
|
|
1501
|
+
missingRequired.join(', ') +
|
|
1515
1502
|
'. Please check if a newer agent version supports these policies ' +
|
|
1516
1503
|
'or contact support.'
|
|
1517
1504
|
}
|
|
@@ -1526,10 +1513,10 @@ Config.prototype.applyLasp = function applyLasp(agent, policies) {
|
|
|
1526
1513
|
|
|
1527
1514
|
Config.prototype.validateFlags = function validateFlags() {
|
|
1528
1515
|
Object.keys(this.feature_flag).forEach(function forEachFlag(key) {
|
|
1529
|
-
if (
|
|
1516
|
+
if (featureFlag.released.indexOf(key) > -1) {
|
|
1530
1517
|
logger.warn('Feature flag %s has been released', key)
|
|
1531
1518
|
}
|
|
1532
|
-
if (
|
|
1519
|
+
if (featureFlag.unreleased.indexOf(key) > -1) {
|
|
1533
1520
|
logger.warn('Feature flag %s has been deprecated', key)
|
|
1534
1521
|
}
|
|
1535
1522
|
})
|
|
@@ -1556,9 +1543,9 @@ function redactValue(value) {
|
|
|
1556
1543
|
* @return Object containing simple key-value pairs of settings
|
|
1557
1544
|
*/
|
|
1558
1545
|
Config.prototype.publicSettings = function publicSettings() {
|
|
1559
|
-
|
|
1546
|
+
let settings = Object.create(null)
|
|
1560
1547
|
|
|
1561
|
-
for (
|
|
1548
|
+
for (const key in this) {
|
|
1562
1549
|
if (this.hasOwnProperty(key) && !REMOVE_BEFORE_SEND.has(key)) {
|
|
1563
1550
|
if (HSM.REDACT_BEFORE_SEND.has(key)) {
|
|
1564
1551
|
const value = this[key]
|
|
@@ -1596,6 +1583,19 @@ Config.prototype.getAggregatorConfig = function getAggregatorConfig(method) {
|
|
|
1596
1583
|
}
|
|
1597
1584
|
}
|
|
1598
1585
|
|
|
1586
|
+
Config.prototype._warnDeprecations = function _warnDeprecations() {
|
|
1587
|
+
// DT overrides CAT so only warn when CAT is actually used.
|
|
1588
|
+
if (this.cross_application_tracer.enabled && !this.distributed_tracing.enabled) {
|
|
1589
|
+
const deprecationWarning = [
|
|
1590
|
+
'[Deprecation Warning]: Cross Application Tracing (CAT) has been deprecated and will be ',
|
|
1591
|
+
'removed in a future major release. CAT has been replaced by Distributed Tracing (DT). ',
|
|
1592
|
+
'Enable DT by setting distributed_tracing: { enabled: true }.'
|
|
1593
|
+
].join('')
|
|
1594
|
+
|
|
1595
|
+
logger.infoOnce('Deprecation:CAT', deprecationWarning)
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
1599
|
/**
|
|
1600
1600
|
* Create a configuration, either from a configuration file or the node
|
|
1601
1601
|
* process's environment.
|
|
@@ -1626,7 +1626,9 @@ function initialize(config) {
|
|
|
1626
1626
|
*/
|
|
1627
1627
|
logger = require('../logger')
|
|
1628
1628
|
|
|
1629
|
-
if (config)
|
|
1629
|
+
if (config) {
|
|
1630
|
+
return new Config(config)
|
|
1631
|
+
}
|
|
1630
1632
|
|
|
1631
1633
|
if (isTruthular(process.env.NEW_RELIC_NO_CONFIG_FILE)) {
|
|
1632
1634
|
logger.info('NEW_RELIC_NO_CONFIG_FILE set, deferring to environment variables.')
|
|
@@ -1634,31 +1636,36 @@ function initialize(config) {
|
|
|
1634
1636
|
return createNewConfigObject(config)
|
|
1635
1637
|
}
|
|
1636
1638
|
|
|
1637
|
-
|
|
1639
|
+
const filepath = _findConfigFile()
|
|
1638
1640
|
if (!filepath) {
|
|
1639
|
-
logger.info(
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1641
|
+
logger.info(
|
|
1642
|
+
[
|
|
1643
|
+
'Unable to find configuration file.',
|
|
1644
|
+
'If a configuration file is desired (common for non-containerized environments),',
|
|
1645
|
+
`a base configuration file can be copied from ${BASE_CONFIG_PATH}`,
|
|
1646
|
+
'and renamed to "newrelic.js" in the directory from which you will start',
|
|
1647
|
+
'your application.',
|
|
1648
|
+
'Attempting to start agent using environment variables.'
|
|
1649
|
+
].join(' ')
|
|
1650
|
+
)
|
|
1646
1651
|
|
|
1647
1652
|
return createNewConfigObject(config)
|
|
1648
1653
|
}
|
|
1649
1654
|
|
|
1650
|
-
|
|
1655
|
+
let userConf
|
|
1651
1656
|
try {
|
|
1652
1657
|
userConf = require(filepath).config
|
|
1653
1658
|
} catch (error) {
|
|
1654
1659
|
logger.error(error)
|
|
1655
1660
|
|
|
1656
|
-
logger.warn(
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1661
|
+
logger.warn(
|
|
1662
|
+
[
|
|
1663
|
+
`Unable to read existing configuration file "${filepath}".`,
|
|
1664
|
+
'To allow reading of the file (if desired),',
|
|
1665
|
+
'please ensure the application has read access and the file is exporting valid JSON.',
|
|
1666
|
+
'Attempting to start agent using enviornment variables.'
|
|
1667
|
+
].join(' ')
|
|
1668
|
+
)
|
|
1662
1669
|
}
|
|
1663
1670
|
|
|
1664
1671
|
if (!userConf) {
|
|
@@ -1679,7 +1686,9 @@ function initialize(config) {
|
|
|
1679
1686
|
*/
|
|
1680
1687
|
function createNewConfigObject(config) {
|
|
1681
1688
|
config = new Config(Object.create(null))
|
|
1682
|
-
if (config.newrelic_home)
|
|
1689
|
+
if (config.newrelic_home) {
|
|
1690
|
+
delete config.newrelic_home
|
|
1691
|
+
}
|
|
1683
1692
|
return config
|
|
1684
1693
|
}
|
|
1685
1694
|
|
|
@@ -1700,7 +1709,7 @@ function getOrCreateInstance() {
|
|
|
1700
1709
|
|
|
1701
1710
|
// Config construction has potential to throw due to invalid settings.
|
|
1702
1711
|
// This allows the agent to return a stub api without crashing the process.
|
|
1703
|
-
_configInstance = Object.assign(defaultConfig(), {agent_enabled: false})
|
|
1712
|
+
_configInstance = Object.assign(defaultConfig(), { agent_enabled: false })
|
|
1704
1713
|
_configInstance.setLogger = Config.prototype.setLogger
|
|
1705
1714
|
}
|
|
1706
1715
|
}
|
|
@@ -1716,8 +1725,6 @@ function createInstance(config) {
|
|
|
1716
1725
|
return _configInstance
|
|
1717
1726
|
}
|
|
1718
1727
|
|
|
1719
|
-
const REMOVE_BEFORE_SEND = new Set(['attributeFilter'])
|
|
1720
|
-
|
|
1721
1728
|
/**
|
|
1722
1729
|
* Preserve the legacy initializer, but also allow consumers to manage their
|
|
1723
1730
|
* own configuration if they choose.
|
|
@@ -1726,6 +1733,5 @@ Config.initialize = initialize
|
|
|
1726
1733
|
Config.getOrCreateInstance = getOrCreateInstance
|
|
1727
1734
|
Config.getInstance = getInstance
|
|
1728
1735
|
Config.createInstance = createInstance
|
|
1729
|
-
Config.SPAN_EVENT_LIMIT = SPAN_EVENT_LIMIT
|
|
1730
1736
|
|
|
1731
1737
|
module.exports = Config
|