newrelic 13.4.0 → 13.6.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 +72 -0
- package/api.js +4 -4
- package/lib/agent.js +4 -4
- package/lib/aggregators/event-aggregator.js +0 -2
- package/lib/aggregators/log-aggregator.js +2 -2
- package/lib/attributes.js +2 -2
- package/lib/collector/api.js +7 -7
- package/lib/collector/http-agents.js +2 -2
- package/lib/collector/remote-method.js +1 -1
- package/lib/collector/serverless.js +1 -1
- package/lib/config/attribute-filter.js +7 -7
- package/lib/config/build-instrumentation-config.js +13 -3
- package/lib/config/default.js +26 -15
- package/lib/config/formatters.js +3 -3
- package/lib/config/hsm.js +1 -1
- package/lib/config/index.js +61 -46
- package/lib/config/merge-server-config.js +6 -6
- package/lib/core-instrumentation.js +4 -0
- package/lib/db/query-parsers/elasticsearch.js +5 -4
- package/lib/db/query-parsers/sql.js +1 -1
- package/lib/environment.js +16 -16
- package/lib/errors/index.js +1 -1
- package/lib/harvester.js +8 -6
- package/lib/header-attributes.js +3 -3
- package/lib/header-processing.js +3 -3
- package/lib/health-reporter.js +2 -2
- package/lib/instrumentation/@google/genai.js +6 -9
- package/lib/instrumentation/@prisma/client.js +1 -1
- package/lib/instrumentation/aws-sdk/util.js +3 -3
- package/lib/instrumentation/aws-sdk/v2/instrumentation-helper.js +1 -1
- package/lib/instrumentation/aws-sdk/v3/bedrock.js +16 -14
- package/lib/instrumentation/aws-sdk/v3/common.js +11 -11
- package/lib/instrumentation/aws-sdk/v3/dynamodb.js +10 -10
- package/lib/instrumentation/aws-sdk/v3/lambda.js +3 -3
- package/lib/instrumentation/aws-sdk/v3/sns.js +7 -7
- package/lib/instrumentation/aws-sdk/v3/sqs.js +6 -6
- package/lib/instrumentation/bunyan.js +1 -5
- package/lib/instrumentation/core/child_process.js +4 -4
- package/lib/instrumentation/core/fs.js +2 -2
- package/lib/instrumentation/core/http2.js +266 -0
- package/lib/instrumentation/core/timers.js +4 -4
- package/lib/instrumentation/fastify/spec-builders.js +3 -23
- package/lib/instrumentation/fastify.js +23 -94
- package/lib/instrumentation/grpc-js/grpc.js +7 -7
- package/lib/instrumentation/kafkajs/consumer.js +1 -1
- package/lib/instrumentation/koa/instrumentation.js +1 -1
- package/lib/instrumentation/koa/route-instrumentation.js +16 -18
- package/lib/instrumentation/langchain/runnable.js +3 -3
- package/lib/instrumentation/langchain/vectorstore.js +3 -2
- package/lib/instrumentation/memcached.js +1 -1
- package/lib/instrumentation/nextjs/next-server.js +1 -3
- package/lib/instrumentation/nextjs/utils.js +2 -2
- package/lib/instrumentation/restify.js +2 -2
- package/lib/instrumentation/when/contextualizer.js +1 -1
- package/lib/instrumentation/when/index.js +5 -5
- package/lib/instrumentation/winston.js +1 -1
- package/lib/instrumentation-descriptor.js +2 -11
- package/lib/instrumentation-tracker.js +2 -2
- package/lib/instrumentations.js +1 -19
- package/lib/llm-events/aws-bedrock/bedrock-response.js +9 -0
- package/lib/llm-events/aws-bedrock/chat-completion-message.js +32 -4
- package/lib/llm-events/aws-bedrock/chat-completion-summary.js +32 -2
- package/lib/llm-events/aws-bedrock/embedding.js +37 -4
- package/lib/llm-events/aws-bedrock/stream-handler.js +22 -0
- package/lib/llm-events/aws-bedrock/utils.js +59 -1
- package/lib/llm-events/google-genai/chat-completion-message.js +33 -5
- package/lib/llm-events/google-genai/chat-completion-summary.js +33 -0
- package/lib/llm-events/google-genai/embedding.js +34 -4
- package/lib/llm-events/google-genai/utils.js +32 -0
- package/lib/llm-events/openai/chat-completion-message.js +33 -6
- package/lib/llm-events/openai/chat-completion-summary.js +36 -0
- package/lib/llm-events/openai/embedding.js +34 -4
- package/lib/llm-events/openai/utils.js +34 -0
- package/lib/llm-events/utils.js +110 -0
- package/lib/metrics/index.js +7 -7
- package/lib/metrics/normalizer/tx_segment.js +26 -28
- package/lib/metrics/normalizer.js +9 -7
- package/lib/metrics/recorders/database-operation.js +2 -3
- package/lib/metrics/recorders/distributed-trace.js +2 -2
- package/lib/metrics/recorders/middleware.js +1 -2
- package/lib/otel/context-manager.js +3 -3
- package/lib/otel/traces/rules.js +2 -2
- package/lib/otel/traces/segments/database.js +1 -1
- package/lib/otel/traces/utils.js +9 -9
- package/lib/{adaptive-sampler.js → samplers/adaptive-sampler.js} +8 -0
- package/lib/serverless/aws-lambda.js +9 -9
- package/lib/shim/datastore-shim.js +9 -9
- package/lib/shim/message-shim/consume.js +3 -3
- package/lib/shim/message-shim/index.js +8 -8
- package/lib/shim/message-shim/subscribe-consume.js +12 -10
- package/lib/shim/promise-shim.js +4 -5
- package/lib/shim/shim.js +23 -35
- package/lib/shim/specs/class.js +3 -3
- package/lib/shim/specs/middleware-mounter.js +2 -2
- package/lib/shim/specs/middleware.js +3 -3
- package/lib/shim/specs/query.js +1 -1
- package/lib/shim/specs/recorder.js +1 -1
- package/lib/shim/specs/wrap.js +2 -2
- package/lib/shim/transaction-shim.js +7 -7
- package/lib/shim/webframework-shim/common.js +2 -2
- package/lib/shim/webframework-shim/index.js +18 -10
- package/lib/shim/webframework-shim/middleware.js +12 -16
- package/lib/shimmer.js +75 -129
- package/lib/spans/span-context.js +1 -1
- package/lib/spans/span-event.js +1 -1
- package/lib/spans/streaming-span-event-aggregator.js +4 -1
- package/lib/spans/streaming-span-event.js +1 -1
- package/lib/stats/apdex.js +1 -1
- package/lib/subscriber-configs.js +5 -1
- package/lib/subscribers/amqplib/config.js +2 -0
- package/lib/subscribers/amqplib/connect.js +2 -2
- package/lib/subscribers/amqplib/send-or-enqueue.js +0 -2
- package/lib/subscribers/base.js +50 -32
- package/lib/subscribers/create-config.js +2 -2
- package/lib/subscribers/db-operation.js +12 -0
- package/lib/subscribers/dc-base.js +91 -0
- package/lib/subscribers/express/config.js +102 -0
- package/lib/subscribers/express/param.js +22 -0
- package/lib/subscribers/express/render.js +28 -0
- package/lib/subscribers/express/route.js +55 -0
- package/lib/subscribers/express/router-param.js +24 -0
- package/lib/subscribers/express/router-route.js +24 -0
- package/lib/subscribers/express/router-use.js +24 -0
- package/lib/subscribers/express/use.js +44 -0
- package/lib/subscribers/fastify/add-hook.js +45 -0
- package/lib/subscribers/fastify/config.js +39 -0
- package/lib/subscribers/fastify/decorate.js +33 -0
- package/lib/subscribers/fastify/index.js +32 -0
- package/lib/subscribers/ioredis/config.js +3 -3
- package/lib/subscribers/ioredis/index.js +24 -1
- package/lib/subscribers/mcp-sdk/client-request.js +1 -1
- package/lib/subscribers/mcp-sdk/config.js +2 -0
- package/lib/subscribers/middleware-wrapper.js +269 -0
- package/lib/subscribers/middleware.js +20 -0
- package/lib/subscribers/openai/base.js +5 -6
- package/lib/subscribers/openai/utils.js +6 -4
- package/lib/subscribers/pg/config.js +91 -0
- package/lib/subscribers/pg/connect.js +28 -0
- package/lib/subscribers/pg/native-connect.js +25 -0
- package/lib/subscribers/pg/native-query.js +22 -0
- package/lib/subscribers/pg/query.js +66 -0
- package/lib/subscribers/pino/index.js +2 -2
- package/lib/subscribers/propagation.js +1 -21
- package/lib/subscribers/undici/config.js +11 -0
- package/lib/subscribers/undici/index.js +195 -0
- package/lib/synthetics.js +4 -4
- package/lib/system-metrics-sampler.js +5 -5
- package/lib/tracking-packages.js +25 -0
- package/lib/transaction/dt-payload.js +1 -1
- package/lib/transaction/index.js +32 -28
- package/lib/transaction/name-state.js +6 -6
- package/lib/transaction/trace/aggregator.js +1 -1
- package/lib/transaction/trace/index.js +3 -1
- package/lib/transaction/trace/segment.js +3 -3
- package/lib/transaction/tracer/index.js +1 -1
- package/lib/uninstrumented.js +4 -4
- package/lib/util/cat.js +2 -2
- package/lib/util/hashes.js +4 -4
- package/lib/util/label-parser.js +7 -7
- package/lib/util/llm-utils.js +3 -3
- package/lib/util/logger.js +6 -6
- package/lib/util/process-version.js +1 -1
- package/lib/util/stream-sink.js +1 -1
- package/lib/utilization/docker-info.js +2 -2
- package/lib/utilization/ecs-info.js +1 -1
- package/lib/utilization/index.js +2 -2
- package/lib/w3c/traceparent.js +2 -2
- package/lib/w3c/tracestate.js +1 -1
- package/newrelic.js +1 -1
- package/package.json +1 -1
- package/lib/instrumentation/express.js +0 -176
- package/lib/instrumentation/pg.js +0 -137
- package/lib/instrumentation/undici.js +0 -229
package/lib/config/index.js
CHANGED
|
@@ -123,7 +123,8 @@ function Config(config) {
|
|
|
123
123
|
this.primary_application_id = null
|
|
124
124
|
this.trusted_account_ids = null
|
|
125
125
|
this.trusted_account_key = null
|
|
126
|
-
|
|
126
|
+
|
|
127
|
+
this.sampling_target = this.distributed_tracing.sampler.adaptive_sampling_target
|
|
127
128
|
this.sampling_target_period_in_seconds = 60
|
|
128
129
|
this.max_payload_size_in_bytes = DEFAULT_MAX_PAYLOAD_SIZE_IN_BYTES
|
|
129
130
|
|
|
@@ -184,9 +185,9 @@ function Config(config) {
|
|
|
184
185
|
if (this.security_policies_token) {
|
|
185
186
|
throw new Error(
|
|
186
187
|
'Security Policies and High Security Mode cannot both be present ' +
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
'in the agent configuration. If Security Policies have been set ' +
|
|
189
|
+
'for your account, please ensure the security_policies_token is ' +
|
|
190
|
+
'set but high_security is disabled (default).'
|
|
190
191
|
)
|
|
191
192
|
}
|
|
192
193
|
this._applyHighSecurity()
|
|
@@ -199,8 +200,20 @@ function Config(config) {
|
|
|
199
200
|
this.parsedLabels = parseLabels(this.labels, logger)
|
|
200
201
|
this.loggingLabels = this._setApplicationLoggingLabels()
|
|
201
202
|
}
|
|
203
|
+
|
|
202
204
|
util.inherits(Config, EventEmitter)
|
|
203
205
|
|
|
206
|
+
// Expose sampling_target as an accessor that proxies to distributed_tracing.sampler.adaptive_sampling_target.
|
|
207
|
+
Object.defineProperty(Config.prototype, 'sampling_target', {
|
|
208
|
+
get: function () {
|
|
209
|
+
return this.distributed_tracing.sampler.adaptive_sampling_target
|
|
210
|
+
},
|
|
211
|
+
set: function (value) {
|
|
212
|
+
this.distributed_tracing.sampler.adaptive_sampling_target = value
|
|
213
|
+
this.emit('sampling_target', value)
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
|
|
204
217
|
/**
|
|
205
218
|
* Compares the labels list to the application logging excluded label list and removes any labels that need to be excluded.
|
|
206
219
|
* Then prefixing each label with "tags."
|
|
@@ -264,9 +277,9 @@ Config.prototype.onConnect = function onConnect(json, recursion) {
|
|
|
264
277
|
return
|
|
265
278
|
}
|
|
266
279
|
|
|
267
|
-
Object.keys(json)
|
|
280
|
+
for (const key of Object.keys(json)) {
|
|
268
281
|
this._fromServer(json, key)
|
|
269
|
-
}
|
|
282
|
+
}
|
|
270
283
|
|
|
271
284
|
this._warnDeprecations()
|
|
272
285
|
|
|
@@ -639,11 +652,11 @@ Config.prototype._alwaysUpdateIfChanged = function _alwaysUpdateIfChanged(json,
|
|
|
639
652
|
const value = json[key]
|
|
640
653
|
if (value != null && this[key] !== value) {
|
|
641
654
|
if (Array.isArray(value) && Array.isArray(this[key])) {
|
|
642
|
-
|
|
655
|
+
for (const element of value) {
|
|
643
656
|
if (this[key].indexOf(element) === -1) {
|
|
644
657
|
this[key].push(element)
|
|
645
658
|
}
|
|
646
|
-
}
|
|
659
|
+
}
|
|
647
660
|
} else {
|
|
648
661
|
this[key] = value
|
|
649
662
|
}
|
|
@@ -690,16 +703,16 @@ function _validateThenUpdateStatusCodes(remote, local, remoteKey, localKey) {
|
|
|
690
703
|
}
|
|
691
704
|
|
|
692
705
|
let valid = true
|
|
693
|
-
|
|
706
|
+
for (const thingToTest of valueToTest) {
|
|
694
707
|
if (!(typeof thingToTest === 'string' || typeof thingToTest === 'number')) {
|
|
695
708
|
logger.warn(
|
|
696
709
|
'Saw SSC (ignore|expect)_status_code that is not a number or string,' +
|
|
697
|
-
|
|
710
|
+
'will not merge: %s',
|
|
698
711
|
thingToTest
|
|
699
712
|
)
|
|
700
713
|
valid = false
|
|
701
714
|
}
|
|
702
|
-
}
|
|
715
|
+
}
|
|
703
716
|
if (!valid) {
|
|
704
717
|
return
|
|
705
718
|
}
|
|
@@ -734,7 +747,7 @@ function _validateThenUpdateErrorClasses(remote, local, remoteKey, localKey) {
|
|
|
734
747
|
}
|
|
735
748
|
|
|
736
749
|
let valid = true
|
|
737
|
-
Object.keys(valueToTest)
|
|
750
|
+
for (const key of Object.keys(valueToTest)) {
|
|
738
751
|
const thingToTest = valueToTest[key]
|
|
739
752
|
if (typeof thingToTest !== 'string') {
|
|
740
753
|
logger.warn(
|
|
@@ -743,7 +756,7 @@ function _validateThenUpdateErrorClasses(remote, local, remoteKey, localKey) {
|
|
|
743
756
|
)
|
|
744
757
|
valid = false
|
|
745
758
|
}
|
|
746
|
-
}
|
|
759
|
+
}
|
|
747
760
|
if (!valid) {
|
|
748
761
|
return
|
|
749
762
|
}
|
|
@@ -788,13 +801,13 @@ function _validateThenUpdateErrorMessages(remote, local, remoteKey, localKey) {
|
|
|
788
801
|
}
|
|
789
802
|
|
|
790
803
|
let valid = true
|
|
791
|
-
Object.keys(valueToTest)
|
|
804
|
+
for (const key of Object.keys(valueToTest)) {
|
|
792
805
|
const arrayToTest = valueToTest[key]
|
|
793
806
|
if (!Array.isArray(arrayToTest)) {
|
|
794
807
|
logger.warn('Saw SSC message array that is not an array, will not merge: %s', arrayToTest)
|
|
795
808
|
valid = false
|
|
796
809
|
}
|
|
797
|
-
}
|
|
810
|
+
}
|
|
798
811
|
if (!valid) {
|
|
799
812
|
return
|
|
800
813
|
}
|
|
@@ -858,7 +871,7 @@ Config.prototype.logDisabled = function logDisabled(json, key) {
|
|
|
858
871
|
if (value != null) {
|
|
859
872
|
logger.debug(
|
|
860
873
|
'Server-side configuration of %s is currently disabled by local configuration. ' +
|
|
861
|
-
|
|
874
|
+
'(Server sent value of %s.)',
|
|
862
875
|
key,
|
|
863
876
|
value
|
|
864
877
|
)
|
|
@@ -877,7 +890,7 @@ Config.prototype.logUnsupported = function logUnsupported(json, key) {
|
|
|
877
890
|
if (value !== null && value !== undefined) {
|
|
878
891
|
logger.debug(
|
|
879
892
|
'Server-side configuration of %s is currently not supported by the ' +
|
|
880
|
-
|
|
893
|
+
'Node.js agent. (Server sent value of %s.)',
|
|
881
894
|
key,
|
|
882
895
|
value
|
|
883
896
|
)
|
|
@@ -1045,15 +1058,15 @@ Config.prototype._fromPassed = function _fromPassed(external, internal, arbitrar
|
|
|
1045
1058
|
internal = this
|
|
1046
1059
|
}
|
|
1047
1060
|
|
|
1048
|
-
Object.keys(external)
|
|
1061
|
+
for (const key of Object.keys(external)) {
|
|
1049
1062
|
// if it's not in the defaults, it doesn't exist
|
|
1050
1063
|
if (!arbitrary && !(key in internal)) {
|
|
1051
|
-
|
|
1064
|
+
continue
|
|
1052
1065
|
}
|
|
1053
1066
|
|
|
1054
1067
|
if (key === 'ssl' && !isTruthular(external.ssl)) {
|
|
1055
1068
|
logger.warn(SSL_WARNING)
|
|
1056
|
-
|
|
1069
|
+
continue
|
|
1057
1070
|
}
|
|
1058
1071
|
|
|
1059
1072
|
let node = null
|
|
@@ -1061,7 +1074,7 @@ Config.prototype._fromPassed = function _fromPassed(external, internal, arbitrar
|
|
|
1061
1074
|
node = external[key]
|
|
1062
1075
|
} catch {
|
|
1063
1076
|
logger.warn('Error thrown on access of user config for key: %s', key)
|
|
1064
|
-
|
|
1077
|
+
continue
|
|
1065
1078
|
}
|
|
1066
1079
|
|
|
1067
1080
|
if (typeof node === 'object' && !Array.isArray(node) && !(node instanceof RegExp)) {
|
|
@@ -1071,7 +1084,7 @@ Config.prototype._fromPassed = function _fromPassed(external, internal, arbitrar
|
|
|
1071
1084
|
} else {
|
|
1072
1085
|
internal[key] = node
|
|
1073
1086
|
}
|
|
1074
|
-
}
|
|
1087
|
+
}
|
|
1075
1088
|
}
|
|
1076
1089
|
|
|
1077
1090
|
/**
|
|
@@ -1104,12 +1117,12 @@ Config.prototype._fromSpecial = function _fromSpecial() {
|
|
|
1104
1117
|
Config.prototype._featureFlagsFromEnv = function _featureFlagsFromEnv() {
|
|
1105
1118
|
const flags = Object.keys(featureFlag.prerelease).concat(featureFlag.released)
|
|
1106
1119
|
const config = this
|
|
1107
|
-
|
|
1120
|
+
for (const flag of flags) {
|
|
1108
1121
|
const envVal = process.env['NEW_RELIC_FEATURE_FLAG_' + flag.toUpperCase()]
|
|
1109
1122
|
if (envVal) {
|
|
1110
1123
|
config.feature_flag[flag] = isTruthular(envVal)
|
|
1111
1124
|
}
|
|
1112
|
-
}
|
|
1125
|
+
}
|
|
1113
1126
|
}
|
|
1114
1127
|
|
|
1115
1128
|
/**
|
|
@@ -1218,8 +1231,8 @@ Config.prototype._serverlessLogging = function _serverlessLogging(inputConfig) {
|
|
|
1218
1231
|
|
|
1219
1232
|
logger.info(
|
|
1220
1233
|
'Logging is disabled by default when serverless_mode is enabled. ' +
|
|
1221
|
-
|
|
1222
|
-
|
|
1234
|
+
'If desired, enable logging via config file or environment variable and ' +
|
|
1235
|
+
'set filepath to a valid path for current environment, stdout or stderr.'
|
|
1223
1236
|
)
|
|
1224
1237
|
}
|
|
1225
1238
|
}
|
|
@@ -1241,17 +1254,17 @@ Config.prototype._serverlessNativeMetrics = function _serverlessNativeMetrics(in
|
|
|
1241
1254
|
) {
|
|
1242
1255
|
logger.info(
|
|
1243
1256
|
'Enabling the native-metrics module when in serverless mode may greatly ' +
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1257
|
+
'increase cold-start times. Given the limited benefit of the VM metrics' +
|
|
1258
|
+
'and general lack of control in a serverless environment, we do not ' +
|
|
1259
|
+
'recommend this trade-off.'
|
|
1247
1260
|
)
|
|
1248
1261
|
} else {
|
|
1249
1262
|
this.plugins.native_metrics.enabled = false
|
|
1250
1263
|
|
|
1251
1264
|
logger.info(
|
|
1252
1265
|
'The native-metrics module is disabled by default when serverless_mode ' +
|
|
1253
|
-
|
|
1254
|
-
|
|
1266
|
+
'is enabled. If desired, enable the native-metrics module via config file ' +
|
|
1267
|
+
'or environment variable.'
|
|
1255
1268
|
)
|
|
1256
1269
|
}
|
|
1257
1270
|
}
|
|
@@ -1305,8 +1318,8 @@ Config.prototype._serverlessDT = function _serverlessDT() {
|
|
|
1305
1318
|
if (this.distributed_tracing.enabled) {
|
|
1306
1319
|
logger.warn(
|
|
1307
1320
|
'Using distributed tracing in serverless mode requires account_id be ' +
|
|
1308
|
-
|
|
1309
|
-
|
|
1321
|
+
'defined, either in your newrelic.js file or via environment variables. ' +
|
|
1322
|
+
'Disabling distributed tracing.'
|
|
1310
1323
|
)
|
|
1311
1324
|
this.distributed_tracing.enabled = false
|
|
1312
1325
|
}
|
|
@@ -1328,16 +1341,16 @@ Config.prototype._serverlessDT = function _serverlessDT() {
|
|
|
1328
1341
|
*/
|
|
1329
1342
|
Config.prototype._preventServerlessDT = function _preventServerlessDT() {
|
|
1330
1343
|
// Don't allow DT config settings to be set if serverless_mode is disabled
|
|
1331
|
-
|
|
1344
|
+
for (const key of SERVERLESS_DT_KEYS) {
|
|
1332
1345
|
if (this[key]) {
|
|
1333
1346
|
logger.warn(
|
|
1334
1347
|
key +
|
|
1335
|
-
|
|
1336
|
-
|
|
1348
|
+
' was configured locally without enabling serverless_mode. ' +
|
|
1349
|
+
'This local value will be ignored and set by the New Relic servers.'
|
|
1337
1350
|
)
|
|
1338
1351
|
this[key] = null
|
|
1339
1352
|
}
|
|
1340
|
-
}
|
|
1353
|
+
}
|
|
1341
1354
|
}
|
|
1342
1355
|
|
|
1343
1356
|
/**
|
|
@@ -1489,7 +1502,9 @@ Config.prototype._applyHighSecurity = function _applyHighSecurity() {
|
|
|
1489
1502
|
this.attributes.exclude.push('request.parameters.*')
|
|
1490
1503
|
|
|
1491
1504
|
function checkNode(base, target, settings) {
|
|
1492
|
-
Object.keys(settings)
|
|
1505
|
+
for (const key of Object.keys(settings)) {
|
|
1506
|
+
checkKey(base, target, settings, key)
|
|
1507
|
+
}
|
|
1493
1508
|
}
|
|
1494
1509
|
|
|
1495
1510
|
function checkKey(base, target, settings, key) {
|
|
@@ -1518,7 +1533,7 @@ Config.prototype._applyHighSecurity = function _applyHighSecurity() {
|
|
|
1518
1533
|
* @param {Array} keys keys from a LASP policy
|
|
1519
1534
|
* @returns {CollectorResponse} creates CollectorResponse with either preserve or shutdown
|
|
1520
1535
|
*/
|
|
1521
|
-
function
|
|
1536
|
+
function _laspResponse(keys) {
|
|
1522
1537
|
if (keys.length) {
|
|
1523
1538
|
logger.error('The agent received one or more unexpected security policies and will shut down.')
|
|
1524
1539
|
return CollectorResponse.fatal(null)
|
|
@@ -1530,7 +1545,7 @@ function _laspReponse(keys) {
|
|
|
1530
1545
|
* Applies the server side LASP policies to a local configuration object
|
|
1531
1546
|
*
|
|
1532
1547
|
* @param {Agent} agent Agent instance
|
|
1533
|
-
* @param {
|
|
1548
|
+
* @param {object} policies server side LASP policy
|
|
1534
1549
|
* @returns {object} { missingRequired, finalPolicies } list of missing required fields and finalized LASP policy
|
|
1535
1550
|
*/
|
|
1536
1551
|
Config.prototype._buildLaspPolicy = function _buildLaspPolicy(agent, policies) {
|
|
@@ -1604,18 +1619,18 @@ Config.prototype.applyLasp = function applyLasp(agent, policies) {
|
|
|
1604
1619
|
const keys = Object.keys(policies)
|
|
1605
1620
|
|
|
1606
1621
|
if (!this.security_policies_token) {
|
|
1607
|
-
return
|
|
1622
|
+
return _laspResponse(keys)
|
|
1608
1623
|
}
|
|
1609
1624
|
|
|
1610
1625
|
const { finalPolicies, missingRequired } = this._buildLaspPolicy(agent, policies)
|
|
1611
1626
|
|
|
1612
1627
|
const missingLASP = []
|
|
1613
|
-
Object.keys(LASP_MAP)
|
|
1628
|
+
for (const name of Object.keys(LASP_MAP)) {
|
|
1614
1629
|
if (!policies[name]) {
|
|
1615
1630
|
// agent is expecting a policy that was not sent from server -- fail
|
|
1616
1631
|
missingLASP.push(name)
|
|
1617
1632
|
}
|
|
1618
|
-
}
|
|
1633
|
+
}
|
|
1619
1634
|
|
|
1620
1635
|
let fatalMessage = null
|
|
1621
1636
|
if (missingLASP.length) {
|
|
@@ -1642,14 +1657,14 @@ Config.prototype.applyLasp = function applyLasp(agent, policies) {
|
|
|
1642
1657
|
}
|
|
1643
1658
|
|
|
1644
1659
|
Config.prototype.validateFlags = function validateFlags() {
|
|
1645
|
-
Object.keys(this.feature_flag)
|
|
1660
|
+
for (const key of Object.keys(this.feature_flag)) {
|
|
1646
1661
|
if (featureFlag.released.indexOf(key) > -1) {
|
|
1647
1662
|
logger.warn('Feature flag %s has been released', key)
|
|
1648
1663
|
}
|
|
1649
1664
|
if (featureFlag.unreleased.indexOf(key) > -1) {
|
|
1650
1665
|
logger.warn('Feature flag %s has been deprecated', key)
|
|
1651
1666
|
}
|
|
1652
|
-
}
|
|
1667
|
+
}
|
|
1653
1668
|
}
|
|
1654
1669
|
|
|
1655
1670
|
function redactValue(value) {
|
|
@@ -1670,7 +1685,7 @@ function redactValue(value) {
|
|
|
1670
1685
|
* Get a JSONifiable object containing all settings we want to report to the
|
|
1671
1686
|
* collector and store in the environment_values table.
|
|
1672
1687
|
*
|
|
1673
|
-
* @returns {object} containing simple key-value pairs of settings
|
|
1688
|
+
* @returns {object|undefined} containing simple key-value pairs of settings, or undefined if an error occurred
|
|
1674
1689
|
*/
|
|
1675
1690
|
Config.prototype.publicSettings = function publicSettings() {
|
|
1676
1691
|
let settings = Object.create(null)
|
|
@@ -32,28 +32,28 @@ class MergeServerConfig {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
updateArray(value, local, localKey) {
|
|
35
|
-
|
|
35
|
+
for (const element of value) {
|
|
36
36
|
if (local[localKey].indexOf(element) === -1) {
|
|
37
37
|
local[localKey].push(element)
|
|
38
38
|
}
|
|
39
|
-
}
|
|
39
|
+
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
updateObject(value, local, localKey) {
|
|
43
43
|
// go through each key of the object and update it
|
|
44
|
-
Object.keys(value)
|
|
44
|
+
for (const element of Object.keys(value)) {
|
|
45
45
|
if (Array.isArray(local[localKey][element]) && Array.isArray(value[element])) {
|
|
46
46
|
// if both key-values are arrays, push the remote value onto the local array
|
|
47
|
-
value[element]
|
|
47
|
+
for (const elementValue of value[element]) {
|
|
48
48
|
if (local[localKey][element].indexOf(elementValue) === -1) {
|
|
49
49
|
local[localKey][element].push(elementValue)
|
|
50
50
|
}
|
|
51
|
-
}
|
|
51
|
+
}
|
|
52
52
|
} else {
|
|
53
53
|
// otherwise, replace the local value with the server value
|
|
54
54
|
local[localKey][element] = value[element]
|
|
55
55
|
}
|
|
56
|
-
}
|
|
56
|
+
}
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -32,6 +32,10 @@ module.exports = {
|
|
|
32
32
|
type: InstrumentationDescriptor.TYPE_TRANSACTION,
|
|
33
33
|
file: 'http.js'
|
|
34
34
|
},
|
|
35
|
+
http2: {
|
|
36
|
+
type: InstrumentationDescriptor.TYPE_TRANSACTION,
|
|
37
|
+
file: 'http2.js'
|
|
38
|
+
},
|
|
35
39
|
inspector: {
|
|
36
40
|
type: InstrumentationDescriptor.TYPE_GENERIC,
|
|
37
41
|
file: 'inspector.js'
|
|
@@ -72,18 +72,19 @@ function parsePath(pathString, method) {
|
|
|
72
72
|
operation = 'index.create'
|
|
73
73
|
return { collection, operation }
|
|
74
74
|
}
|
|
75
|
-
path.
|
|
75
|
+
for (let idx = 0; idx < path.length; idx++) {
|
|
76
|
+
const segment = path[idx]
|
|
76
77
|
const prev = idx - 1
|
|
77
|
-
let opname
|
|
78
78
|
if (segment === '_search') {
|
|
79
79
|
collection = path?.[prev] || defaultCollection
|
|
80
80
|
operation = 'search'
|
|
81
81
|
} else if (segment[0] === '_') {
|
|
82
|
-
opname = segment.substring(1)
|
|
82
|
+
const opname = segment.substring(1)
|
|
83
83
|
collection = path?.[prev] || defaultCollection
|
|
84
84
|
operation = `${opname}.${suffix}`
|
|
85
85
|
}
|
|
86
|
-
}
|
|
86
|
+
}
|
|
87
|
+
|
|
87
88
|
if (!operation && !collection) {
|
|
88
89
|
// likely creating an index--no underscore segments
|
|
89
90
|
collection = path?.[1] || defaultCollection
|
|
@@ -40,7 +40,7 @@ module.exports = function parseSql(sql) {
|
|
|
40
40
|
try {
|
|
41
41
|
logger.trace('parseSQL got an a non-string sql that looks like: %s', stringify(sql))
|
|
42
42
|
} catch (err) {
|
|
43
|
-
logger.debug(err, '
|
|
43
|
+
logger.debug(err, 'Unable to stringify SQL')
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
return {
|
package/lib/environment.js
CHANGED
|
@@ -240,7 +240,7 @@ function getGlobalPackages() {
|
|
|
240
240
|
*/
|
|
241
241
|
function flattenVersions(packages) {
|
|
242
242
|
const info = Object.create(null)
|
|
243
|
-
|
|
243
|
+
for (const pair of packages) {
|
|
244
244
|
const p = pair[0]
|
|
245
245
|
const v = pair[1]
|
|
246
246
|
|
|
@@ -251,7 +251,7 @@ function flattenVersions(packages) {
|
|
|
251
251
|
} else {
|
|
252
252
|
info[p] = [v]
|
|
253
253
|
}
|
|
254
|
-
}
|
|
254
|
+
}
|
|
255
255
|
|
|
256
256
|
return Object.keys(info)
|
|
257
257
|
.map((key) => [key, info[key].join(', ')])
|
|
@@ -277,7 +277,7 @@ function flattenVersions(packages) {
|
|
|
277
277
|
function remapConfigSettings() {
|
|
278
278
|
if (process.config && process.config.variables) {
|
|
279
279
|
const variables = process.config.variables
|
|
280
|
-
Object.keys(variables)
|
|
280
|
+
for (const key of Object.keys(variables)) {
|
|
281
281
|
if (remapping[key]) {
|
|
282
282
|
let value = variables[key]
|
|
283
283
|
|
|
@@ -290,7 +290,7 @@ function remapConfigSettings() {
|
|
|
290
290
|
|
|
291
291
|
addSetting(remapping[key], value)
|
|
292
292
|
}
|
|
293
|
-
}
|
|
293
|
+
}
|
|
294
294
|
|
|
295
295
|
addMissingProcessVars()
|
|
296
296
|
}
|
|
@@ -334,10 +334,10 @@ async function getOtherPackages() {
|
|
|
334
334
|
2
|
|
335
335
|
)
|
|
336
336
|
|
|
337
|
-
|
|
337
|
+
for (const pkg of otherPackages) {
|
|
338
338
|
other.packages.push.apply(other.packages, pkg.packages)
|
|
339
339
|
other.dependencies.push.apply(other.dependencies, pkg.dependencies)
|
|
340
|
-
}
|
|
340
|
+
}
|
|
341
341
|
|
|
342
342
|
_log('Done getting other packages')
|
|
343
343
|
return other
|
|
@@ -442,21 +442,21 @@ function refreshSyncOnly() {
|
|
|
442
442
|
settings = Object.create(null)
|
|
443
443
|
// add persisted settings
|
|
444
444
|
if (framework.length) {
|
|
445
|
-
|
|
445
|
+
for (const fw of framework) {
|
|
446
446
|
addSetting('Framework', fw)
|
|
447
|
-
}
|
|
447
|
+
}
|
|
448
448
|
}
|
|
449
449
|
|
|
450
450
|
if (dispatcher.length) {
|
|
451
|
-
|
|
451
|
+
for (const d of dispatcher) {
|
|
452
452
|
addSetting('Dispatcher', d)
|
|
453
|
-
}
|
|
453
|
+
}
|
|
454
454
|
}
|
|
455
455
|
|
|
456
456
|
if (dispatcherVersion.length) {
|
|
457
|
-
|
|
457
|
+
for (const d of dispatcher) {
|
|
458
458
|
addSetting(DISPATCHER_VERSION, d)
|
|
459
|
-
}
|
|
459
|
+
}
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
gatherEnv()
|
|
@@ -498,11 +498,11 @@ async function getJSON() {
|
|
|
498
498
|
}
|
|
499
499
|
|
|
500
500
|
const items = []
|
|
501
|
-
Object.
|
|
502
|
-
|
|
501
|
+
for (const [key, value] of Object.entries(settings)) {
|
|
502
|
+
for (const setting of value) {
|
|
503
503
|
items.push([key, setting])
|
|
504
|
-
}
|
|
505
|
-
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
506
|
_log('JSON got')
|
|
507
507
|
return items
|
|
508
508
|
}
|
package/lib/errors/index.js
CHANGED
|
@@ -58,7 +58,7 @@ class Exception {
|
|
|
58
58
|
* because everything's an object in JS. I'm not entirely sure why we do this, but
|
|
59
59
|
* weird enough to make note of
|
|
60
60
|
*
|
|
61
|
-
* @param {Transaction} transaction The agent transaction, coming from the
|
|
61
|
+
* @param {Transaction} transaction The agent transaction, coming from the instrumentation
|
|
62
62
|
* @param {Exception} exception An custom Exception object with the error and other information
|
|
63
63
|
* @param {object} config The configuration to use when creating the object
|
|
64
64
|
* @returns {Array} an Array of Error information, [0] -> placeholder,
|
package/lib/harvester.js
CHANGED
|
@@ -18,11 +18,11 @@ module.exports = class Harvester {
|
|
|
18
18
|
* Calls start on every registered aggregator that is enabled.
|
|
19
19
|
*/
|
|
20
20
|
start() {
|
|
21
|
-
this.aggregators
|
|
21
|
+
for (const aggregator of this.aggregators) {
|
|
22
22
|
if (aggregator.enabled) {
|
|
23
23
|
aggregator.start()
|
|
24
24
|
}
|
|
25
|
-
}
|
|
25
|
+
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -57,7 +57,9 @@ module.exports = class Harvester {
|
|
|
57
57
|
* Calls stop on every registered aggregator.
|
|
58
58
|
*/
|
|
59
59
|
stop() {
|
|
60
|
-
|
|
60
|
+
for (const aggregator of this.aggregators) {
|
|
61
|
+
aggregator.stop()
|
|
62
|
+
}
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
/**
|
|
@@ -66,15 +68,15 @@ module.exports = class Harvester {
|
|
|
66
68
|
* @param {object} config updated agent configuration
|
|
67
69
|
*/
|
|
68
70
|
update(config) {
|
|
69
|
-
this.aggregators
|
|
71
|
+
for (const aggregator of this.aggregators) {
|
|
70
72
|
aggregator.reconfigure(config)
|
|
71
|
-
}
|
|
73
|
+
}
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
/**
|
|
75
77
|
* Registers an aggregator with the Harvester instance.
|
|
76
78
|
*
|
|
77
|
-
* @param {
|
|
79
|
+
* @param {object} aggregator Aggregator instance
|
|
78
80
|
*/
|
|
79
81
|
add(aggregator) {
|
|
80
82
|
this.aggregators.push(aggregator)
|
package/lib/header-attributes.js
CHANGED
|
@@ -78,9 +78,9 @@ _setHeaderAttrNames(REQUEST_HEADER_NAMES, REQUEST_HEADER_PREFIX)
|
|
|
78
78
|
_setHeaderAttrNames(RESPONSE_HEADER_NAMES, RESPONSE_HEADER_PREFIX)
|
|
79
79
|
|
|
80
80
|
function _setHeaderAttrNames(dest, prefix) {
|
|
81
|
-
Object.keys(HEADER_ATTR_NAMES)
|
|
82
|
-
dest[
|
|
83
|
-
}
|
|
81
|
+
for (const header of Object.keys(HEADER_ATTR_NAMES)) {
|
|
82
|
+
dest[header] = prefix + HEADER_ATTR_NAMES[header]
|
|
83
|
+
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
function _headerToCamelCase(header) {
|
package/lib/header-processing.js
CHANGED
|
@@ -15,8 +15,8 @@ const CONTENT_LENGTH_REGEX = /^Content-Length$/i
|
|
|
15
15
|
* Queue time is provided by certain providers by stamping the request
|
|
16
16
|
* header with the time the request arrived at the router.
|
|
17
17
|
*
|
|
18
|
-
* @param {
|
|
19
|
-
* @param {
|
|
18
|
+
* @param {object} logger Logger instance
|
|
19
|
+
* @param {object} requestHeaders Incoming request headers
|
|
20
20
|
*/
|
|
21
21
|
function getQueueTime(logger, requestHeaders) {
|
|
22
22
|
const headerValue = requestHeaders[REQUEST_START_HEADER] || requestHeaders[QUEUE_HEADER]
|
|
@@ -62,7 +62,7 @@ function convertUnit(time) {
|
|
|
62
62
|
*
|
|
63
63
|
* If no header is found, returns -1
|
|
64
64
|
*
|
|
65
|
-
* @param {
|
|
65
|
+
* @param {object} headers Incoming request headers
|
|
66
66
|
*/
|
|
67
67
|
function getContentLengthFromHeaders(headers) {
|
|
68
68
|
const contentLength = -1
|
package/lib/health-reporter.js
CHANGED
|
@@ -112,7 +112,7 @@ class HealthReporter {
|
|
|
112
112
|
* object that has an `agent_control` property which is an instance of
|
|
113
113
|
* {@link AgentControlConfig}.
|
|
114
114
|
* @param {object} [params.logger] A standard logger instance.
|
|
115
|
-
* @param {
|
|
115
|
+
* @param {Function} [params.setInterval] A function to use as `setInterval`.
|
|
116
116
|
* Must return an interval object that supports the `unref()` method.
|
|
117
117
|
*/
|
|
118
118
|
constructor({
|
|
@@ -217,7 +217,7 @@ class HealthReporter {
|
|
|
217
217
|
* initiate an immediate write of the status file, and then invoke the
|
|
218
218
|
* provided callback.
|
|
219
219
|
*
|
|
220
|
-
* @param {
|
|
220
|
+
* @param {Function} done Callback to be invoked after the status file has
|
|
221
221
|
* been updated.
|
|
222
222
|
*/
|
|
223
223
|
stop(done) {
|