newrelic 2.0.0 → 2.2.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/.eslintrc +1 -0
  2. package/.github/PULL_REQUEST_TEMPLATE.md +5 -0
  3. package/NEWS.md +75 -0
  4. package/README.md +24 -12
  5. package/api.js +74 -29
  6. package/index.js +6 -2
  7. package/lib/agent.js +15 -3
  8. package/lib/collector/api.js +11 -9
  9. package/lib/collector/facts.js +9 -9
  10. package/lib/config.default.js +24 -2
  11. package/lib/config.js +70 -7
  12. package/lib/db/parse-sql.js +3 -0
  13. package/lib/db/tracer.js +3 -3
  14. package/lib/feature_flags.js +1 -0
  15. package/lib/instrumentation/core/async_hooks.js +92 -0
  16. package/lib/instrumentation/core/child_process.js +35 -0
  17. package/lib/instrumentation/core/globals.js +4 -23
  18. package/lib/instrumentation/core/http.js +1 -1
  19. package/lib/instrumentation/hapi.js +67 -33
  20. package/lib/instrumentation/ioredis.js +1 -6
  21. package/lib/metrics/names.js +7 -2
  22. package/lib/shim/datastore-shim.js +13 -1
  23. package/lib/shim/shim.js +46 -8
  24. package/lib/shim/webframework-shim.js +4 -2
  25. package/lib/stats/index.js +1 -1
  26. package/lib/system-info.js +21 -42
  27. package/lib/transaction/handle.js +14 -0
  28. package/lib/transaction/index.js +10 -2
  29. package/lib/transaction/tracer/index.js +1 -0
  30. package/lib/util/hashes.js +8 -1
  31. package/lib/util/logger.js +4 -4
  32. package/lib/util/sql/obfuscate.js +10 -4
  33. package/lib/utilization/aws-info.js +46 -0
  34. package/lib/utilization/azure-info.js +54 -0
  35. package/lib/utilization/common.js +106 -0
  36. package/lib/utilization/docker-info.js +100 -0
  37. package/lib/utilization/gcp-info.js +56 -0
  38. package/lib/utilization/index.js +28 -0
  39. package/lib/utilization/pcf-info.js +38 -0
  40. package/newrelic.js +1 -2
  41. package/package.json +2 -1
  42. package/stub_api.js +26 -9
  43. package/lib/aws-info.js +0 -100
  44. package/lib/parse-dockerinfo.js +0 -57
@@ -0,0 +1,38 @@
1
+ 'use strict'
2
+
3
+ var logger = require('../logger.js').child({component: 'pcf-info'})
4
+ var NAMES = require('../metrics/names.js')
5
+ var common = require('./common')
6
+
7
+ module.exports = fetchPCFInfo
8
+
9
+ function fetchPCFInfo(agent, callback) {
10
+ if (!agent.config.utilization || !agent.config.utilization.detect_pcf) {
11
+ return setImmediate(callback, null, null)
12
+ }
13
+
14
+ var metadataMap = {
15
+ 'CF_INSTANCE_GUID': 'cf_instance_guid',
16
+ 'CF_INSTANCE_IP': 'cf_instance_ip',
17
+ 'MEMORY_LIMIT': 'memory_limit'
18
+ }
19
+
20
+ var results = {}
21
+ var keys = Object.keys(metadataMap)
22
+ for (var i = 0; i < keys.length; i++) {
23
+ var key = keys[i]
24
+ var value = process.env[key]
25
+ if (value == null) {
26
+ logger.trace('Could not find environment value for %s', key)
27
+ return setImmediate(callback, null, null)
28
+ }
29
+ if (!common.checkValueString(value)) {
30
+ logger.trace('Invalid environment value for %s: %j', key, value)
31
+ agent.metrics.getOrCreateMetric(NAMES.UTILIZATION.PCF_ERROR).incrementCallCount()
32
+ return setImmediate(callback, null, null)
33
+ }
34
+ results[metadataMap[key]] = value
35
+ }
36
+
37
+ setImmediate(callback, null, results)
38
+ }
package/newrelic.js CHANGED
@@ -1,9 +1,8 @@
1
1
  'use strict'
2
-
3
2
  /**
4
3
  * New Relic agent configuration.
5
4
  *
6
- * See lib/config.default.js in the agent distribution for a more complete
5
+ * See lib/config.defaults.js in the agent distribution for a more complete
7
6
  * description of configuration variables and their potential values.
8
7
  */
9
8
  exports.config = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "newrelic",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "author": "New Relic Node.js agent team <nodejs@newrelic.com>",
5
5
  "licenses": [
6
6
  {
@@ -115,6 +115,7 @@
115
115
  },
116
116
  "devDependencies": {
117
117
  "async": "^2.1.4",
118
+ "benchmark": "^2.1.4",
118
119
  "bluebird": "^3.4.7",
119
120
  "eslint": "^2.9.0",
120
121
  "jsdoc": "^3.4.0",
package/stub_api.js CHANGED
@@ -3,13 +3,16 @@
3
3
  var logger = require('./lib/logger.js')
4
4
  var RealAPI = require('./api.js')
5
5
  var TransactionHandle = require('./lib/transaction/handle')
6
+ var util = require('util')
6
7
 
7
8
 
8
9
  /* eslint-disable no-eval */
9
10
  function stubFunction(name) {
10
- return eval("(function () {return function " + name + "() {" +
11
- "logger.debug('Not calling " + name + " because New Relic is disabled.');" +
12
- "}}())")
11
+ return eval(
12
+ "(function () {return function " + name + "() {" +
13
+ "logger.debug('Not calling " + name + " because New Relic is disabled.');" +
14
+ "}}())"
15
+ )
13
16
  }
14
17
  /* eslint-enable no-eval */
15
18
 
@@ -28,8 +31,22 @@ for (var i = 0; i < length; i++) {
28
31
  }
29
32
 
30
33
  Stub.prototype.createTracer = createTracer
31
- Stub.prototype.createWebTransaction = createWebTransaction
32
- Stub.prototype.createBackgroundTransaction = createBackgroundTransaction
34
+ Stub.prototype.createWebTransaction = util.deprecate(
35
+ createWebTransaction, [
36
+ 'API#createWebTransaction is being deprecated!',
37
+ 'Please use API#startWebTransaction for transaction creation',
38
+ 'and API#getTransaction for transaction management including',
39
+ 'ending transactions.'
40
+ ].join(' ')
41
+ )
42
+ Stub.prototype.createBackgroundTransaction = util.deprecate(
43
+ createBackgroundTransaction, [
44
+ 'API#createBackgroundTransaction is being deprecated!',
45
+ 'Please use API#startBackgroundTransaction for transaction creation',
46
+ 'and API#getTransaction for transaction management including',
47
+ 'ending transactions.'
48
+ ].join(' ')
49
+ )
33
50
  Stub.prototype.startWebTransaction = startWebTransaction
34
51
  Stub.prototype.startBackgroundTransaction = startBackgroundTransaction
35
52
  Stub.prototype.getTransaction = getTransaction
@@ -89,17 +106,17 @@ function startBackgroundTransaction(name, group, callback) {
89
106
  // Normally the following call executes callback asynchronously
90
107
  function shutdown(options, cb) {
91
108
  logger.debug('Not calling shutdown because New Relic is disabled.')
92
-
109
+
93
110
  var callback = cb
94
111
  if (!callback) {
95
112
  if (typeof options === 'function') {
96
113
  callback = options
97
114
  } else {
98
- callback = new Function()
115
+ callback = function __NR_defaultCb() {}
99
116
  }
100
117
  }
101
-
102
- process.nextTick(callback)
118
+
119
+ setImmediate(callback)
103
120
  }
104
121
 
105
122
  module.exports = Stub
package/lib/aws-info.js DELETED
@@ -1,100 +0,0 @@
1
- 'use strict'
2
-
3
- var logger = require('./logger.js').child({component: 'aws-info'})
4
- var http = require('http')
5
- var NAMES = require('./metrics/names.js')
6
- var concat = require('concat-stream')
7
-
8
- module.exports = fetchAWSInfo
9
- module.exports.clearCache = function clearAWSCache() {
10
- resultDict = null
11
- }
12
-
13
- var resultDict
14
-
15
- function fetchAWSInfo(agent, callback) {
16
- if (!agent.config.utilization || !agent.config.utilization.detect_aws) {
17
- return callback(null)
18
- }
19
-
20
- if (resultDict) {
21
- return callback(resultDict)
22
- }
23
-
24
- var awsQuery = module.exports._awsQuery
25
-
26
- awsQuery('instance-type', agent, function getInstanceType(type) {
27
- if (!type) return callback(null)
28
- awsQuery('instance-id', agent, function getInstanceId(id) {
29
- if (!id) return callback(null)
30
- awsQuery('placement/availability-zone', agent, function getZone(zone) {
31
- if (!zone) return callback(null)
32
- resultDict = {
33
- type: type,
34
- id: id,
35
- zone: zone
36
- }
37
- return callback(resultDict)
38
- })
39
- })
40
- })
41
- }
42
-
43
-
44
- module.exports._awsQuery = function awsQuery(key, agent, callback) {
45
- var instanceHost = '169.254.169.254'
46
- var apiVersion = '2008-02-01'
47
- var url = ['http:/', instanceHost, apiVersion, 'meta-data', key].join('/')
48
- var req = http.get(url, function awsRequest(res) {
49
- res.pipe(concat(respond))
50
- function respond(data) {
51
- var valid = checkResponseString(data)
52
- if (!valid) {
53
- var awsError = agent.metrics.getOrCreateMetric(NAMES.UTILIZATION.AWS_ERROR)
54
- awsError.incrementCallCount()
55
- logger.debug('Response for attribute ' + key + ': %s'
56
- , data)
57
- data = null
58
- } else {
59
- data = data.toString('utf8')
60
- }
61
-
62
- agent.removeListener('errored', abortRequest)
63
- agent.removeListener('stopped', abortRequest)
64
- callback(data)
65
- }
66
- })
67
- req.setTimeout(1000, function awsTimeout() {
68
- logger.debug('Request for attribute %s timed out', key)
69
- callback(null)
70
- })
71
- req.on('error', function awsError(err) {
72
- logger.debug('Message for attribute %s: %s', key, err.message)
73
- callback(null)
74
- })
75
-
76
- agent.once('errored', abortRequest)
77
- agent.once('stopped', abortRequest)
78
-
79
- function abortRequest() {
80
- logger.debug('Abborting request for attribute %s', key)
81
- req.abort()
82
- agent.removeListener('errored', abortRequest)
83
- agent.removeListener('stopped', abortRequest)
84
- }
85
- }
86
-
87
- function checkResponseString(str) {
88
- var validCharacters = /[0-9a-zA-Z_ ./-]/
89
- var valid = str.length <= 255 && str.length > 0
90
-
91
- var i = 0
92
- var len = str.length
93
-
94
- while (valid && i < len) {
95
- valid = valid && (str[i] > 127 || String.fromCharCode(str[i]).match(validCharacters))
96
- i++
97
- }
98
-
99
- return valid
100
- }
@@ -1,57 +0,0 @@
1
- 'use strict'
2
-
3
- var logger = require('./logger.js').child({component: 'dockerinfo'})
4
- var NAMES = require('./metrics/names.js')
5
- module.exports = parseDockerInfo
6
-
7
- function parseDockerInfo(agent, data) {
8
- if (!agent.config.utilization || !agent.config.utilization.detect_docker) return null
9
- var cpuCgroup = parseCgroupIds(data).cpu
10
- // if we can't parse the cgroups, or if the cpu is not in a cgroup
11
- var dockerError = agent.metrics.getOrCreateMetric(NAMES.UTILIZATION.DOCKER_ERROR)
12
- if (!cpuCgroup) {
13
- logger.debug('Could not parse cgroup data from: ' + data)
14
- dockerError.incrementCallCount()
15
- return null
16
- }
17
-
18
- // if cpu isn't in a cgroup
19
- if (cpuCgroup === '/') return null
20
-
21
- var patterns = [
22
- /^\/docker\/([0-9a-f]+)$/, // docker native driver w/out systemd
23
- /^\/system\.slice\/docker-([0-9a-f]+)\.scope$/, // with systemd
24
- /^\/lxc\/([0-9a-f]+)$/ // docker lxc driver
25
- ]
26
- for (var i = 0; i < patterns.length; i++) {
27
- var pattern = patterns[i]
28
- var matches = cpuCgroup.match(pattern)
29
- if (matches) {
30
- var id = matches[1]
31
- if (id.length !== 64) {
32
- dockerError.incrementCallCount()
33
- logger.debug('Encountered a malformed docker id: ', id)
34
- return null
35
- }
36
- return id
37
- }
38
- }
39
-
40
- logger.debug('Unable to recognise cgroup format')
41
-
42
- return null
43
- }
44
-
45
- function parseCgroupIds(cgroupInfo) {
46
- var cgroupIds = {}
47
- cgroupInfo.split('\n').forEach(function parseCgroupInfo(line) {
48
- var parts = line.split(':')
49
- if (parts.length !== 3) return
50
- var subsystems = parts[1]
51
- var cgroupId = parts[2]
52
- subsystems.split(',').forEach(function assignGroupIds(subsystem) {
53
- cgroupIds[subsystem] = cgroupId
54
- })
55
- })
56
- return cgroupIds
57
- }