newrelic 7.5.2 → 8.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 +4989 -4886
- package/THIRD_PARTY_NOTICES.md +625 -216
- package/api.js +105 -174
- package/bin/test-naming-rules.js +38 -32
- package/bin/tracetractor +0 -1
- package/index.js +12 -18
- package/lib/agent.js +108 -111
- package/lib/aggregators/base-aggregator.js +1 -1
- package/lib/aggregators/event-aggregator.js +6 -6
- package/lib/attributes.js +12 -13
- package/lib/collector/api.js +32 -42
- package/lib/collector/facts.js +67 -65
- package/lib/collector/http-agents.js +30 -27
- package/lib/collector/parse-response.js +1 -2
- package/lib/collector/remote-method.js +43 -36
- package/lib/collector/serverless.js +13 -18
- package/lib/collector/ssl/certificates.js +1056 -1056
- package/lib/config/attribute-filter.js +90 -82
- package/lib/config/default.js +30 -18
- package/lib/config/env.js +17 -12
- package/lib/config/harvest-config-validator.js +1 -1
- package/lib/config/index.js +160 -177
- package/lib/config/merge-server-config.js +7 -5
- package/lib/custom-events/custom-event-aggregator.js +1 -1
- package/lib/db/parse-sql.js +6 -9
- package/lib/db/parsed-statement.js +6 -13
- package/lib/db/query-parsers/sql.js +6 -9
- package/lib/db/query-sample.js +7 -3
- package/lib/db/query-trace-aggregator.js +12 -12
- package/lib/db/utils.js +1 -1
- package/lib/environment.js +173 -138
- package/lib/errors/error-collector.js +18 -31
- package/lib/errors/error-event-aggregator.js +1 -1
- package/lib/errors/error-trace-aggregator.js +2 -3
- package/lib/errors/helper.js +21 -30
- package/lib/errors/index.js +16 -28
- package/lib/feature_flags.js +5 -8
- package/lib/grpc/connection/states.js +6 -6
- package/lib/grpc/connection.js +35 -46
- package/lib/header-attributes.js +49 -53
- package/lib/instrumentation/amqplib.js +8 -17
- package/lib/instrumentation/bluebird.js +61 -20
- package/lib/instrumentation/cassandra-driver.js +2 -2
- package/lib/instrumentation/connect.js +4 -3
- package/lib/instrumentation/core/async_hooks.js +11 -4
- 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 +2 -8
- package/lib/instrumentation/core/fs.js +22 -37
- package/lib/instrumentation/core/globals.js +3 -7
- package/lib/instrumentation/core/http-outbound.js +15 -40
- package/lib/instrumentation/core/http.js +29 -63
- package/lib/instrumentation/core/inspector.js +6 -10
- package/lib/instrumentation/core/net.js +3 -1
- package/lib/instrumentation/core/timers.js +17 -24
- package/lib/instrumentation/core/zlib.js +2 -10
- package/lib/instrumentation/express.js +4 -2
- package/lib/instrumentation/fastify/spec-builders.js +5 -0
- package/lib/instrumentation/fastify.js +37 -10
- package/lib/instrumentation/hapi/hapi-17.js +9 -10
- package/lib/instrumentation/hapi.js +15 -15
- package/lib/instrumentation/ioredis.js +1 -2
- package/lib/instrumentation/memcached.js +39 -43
- package/lib/instrumentation/mongodb/common.js +218 -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 +33 -26
- package/lib/instrumentation/oracle.js +10 -14
- package/lib/instrumentation/pg.js +30 -21
- package/lib/instrumentation/promise.js +20 -17
- package/lib/instrumentation/redis.js +30 -30
- package/lib/instrumentation/when.js +9 -1
- package/lib/instrumentations.js +24 -24
- package/lib/logger.js +1 -1
- package/lib/metrics/index.js +37 -17
- package/lib/metrics/mapper.js +9 -9
- package/lib/metrics/metric-aggregator.js +5 -10
- package/lib/metrics/names.js +8 -7
- package/lib/metrics/normalizer/rule.js +6 -7
- package/lib/metrics/normalizer/tx_segment.js +17 -13
- package/lib/metrics/normalizer.js +30 -33
- package/lib/metrics/recorders/custom.js +3 -1
- package/lib/metrics/recorders/distributed-trace.js +3 -18
- package/lib/metrics/recorders/generic.js +3 -2
- package/lib/metrics/recorders/http.js +4 -6
- package/lib/metrics/recorders/http_external.js +1 -3
- package/lib/metrics/recorders/message-transaction.js +2 -12
- package/lib/metrics/recorders/other.js +2 -12
- package/lib/parse-proc-cpuinfo.js +11 -16
- package/lib/parse-proc-meminfo.js +5 -3
- package/lib/prioritized-attributes.js +12 -17
- package/lib/priority-queue.js +1 -1
- package/lib/proxy/grpc.js +1 -1
- package/lib/reservoir.js +9 -3
- package/lib/sampler.js +12 -13
- 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 +29 -38
- package/lib/shim/index.js +8 -9
- package/lib/shim/message-shim.js +111 -113
- package/lib/shim/promise-shim.js +18 -13
- package/lib/shim/shim.js +72 -66
- package/lib/shim/specs/index.js +18 -19
- package/lib/shim/transaction-shim.js +26 -36
- package/lib/shim/webframework-shim.js +25 -35
- package/lib/shimmer.js +184 -166
- package/lib/spans/create-span-event-aggregator.js +24 -44
- package/lib/spans/span-context.js +4 -10
- package/lib/spans/span-event-aggregator.js +68 -13
- package/lib/spans/span-event.js +5 -7
- package/lib/spans/span-streamer.js +10 -18
- package/lib/spans/streaming-span-event-aggregator.js +1 -1
- package/lib/spans/streaming-span-event.js +4 -4
- package/lib/stats/apdex.js +5 -11
- package/lib/stats/index.js +12 -17
- package/lib/system-info.js +7 -3
- package/lib/timer.js +30 -16
- package/lib/transaction/dt-payload.js +1 -1
- package/lib/transaction/handle.js +19 -19
- package/lib/transaction/index.js +94 -112
- package/lib/transaction/name-state.js +5 -6
- package/lib/transaction/trace/aggregator.js +78 -73
- package/lib/transaction/trace/exclusive-time-calculator.js +5 -9
- package/lib/transaction/trace/index.js +26 -24
- package/lib/transaction/trace/segment.js +39 -56
- package/lib/transaction/tracecontext.js +37 -45
- package/lib/transaction/tracer/index.js +79 -44
- package/lib/transaction/transaction-event-aggregator.js +29 -31
- package/lib/uninstrumented.js +4 -5
- package/lib/util/attribute-types.js +1 -5
- package/lib/util/byte-limit.js +0 -1
- package/lib/util/cat.js +5 -13
- package/lib/util/codec.js +8 -4
- package/lib/util/deep-equal.js +48 -18
- package/lib/util/flatten.js +5 -2
- package/lib/util/hashes.js +2 -2
- package/lib/util/label-parser.js +7 -13
- package/lib/util/logger.js +31 -13
- package/lib/util/process-version.js +1 -1
- package/lib/util/properties.js +1 -1
- package/lib/util/sql/obfuscate.js +7 -17
- package/lib/util/stream-sink.js +2 -3
- package/lib/util/urltils.js +9 -13
- package/lib/utilization/aws-info.js +2 -3
- package/lib/utilization/azure-info.js +32 -30
- package/lib/utilization/common.js +5 -4
- package/lib/utilization/docker-info.js +4 -6
- package/lib/utilization/gcp-info.js +36 -35
- package/lib/utilization/index.js +1 -1
- package/lib/utilization/kubernetes-info.js +2 -2
- package/lib/utilization/pcf-info.js +4 -4
- package/package.json +32 -18
- package/stub_api.js +8 -6
package/lib/errors/helper.js
CHANGED
|
@@ -11,9 +11,11 @@ module.exports = {
|
|
|
11
11
|
if (transaction && urltils.isExpectedError(config, transaction.statusCode)) {
|
|
12
12
|
isExpectedTransactionCode = true
|
|
13
13
|
}
|
|
14
|
-
return
|
|
14
|
+
return (
|
|
15
|
+
this.isExpectedErrorMessage(config, type, message) ||
|
|
15
16
|
this.isExpectedErrorClass(config, type) ||
|
|
16
17
|
isExpectedTransactionCode
|
|
18
|
+
)
|
|
17
19
|
},
|
|
18
20
|
isExpectedErrorMessage: function isExpectedErrorMessage(config, type, message) {
|
|
19
21
|
if (!config.error_collector.expected_messages[type]) {
|
|
@@ -34,29 +36,15 @@ module.exports = {
|
|
|
34
36
|
}
|
|
35
37
|
return false
|
|
36
38
|
},
|
|
37
|
-
isExpectedException: function isExpectedException(
|
|
38
|
-
transaction,
|
|
39
|
-
exception,
|
|
40
|
-
config,
|
|
41
|
-
urltils
|
|
42
|
-
) {
|
|
43
|
-
let {type, message} = this.extractErrorInformation(
|
|
44
|
-
transaction,
|
|
45
|
-
exception,
|
|
46
|
-
config,
|
|
47
|
-
urltils
|
|
48
|
-
)
|
|
39
|
+
isExpectedException: function isExpectedException(transaction, exception, config, urltils) {
|
|
40
|
+
let { type, message } = this.extractErrorInformation(transaction, exception, config, urltils)
|
|
49
41
|
|
|
50
|
-
return
|
|
51
|
-
this.isExpectedErrorMessage(config, type, message)
|
|
42
|
+
return (
|
|
43
|
+
this.isExpectedErrorClass(config, type) || this.isExpectedErrorMessage(config, type, message)
|
|
44
|
+
)
|
|
52
45
|
},
|
|
53
46
|
|
|
54
|
-
extractErrorInformation: function extractErrorInformation(
|
|
55
|
-
transaction,
|
|
56
|
-
error,
|
|
57
|
-
config,
|
|
58
|
-
urltils
|
|
59
|
-
) {
|
|
47
|
+
extractErrorInformation: function extractErrorInformation(transaction, error, config, urltils) {
|
|
60
48
|
let name = 'Unknown'
|
|
61
49
|
let message = ''
|
|
62
50
|
let type = 'Error'
|
|
@@ -79,8 +67,11 @@ module.exports = {
|
|
|
79
67
|
} else if (error.constructor && error.constructor.name) {
|
|
80
68
|
type = error.constructor.name
|
|
81
69
|
}
|
|
82
|
-
} else if (
|
|
83
|
-
|
|
70
|
+
} else if (
|
|
71
|
+
transaction &&
|
|
72
|
+
transaction.statusCode &&
|
|
73
|
+
urltils.isError(config, transaction.statusCode)
|
|
74
|
+
) {
|
|
84
75
|
message = 'HttpError ' + transaction.statusCode
|
|
85
76
|
}
|
|
86
77
|
|
|
@@ -94,9 +85,9 @@ module.exports = {
|
|
|
94
85
|
}
|
|
95
86
|
|
|
96
87
|
return {
|
|
97
|
-
name:name,
|
|
98
|
-
message:message,
|
|
99
|
-
type:type
|
|
88
|
+
name: name,
|
|
89
|
+
message: message,
|
|
90
|
+
type: type
|
|
100
91
|
}
|
|
101
92
|
},
|
|
102
93
|
|
|
@@ -104,18 +95,18 @@ module.exports = {
|
|
|
104
95
|
// extract _just_ the error information, not transaction stuff
|
|
105
96
|
let errorInfo = this.extractErrorInformation(null, error, config, null)
|
|
106
97
|
|
|
107
|
-
return
|
|
98
|
+
return (
|
|
99
|
+
this.shouldIgnoreErrorClass(errorInfo, config) ||
|
|
108
100
|
this.shouldIgnoreErrorMessage(errorInfo, config) ||
|
|
109
101
|
this.shouldIgnoreStatusCode(transaction, config)
|
|
102
|
+
)
|
|
110
103
|
},
|
|
111
104
|
|
|
112
105
|
shouldIgnoreStatusCode: function shouldIgnoreStatusCode(transaction, config) {
|
|
113
106
|
if (!transaction) {
|
|
114
107
|
return false
|
|
115
108
|
}
|
|
116
|
-
return config.error_collector.ignore_status_codes.indexOf(
|
|
117
|
-
transaction.statusCode
|
|
118
|
-
) !== -1
|
|
109
|
+
return config.error_collector.ignore_status_codes.indexOf(transaction.statusCode) !== -1
|
|
119
110
|
},
|
|
120
111
|
|
|
121
112
|
shouldIgnoreErrorClass: function shouldIgnoreErrorClass(errorInfo, config) {
|
package/lib/errors/index.js
CHANGED
|
@@ -12,7 +12,7 @@ var urltils = require('../util/urltils')
|
|
|
12
12
|
const errorHelper = require('../errors/helper')
|
|
13
13
|
|
|
14
14
|
class Exception {
|
|
15
|
-
constructor({error, timestamp, customAttributes, agentAttributes}) {
|
|
15
|
+
constructor({ error, timestamp, customAttributes, agentAttributes }) {
|
|
16
16
|
this.error = error
|
|
17
17
|
this.timestamp = timestamp || 0
|
|
18
18
|
this.customAttributes = customAttributes || {}
|
|
@@ -26,7 +26,7 @@ class Exception {
|
|
|
26
26
|
return errorDetails
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
isExpected(config, {type, message}) {
|
|
29
|
+
isExpected(config, { type, message }) {
|
|
30
30
|
if (!this._expected) {
|
|
31
31
|
this._expected =
|
|
32
32
|
errorHelper.isExpectedErrorClass(config, type) ||
|
|
@@ -51,7 +51,7 @@ class Exception {
|
|
|
51
51
|
*/
|
|
52
52
|
function createError(transaction, exception, config) {
|
|
53
53
|
const error = exception.error
|
|
54
|
-
let {name, message, type} = errorHelper.extractErrorInformation(
|
|
54
|
+
let { name, message, type } = errorHelper.extractErrorInformation(
|
|
55
55
|
transaction,
|
|
56
56
|
error,
|
|
57
57
|
config,
|
|
@@ -85,10 +85,7 @@ function createError(transaction, exception, config) {
|
|
|
85
85
|
if (!config.high_security && config.api.custom_attributes_enabled && customAttributes) {
|
|
86
86
|
for (let key in customAttributes) {
|
|
87
87
|
if (props.hasOwn(customAttributes, key)) {
|
|
88
|
-
const dest = config.attributeFilter.filterTransaction(
|
|
89
|
-
DESTINATIONS.ERROR_EVENT,
|
|
90
|
-
key
|
|
91
|
-
)
|
|
88
|
+
const dest = config.attributeFilter.filterTransaction(DESTINATIONS.ERROR_EVENT, key)
|
|
92
89
|
if (dest & DESTINATIONS.ERROR_EVENT) {
|
|
93
90
|
params.userAttributes[key] = customAttributes[key]
|
|
94
91
|
}
|
|
@@ -139,32 +136,23 @@ function createEvent(transaction, error, timestamp, config) {
|
|
|
139
136
|
var userAttributes = Object.assign(Object.create(null), errorParams.userAttributes)
|
|
140
137
|
var agentAttributes = Object.assign(Object.create(null), errorParams.agentAttributes)
|
|
141
138
|
|
|
142
|
-
var errorEvent = [
|
|
143
|
-
intrinsicAttributes,
|
|
144
|
-
userAttributes,
|
|
145
|
-
agentAttributes
|
|
146
|
-
]
|
|
139
|
+
var errorEvent = [intrinsicAttributes, userAttributes, agentAttributes]
|
|
147
140
|
|
|
148
141
|
return errorEvent
|
|
149
142
|
}
|
|
150
143
|
|
|
151
144
|
// eslint-disable-next-line max-params
|
|
152
|
-
function _getErrorEventIntrinsicAttrs(
|
|
153
|
-
transaction,
|
|
154
|
-
errorClass,
|
|
155
|
-
message,
|
|
156
|
-
expected,
|
|
157
|
-
timestamp,
|
|
158
|
-
conf
|
|
159
|
-
) {
|
|
145
|
+
function _getErrorEventIntrinsicAttrs(transaction, errorClass, message, expected, timestamp, conf) {
|
|
160
146
|
// the server expects seconds instead of milliseconds
|
|
161
|
-
if (timestamp)
|
|
147
|
+
if (timestamp) {
|
|
148
|
+
timestamp = timestamp / 1000
|
|
149
|
+
}
|
|
162
150
|
|
|
163
151
|
var attributes = {
|
|
164
|
-
type:
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
timestamp: timestamp,
|
|
152
|
+
'type': 'TransactionError',
|
|
153
|
+
'error.class': errorClass,
|
|
154
|
+
'error.message': conf.high_security ? '' : message,
|
|
155
|
+
'timestamp': timestamp,
|
|
168
156
|
'error.expected': expected
|
|
169
157
|
}
|
|
170
158
|
|
|
@@ -190,9 +178,9 @@ function _getErrorEventIntrinsicAttrs(
|
|
|
190
178
|
}
|
|
191
179
|
|
|
192
180
|
if (transaction.syntheticsData) {
|
|
193
|
-
attributes[
|
|
194
|
-
attributes[
|
|
195
|
-
attributes[
|
|
181
|
+
attributes['nr.syntheticsResourceId'] = transaction.syntheticsData.resourceId
|
|
182
|
+
attributes['nr.syntheticsJobId'] = transaction.syntheticsData.jobId
|
|
183
|
+
attributes['nr.syntheticsMonitorId'] = transaction.syntheticsData.monitorId
|
|
196
184
|
}
|
|
197
185
|
|
|
198
186
|
if (transaction.agent.config.distributed_tracing.enabled) {
|
package/lib/feature_flags.js
CHANGED
|
@@ -9,14 +9,12 @@
|
|
|
9
9
|
exports.prerelease = {
|
|
10
10
|
express5: false,
|
|
11
11
|
await_support: true,
|
|
12
|
-
serverless_mode: true, // TODO: Move to released & remove code checks next Major.
|
|
13
12
|
promise_segments: false,
|
|
14
13
|
reverse_naming_rules: false,
|
|
15
14
|
fastify_instrumentation: false,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
new_promise_tracking: false
|
|
15
|
+
certificate_bundle: false,
|
|
16
|
+
new_promise_tracking: false,
|
|
17
|
+
unresolved_promise_cleanup: true
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
// flags that are no longer used for released features
|
|
@@ -28,12 +26,11 @@ exports.released = [
|
|
|
28
26
|
'express_segments',
|
|
29
27
|
'native_metrics',
|
|
30
28
|
'protocol_17',
|
|
29
|
+
'serverless_mode',
|
|
31
30
|
'send_request_uri_attribute',
|
|
32
31
|
'synthetics',
|
|
33
32
|
'dt_format_w3c'
|
|
34
33
|
]
|
|
35
34
|
|
|
36
35
|
// flags that are no longer used for unreleased features
|
|
37
|
-
exports.unreleased = [
|
|
38
|
-
'unreleased'
|
|
39
|
-
]
|
|
36
|
+
exports.unreleased = ['unreleased']
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
module.exports = {
|
|
8
|
-
disconnected:0,
|
|
9
|
-
connecting:1,
|
|
10
|
-
connected:2,
|
|
11
|
-
0:'disconnected',
|
|
12
|
-
1:'connecting',
|
|
13
|
-
2:'connected'
|
|
8
|
+
disconnected: 0,
|
|
9
|
+
connecting: 1,
|
|
10
|
+
connected: 2,
|
|
11
|
+
0: 'disconnected',
|
|
12
|
+
1: 'connecting',
|
|
13
|
+
2: 'connected'
|
|
14
14
|
}
|
package/lib/grpc/connection.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const protoLoader = require('@grpc/proto-loader')
|
|
9
9
|
const grpc = require('../proxy/grpc')
|
|
10
|
-
const logger = require('../logger').child({component: 'grpc_connection'})
|
|
10
|
+
const logger = require('../logger').child({ component: 'grpc_connection' })
|
|
11
11
|
const EventEmitter = require('events')
|
|
12
12
|
const NAMES = require('../metrics/names')
|
|
13
13
|
const util = require('util')
|
|
@@ -20,15 +20,9 @@ const GRPC_TEST_META = {
|
|
|
20
20
|
|
|
21
21
|
const connectionStates = require('./connection/states')
|
|
22
22
|
|
|
23
|
-
const PROTO_OPTIONS = {keepCase: true,
|
|
24
|
-
longs: String,
|
|
25
|
-
enums: String,
|
|
26
|
-
defaults: true,
|
|
27
|
-
oneofs: true
|
|
28
|
-
}
|
|
23
|
+
const PROTO_OPTIONS = { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true }
|
|
29
24
|
|
|
30
|
-
const PROTO_DEFINITION_PATH = __dirname +
|
|
31
|
-
'../../../lib/grpc/endpoints/infinite-tracing/v1.proto'
|
|
25
|
+
const PROTO_DEFINITION_PATH = __dirname + '../../../lib/grpc/endpoints/infinite-tracing/v1.proto'
|
|
32
26
|
|
|
33
27
|
const DEFAULT_RECONNECT_DELAY_MS = 15 * 1000
|
|
34
28
|
|
|
@@ -77,14 +71,14 @@ class GrpcConnection extends EventEmitter {
|
|
|
77
71
|
* but before the actual connection.
|
|
78
72
|
*
|
|
79
73
|
* @param {string} endpoint the GRPC server's endpoint
|
|
80
|
-
* @param {string}
|
|
81
|
-
* @param {string}
|
|
74
|
+
* @param {string} licenseKey the agent license key
|
|
75
|
+
* @param {string} runId the current agent run id (also called agent run token)
|
|
82
76
|
* @param {object} requestHeadersMap request headers map received from server connect.
|
|
83
77
|
* @param {string} [rootCerts] string of root (ca) certificates to attach to the connection.
|
|
84
78
|
*/
|
|
85
|
-
setConnectionDetails(
|
|
86
|
-
this._licenseKey =
|
|
87
|
-
this._runId =
|
|
79
|
+
setConnectionDetails(licenseKey, runId, requestHeadersMap, rootCerts) {
|
|
80
|
+
this._licenseKey = licenseKey
|
|
81
|
+
this._runId = runId
|
|
88
82
|
this._requestHeadersMap = requestHeadersMap
|
|
89
83
|
this._rootCerts = rootCerts
|
|
90
84
|
|
|
@@ -129,10 +123,7 @@ class GrpcConnection extends EventEmitter {
|
|
|
129
123
|
// immediately.
|
|
130
124
|
this._setState(connectionStates.connected, this.stream)
|
|
131
125
|
} catch (err) {
|
|
132
|
-
logger.warn(
|
|
133
|
-
err,
|
|
134
|
-
'Unexpected error establishing gRPC stream, will not attempt reconnect.'
|
|
135
|
-
)
|
|
126
|
+
logger.warn(err, 'Unexpected error establishing gRPC stream, will not attempt reconnect.')
|
|
136
127
|
this._disconnect()
|
|
137
128
|
}
|
|
138
129
|
}
|
|
@@ -153,13 +144,13 @@ class GrpcConnection extends EventEmitter {
|
|
|
153
144
|
/**
|
|
154
145
|
* Method returns GRPC metadata for initial connection
|
|
155
146
|
*
|
|
156
|
-
* @param {string}
|
|
157
|
-
* @param {string}
|
|
147
|
+
* @param {string} licenseKey
|
|
148
|
+
* @param {string} runId
|
|
158
149
|
*/
|
|
159
|
-
_getMetadata(
|
|
150
|
+
_getMetadata(licenseKey, runId, requestHeadersMap, env) {
|
|
160
151
|
const metadata = new grpc.Metadata()
|
|
161
|
-
metadata.add('license_key',
|
|
162
|
-
metadata.add('agent_run_token',
|
|
152
|
+
metadata.add('license_key', licenseKey)
|
|
153
|
+
metadata.add('agent_run_token', runId)
|
|
163
154
|
|
|
164
155
|
// p17 spec: If request_headers_map is empty or absent,
|
|
165
156
|
// the agent SHOULD NOT apply anything to its requests.
|
|
@@ -199,10 +190,7 @@ class GrpcConnection extends EventEmitter {
|
|
|
199
190
|
|
|
200
191
|
logger.trace('Reconnecting to gRPC endpoint in [%s] seconds', reconnectDelayMs)
|
|
201
192
|
|
|
202
|
-
setTimeout(
|
|
203
|
-
this.connectSpans.bind(this),
|
|
204
|
-
reconnectDelayMs
|
|
205
|
-
)
|
|
193
|
+
setTimeout(this.connectSpans.bind(this), reconnectDelayMs)
|
|
206
194
|
}
|
|
207
195
|
|
|
208
196
|
_disconnect() {
|
|
@@ -251,7 +239,7 @@ class GrpcConnection extends EventEmitter {
|
|
|
251
239
|
// if we are not going to use the data.
|
|
252
240
|
stream.on('data', function data(response) {
|
|
253
241
|
if (logger.traceEnabled()) {
|
|
254
|
-
logger.trace(
|
|
242
|
+
logger.trace('gRPC span response stream: %s', JSON.stringify(response))
|
|
255
243
|
}
|
|
256
244
|
})
|
|
257
245
|
|
|
@@ -259,13 +247,12 @@ class GrpcConnection extends EventEmitter {
|
|
|
259
247
|
// and we need to disconnect
|
|
260
248
|
stream.on('status', (grpcStatus) => {
|
|
261
249
|
logger.trace('gRPC Status Received [%s]: %s', grpcStatus.code, grpcStatus.details)
|
|
262
|
-
const grpcStatusName =
|
|
263
|
-
grpc.status[grpcStatus.code] ? grpc.status[grpcStatus.code] : 'UNKNOWN'
|
|
250
|
+
const grpcStatusName = grpc.status[grpcStatus.code] ? grpc.status[grpcStatus.code] : 'UNKNOWN'
|
|
264
251
|
|
|
265
252
|
if (grpc.status[grpc.status.UNIMPLEMENTED] === grpcStatusName) {
|
|
266
|
-
this._metrics
|
|
267
|
-
NAMES.INFINITE_TRACING.SPAN_RESPONSE_GRPC_UNIMPLEMENTED
|
|
268
|
-
|
|
253
|
+
this._metrics
|
|
254
|
+
.getOrCreateMetric(NAMES.INFINITE_TRACING.SPAN_RESPONSE_GRPC_UNIMPLEMENTED)
|
|
255
|
+
.incrementCallCount()
|
|
269
256
|
|
|
270
257
|
// per the spec, An UNIMPLEMENTED status code from gRPC indicates
|
|
271
258
|
// that the versioned Trace Observer is no longer available. Agents
|
|
@@ -277,9 +264,11 @@ class GrpcConnection extends EventEmitter {
|
|
|
277
264
|
} else if (grpc.status[grpc.status.OK] === grpcStatusName) {
|
|
278
265
|
this._reconnect()
|
|
279
266
|
} else {
|
|
280
|
-
this._metrics
|
|
281
|
-
|
|
282
|
-
|
|
267
|
+
this._metrics
|
|
268
|
+
.getOrCreateMetric(
|
|
269
|
+
util.format(NAMES.INFINITE_TRACING.SPAN_RESPONSE_GRPC_STATUS, grpcStatusName)
|
|
270
|
+
)
|
|
271
|
+
.incrementCallCount()
|
|
283
272
|
|
|
284
273
|
this._reconnect(this._reconnectDelayMs)
|
|
285
274
|
}
|
|
@@ -288,7 +277,8 @@ class GrpcConnection extends EventEmitter {
|
|
|
288
277
|
// if we don't listen for the errors they'll bubble
|
|
289
278
|
// up and crash the application
|
|
290
279
|
stream.on('error', (err) => {
|
|
291
|
-
this._metrics
|
|
280
|
+
this._metrics
|
|
281
|
+
.getOrCreateMetric(NAMES.INFINITE_TRACING.SPAN_RESPONSE_ERROR)
|
|
292
282
|
.incrementCallCount()
|
|
293
283
|
|
|
294
284
|
// For errors, the status will either result in a disconnect or a reconnect
|
|
@@ -339,8 +329,12 @@ class GrpcConnection extends EventEmitter {
|
|
|
339
329
|
this._client = this._createClient(this._endpoint)
|
|
340
330
|
}
|
|
341
331
|
|
|
342
|
-
const metadata =
|
|
343
|
-
this.
|
|
332
|
+
const metadata = this._getMetadata(
|
|
333
|
+
this._licenseKey,
|
|
334
|
+
this._runId,
|
|
335
|
+
this._requestHeadersMap,
|
|
336
|
+
process.env
|
|
337
|
+
)
|
|
344
338
|
|
|
345
339
|
const stream = this._client.recordSpan(metadata)
|
|
346
340
|
this._setupSpanStreamObservers(stream)
|
|
@@ -361,17 +355,12 @@ class GrpcConnection extends EventEmitter {
|
|
|
361
355
|
|
|
362
356
|
const packageDefinition = protoLoader.loadSync(PROTO_DEFINITION_PATH, PROTO_OPTIONS)
|
|
363
357
|
|
|
364
|
-
const protoDescriptor = grpc.loadPackageDefinition(
|
|
365
|
-
packageDefinition
|
|
366
|
-
)
|
|
358
|
+
const protoDescriptor = grpc.loadPackageDefinition(packageDefinition)
|
|
367
359
|
|
|
368
360
|
const traceApi = protoDescriptor.com.newrelic.trace.v1
|
|
369
361
|
|
|
370
362
|
const credentials = this._generateCredentials(grpc)
|
|
371
|
-
const client = new traceApi.IngestService(
|
|
372
|
-
endpoint,
|
|
373
|
-
credentials
|
|
374
|
-
)
|
|
363
|
+
const client = new traceApi.IngestService(endpoint, credentials)
|
|
375
364
|
|
|
376
365
|
return client
|
|
377
366
|
}
|
package/lib/header-attributes.js
CHANGED
|
@@ -17,55 +17,55 @@ const COLLECTED_REQUEST_HEADERS = [
|
|
|
17
17
|
]
|
|
18
18
|
|
|
19
19
|
const HEADER_ATTR_NAMES = {
|
|
20
|
-
'accept':
|
|
21
|
-
'accept-charset':
|
|
22
|
-
'accept-encoding':
|
|
20
|
+
'accept': 'accept',
|
|
21
|
+
'accept-charset': 'acceptCharset',
|
|
22
|
+
'accept-encoding': 'acceptEncoding',
|
|
23
23
|
'access-control-allow-headers': 'accessControlAllowHeaders',
|
|
24
24
|
'access-control-allow-methods': 'accessControlAllowMethods',
|
|
25
|
-
'access-control-allow-origin':
|
|
26
|
-
'age':
|
|
27
|
-
'allow':
|
|
28
|
-
'authorization':
|
|
29
|
-
'cache-control':
|
|
30
|
-
'connection':
|
|
31
|
-
'cookie':
|
|
32
|
-
'content-encoding':
|
|
33
|
-
'content-length':
|
|
34
|
-
'content-type':
|
|
35
|
-
'date':
|
|
36
|
-
'etag':
|
|
37
|
-
'expect':
|
|
38
|
-
'expires':
|
|
39
|
-
'forwarded':
|
|
40
|
-
'host':
|
|
41
|
-
'if-match':
|
|
42
|
-
'if-modified-since':
|
|
43
|
-
'last-modified':
|
|
44
|
-
'location':
|
|
45
|
-
'newrelic':
|
|
46
|
-
'origin':
|
|
47
|
-
'proxy-authorization':
|
|
48
|
-
'referer':
|
|
49
|
-
'refresh':
|
|
50
|
-
'server':
|
|
51
|
-
'set-cookie':
|
|
52
|
-
'transfer-encoding':
|
|
53
|
-
'user-agent':
|
|
54
|
-
'upgrade':
|
|
55
|
-
'vary':
|
|
56
|
-
'x-correlation-id':
|
|
57
|
-
'x-csrf-token':
|
|
58
|
-
'x-forwarded-for':
|
|
59
|
-
'x-http-method-override':
|
|
60
|
-
'x-newrelic-app-data':
|
|
61
|
-
'x-newrelic-id':
|
|
62
|
-
'x-newrelic-synthetics':
|
|
63
|
-
'x-newrelic-transaction':
|
|
64
|
-
'x-powered-by':
|
|
65
|
-
'x-queue-start':
|
|
66
|
-
'x-request-id':
|
|
67
|
-
'x-request-start':
|
|
68
|
-
'x-requested-with':
|
|
25
|
+
'access-control-allow-origin': 'accessControlAllowOrigin',
|
|
26
|
+
'age': 'age',
|
|
27
|
+
'allow': 'allow',
|
|
28
|
+
'authorization': 'authorization',
|
|
29
|
+
'cache-control': 'cacheControl',
|
|
30
|
+
'connection': 'connection',
|
|
31
|
+
'cookie': 'cookie',
|
|
32
|
+
'content-encoding': 'contentEncoding',
|
|
33
|
+
'content-length': 'contentLength',
|
|
34
|
+
'content-type': 'contentType',
|
|
35
|
+
'date': 'date',
|
|
36
|
+
'etag': 'eTag',
|
|
37
|
+
'expect': 'expect',
|
|
38
|
+
'expires': 'expires',
|
|
39
|
+
'forwarded': 'forwarded',
|
|
40
|
+
'host': 'host',
|
|
41
|
+
'if-match': 'ifMatch',
|
|
42
|
+
'if-modified-since': 'ifModifiedSince',
|
|
43
|
+
'last-modified': 'lastModified',
|
|
44
|
+
'location': 'location',
|
|
45
|
+
'newrelic': 'newrelic',
|
|
46
|
+
'origin': 'origin',
|
|
47
|
+
'proxy-authorization': 'proxyAuthorization',
|
|
48
|
+
'referer': 'referer',
|
|
49
|
+
'refresh': 'refresh',
|
|
50
|
+
'server': 'server',
|
|
51
|
+
'set-cookie': 'setCookie',
|
|
52
|
+
'transfer-encoding': 'transferEncoding',
|
|
53
|
+
'user-agent': 'userAgent',
|
|
54
|
+
'upgrade': 'upgrade',
|
|
55
|
+
'vary': 'vary',
|
|
56
|
+
'x-correlation-id': 'xCorrelationId',
|
|
57
|
+
'x-csrf-token': 'xCsrfToken',
|
|
58
|
+
'x-forwarded-for': 'xForwardedFor',
|
|
59
|
+
'x-http-method-override': 'xHttpMethodOverride',
|
|
60
|
+
'x-newrelic-app-data': 'xNewrelicAppData',
|
|
61
|
+
'x-newrelic-id': 'xNewrelicId',
|
|
62
|
+
'x-newrelic-synthetics': 'xNewrelicSynthetics',
|
|
63
|
+
'x-newrelic-transaction': 'xNewrelicTransaction',
|
|
64
|
+
'x-powered-by': 'xPoweredBy',
|
|
65
|
+
'x-queue-start': 'xQueueStart',
|
|
66
|
+
'x-request-id': 'xRequestId',
|
|
67
|
+
'x-request-start': 'xRequestStart',
|
|
68
|
+
'x-requested-with': 'xRequestedWith'
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
const REQUEST_HEADER_PREFIX = 'request.headers.'
|
|
@@ -116,7 +116,7 @@ function _collectHeaders(headers, nameMap, prefix, transaction) {
|
|
|
116
116
|
: Object.keys(headers)
|
|
117
117
|
|
|
118
118
|
const segment = transaction.agent.tracer.getSegment()
|
|
119
|
-
|
|
119
|
+
|
|
120
120
|
for (var i = 0; i < headerKeys.length; i++) {
|
|
121
121
|
var headerKey = headerKeys[i]
|
|
122
122
|
var header = headers[headerKey]
|
|
@@ -130,11 +130,7 @@ function _collectHeaders(headers, nameMap, prefix, transaction) {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
var attributeName = nameMap[headerKey] || prefix + _headerToCamelCase(headerKey)
|
|
133
|
-
transaction.trace.attributes.addAttribute(
|
|
134
|
-
DESTS.TRANS_COMMON,
|
|
135
|
-
attributeName,
|
|
136
|
-
header
|
|
137
|
-
)
|
|
133
|
+
transaction.trace.attributes.addAttribute(DESTS.TRANS_COMMON, attributeName, header)
|
|
138
134
|
|
|
139
135
|
segment.addSpanAttribute(attributeName, header)
|
|
140
136
|
}
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
var url = require('url')
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
// TODO: Make this an external module.
|
|
12
11
|
// var newrelic = require('newrelic')
|
|
13
12
|
// newrelic.instrumentMessages('amqplib', instrumentChannelAPI)
|
|
@@ -66,7 +65,6 @@ var CHANNEL_METHODS = [
|
|
|
66
65
|
|
|
67
66
|
var TEMP_RE = /^amq\./
|
|
68
67
|
|
|
69
|
-
|
|
70
68
|
function instrumentChannelAPI(shim, amqp) {
|
|
71
69
|
instrumentAMQP(shim, amqp, true)
|
|
72
70
|
wrapPromiseChannel(shim)
|
|
@@ -79,7 +77,7 @@ function instrumentCallbackAPI(shim, amqp) {
|
|
|
79
77
|
|
|
80
78
|
function instrumentAMQP(shim, amqp, promiseMode) {
|
|
81
79
|
if (!amqp || !amqp.connect) {
|
|
82
|
-
shim.logger.debug(
|
|
80
|
+
shim.logger.debug("This module is not the amqplib we're looking for.")
|
|
83
81
|
return false
|
|
84
82
|
}
|
|
85
83
|
|
|
@@ -95,7 +93,7 @@ function instrumentAMQP(shim, amqp, promiseMode) {
|
|
|
95
93
|
|
|
96
94
|
if (shim.isString(connArgs)) {
|
|
97
95
|
connArgs = url.parse(connArgs)
|
|
98
|
-
params = {host: connArgs.hostname}
|
|
96
|
+
params = { host: connArgs.hostname }
|
|
99
97
|
if (connArgs.port) {
|
|
100
98
|
params.port = connArgs.port
|
|
101
99
|
}
|
|
@@ -138,10 +136,7 @@ function wrapChannel(shim) {
|
|
|
138
136
|
var segment = shim.getSegment()
|
|
139
137
|
var cb = arguments[arguments.length - 1]
|
|
140
138
|
if (!shim.isFunction(cb) || !segment) {
|
|
141
|
-
shim.logger.debug(
|
|
142
|
-
{cb: !!cb, segment: !!segment},
|
|
143
|
-
'Not binding sendOrEnqueue callback'
|
|
144
|
-
)
|
|
139
|
+
shim.logger.debug({ cb: !!cb, segment: !!segment }, 'Not binding sendOrEnqueue callback')
|
|
145
140
|
return fn.apply(this, arguments)
|
|
146
141
|
}
|
|
147
142
|
|
|
@@ -245,7 +240,7 @@ function wrapPromiseChannel(shim) {
|
|
|
245
240
|
headers = message.properties.headers
|
|
246
241
|
}
|
|
247
242
|
|
|
248
|
-
return {parameters: parameters, headers: headers}
|
|
243
|
+
return { parameters: parameters, headers: headers }
|
|
249
244
|
}
|
|
250
245
|
})
|
|
251
246
|
|
|
@@ -255,7 +250,7 @@ function wrapPromiseChannel(shim) {
|
|
|
255
250
|
queue = null
|
|
256
251
|
}
|
|
257
252
|
|
|
258
|
-
return {queue: queue, promise: true}
|
|
253
|
+
return { queue: queue, promise: true }
|
|
259
254
|
})
|
|
260
255
|
|
|
261
256
|
shim.recordSubscribedConsume(proto, 'consume', {
|
|
@@ -328,7 +323,7 @@ function wrapCallbackChannel(shim) {
|
|
|
328
323
|
headers = message.properties.headers
|
|
329
324
|
}
|
|
330
325
|
|
|
331
|
-
return {parameters: parameters, headers: headers}
|
|
326
|
+
return { parameters: parameters, headers: headers }
|
|
332
327
|
}
|
|
333
328
|
})
|
|
334
329
|
|
|
@@ -338,10 +333,9 @@ function wrapCallbackChannel(shim) {
|
|
|
338
333
|
queue = null
|
|
339
334
|
}
|
|
340
335
|
|
|
341
|
-
return {queue: queue, callback: shim.LAST}
|
|
336
|
+
return { queue: queue, callback: shim.LAST }
|
|
342
337
|
})
|
|
343
338
|
|
|
344
|
-
|
|
345
339
|
shim.recordSubscribedConsume(proto, 'consume', {
|
|
346
340
|
name: 'amqplib.Channel#consume',
|
|
347
341
|
queue: shim.FIRST,
|
|
@@ -355,10 +349,7 @@ function wrapCallbackChannel(shim) {
|
|
|
355
349
|
function describeMessage(shim, consumer, name, args) {
|
|
356
350
|
var message = args[0]
|
|
357
351
|
if (!message || !message.properties) {
|
|
358
|
-
shim.logger.debug(
|
|
359
|
-
{message: message},
|
|
360
|
-
'Failed to find message in consume arguments.'
|
|
361
|
-
)
|
|
352
|
+
shim.logger.debug({ message: message }, 'Failed to find message in consume arguments.')
|
|
362
353
|
return null
|
|
363
354
|
}
|
|
364
355
|
|