newrelic 4.8.1 → 4.9.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 +53 -0
- package/api.js +16 -10
- package/bin/travis-setup.sh +18 -7
- package/lib/config/env.js +2 -1
- package/lib/config/index.js +2 -0
- package/lib/db/tracer.js +3 -1
- package/lib/errors/index.js +1 -1
- package/lib/instrumentation/bluebird.js +35 -45
- package/lib/instrumentation/core/child_process.js +41 -38
- package/lib/instrumentation/core/domain.js +6 -5
- package/lib/instrumentation/core/net.js +62 -66
- package/lib/instrumentation/core/timers.js +78 -49
- package/lib/instrumentation/core/zlib.js +22 -8
- package/lib/instrumentations.js +3 -2
- package/lib/shim/constants.js +4 -0
- package/lib/shim/datastore-shim.js +1 -1
- package/lib/shim/index.js +8 -6
- package/lib/shim/promise-shim.js +563 -0
- package/lib/shim/shim.js +38 -11
- package/lib/shimmer.js +1 -0
- package/lib/transaction/index.js +18 -8
- package/lib/transaction/trace/aggregator.js +3 -3
- package/lib/util/codec.js +4 -1
- package/package.json +3 -2
|
@@ -1,70 +1,99 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
var wrap = require('../../shimmer').wrapMethod
|
|
4
|
-
var psemver = require('../../util/process-version')
|
|
5
|
-
|
|
6
3
|
module.exports = initialize
|
|
7
4
|
|
|
8
|
-
function initialize(agent, timers) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
function initialize(agent, timers, moduleName, shim) {
|
|
6
|
+
const processMethods = ['nextTick', '_nextDomainTick', '_tickDomainCallback']
|
|
7
|
+
|
|
8
|
+
shim.wrap(
|
|
9
|
+
process,
|
|
10
|
+
processMethods,
|
|
11
|
+
function wrapProcess(shim, fn) {
|
|
12
|
+
return function wrappedProcess() {
|
|
13
|
+
const segment = shim.getActiveSegment()
|
|
14
|
+
if (!segment) {
|
|
15
|
+
return fn.apply(this, arguments)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Manual copy because helper methods add significant overhead in some usages
|
|
19
|
+
var len = arguments.length
|
|
20
|
+
var args = new Array(len)
|
|
21
|
+
for (var i = 0; i < len; ++i) {
|
|
22
|
+
args[i] = arguments[i]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
shim.bindSegment(args, shim.FIRST, segment)
|
|
26
|
+
|
|
27
|
+
return fn.apply(this, args)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
)
|
|
15
31
|
|
|
16
|
-
|
|
32
|
+
instrumentTimerMethods(timers)
|
|
17
33
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
34
|
+
// If we need to instrument separate references to timers on the global object,
|
|
35
|
+
// do that now.
|
|
36
|
+
if (!shim.isWrapped(global.setTimeout)) {
|
|
37
|
+
instrumentTimerMethods(global)
|
|
38
|
+
}
|
|
21
39
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
40
|
+
function instrumentTimerMethods(nodule) {
|
|
41
|
+
const asynchronizers = [
|
|
42
|
+
'setTimeout',
|
|
43
|
+
'setInterval'
|
|
44
|
+
]
|
|
26
45
|
|
|
27
|
-
|
|
28
|
-
var wrapped = agent.tracer.wrapFunctionFirst('timers.' + method, null, original)
|
|
46
|
+
shim.record(nodule, asynchronizers, recordAsynchronizers)
|
|
29
47
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return wrapped
|
|
34
|
-
})
|
|
48
|
+
// We don't want to create segments for setImmediate calls, as the
|
|
49
|
+
// object allocation may incur too much overhead in some situations
|
|
50
|
+
shim.wrap(nodule, 'setImmediate', wrapSetImmediate)
|
|
35
51
|
|
|
36
|
-
|
|
37
|
-
// object allocation may incur too much overhead in some situations
|
|
38
|
-
var uninstrumented = [
|
|
39
|
-
'setImmediate'
|
|
40
|
-
]
|
|
52
|
+
shim.wrap(nodule, 'clearTimeout', wrapClearTimeout)
|
|
41
53
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
Object.getOwnPropertySymbols(original).forEach((symbol) => {
|
|
45
|
-
wrapped[symbol] = original[symbol]
|
|
46
|
-
})
|
|
54
|
+
makeWrappedPromisifyCompatible(shim, nodule)
|
|
55
|
+
}
|
|
47
56
|
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
function wrapSetImmediate(shim, fn) {
|
|
58
|
+
return function wrappedSetImmediate() {
|
|
59
|
+
const args = shim.argsToArray.apply(shim, arguments)
|
|
60
|
+
shim.bindSegment(args, shim.FIRST)
|
|
50
61
|
|
|
51
|
-
|
|
62
|
+
return fn.apply(this, args)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
52
65
|
|
|
53
|
-
|
|
54
|
-
return function
|
|
55
|
-
var segment
|
|
66
|
+
function wrapClearTimeout(shim, fn) {
|
|
67
|
+
return function wrappedClearTimeout(timer) {
|
|
56
68
|
if (timer && timer._onTimeout) {
|
|
57
|
-
segment =
|
|
58
|
-
|
|
69
|
+
const segment = timer._onTimeout.__NR_segment
|
|
70
|
+
if (segment) {
|
|
71
|
+
segment.ignore = true
|
|
72
|
+
}
|
|
59
73
|
}
|
|
60
74
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
75
|
+
return fn.apply(this, arguments)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function recordAsynchronizers(shim, fn, name) {
|
|
80
|
+
return {name: 'timers.' + name, callback: shim.FIRST}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
64
83
|
|
|
65
|
-
|
|
84
|
+
function makeWrappedPromisifyCompatible(shim, timers) {
|
|
85
|
+
const originalSetTimout = shim.getOriginal(timers.setTimeout)
|
|
86
|
+
Object.getOwnPropertySymbols(originalSetTimout).forEach((symbol) => {
|
|
87
|
+
timers.setTimeout[symbol] = originalSetTimout[symbol]
|
|
88
|
+
})
|
|
66
89
|
|
|
67
|
-
|
|
68
|
-
|
|
90
|
+
const originalSetInterval = shim.getOriginal(timers.setInterval)
|
|
91
|
+
Object.getOwnPropertySymbols(originalSetInterval).forEach((symbol) => {
|
|
92
|
+
timers.setInterval[symbol] = originalSetInterval[symbol]
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
const originalSetImmediate = shim.getOriginal(timers.setImmediate)
|
|
96
|
+
Object.getOwnPropertySymbols(originalSetImmediate).forEach((symbol) => {
|
|
97
|
+
timers.setImmediate[symbol] = originalSetImmediate[symbol]
|
|
69
98
|
})
|
|
70
99
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const recorder = require('../../metrics/recorders/generic')
|
|
4
4
|
|
|
5
5
|
module.exports = initialize
|
|
6
6
|
|
|
@@ -14,22 +14,36 @@ var methods = [
|
|
|
14
14
|
'unzip'
|
|
15
15
|
]
|
|
16
16
|
|
|
17
|
-
function initialize(agent, zlib) {
|
|
18
|
-
|
|
17
|
+
function initialize(agent, zlib, moduleName, shim) {
|
|
18
|
+
shim.record(zlib, methods, recordZLib)
|
|
19
|
+
|
|
19
20
|
if (zlib.Deflate && zlib.Deflate.prototype) {
|
|
20
21
|
var proto = Object.getPrototypeOf(zlib.Deflate.prototype)
|
|
21
22
|
if (proto._transform) {
|
|
22
23
|
// streams2
|
|
23
|
-
wrap(proto, '
|
|
24
|
+
shim.wrap(proto, '_transform', wrapNoSegment)
|
|
24
25
|
} else if (proto.write && proto.flush && proto.end) {
|
|
25
26
|
// plain ol' streams
|
|
26
|
-
wrap(proto,
|
|
27
|
+
shim.wrap(proto, ['write', 'flush', 'end'], wrapNoSegment)
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
function recordZLib(shim, fn, name) {
|
|
32
|
+
return {name: `zlib.${name}`, callback: shim.LAST, recorder}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function wrapNoSegment(shim, fn) {
|
|
37
|
+
return function wrappedZLibNoSegment() {
|
|
38
|
+
if (!shim.getActiveSegment()) {
|
|
39
|
+
return fn.apply(this, arguments)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const args = shim.argsToArray.apply(shim, arguments)
|
|
43
|
+
const cbIndex = args.length - 1
|
|
44
|
+
|
|
45
|
+
shim.bindSegment(args, cbIndex)
|
|
31
46
|
|
|
32
|
-
|
|
33
|
-
return agent.tracer.wrapFunctionLast('zlib.' + method, null, fn)
|
|
47
|
+
return fn.apply(this, args)
|
|
34
48
|
}
|
|
35
49
|
}
|
package/lib/instrumentations.js
CHANGED
|
@@ -6,8 +6,9 @@ var MODULE_TYPE = require('./shim/constants').MODULE_TYPE
|
|
|
6
6
|
module.exports = function instrumentations() {
|
|
7
7
|
return {
|
|
8
8
|
'amqplib': {type: MODULE_TYPE.MESSAGE},
|
|
9
|
+
'cassandra-driver': {type: MODULE_TYPE.DATASTORE},
|
|
9
10
|
'connect': {type: MODULE_TYPE.WEB_FRAMEWORK},
|
|
10
|
-
'bluebird': {type:
|
|
11
|
+
'bluebird': {type: MODULE_TYPE.PROMISE},
|
|
11
12
|
'director': {type: MODULE_TYPE.WEB_FRAMEWORK},
|
|
12
13
|
'express': {type: MODULE_TYPE.WEB_FRAMEWORK},
|
|
13
14
|
'generic-pool': {type: MODULE_TYPE.GENERIC},
|
|
@@ -18,11 +19,11 @@ module.exports = function instrumentations() {
|
|
|
18
19
|
'mongodb': {type: MODULE_TYPE.DATASTORE},
|
|
19
20
|
'mysql': {type: MODULE_TYPE.DATASTORE},
|
|
20
21
|
'node-cassandra-cql': {type: MODULE_TYPE.DATASTORE},
|
|
21
|
-
'cassandra-driver': {type: MODULE_TYPE.DATASTORE},
|
|
22
22
|
'pg': {type: MODULE_TYPE.DATASTORE},
|
|
23
23
|
'q': {type: null},
|
|
24
24
|
'redis': {type: MODULE_TYPE.DATASTORE},
|
|
25
25
|
'restify': {type: MODULE_TYPE.WEB_FRAMEWORK},
|
|
26
|
+
'superagent': {module: '@newrelic/superagent'},
|
|
26
27
|
'oracle': {type: null},
|
|
27
28
|
'vision': {type: MODULE_TYPE.WEB_FRAMEWORK},
|
|
28
29
|
'when': {type: null}
|
package/lib/shim/constants.js
CHANGED
|
@@ -17,6 +17,10 @@ var MODULE_TYPE = {
|
|
|
17
17
|
/** Messaging module, such as AMQP */
|
|
18
18
|
MESSAGE: 'message',
|
|
19
19
|
|
|
20
|
+
/** Promise module, such as Bluebird */
|
|
21
|
+
PROMISE: 'promise',
|
|
22
|
+
|
|
23
|
+
/** @private */
|
|
20
24
|
TRANSACTION: 'transaction',
|
|
21
25
|
|
|
22
26
|
/** Web server framework module, such as Express or Restify. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
var hasOwnProperty = require('../util/properties').hasOwn
|
|
4
|
-
var logger = require('../logger
|
|
4
|
+
var logger = require('../logger').child({component: 'DatastoreShim'})
|
|
5
5
|
var metrics = require('../metrics/names')
|
|
6
6
|
var parseSql = require('../db/query-parsers/sql')
|
|
7
7
|
var ParsedStatement = require('../db/parsed-statement')
|
package/lib/shim/index.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const constants = require('./constants')
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
const Shim = require('./shim')
|
|
6
|
+
const DatastoreShim = require('./datastore-shim')
|
|
7
|
+
const MessageShim = require('./message-shim')
|
|
8
|
+
const PromiseShim = require('./promise-shim')
|
|
9
|
+
const TransactionShim = require('./transaction-shim')
|
|
10
|
+
const WebFrameworkShim = require('./webframework-shim')
|
|
10
11
|
|
|
11
12
|
exports.constants = constants
|
|
12
13
|
exports.Shim = Shim
|
|
13
14
|
exports.DatastoreShim = DatastoreShim
|
|
14
15
|
exports.MessageShim = MessageShim
|
|
16
|
+
exports.PromiseShim = PromiseShim
|
|
15
17
|
exports.TransactionShim = TransactionShim
|
|
16
18
|
exports.WebFrameworkShim = WebFrameworkShim
|