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/shimmer.js
CHANGED
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
const path = require('path')
|
|
9
|
+
const fs = require('./util/unwrapped-core').fs
|
|
10
|
+
const logger = require('./logger').child({ component: 'shimmer' })
|
|
11
|
+
const INSTRUMENTATIONS = require('./instrumentations')()
|
|
12
|
+
const properties = require('./util/properties')
|
|
13
|
+
const shims = require('./shim')
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
const MODULE_TYPE = shims.constants.MODULE_TYPE
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const CORE_INSTRUMENTATION = {
|
|
18
18
|
child_process: {
|
|
19
19
|
type: MODULE_TYPE.GENERIC,
|
|
20
20
|
file: 'child_process.js'
|
|
@@ -73,114 +73,12 @@ const FORCE_MODULE_RESOLUTION_WARNING =
|
|
|
73
73
|
* maneuver, but it should be pretty safe if there's a desire to reboot the
|
|
74
74
|
* agent in flight.
|
|
75
75
|
*
|
|
76
|
-
* All of the wrapped methods are tracked in this
|
|
76
|
+
* All of the wrapped methods are tracked in this constiable and used by unwrapAll
|
|
77
77
|
* below.
|
|
78
78
|
*/
|
|
79
|
-
|
|
79
|
+
let instrumented = []
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
if (shimmer.debug) {
|
|
83
|
-
shim.enableDebug()
|
|
84
|
-
instrumented.push(shim)
|
|
85
|
-
instrumented.push({__NR_unwrap: function unwrapNodule() {
|
|
86
|
-
delete nodule.__NR_instrumented_errored
|
|
87
|
-
delete nodule.__NR_instrumented
|
|
88
|
-
delete nodule.__NR_shim
|
|
89
|
-
}})
|
|
90
|
-
nodule.__NR_shim = shim
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* All instrumentation files must export the same interface: a single
|
|
96
|
-
* initialization function that takes the agent and the module to be
|
|
97
|
-
* instrumented.
|
|
98
|
-
*/
|
|
99
|
-
function instrument(agent, nodule, moduleName, resolvedName) {
|
|
100
|
-
var instrumentation = shimmer.registeredInstrumentations[moduleName]
|
|
101
|
-
if (properties.hasOwn(nodule, '__NR_instrumented')
|
|
102
|
-
|| properties.hasOwn(nodule, '__NR_instrumented_errored')) {
|
|
103
|
-
logger.trace(
|
|
104
|
-
'Already instrumented or failed to instrument %s, skipping redundant instrumentation',
|
|
105
|
-
moduleName
|
|
106
|
-
)
|
|
107
|
-
return nodule
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
var shim = shims.createShimFromType(
|
|
112
|
-
instrumentation.type,
|
|
113
|
-
agent,
|
|
114
|
-
moduleName,
|
|
115
|
-
resolvedName
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
applyDebugState(shimmer, shim, nodule)
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
if (instrumentation.onRequire(shim, nodule, moduleName) !== false) {
|
|
122
|
-
nodule = shim.getExport(nodule)
|
|
123
|
-
nodule.__NR_instrumented = true
|
|
124
|
-
}
|
|
125
|
-
} catch (instrumentationError) {
|
|
126
|
-
nodule.__NR_instrumented_errored = true
|
|
127
|
-
if (instrumentation.onError) {
|
|
128
|
-
try {
|
|
129
|
-
instrumentation.onError(instrumentationError)
|
|
130
|
-
} catch (e) {
|
|
131
|
-
logger.warn(
|
|
132
|
-
e, instrumentationError,
|
|
133
|
-
'Custom instrumentation for %s failed, then the onError handler threw an error',
|
|
134
|
-
moduleName
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
|
-
} else {
|
|
138
|
-
logger.warn(
|
|
139
|
-
instrumentationError,
|
|
140
|
-
'Custom instrumentation for %s failed. Please report this to the ' +
|
|
141
|
-
'maintainers of the custom instrumentation.',
|
|
142
|
-
moduleName
|
|
143
|
-
)
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return nodule
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function _firstPartyInstrumentation(agent, fileName, shim, nodule, moduleName) {
|
|
151
|
-
var fullPath = path.resolve(fileName)
|
|
152
|
-
if (!fs.existsSync(fileName)) {
|
|
153
|
-
return logger.warn(
|
|
154
|
-
'Tried to load instrumentation from %s, but file does not exist',
|
|
155
|
-
fullPath
|
|
156
|
-
)
|
|
157
|
-
}
|
|
158
|
-
try {
|
|
159
|
-
return require(fileName)(agent, nodule, moduleName, shim)
|
|
160
|
-
} catch (error) {
|
|
161
|
-
logger.warn(
|
|
162
|
-
error,
|
|
163
|
-
'Failed to instrument module %s using %s',
|
|
164
|
-
path.basename(fileName, '.js'),
|
|
165
|
-
fullPath
|
|
166
|
-
)
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function _postLoad(agent, nodule, name, resolvedName) {
|
|
171
|
-
var instrumentation
|
|
172
|
-
instrumentation = shimmer.getInstrumentationNameFromModuleName(name)
|
|
173
|
-
|
|
174
|
-
// Check if this is a known instrumentation and then run it.
|
|
175
|
-
if (shimmer.registeredInstrumentations[instrumentation]) {
|
|
176
|
-
logger.trace('Instrumenting %s.', name)
|
|
177
|
-
return instrument(agent, nodule, instrumentation, resolvedName)
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return nodule
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
var shimmer = module.exports = {
|
|
81
|
+
const shimmer = (module.exports = {
|
|
184
82
|
/**
|
|
185
83
|
* If debug isn't false, the agent will retain references to wrapped methods
|
|
186
84
|
* for the entire lifetime of the agent. Some instrumentation depends on
|
|
@@ -218,17 +116,18 @@ var shimmer = module.exports = {
|
|
|
218
116
|
*/
|
|
219
117
|
wrapMethod: function wrapMethod(nodule, noduleName, methods, wrapper) {
|
|
220
118
|
if (!methods) {
|
|
221
|
-
return logger.warn(
|
|
222
|
-
new Error(),
|
|
223
|
-
"Must include a method name to wrap. Called from:"
|
|
224
|
-
)
|
|
119
|
+
return logger.warn(new Error(), 'Must include a method name to wrap. Called from:')
|
|
225
120
|
}
|
|
226
121
|
|
|
227
|
-
if (!noduleName)
|
|
228
|
-
|
|
122
|
+
if (!noduleName) {
|
|
123
|
+
noduleName = '[unknown]'
|
|
124
|
+
}
|
|
125
|
+
if (!Array.isArray(methods)) {
|
|
126
|
+
methods = [methods]
|
|
127
|
+
}
|
|
229
128
|
|
|
230
|
-
methods.forEach(
|
|
231
|
-
|
|
129
|
+
methods.forEach((method) => {
|
|
130
|
+
const fqmn = noduleName + '.' + method
|
|
232
131
|
|
|
233
132
|
if (!nodule) {
|
|
234
133
|
return logger.debug("Can't wrap %s from nonexistent object.", fqmn)
|
|
@@ -238,24 +137,31 @@ var shimmer = module.exports = {
|
|
|
238
137
|
return logger.debug("Can't wrap %s without a wrapper generator.", fqmn)
|
|
239
138
|
}
|
|
240
139
|
|
|
241
|
-
|
|
140
|
+
const original = nodule[method]
|
|
242
141
|
|
|
243
|
-
if (!original)
|
|
244
|
-
|
|
142
|
+
if (!original) {
|
|
143
|
+
return logger.trace('%s not defined, so not wrapping.', fqmn)
|
|
144
|
+
}
|
|
145
|
+
if (original.__NR_unwrap) {
|
|
146
|
+
return logger.debug('%s already wrapped by agent.', fqmn)
|
|
147
|
+
}
|
|
245
148
|
|
|
246
|
-
|
|
149
|
+
const wrapped = wrapper(original, method)
|
|
247
150
|
Object.keys(original).forEach((key) => {
|
|
248
151
|
wrapped[key] = original[key]
|
|
249
152
|
})
|
|
250
153
|
wrapped.__NR_original = original
|
|
154
|
+
// eslint-disable-next-line camelcase
|
|
251
155
|
wrapped.__NR_unwrap = function __NR_unwrap() {
|
|
252
156
|
nodule[method] = original
|
|
253
|
-
logger.trace(
|
|
157
|
+
logger.trace('Removed instrumentation from %s.', fqmn)
|
|
254
158
|
}
|
|
255
159
|
|
|
256
160
|
nodule[method] = wrapped
|
|
257
|
-
if (shimmer.debug)
|
|
258
|
-
|
|
161
|
+
if (shimmer.debug) {
|
|
162
|
+
instrumented.push(wrapped)
|
|
163
|
+
}
|
|
164
|
+
logger.trace('Instrumented %s.', fqmn)
|
|
259
165
|
})
|
|
260
166
|
},
|
|
261
167
|
|
|
@@ -277,34 +183,40 @@ var shimmer = module.exports = {
|
|
|
277
183
|
*/
|
|
278
184
|
wrapDeprecated: function wrapDeprecated(nodule, noduleName, property, options) {
|
|
279
185
|
if (!property) {
|
|
280
|
-
logger.warn(new Error(),
|
|
186
|
+
logger.warn(new Error(), 'Must include a function name to wrap. Called from:')
|
|
281
187
|
return
|
|
282
188
|
}
|
|
283
189
|
|
|
284
|
-
if (!noduleName)
|
|
190
|
+
if (!noduleName) {
|
|
191
|
+
noduleName = '[unknown]'
|
|
192
|
+
}
|
|
285
193
|
|
|
286
|
-
|
|
194
|
+
const fqmn = noduleName + '.' + property
|
|
287
195
|
if (!nodule) {
|
|
288
196
|
logger.debug("Can't wrap %s from nonexistent object.", fqmn)
|
|
289
197
|
return
|
|
290
198
|
}
|
|
291
199
|
|
|
292
|
-
|
|
200
|
+
const original = nodule[property]
|
|
293
201
|
if (!original) {
|
|
294
|
-
logger.trace(
|
|
202
|
+
logger.trace('%s not defined, so not wrapping.', fqmn)
|
|
295
203
|
return
|
|
296
204
|
}
|
|
297
205
|
|
|
298
206
|
delete nodule[property]
|
|
299
207
|
|
|
300
|
-
|
|
208
|
+
const descriptor = {
|
|
301
209
|
configurable: true,
|
|
302
210
|
enumerable: true
|
|
303
211
|
}
|
|
304
|
-
if (options.get)
|
|
305
|
-
|
|
212
|
+
if (options.get) {
|
|
213
|
+
descriptor.get = options.get
|
|
214
|
+
}
|
|
215
|
+
if (options.set) {
|
|
216
|
+
descriptor.set = options.set
|
|
217
|
+
}
|
|
306
218
|
Object.defineProperty(nodule, property, descriptor)
|
|
307
|
-
logger.trace(
|
|
219
|
+
logger.trace('Instrumented %s.', fqmn)
|
|
308
220
|
|
|
309
221
|
if (shimmer.debug) {
|
|
310
222
|
instrumented.push({
|
|
@@ -319,30 +231,42 @@ var shimmer = module.exports = {
|
|
|
319
231
|
},
|
|
320
232
|
|
|
321
233
|
unwrapMethod: function unwrapMethod(nodule, noduleName, method) {
|
|
322
|
-
if (!noduleName)
|
|
323
|
-
|
|
324
|
-
|
|
234
|
+
if (!noduleName) {
|
|
235
|
+
noduleName = '[unknown]'
|
|
236
|
+
}
|
|
237
|
+
if (!method) {
|
|
238
|
+
return logger.debug(
|
|
239
|
+
'Must include a method name to unwrap. ' + 'Called from: %s',
|
|
240
|
+
new Error().stack
|
|
241
|
+
)
|
|
242
|
+
}
|
|
325
243
|
|
|
326
|
-
|
|
244
|
+
const fqmn = noduleName + '.' + method
|
|
327
245
|
|
|
328
246
|
if (!nodule) {
|
|
329
247
|
return logger.debug("Can't unwrap %s from nonexistent object.", fqmn)
|
|
330
248
|
}
|
|
331
249
|
|
|
332
|
-
|
|
250
|
+
const wrapped = nodule[method]
|
|
333
251
|
|
|
334
252
|
// keep instrumented up to date
|
|
335
|
-
|
|
336
|
-
if (pos !== -1)
|
|
253
|
+
const pos = instrumented.indexOf(wrapped)
|
|
254
|
+
if (pos !== -1) {
|
|
255
|
+
instrumented.splice(pos, 1)
|
|
256
|
+
}
|
|
337
257
|
|
|
338
|
-
if (!wrapped)
|
|
339
|
-
|
|
258
|
+
if (!wrapped) {
|
|
259
|
+
return logger.debug('%s not defined, so not unwrapping.', fqmn)
|
|
260
|
+
}
|
|
261
|
+
if (!wrapped.__NR_unwrap) {
|
|
262
|
+
return logger.debug("%s isn't unwrappable.", fqmn)
|
|
263
|
+
}
|
|
340
264
|
|
|
341
265
|
wrapped.__NR_unwrap()
|
|
342
266
|
},
|
|
343
267
|
|
|
344
268
|
unwrapAll: function unwrapAll() {
|
|
345
|
-
instrumented.forEach(
|
|
269
|
+
instrumented.forEach((wrapper) => {
|
|
346
270
|
wrapper.__NR_unwrap()
|
|
347
271
|
})
|
|
348
272
|
instrumented = []
|
|
@@ -353,9 +277,9 @@ var shimmer = module.exports = {
|
|
|
353
277
|
* have an opportunity to patch them with instrumentation.
|
|
354
278
|
*/
|
|
355
279
|
patchModule: function patchModule(agent) {
|
|
356
|
-
logger.trace(
|
|
357
|
-
|
|
358
|
-
|
|
280
|
+
logger.trace('Wrapping module loader.')
|
|
281
|
+
const Module = require('module')
|
|
282
|
+
const filepathMap = {}
|
|
359
283
|
|
|
360
284
|
shimmer.wrapMethod(Module, 'Module', '_resolveFilename', function wrapRes(resolve) {
|
|
361
285
|
return function wrappedResolveFilename(file) {
|
|
@@ -404,8 +328,8 @@ var shimmer = module.exports = {
|
|
|
404
328
|
},
|
|
405
329
|
|
|
406
330
|
unpatchModule: function unpatchModule() {
|
|
407
|
-
logger.trace(
|
|
408
|
-
|
|
331
|
+
logger.trace('Unwrapping to previous module loader.')
|
|
332
|
+
const Module = require('module')
|
|
409
333
|
|
|
410
334
|
shimmer.unwrapMethod(Module, 'Module', '_resolveFilename')
|
|
411
335
|
shimmer.unwrapMethod(Module, 'Module', '_load')
|
|
@@ -414,8 +338,8 @@ var shimmer = module.exports = {
|
|
|
414
338
|
bootstrapInstrumentation: function bootstrapInstrumentation(agent) {
|
|
415
339
|
// Instrument global.
|
|
416
340
|
const globalShim = new shims.Shim(agent, 'globals', 'globals')
|
|
417
|
-
applyDebugState(
|
|
418
|
-
|
|
341
|
+
applyDebugState(globalShim, global)
|
|
342
|
+
const globalsFilepath = path.join(__dirname, 'instrumentation', 'core', 'globals.js')
|
|
419
343
|
_firstPartyInstrumentation(agent, globalsFilepath, globalShim, global, 'globals')
|
|
420
344
|
|
|
421
345
|
// Instrument each of the core modules.
|
|
@@ -427,27 +351,23 @@ var shimmer = module.exports = {
|
|
|
427
351
|
try {
|
|
428
352
|
uninstrumented = require(mojule)
|
|
429
353
|
} catch (err) {
|
|
430
|
-
logger.trace(
|
|
431
|
-
'Could not load core module %s got error %s',
|
|
432
|
-
mojule,
|
|
433
|
-
err
|
|
434
|
-
)
|
|
354
|
+
logger.trace('Could not load core module %s got error %s', mojule, err)
|
|
435
355
|
}
|
|
436
356
|
|
|
437
357
|
const shim = shims.createShimFromType(core.type, agent, mojule, mojule)
|
|
438
|
-
applyDebugState(
|
|
358
|
+
applyDebugState(shim, core)
|
|
439
359
|
_firstPartyInstrumentation(agent, filePath, shim, uninstrumented, mojule)
|
|
440
360
|
})
|
|
441
361
|
|
|
442
362
|
// Register all the first-party instrumentations.
|
|
443
363
|
Object.keys(INSTRUMENTATIONS).forEach(function forEachInstrumentation(moduleName) {
|
|
444
|
-
|
|
364
|
+
const instrInfo = INSTRUMENTATIONS[moduleName]
|
|
445
365
|
if (instrInfo.module) {
|
|
446
366
|
// Because external instrumentations can change independent of
|
|
447
367
|
// the agent core, we don't want breakages in them to entirely
|
|
448
368
|
// disable the agent.
|
|
449
369
|
try {
|
|
450
|
-
|
|
370
|
+
const hooks = require(instrInfo.module + '/nr-hooks')
|
|
451
371
|
hooks.forEach(shimmer.registerInstrumentation)
|
|
452
372
|
} catch (e) {
|
|
453
373
|
logger.warn('Failed to load instrumentation for ' + instrInfo.module, e)
|
|
@@ -457,7 +377,7 @@ var shimmer = module.exports = {
|
|
|
457
377
|
// TODO: Remove this code when amqplib instrumentation is made external.
|
|
458
378
|
require('./instrumentation/amqplib').selfRegister(shimmer)
|
|
459
379
|
} else {
|
|
460
|
-
|
|
380
|
+
const fileName = path.join(__dirname, 'instrumentation', moduleName + '.js')
|
|
461
381
|
shimmer.registerInstrumentation({
|
|
462
382
|
moduleName: moduleName,
|
|
463
383
|
type: instrInfo.type,
|
|
@@ -469,7 +389,7 @@ var shimmer = module.exports = {
|
|
|
469
389
|
// Even though domain is a core module we add it as a registered
|
|
470
390
|
// instrumentation to be lazy-loaded because we do not want to cause domain
|
|
471
391
|
// usage.
|
|
472
|
-
|
|
392
|
+
const domainPath = path.join(__dirname, 'instrumentation/core/domain.js')
|
|
473
393
|
shimmer.registerInstrumentation({
|
|
474
394
|
moduleName: 'domain',
|
|
475
395
|
type: null,
|
|
@@ -510,12 +430,13 @@ var shimmer = module.exports = {
|
|
|
510
430
|
* the same.
|
|
511
431
|
*/
|
|
512
432
|
getInstrumentationNameFromModuleName(moduleName) {
|
|
513
|
-
|
|
433
|
+
let instrumentation
|
|
514
434
|
// XXX When updating these special cases, also update `uninstrumented`.
|
|
515
435
|
// To allow for instrumenting both 'pg' and 'pg.js'.
|
|
516
436
|
if (moduleName === 'pg.js') {
|
|
517
437
|
instrumentation = 'pg'
|
|
518
|
-
}
|
|
438
|
+
}
|
|
439
|
+
if (moduleName === 'mysql2') {
|
|
519
440
|
// mysql2 (https://github.com/sidorares/node-mysql2) is a drop in replacement for
|
|
520
441
|
// mysql which conforms to the existing mysql API. If we see mysql2, treat it as
|
|
521
442
|
// mysql
|
|
@@ -525,4 +446,101 @@ var shimmer = module.exports = {
|
|
|
525
446
|
}
|
|
526
447
|
return instrumentation
|
|
527
448
|
}
|
|
449
|
+
})
|
|
450
|
+
|
|
451
|
+
function applyDebugState(shim, nodule) {
|
|
452
|
+
if (shimmer.debug) {
|
|
453
|
+
shim.enableDebug()
|
|
454
|
+
instrumented.push(shim)
|
|
455
|
+
instrumented.push({
|
|
456
|
+
__NR_unwrap: function unwrapNodule() {
|
|
457
|
+
delete nodule.__NR_instrumented_errored
|
|
458
|
+
delete nodule.__NR_instrumented
|
|
459
|
+
delete nodule.__NR_shim
|
|
460
|
+
}
|
|
461
|
+
})
|
|
462
|
+
nodule.__NR_shim = shim
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* All instrumentation files must export the same interface: a single
|
|
468
|
+
* initialization function that takes the agent and the module to be
|
|
469
|
+
* instrumented.
|
|
470
|
+
*/
|
|
471
|
+
function instrument(agent, nodule, moduleName, resolvedName) {
|
|
472
|
+
const instrumentation = shimmer.registeredInstrumentations[moduleName]
|
|
473
|
+
if (
|
|
474
|
+
properties.hasOwn(nodule, '__NR_instrumented') ||
|
|
475
|
+
properties.hasOwn(nodule, '__NR_instrumented_errored')
|
|
476
|
+
) {
|
|
477
|
+
logger.trace(
|
|
478
|
+
'Already instrumented or failed to instrument %s, skipping redundant instrumentation',
|
|
479
|
+
moduleName
|
|
480
|
+
)
|
|
481
|
+
return nodule
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const shim = shims.createShimFromType(instrumentation.type, agent, moduleName, resolvedName)
|
|
485
|
+
|
|
486
|
+
applyDebugState(shim, nodule)
|
|
487
|
+
|
|
488
|
+
try {
|
|
489
|
+
if (instrumentation.onRequire(shim, nodule, moduleName) !== false) {
|
|
490
|
+
nodule = shim.getExport(nodule)
|
|
491
|
+
nodule.__NR_instrumented = true
|
|
492
|
+
}
|
|
493
|
+
} catch (instrumentationError) {
|
|
494
|
+
nodule.__NR_instrumented_errored = true
|
|
495
|
+
if (instrumentation.onError) {
|
|
496
|
+
try {
|
|
497
|
+
instrumentation.onError(instrumentationError)
|
|
498
|
+
} catch (e) {
|
|
499
|
+
logger.warn(
|
|
500
|
+
e,
|
|
501
|
+
instrumentationError,
|
|
502
|
+
'Custom instrumentation for %s failed, then the onError handler threw an error',
|
|
503
|
+
moduleName
|
|
504
|
+
)
|
|
505
|
+
}
|
|
506
|
+
} else {
|
|
507
|
+
logger.warn(
|
|
508
|
+
instrumentationError,
|
|
509
|
+
'Custom instrumentation for %s failed. Please report this to the ' +
|
|
510
|
+
'maintainers of the custom instrumentation.',
|
|
511
|
+
moduleName
|
|
512
|
+
)
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
return nodule
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
function _firstPartyInstrumentation(agent, fileName, shim, nodule, moduleName) {
|
|
520
|
+
const fullPath = path.resolve(fileName)
|
|
521
|
+
if (!fs.existsSync(fileName)) {
|
|
522
|
+
return logger.warn('Tried to load instrumentation from %s, but file does not exist', fullPath)
|
|
523
|
+
}
|
|
524
|
+
try {
|
|
525
|
+
return require(fileName)(agent, nodule, moduleName, shim)
|
|
526
|
+
} catch (error) {
|
|
527
|
+
logger.warn(
|
|
528
|
+
error,
|
|
529
|
+
'Failed to instrument module %s using %s',
|
|
530
|
+
path.basename(fileName, '.js'),
|
|
531
|
+
fullPath
|
|
532
|
+
)
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
function _postLoad(agent, nodule, name, resolvedName) {
|
|
537
|
+
const instrumentation = shimmer.getInstrumentationNameFromModuleName(name)
|
|
538
|
+
|
|
539
|
+
// Check if this is a known instrumentation and then run it.
|
|
540
|
+
if (shimmer.registeredInstrumentations[instrumentation]) {
|
|
541
|
+
logger.trace('Instrumenting %s.', name)
|
|
542
|
+
return instrument(agent, nodule, instrumentation, resolvedName)
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return nodule
|
|
528
546
|
}
|
|
@@ -10,21 +10,24 @@ const SpanEventAggregator = require('./span-event-aggregator')
|
|
|
10
10
|
const StreamingSpanEventAggregator = require('./streaming-span-event-aggregator')
|
|
11
11
|
|
|
12
12
|
function createSpanEventAggregator(config, collector, metrics) {
|
|
13
|
-
const
|
|
13
|
+
const traceObserver = config.infinite_tracing.trace_observer
|
|
14
14
|
|
|
15
|
-
if (
|
|
16
|
-
|
|
15
|
+
if (traceObserver.host) {
|
|
16
|
+
traceObserver.host = traceObserver.host.trim()
|
|
17
17
|
|
|
18
|
-
if (typeof
|
|
19
|
-
|
|
18
|
+
if (typeof traceObserver.port !== 'string') {
|
|
19
|
+
traceObserver.port = String(traceObserver.port)
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
traceObserver.port = traceObserver.port.trim()
|
|
22
22
|
|
|
23
23
|
try {
|
|
24
24
|
return createStreamingAggregator(config, collector, metrics)
|
|
25
25
|
} catch (err) {
|
|
26
|
-
logger.warn(
|
|
27
|
-
|
|
26
|
+
logger.warn(
|
|
27
|
+
err,
|
|
28
|
+
'Failed to create streaming span event aggregator for infinite tracing. ' +
|
|
29
|
+
'Reverting to standard span event aggregator and disabling infinite tracing'
|
|
30
|
+
)
|
|
28
31
|
config.infinite_tracing.trace_observer = {
|
|
29
32
|
host: '',
|
|
30
33
|
port: ''
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
const {MAXIMUM_CUSTOM_ATTRIBUTES} = require('../attributes')
|
|
9
|
-
const {PrioritizedAttributes, ATTRIBUTE_PRIORITY} = require('../prioritized-attributes')
|
|
10
|
-
const {DESTINATIONS} = require('../config/attribute-filter')
|
|
8
|
+
const { MAXIMUM_CUSTOM_ATTRIBUTES } = require('../attributes')
|
|
9
|
+
const { PrioritizedAttributes, ATTRIBUTE_PRIORITY } = require('../prioritized-attributes')
|
|
10
|
+
const { DESTINATIONS } = require('../config/attribute-filter')
|
|
11
11
|
|
|
12
12
|
// Scoping impacts memoization. We could decide to add a scope instead of including
|
|
13
13
|
// spans in segment scope in the future.
|
|
@@ -31,13 +31,7 @@ class SpanContext {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
addCustomAttribute(key, value, priority) {
|
|
34
|
-
this.customAttributes.addAttribute(
|
|
35
|
-
DESTINATIONS.SPAN_EVENT,
|
|
36
|
-
key,
|
|
37
|
-
value,
|
|
38
|
-
false,
|
|
39
|
-
priority
|
|
40
|
-
)
|
|
34
|
+
this.customAttributes.addAttribute(DESTINATIONS.SPAN_EVENT, key, value, false, priority)
|
|
41
35
|
}
|
|
42
36
|
|
|
43
37
|
/**
|