newrelic 4.6.0 → 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.
Files changed (44) hide show
  1. package/NEWS.md +222 -1
  2. package/api.js +24 -11
  3. package/bin/compare-bench-results.js +167 -0
  4. package/bin/run-bench.js +87 -44
  5. package/bin/travis-setup.sh +18 -7
  6. package/index.js +16 -8
  7. package/lib/collector/remote-method.js +12 -0
  8. package/lib/config/default.js +5 -0
  9. package/lib/config/env.js +2 -1
  10. package/lib/config/index.js +5 -0
  11. package/lib/db/tracer.js +17 -6
  12. package/lib/environment.js +1 -1
  13. package/lib/errors/index.js +1 -1
  14. package/lib/instrumentation/bluebird.js +35 -45
  15. package/lib/instrumentation/core/async_hooks.js +8 -8
  16. package/lib/instrumentation/core/child_process.js +41 -34
  17. package/lib/instrumentation/core/crypto.js +9 -14
  18. package/lib/instrumentation/core/dns.js +9 -13
  19. package/lib/instrumentation/core/domain.js +10 -12
  20. package/lib/instrumentation/core/fs.js +47 -38
  21. package/lib/instrumentation/core/globals.js +12 -17
  22. package/lib/instrumentation/core/http.js +3 -3
  23. package/lib/instrumentation/core/inspector.js +8 -7
  24. package/lib/instrumentation/core/net.js +62 -66
  25. package/lib/instrumentation/core/timers.js +79 -40
  26. package/lib/instrumentation/core/zlib.js +22 -8
  27. package/lib/instrumentation/mongodb.js +158 -115
  28. package/lib/instrumentations.js +3 -2
  29. package/lib/priority-queue.js +5 -2
  30. package/lib/shim/constants.js +6 -0
  31. package/lib/shim/datastore-shim.js +1 -1
  32. package/lib/shim/index.js +9 -5
  33. package/lib/shim/message-shim.js +5 -4
  34. package/lib/shim/promise-shim.js +563 -0
  35. package/lib/shim/shim.js +90 -11
  36. package/lib/shim/specs/index.js +8 -5
  37. package/lib/shimmer.js +70 -28
  38. package/lib/transaction/dt-payload.js +16 -0
  39. package/lib/transaction/handle.js +1 -1
  40. package/lib/transaction/index.js +22 -8
  41. package/lib/transaction/trace/aggregator.js +3 -3
  42. package/lib/transaction/trace/index.js +30 -37
  43. package/lib/util/codec.js +4 -1
  44. package/package.json +10 -4
package/index.js CHANGED
@@ -1,21 +1,22 @@
1
1
  'use strict'
2
2
 
3
3
  // Record opening times before loading any other files.
4
- var preAgentTime = process.uptime()
5
- var agentStart = Date.now()
4
+ const preAgentTime = process.uptime()
5
+ const agentStart = Date.now()
6
6
 
7
7
  // Load unwrapped core now to ensure it gets the freshest properties.
8
8
  require('./lib/util/unwrapped-core')
9
9
 
10
- var featureFlags = require('./lib/feature_flags').prerelease
11
- var logger = require('./lib/logger')
12
- var psemver = require('./lib/util/process-version')
10
+ const featureFlags = require('./lib/feature_flags').prerelease
11
+ const psemver = require('./lib/util/process-version')
12
+ let logger = require('./lib/logger') // Gets re-loaded after initialization.
13
13
 
14
14
 
15
- var agentVersion = require('./package.json').version
15
+ const pkgJSON = require('./package.json')
16
16
  logger.info(
17
- "Using New Relic for Node.js. Agent version: %s; Node version: %s.",
18
- agentVersion, process.version
17
+ 'Using New Relic for Node.js. Agent version: %s; Node version: %s.',
18
+ pkgJSON.version,
19
+ process.version
19
20
  )
20
21
 
21
22
  if (require.cache.__NR_cache) {
@@ -49,6 +50,13 @@ function initialize() {
49
50
 
50
51
  logger.error(message)
51
52
  throw new Error(message)
53
+ } else if (!psemver.satisfies(pkgJSON.engines.node)) {
54
+ logger.warn(
55
+ 'New Relic for Node.js %s has not been tested on Node.js %s. Please ' +
56
+ 'update the agent or downgrade your version of Node.js',
57
+ pkgJSON.version,
58
+ process.version
59
+ )
52
60
  }
53
61
 
54
62
  logger.debug("Current working directory at module load is %s.", process.cwd())
@@ -10,6 +10,7 @@ var stringify = require('json-stringify-safe')
10
10
  var Sink = require('../util/stream-sink')
11
11
  var agents = require('./http-agents')
12
12
  var certificates = require('./ssl/certificates')
13
+ const isValidLength = require('../util/byte-limit').isValidLength
13
14
 
14
15
  /*
15
16
  *
@@ -147,8 +148,19 @@ RemoteMethod.prototype._safeRequest = function _safeRequest(options) {
147
148
  var protocol = 'https'
148
149
  var logConfig = this._config.logging
149
150
  var auditLog = this._config.audit_log
151
+ const maxPayloadSize = this._config.max_payload_size_in_bytes
150
152
  var level = 'trace'
151
153
 
154
+ if (!isValidLength(options.body, maxPayloadSize + 1)) {
155
+ logger.warn(
156
+ 'The payload size %d being sent to method %s exceeded the maximum size of %d',
157
+ Buffer.byteLength(options.body, 'utf8'),
158
+ this.name,
159
+ maxPayloadSize
160
+ )
161
+ throw new Error('Maximum payload size exceeded')
162
+ }
163
+
152
164
  // If trace level is not explicity enabled check to see if the audit log is
153
165
  // enabled.
154
166
  if (logConfig != null && logConfig.level !== 'trace' && auditLog.enabled) {
@@ -793,6 +793,11 @@ exports.config = {
793
793
 
794
794
  /**
795
795
  * Controls the method of cross agent tracing in the agent.
796
+ * Distributed tracing lets you see the path that a request takes through your
797
+ * distributed system. Enabling distributed tracing changes the behavior of some
798
+ * New Relic features, so carefully consult the transition guide before you enable
799
+ * this feature: https://docs.newrelic.com/docs/transition-guide-distributed-tracing
800
+ * Default is false.
796
801
  */
797
802
  distributed_tracing: {
798
803
  /**
package/lib/config/env.js CHANGED
@@ -184,7 +184,8 @@ const BOOLEAN_VARS = new Set([
184
184
  ])
185
185
 
186
186
  const FLOAT_VARS = new Set([
187
- 'NEW_RELIC_APDEX'
187
+ 'NEW_RELIC_APDEX',
188
+ 'NEW_RELIC_TRACER_THRESHOLD'
188
189
  ])
189
190
 
190
191
  const INT_VARS = new Set([
@@ -21,6 +21,7 @@ var logger = null // Lazy-loaded in `initialize`.
21
21
  /**
22
22
  * CONSTANTS -- we gotta lotta 'em
23
23
  */
24
+ const DEFAULT_MAX_PAYLOAD_SIZE_IN_BYTES = 1000000
24
25
  const DEFAULT_CONFIG_PATH = require.resolve('./default')
25
26
  const DEFAULT_CONFIG = require('./default').config
26
27
  const DEFAULT_FILENAME = 'newrelic.js'
@@ -122,10 +123,12 @@ function Config(config) {
122
123
  this.cross_process_id = null
123
124
  this.encoding_key = null
124
125
  this.obfuscatedId = null
126
+ this.primary_application_id = null
125
127
  this.trusted_account_ids = null
126
128
  this.trusted_account_key = null
127
129
  this.sampling_target = 10
128
130
  this.sampling_target_period_in_seconds = 60
131
+ this.max_payload_size_in_bytes = DEFAULT_MAX_PAYLOAD_SIZE_IN_BYTES
129
132
 
130
133
  // how frequently harvester runs
131
134
  this.data_report_period = 60
@@ -272,7 +275,9 @@ Config.prototype._fromServer = function _fromServer(params, key) {
272
275
  case 'application_id':
273
276
  case 'collect_errors':
274
277
  case 'collect_traces':
278
+ case 'primary_application_id':
275
279
  case 'product_level':
280
+ case 'max_payload_size_in_bytes':
276
281
  case 'sampling_target':
277
282
  case 'sampling_target_period_in_seconds':
278
283
  case 'trusted_account_ids':
package/lib/db/tracer.js CHANGED
@@ -46,27 +46,36 @@ QueryTracer.prototype.merge = function merge(tracer) {
46
46
 
47
47
  QueryTracer.prototype.addQuery = function addQuery(segment, type, query, trace) {
48
48
  const ttConfig = this.config.transaction_tracer
49
- if (segment.getDurationInMillis() < ttConfig.explain_threshold) {
50
- return
51
- }
52
- const slowQuery = new SlowQuery(segment, type, query, trace)
53
49
 
50
+ // If DT is enabled and the segment is part of a sampled transaction
51
+ // (i.e. we are creating a span event for this segment), then we need
52
+ // to collect the sql trace.
53
+ var slowQuery
54
54
  switch (ttConfig.record_sql) {
55
55
  case 'raw':
56
+ slowQuery = new SlowQuery(segment, type, query, trace)
56
57
  logger.trace('recording raw sql')
57
58
  segment.parameters.sql = slowQuery.query
58
59
  break
59
60
  case 'obfuscated':
61
+ slowQuery = new SlowQuery(segment, type, query, trace)
60
62
  logger.trace('recording obfuscated sql')
61
63
  segment.parameters.sql_obfuscated = slowQuery.obfuscated
62
64
  break
63
65
  default:
64
66
  logger.trace(
65
- 'not collecting slow-query because transaction_tracer.record_sql was set to %s',
67
+ 'not recording sql statement, transaction_tracer.record_sql was set to %s',
66
68
  ttConfig.record_sql
67
69
  )
68
70
  return
69
71
  }
72
+
73
+ if (segment.getDurationInMillis() < ttConfig.explain_threshold) {
74
+ return
75
+ }
76
+
77
+ slowQuery = slowQuery || new SlowQuery(segment, type, query, trace)
78
+
70
79
  segment.parameters.backtrace = slowQuery.trace
71
80
 
72
81
  if (!this.config.slow_sql.enabled) {
@@ -177,7 +186,9 @@ function SlowQuery(segment, type, query, trace) {
177
186
  }
178
187
 
179
188
  function normalizedHash(value) {
180
- return parseInt(crypto.createHash('md5').update(value).digest('hex').slice(-4), 16)
189
+ // We leverage the last 16 hex digits of which would mostly fit in a long and
190
+ // rely on parseInt to drop bits that do not fit in a JS number
191
+ return parseInt(crypto.createHash('sha1').update(value).digest('hex').slice(-16), 16)
181
192
  }
182
193
 
183
194
  function formatTrace(trace) {
@@ -305,7 +305,7 @@ function getGlobalPackages(cb) {
305
305
  * package appears at most once, with all the versions joined into a
306
306
  * comma-delimited list.
307
307
  *
308
- * @return {Array.<String>[]} Sorted list of [name, version] pairs.
308
+ * @return {Array.<string[]>} Sorted list of [name, version] pairs.
309
309
  */
310
310
  function flattenVersions(packages) {
311
311
  var info = Object.create(null)
@@ -74,7 +74,7 @@ function createError(transaction, exception, customAttributes, config) {
74
74
  }
75
75
  }
76
76
 
77
- if (!config.high_security && customAttributes) {
77
+ if (!config.high_security && config.api.custom_attributes_enabled && customAttributes) {
78
78
  for (var key in customAttributes) {
79
79
  if (props.hasOwn(customAttributes, key)) {
80
80
  var dest = config.attributeFilter.filter(DESTINATIONS.ERROR_EVENT, key)
@@ -1,39 +1,5 @@
1
1
  'use strict'
2
2
 
3
- var promInit = require('./promise')
4
- var shimmer = require('../shimmer')
5
-
6
- var BLUEBIRD_SPEC = {
7
- name: 'bluebird',
8
- constructor: 'Promise',
9
- $proto: {
10
- cast: [
11
- 'all', 'any', 'bind', 'call', 'catchReturn', 'catchThrow', 'delay', 'get',
12
- 'props', 'race', 'reflect', 'return', 'some', 'thenReturn', 'thenThrow',
13
- 'throw', 'timeout'
14
- ],
15
- then: [
16
- 'asCallback', 'done', 'each', 'filter', 'finally', 'lastly', 'map',
17
- 'mapSeries', 'nodeify', 'reduce', 'spread', 'tap', 'tapCatch', 'then'
18
- ],
19
- catch: ['catch', 'caught', 'error'],
20
-
21
- // _resolveFromResolver is in bluebird 2.x
22
- // _execute is in bluebird 3.x
23
- executor: ['_execute', '_resolveFromResolver']
24
- },
25
- $static: {
26
- cast: [
27
- 'all', 'any', 'attempt', 'bind', 'cast', 'delay', 'each', 'filter',
28
- 'fromCallback', 'fromNode', 'fulfilled', 'join', 'map', 'mapSeries',
29
- 'props', 'race', 'reduce', 'reject', 'rejected', 'resolve', 'some', 'try'
30
- ],
31
- promisify: [
32
- 'coroutine', 'method', 'promisify'
33
- ]
34
- }
35
- }
36
-
37
3
  // XXX We are not instrumenting bluebird's cancellation feature because it seems
38
4
  // rather like an edge case feature. It is not enabled by default and has strange
39
5
  // effects on the interface. If our lack of support for cancellation becomes an
@@ -41,31 +7,55 @@ var BLUEBIRD_SPEC = {
41
7
  //
42
8
  // http://bluebirdjs.com/docs/api/cancellation.html
43
9
 
10
+ module.exports = function initialize(agent, bluebird, moduleName, shim) {
11
+ const Promise = bluebird.Promise
12
+ const proto = Promise && Promise.prototype
13
+ if (!proto) {
14
+ shim.logger.debug('Could not find promise prototype, not instrumenting.')
15
+ return false
16
+ }
44
17
 
45
- module.exports = function initialize(agent, bluebird) {
46
- promInit(agent, bluebird, BLUEBIRD_SPEC)
18
+ shim.setClass(Promise)
19
+
20
+ // _resolveFromResolver is in bluebird 2.x
21
+ // _execute is in bluebird 3.x
22
+ shim.wrapExecutorCaller(proto, ['_execute', '_resolveFromResolver'])
23
+ shim.wrapThen(proto, [
24
+ 'asCallback', 'done', 'each', 'filter', 'finally', 'lastly', 'map',
25
+ 'mapSeries', 'nodeify', 'reduce', 'spread', 'tap', 'tapCatch', 'then'
26
+ ])
27
+ shim.wrapCatch(proto, ['catch', 'caught', 'error'])
28
+ shim.wrapCast(proto, [
29
+ 'all', 'any', 'bind', 'call', 'catchReturn', 'catchThrow', 'delay', 'get',
30
+ 'props', 'race', 'reflect', 'return', 'some', 'thenReturn', 'thenThrow',
31
+ 'throw', 'timeout'
32
+ ])
33
+
34
+ shim.wrapCast(Promise, [
35
+ 'all', 'any', 'attempt', 'bind', 'cast', 'delay', 'each', 'filter',
36
+ 'fromCallback', 'fromNode', 'fulfilled', 'join', 'map', 'mapSeries',
37
+ 'props', 'race', 'reduce', 'reject', 'rejected', 'resolve', 'some', 'try'
38
+ ])
39
+ shim.wrapPromisify(Promise, ['coroutine', 'method', 'promisify'])
47
40
 
48
41
  // Using `getNewLibraryCopy` needs to trigger re-instrumenting.
49
- shimmer.wrapMethod(
42
+ shim.wrap(
50
43
  bluebird.Promise,
51
- 'bluebird',
52
44
  'getNewLibraryCopy',
53
- function wrapNewCopy(original) {
45
+ function wrapNewCopy(shim, original) {
54
46
  return function wrappedNewCopy() {
47
+ shim.logger.trace('Instrumenting new library copy...')
55
48
  var copy = original.apply(this, arguments)
56
- module.exports(agent, copy)
49
+ module.exports(agent, copy, moduleName, shim)
57
50
  return copy
58
51
  }
59
52
  }
60
53
  )
61
54
 
62
55
  // Need to copy over `coroutine.addYieldHandler`
63
- var Promise = bluebird.Promise
64
56
  var coroutine = Promise && Promise.coroutine
65
- if (shimmer.isWrapped(coroutine)) {
66
- var original = agent.tracer.getOriginal(coroutine)
57
+ if (shim.isWrapped(coroutine)) {
58
+ var original = shim.getOriginal(coroutine)
67
59
  coroutine.addYieldHandler = original && original.addYieldHandler
68
60
  }
69
61
  }
70
-
71
- module.exports.SPEC = BLUEBIRD_SPEC
@@ -24,9 +24,9 @@ var NATIVE_PROMISE_SPEC = {
24
24
  }
25
25
  }
26
26
 
27
- function initialize(agent) {
27
+ function initialize(agent, shim) {
28
28
  var enableHooks = agent.config.checkAsyncHookStatus()
29
- if (enableHooks && tryAsyncHooks(agent)) {
29
+ if (enableHooks && tryAsyncHooks(agent, shim)) {
30
30
  logger.debug('Using async_hooks.')
31
31
  } else {
32
32
  logger.debug('Using promise instrumentation.')
@@ -34,7 +34,7 @@ function initialize(agent) {
34
34
  }
35
35
  }
36
36
 
37
- function tryAsyncHooks(agent) {
37
+ function tryAsyncHooks(agent, shim) {
38
38
  var asyncHooks = null
39
39
  try {
40
40
  asyncHooks = require('async_hooks')
@@ -57,7 +57,7 @@ function tryAsyncHooks(agent) {
57
57
  return
58
58
  }
59
59
 
60
- var activeSegment = agent.tracer.getSegment() || parentSegment
60
+ var activeSegment = shim.getActiveSegment() || parentSegment
61
61
  if (promiseWrap && promiseWrap.promise) {
62
62
  promiseWrap.promise.__NR_id = id
63
63
  }
@@ -71,8 +71,8 @@ function tryAsyncHooks(agent) {
71
71
  return
72
72
  }
73
73
 
74
- segmentMap.set(id, agent.tracer.getSegment())
75
- agent.tracer.segment = hookSegment
74
+ segmentMap.set(id, shim.getActiveSegment())
75
+ shim.setActiveSegment(hookSegment)
76
76
  },
77
77
  after: function afterHook(id) {
78
78
  var hookSegment = segmentMap.get(id)
@@ -85,8 +85,8 @@ function tryAsyncHooks(agent) {
85
85
  return
86
86
  }
87
87
 
88
- segmentMap.set(id, agent.tracer.getSegment())
89
- agent.tracer.segment = hookSegment
88
+ segmentMap.set(id, shim.getActiveSegment())
89
+ shim.setActiveSegment(hookSegment)
90
90
  },
91
91
  destroy: function destHook(id) {
92
92
  segmentMap.delete(id)
@@ -1,50 +1,57 @@
1
1
  'use strict'
2
2
 
3
- var wrap = require('../../shimmer').wrapMethod
4
- var isWrapped = require('../../shimmer').isWrapped
5
-
6
3
  module.exports = initialize
7
4
 
8
- function initialize(agent, childProcess) {
9
- var methods = ['exec', 'execFile']
5
+ function initialize(agent, childProcess, moduleName, shim) {
6
+ if (!childProcess) {
7
+ shim.log.debug('Could not find child_process, not instrumenting')
8
+ return false
9
+ }
10
10
 
11
- wrap(childProcess, 'childProcess', methods, wrapMethod)
11
+ const methods = ['exec', 'execFile']
12
12
 
13
- function wrapMethod(fn, method) {
14
- return agent.tracer.wrapFunctionLast('child_process.' + method, null, fn)
15
- }
13
+ shim.record(
14
+ childProcess,
15
+ methods,
16
+ function recordExec(shim, fn, name) {
17
+ return {name: 'child_process.' + name, callback: shim.LAST}
18
+ }
19
+ )
16
20
 
17
- var childProcessProto = childProcess && childProcess.ChildProcess
18
- // ChildProcess is exposed on Node 4 and higher
19
- if (childProcessProto) {
20
- wrapChildProcessCls(childProcess.ChildProcess)
21
+ if (childProcess.ChildProcess) {
22
+ wrapChildProcessClass(shim, childProcess.ChildProcess)
21
23
  } else {
22
- wrap(childProcess, 'childProcess', ['fork', 'spawn'], wrapSpawn)
24
+ shim.logger.warn('childProcess.ChildProcess should be available in v2.2.0 or higher')
23
25
  }
24
26
 
25
- function wrapSpawn(fn) {
26
- return function wrapped() {
27
- var child = fn.apply(this, arguments)
28
- if (child && child.constructor && child.constructor.prototype) {
29
- wrapChildProcessCls(child.constructor)
30
- }
31
- return child
32
- }
33
- }
27
+ function wrapChildProcessClass(shim, childProcessClass) {
28
+ shim.wrap(
29
+ childProcessClass.prototype,
30
+ 'on',
31
+ function wrapChildProcessClassOn(shim, fn) {
32
+ return function wrappedChildProcessOn() {
33
+ const args = shim.argsToArray.apply(shim, arguments)
34
+ const cbIndex = args.length - 1
34
35
 
35
- function wrapChildProcessCls(childProcessCls) {
36
- if (!childProcessCls || !childProcessCls.prototype ||
37
- isWrapped(childProcessCls.prototype.on)) {
38
- return
39
- }
36
+ shim.bindSegment(args, cbIndex)
40
37
 
41
- wrap(
42
- childProcessCls.prototype,
43
- 'childProcess.ChildProcess.prototype',
44
- 'on',
45
- function wrapEmit(fn) {
46
- return agent.tracer.wrapFunctionNoSegment(fn, ['on', 'addListener'])
38
+ return fn.apply(this, args)
39
+ }
47
40
  }
48
41
  )
49
42
  }
43
+
44
+ makePromisifyCompatible(shim, childProcess)
45
+ }
46
+
47
+ function makePromisifyCompatible(shim, childProcess) {
48
+ const originalExec = shim.getOriginal(childProcess.exec)
49
+ Object.getOwnPropertySymbols(originalExec).forEach((symbol) => {
50
+ childProcess.exec[symbol] = originalExec[symbol]
51
+ })
52
+
53
+ const originalExecFile = shim.getOriginal(childProcess.execFile)
54
+ Object.getOwnPropertySymbols(originalExecFile).forEach((symbol) => {
55
+ childProcess.execFile[symbol] = originalExecFile[symbol]
56
+ })
50
57
  }
@@ -1,13 +1,10 @@
1
1
  'use strict'
2
2
 
3
- var wrap = require('../../shimmer').wrapMethod
4
-
5
3
  module.exports = initialize
6
4
 
7
- function initialize(agent, crypto) {
8
- wrap(
5
+ function initialize(agent, crypto, moduleName, shim) {
6
+ shim.record(
9
7
  crypto,
10
- 'crypto',
11
8
  [
12
9
  'pbkdf2',
13
10
  'randomBytes',
@@ -15,14 +12,12 @@ function initialize(agent, crypto) {
15
12
  'randomFill',
16
13
  'scrypt'
17
14
  ],
18
- wrapCryptoMethod
19
- )
20
-
21
- function wrapCryptoMethod(fn, method) {
22
- return agent.tracer.wrapFunctionLast('crypto.' + method, null, wrappedCrypto)
23
-
24
- function wrappedCrypto() {
25
- return fn.apply(this, arguments)
15
+ function recordCryptoMethod(shim, fn, name) {
16
+ return {
17
+ name: 'crypto.' + name,
18
+ callback: shim.LAST,
19
+ callbackRequired: true // sync version used too heavily - too much overhead
20
+ }
26
21
  }
27
- }
22
+ )
28
23
  }
@@ -1,11 +1,9 @@
1
1
  'use strict'
2
2
 
3
- var shimmer = require('../../shimmer')
4
-
5
3
  module.exports = initialize
6
4
 
7
- function initialize(agent, dns) {
8
- var methods = [
5
+ function initialize(agent, dns, moduleName, shim) {
6
+ const methods = [
9
7
  'lookup',
10
8
  'resolve',
11
9
  'resolve4',
@@ -20,13 +18,11 @@ function initialize(agent, dns) {
20
18
  'reverse'
21
19
  ]
22
20
 
23
- shimmer.wrapMethod(dns, 'dns', methods, function wrapMethods(fn, method) {
24
- return agent.tracer.wrapFunction('dns.' + method, null, fn, wrapDnsArgs)
25
- })
26
-
27
- function wrapDnsArgs(segment, args) {
28
- var lastIdx = args.length - 1
29
- args[lastIdx] = agent.tracer.bindFunction(args[lastIdx], segment, true)
30
- return args
31
- }
21
+ shim.record(
22
+ dns,
23
+ methods,
24
+ function recordDnsMethod(shim, fn, name) {
25
+ return { name: 'dns.' + name, callback: shim.LAST }
26
+ }
27
+ )
32
28
  }
@@ -1,33 +1,31 @@
1
1
  'use strict'
2
2
 
3
- var wrap = require('../../shimmer').wrapMethod
4
-
5
3
  module.exports = initialize
6
4
 
7
- function initialize(agent, domain) {
5
+ function initialize(agent, domain, name, shim) {
8
6
  var proto = domain.Domain.prototype
9
- wrap(
7
+ shim.wrap(
10
8
  proto,
11
- 'domain.Domain.prototype',
12
9
  'emit',
13
10
  wrapEmit
14
11
  )
15
12
 
16
- function wrapEmit(original) {
13
+ function wrapEmit(shim, original) {
17
14
  return function wrappedEmit(ev) {
18
- var shouldRestoreContext = ev === 'error' &&
19
- agent.tracer.segment === null &&
20
- this.__NR_transactionSegment
15
+ var shouldRestoreContext =
16
+ ev === 'error' &&
17
+ shim.getActiveSegment() === null &&
18
+ shim.getSegment(this)
19
+
21
20
  if (!shouldRestoreContext) {
22
21
  return original.apply(this, arguments)
23
22
  }
24
23
 
25
- agent.tracer.segment = this.__NR_transactionSegment
24
+ shim.setActiveSegment(shim.getSegment(this))
26
25
  try {
27
26
  return original.apply(this, arguments)
28
27
  } finally {
29
- agent.tracer.segment = null
30
- this.__NR_transactionSegment = null
28
+ shim.setActiveSegment(null)
31
29
  }
32
30
  }
33
31
  }