newrelic 8.3.0 → 8.5.2

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 (134) hide show
  1. package/NEWS.md +76 -0
  2. package/README.md +7 -6
  3. package/THIRD_PARTY_NOTICES.md +95 -35
  4. package/api.js +74 -68
  5. package/bin/test-naming-rules.js +22 -22
  6. package/lib/agent.js +4 -4
  7. package/lib/attributes.js +2 -2
  8. package/lib/collector/api.js +12 -12
  9. package/lib/collector/facts.js +1 -1
  10. package/lib/collector/http-agents.js +12 -11
  11. package/lib/collector/key-parser.js +1 -1
  12. package/lib/collector/remote-method.js +27 -26
  13. package/lib/config/attribute-filter.js +23 -23
  14. package/lib/config/default.js +12 -10
  15. package/lib/config/hsm.js +1 -1
  16. package/lib/config/index.js +82 -66
  17. package/lib/config/lasp.js +3 -3
  18. package/lib/config/merge-server-config.js +1 -1
  19. package/lib/db/parse-sql.js +8 -8
  20. package/lib/db/parsed-statement.js +9 -8
  21. package/lib/db/query-parsers/sql.js +7 -7
  22. package/lib/db/query-sample.js +9 -9
  23. package/lib/db/query-trace-aggregator.js +4 -4
  24. package/lib/db/statement-matcher.js +5 -5
  25. package/lib/db/utils.js +1 -1
  26. package/lib/environment.js +43 -43
  27. package/lib/errors/error-collector.js +2 -2
  28. package/lib/errors/error-trace-aggregator.js +1 -1
  29. package/lib/errors/helper.js +3 -3
  30. package/lib/errors/index.js +17 -17
  31. package/lib/feature_flags.js +7 -5
  32. package/lib/header-attributes.js +6 -6
  33. package/lib/header-processing.js +1 -1
  34. package/lib/instrumentation/amqplib.js +26 -26
  35. package/lib/instrumentation/bluebird.js +3 -3
  36. package/lib/instrumentation/cassandra-driver.js +7 -3
  37. package/lib/instrumentation/connect.js +4 -4
  38. package/lib/instrumentation/core/async_hooks.js +6 -6
  39. package/lib/instrumentation/core/domain.js +2 -2
  40. package/lib/instrumentation/core/globals.js +1 -1
  41. package/lib/instrumentation/core/http-outbound.js +15 -84
  42. package/lib/instrumentation/core/http.js +34 -67
  43. package/lib/instrumentation/core/inspector.js +2 -2
  44. package/lib/instrumentation/core/timers.js +7 -7
  45. package/lib/instrumentation/core/zlib.js +2 -2
  46. package/lib/instrumentation/director.js +4 -4
  47. package/lib/instrumentation/express.js +8 -8
  48. package/lib/instrumentation/fastify/spec-builders.js +57 -47
  49. package/lib/instrumentation/fastify.js +85 -24
  50. package/lib/instrumentation/generic-pool.js +1 -1
  51. package/lib/instrumentation/hapi/hapi-17.js +11 -11
  52. package/lib/instrumentation/hapi/shared.js +1 -1
  53. package/lib/instrumentation/hapi.js +22 -22
  54. package/lib/instrumentation/ioredis.js +7 -7
  55. package/lib/instrumentation/memcached.js +7 -7
  56. package/lib/instrumentation/mongodb/common.js +16 -5
  57. package/lib/instrumentation/mysql.js +19 -19
  58. package/lib/instrumentation/oracle.js +15 -15
  59. package/lib/instrumentation/pg.js +4 -4
  60. package/lib/instrumentation/promise.js +46 -46
  61. package/lib/instrumentation/q.js +2 -2
  62. package/lib/instrumentation/redis.js +11 -11
  63. package/lib/instrumentation/restify.js +1 -1
  64. package/lib/instrumentation/undici.js +242 -0
  65. package/lib/instrumentation/vision.js +4 -4
  66. package/lib/instrumentation/when.js +3 -3
  67. package/lib/instrumentations.js +2 -1
  68. package/lib/logger.js +5 -5
  69. package/lib/metrics/index.js +15 -15
  70. package/lib/metrics/mapper.js +7 -7
  71. package/lib/metrics/normalizer/rule.js +9 -9
  72. package/lib/metrics/normalizer/tx_segment.js +17 -17
  73. package/lib/metrics/normalizer.js +22 -22
  74. package/lib/metrics/recorders/custom.js +5 -5
  75. package/lib/metrics/recorders/generic.js +3 -3
  76. package/lib/metrics/recorders/http.js +7 -7
  77. package/lib/metrics/recorders/http_external.js +7 -7
  78. package/lib/metrics/recorders/message-transaction.js +5 -6
  79. package/lib/metrics/recorders/other.js +5 -5
  80. package/lib/parse-proc-cpuinfo.js +25 -19
  81. package/lib/parse-proc-meminfo.js +8 -2
  82. package/lib/prioritized-attributes.js +2 -2
  83. package/lib/priority-queue.js +10 -10
  84. package/lib/reservoir.js +3 -3
  85. package/lib/sampler.js +26 -26
  86. package/lib/serverless/aws-lambda.js +8 -2
  87. package/lib/shim/datastore-shim.js +35 -32
  88. package/lib/shim/index.js +2 -2
  89. package/lib/shim/message-shim.js +47 -47
  90. package/lib/shim/promise-shim.js +1 -1
  91. package/lib/shim/shim.js +61 -61
  92. package/lib/shim/specs/index.js +3 -3
  93. package/lib/shim/transaction-shim.js +44 -192
  94. package/lib/shim/webframework-shim.js +52 -52
  95. package/lib/spans/span-event.js +1 -1
  96. package/lib/spans/streaming-span-attributes.js +1 -1
  97. package/lib/stats/apdex.js +2 -2
  98. package/lib/stats/index.js +2 -2
  99. package/lib/system-info.js +23 -23
  100. package/lib/timer.js +5 -5
  101. package/lib/transaction/dt-payload.js +1 -1
  102. package/lib/transaction/index.js +40 -40
  103. package/lib/transaction/name-state.js +14 -14
  104. package/lib/transaction/trace/exclusive-time-calculator.js +6 -6
  105. package/lib/transaction/trace/index.js +14 -14
  106. package/lib/transaction/trace/segment.js +18 -18
  107. package/lib/transaction/tracecontext.js +1 -1
  108. package/lib/transaction/tracer/index.js +53 -49
  109. package/lib/uninstrumented.js +7 -7
  110. package/lib/util/arity.js +2 -2
  111. package/lib/util/byte-limit.js +4 -4
  112. package/lib/util/cat.js +269 -24
  113. package/lib/util/codec.js +2 -2
  114. package/lib/util/copy.js +2 -2
  115. package/lib/util/deep-equal.js +10 -10
  116. package/lib/util/flatten.js +4 -4
  117. package/lib/util/hashes.js +14 -14
  118. package/lib/util/label-parser.js +17 -17
  119. package/lib/util/logger.js +24 -24
  120. package/lib/util/process-version.js +2 -2
  121. package/lib/util/properties.js +4 -4
  122. package/lib/util/sql/obfuscate.js +15 -15
  123. package/lib/util/stream-sink.js +3 -3
  124. package/lib/util/unwrapped-core.js +2 -2
  125. package/lib/util/urltils.js +16 -16
  126. package/lib/utilization/aws-info.js +7 -7
  127. package/lib/utilization/azure-info.js +6 -6
  128. package/lib/utilization/common.js +13 -13
  129. package/lib/utilization/docker-info.js +11 -11
  130. package/lib/utilization/gcp-info.js +4 -4
  131. package/lib/utilization/index.js +5 -5
  132. package/lib/utilization/pcf-info.js +9 -9
  133. package/package.json +13 -6
  134. package/stub_api.js +8 -8
@@ -0,0 +1,242 @@
1
+ /*
2
+ * Copyright 2021 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ 'use strict'
7
+
8
+ const cat = require('../util/cat')
9
+ const recordExternal = require('../metrics/recorders/http_external')
10
+ const logger = require('../logger').child({ component: 'undici' })
11
+ const NAMES = require('../metrics/names')
12
+ const NEWRELIC_SYNTHETICS_HEADER = 'x-newrelic-synthetics'
13
+ const SYMBOLS = {
14
+ SEGMENT: Symbol('__NR_segment'),
15
+ PARENT_SEGMENT: Symbol('__NR_parent_segment')
16
+ }
17
+ const { executionAsyncResource } = require('async_hooks')
18
+
19
+ let diagnosticsChannel = null
20
+ try {
21
+ diagnosticsChannel = require('diagnostics_channel')
22
+ } catch (e) {
23
+ // quick check to see if module exists
24
+ // module was not added until v15.x
25
+ }
26
+
27
+ module.exports = function addUndiciChannels(agent, undici, modName, shim) {
28
+ if (!diagnosticsChannel || !agent.config.feature_flag.undici_instrumentation) {
29
+ logger.warn(
30
+ 'diagnostics_channel or feature_flag.undici_instrumentation = false. Skipping undici instrumentation.'
31
+ )
32
+ return
33
+ }
34
+
35
+ /**
36
+ * Retrieves the current segment in transaction(parent in our context) from executionAsyncResource
37
+ * or from `shim.getSegment()` then adds to the executionAsyncResource for future
38
+ * undici requests within same async context.
39
+ *
40
+ * It was found that when running concurrent undici requests
41
+ * within a transaction that the parent segment would get out of sync
42
+ * depending on the async context of the transaction. By using
43
+ * `async_hooks.executionResource` it is more reliable.
44
+ *
45
+ * Note: However, if you have concurrent undici requests in a transaction
46
+ * and the request to the transaction is using a keep alive there is a chance the
47
+ * executionAsyncResource may be incorrect because of shared connections. To revert to a more
48
+ * naive tracking of parent set `config.feature_flag.undici_async_tracking: false` and
49
+ * it will just call `shim.getSegment()`
50
+ */
51
+ function getParentSegment() {
52
+ if (agent.config.feature_flag.undici_async_tracking) {
53
+ const resource = executionAsyncResource()
54
+
55
+ if (!resource[SYMBOLS.PARENT_SEGMENT]) {
56
+ const parent = shim.getSegment()
57
+ resource[SYMBOLS.PARENT_SEGMENT] = parent
58
+ }
59
+ return resource[SYMBOLS.PARENT_SEGMENT]
60
+ }
61
+ return shim.getSegment()
62
+ }
63
+
64
+ /**
65
+ * This event occurs after the Undici Request is created
66
+ * We will check current segment for opaque and also attach
67
+ * relevant headers to outgoing http request
68
+ *
69
+ * @param {object} params
70
+ * @param {object} params.request undici request object
71
+ */
72
+ diagnosticsChannel.channel('undici:request:create').subscribe(({ request }) => {
73
+ const parent = getParentSegment()
74
+ request[SYMBOLS.PARENT_SEGMENT] = parent
75
+ if (!parent || (parent && parent.opaque)) {
76
+ logger.trace(
77
+ 'Not capturing data for outbound request (%s) because parent segment opaque (%s)',
78
+ request.path,
79
+ parent && parent.name
80
+ )
81
+
82
+ return
83
+ }
84
+
85
+ const transaction = parent.transaction
86
+ const outboundHeaders = Object.create(null)
87
+ if (agent.config.encoding_key && transaction.syntheticsHeader) {
88
+ outboundHeaders[NEWRELIC_SYNTHETICS_HEADER] = transaction.syntheticsHeader
89
+ }
90
+
91
+ if (agent.config.distributed_tracing.enabled) {
92
+ transaction.insertDistributedTraceHeaders(outboundHeaders)
93
+ } else if (agent.config.cross_application_tracer.enabled) {
94
+ cat.addCatHeaders(agent.config, transaction, outboundHeaders)
95
+ } else {
96
+ logger.trace('Both DT and CAT are disabled, not adding headers!')
97
+ }
98
+
99
+ // eslint-disable-next-line guard-for-in
100
+ for (const key in outboundHeaders) {
101
+ request.addHeader(key, outboundHeaders[key])
102
+ }
103
+ })
104
+
105
+ /**
106
+ * This event occurs right before the data is written to the socket.
107
+ * Undici has some abstracted headers that are only created at this time, one
108
+ * is the `host` header which we need to name the Undici segment. So in this
109
+ * handler we create, start and set the segment active, name it, and
110
+ * attach the url/procedure/request.parameters
111
+ *
112
+ * @param {object} params
113
+ * @param {object} params.request undicie request object
114
+ * @param {TLSSocket | net.Socket} socket active socket connection
115
+ */
116
+ diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(({ request, socket }) => {
117
+ const parentSegment = request[SYMBOLS.PARENT_SEGMENT]
118
+ if (!parentSegment || (parentSegment && parentSegment.opaque)) {
119
+ return
120
+ }
121
+
122
+ const port = socket.remotePort
123
+ const isHttps = socket.servername
124
+ let urlString
125
+ if (isHttps) {
126
+ urlString = `https://${socket.servername}`
127
+ urlString += port === 443 ? request.path : `:${port}${request.path}`
128
+ } else {
129
+ urlString = `http://${socket._host}`
130
+ urlString += port === 80 ? request.path : `:${port}${request.path}`
131
+ }
132
+
133
+ const url = new URL(urlString)
134
+
135
+ const name = NAMES.EXTERNAL.PREFIX + url.host + url.pathname
136
+ const segment = shim.createSegment(name, recordExternal(url.host, 'undici'), parentSegment)
137
+ if (segment) {
138
+ segment.start()
139
+ shim.setActiveSegment(segment)
140
+ segment.addAttribute('url', `${url.protocol}//${url.host}${url.pathname}`)
141
+
142
+ url.searchParams.forEach((value, key) => {
143
+ segment.addSpanAttribute(`request.parameters.${key}`, value)
144
+ })
145
+ segment.addAttribute('procedure', request.method || 'GET')
146
+ request[SYMBOLS.SEGMENT] = segment
147
+ }
148
+ })
149
+
150
+ /**
151
+ * This event occurs after the response headers have been received.
152
+ * We will add the relevant http response attributes to active segment.
153
+ * Also add CAT specific keys to active segment.
154
+ *
155
+ * @param {object} params
156
+ * @param {object} params.request undici request object
157
+ * @param {object} params.response { statusCode, headers, statusText }
158
+ */
159
+ diagnosticsChannel.channel('undici:request:headers').subscribe(({ request, response }) => {
160
+ const activeSegment = request[SYMBOLS.SEGMENT]
161
+ if (!activeSegment) {
162
+ return
163
+ }
164
+
165
+ activeSegment.addSpanAttribute('http.statusCode', response.statusCode)
166
+ activeSegment.addSpanAttribute('http.statusText', response.statusText)
167
+
168
+ if (
169
+ agent.config.cross_application_tracer.enabled &&
170
+ !agent.config.distributed_tracing.enabled
171
+ ) {
172
+ try {
173
+ const { appData } = cat.extractCatHeaders(response.headers)
174
+ const decodedAppData = cat.parseAppData(agent.config, appData)
175
+ const attrs = activeSegment.getAttributes()
176
+ const url = new URL(attrs.url)
177
+ cat.assignCatToSegment(decodedAppData, activeSegment, url.host)
178
+ } catch (err) {
179
+ logger.warn(err, 'Cannot add CAT data to segment')
180
+ }
181
+ }
182
+ })
183
+
184
+ /**
185
+ * This event occurs after the response body has been received.
186
+ * We will end the active segment and set the active back to parent before request
187
+ *
188
+ * @param {object} params.request undici request object
189
+ */
190
+ diagnosticsChannel.channel('undici:request:trailers').subscribe(({ request }) => {
191
+ endAndRestoreSegment(request)
192
+ })
193
+
194
+ /**
195
+ * This event occurs right before the request emits an error.
196
+ * We will end the active segment and set the active back to parent before request.
197
+ * We will also log errors to NR
198
+ *
199
+ * Note: This event occurs before the error handler so we will always log it for now.
200
+ */
201
+ diagnosticsChannel.channel('undici:request:error').subscribe(({ request, error }) => {
202
+ endAndRestoreSegment(request, error)
203
+ })
204
+
205
+ /**
206
+ * Gets the active and parent from given ctx(request, client connector)
207
+ * and ends active and restores parent to active. If an error exists
208
+ * it will add the error to the transaction
209
+ *
210
+ * @param {object} ctx request or client connector
211
+ * @param {Error} error
212
+ */
213
+ function endAndRestoreSegment(ctx, error) {
214
+ const activeSegment = ctx[SYMBOLS.SEGMENT]
215
+ const parentSegment = ctx[SYMBOLS.PARENT_SEGMENT]
216
+ if (activeSegment) {
217
+ activeSegment.end()
218
+
219
+ if (error) {
220
+ handleError(activeSegment, error)
221
+ }
222
+
223
+ if (parentSegment) {
224
+ shim.setActiveSegment(parentSegment)
225
+ }
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Adds the error to the active transaction
231
+ *
232
+ * @param {TraceSegment} activeSegment
233
+ * @param {Error} error
234
+ */
235
+ function handleError(activeSegment, error) {
236
+ logger.trace(error, 'Captured outbound error on behalf of the user.')
237
+ const tx = activeSegment.transaction
238
+ shim.agent.errors.add(tx, error)
239
+ }
240
+ }
241
+
242
+ module.exports.SYMBOLS = SYMBOLS
@@ -5,10 +5,10 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var semver = require('semver')
8
+ const semver = require('semver')
9
9
 
10
10
  module.exports = function initialize(agent, vision, moduleName, shim) {
11
- var plugin = vision.plugin
11
+ const plugin = vision.plugin
12
12
 
13
13
  if (!plugin || !plugin.pkg || semver.lt(plugin.pkg.version, '5.0.0')) {
14
14
  shim.logger.debug('Vision instrumentation requires v5 or greater, not instrumenting')
@@ -22,7 +22,7 @@ module.exports = function initialize(agent, vision, moduleName, shim) {
22
22
  return function wrappedRegister(server) {
23
23
  shim.wrap(server, 'decorate', wrapDecorate)
24
24
 
25
- var ret = register.apply(this, arguments)
25
+ const ret = register.apply(this, arguments)
26
26
 
27
27
  shim.unwrapOnce(server, 'decorate')
28
28
 
@@ -37,7 +37,7 @@ function wrapDecorate(shim, decorate) {
37
37
  return decorate.apply(this, arguments)
38
38
  }
39
39
 
40
- var args = shim.argsToArray.apply(shim, arguments)
40
+ const args = shim.argsToArray.apply(shim, arguments)
41
41
  args[2] = shim.recordRender(handler, { promise: true })
42
42
 
43
43
  return decorate.apply(this, args)
@@ -5,9 +5,9 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var promInit = require('./promise')
8
+ const promInit = require('./promise')
9
9
 
10
- var STATIC_PROMISE_METHODS = [
10
+ const STATIC_PROMISE_METHODS = [
11
11
  'reject',
12
12
  'resolve',
13
13
  'all',
@@ -19,7 +19,7 @@ var STATIC_PROMISE_METHODS = [
19
19
  'reduceRight'
20
20
  ]
21
21
 
22
- var WHEN_SPEC = {
22
+ const WHEN_SPEC = {
23
23
  name: 'when',
24
24
  constructor: 'Promise',
25
25
  executor: true,
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var MODULE_TYPE = require('./shim/constants').MODULE_TYPE
8
+ const MODULE_TYPE = require('./shim/constants').MODULE_TYPE
9
9
 
10
10
  // Return a new copy of this array every time we're called
11
11
  module.exports = function instrumentations() {
@@ -31,6 +31,7 @@ module.exports = function instrumentations() {
31
31
  'redis': { type: MODULE_TYPE.DATASTORE },
32
32
  'restify': { type: MODULE_TYPE.WEB_FRAMEWORK },
33
33
  'superagent': { module: '@newrelic/superagent' },
34
+ 'undici': { type: MODULE_TYPE.TRANSACTION },
34
35
  'oracle': { type: null },
35
36
  'vision': { type: MODULE_TYPE.WEB_FRAMEWORK },
36
37
  'when': { type: null }
package/lib/logger.js CHANGED
@@ -5,8 +5,8 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var Logger = require('./util/logger')
9
- var fs = require('./util/unwrapped-core').fs
8
+ const Logger = require('./util/logger')
9
+ const fs = require('./util/unwrapped-core').fs
10
10
 
11
11
  // create bootstrapping logger
12
12
  module.exports = new Logger({
@@ -20,9 +20,9 @@ module.exports = new Logger({
20
20
  * module, and if it gets loaded too early, module.exports will have no
21
21
  * value.
22
22
  */
23
- var config = require('./config').getOrCreateInstance()
23
+ const config = require('./config').getOrCreateInstance()
24
24
  if (config) {
25
- var options = {
25
+ const options = {
26
26
  name: 'newrelic',
27
27
  level: config.logging.level,
28
28
  enabled: config.logging.enabled
@@ -32,7 +32,7 @@ if (config) {
32
32
  module.exports = new Logger(options)
33
33
 
34
34
  if (config.logging.enabled) {
35
- var stream
35
+ let stream
36
36
  switch (config.logging.filepath) {
37
37
  case 'stdout':
38
38
  stream = process.stdout
@@ -82,7 +82,7 @@ function Metrics(apdexT, mapper, normalizer) {
82
82
  Metrics.prototype.measureMilliseconds = measureMilliseconds
83
83
 
84
84
  function measureMilliseconds(name, scope, duration, exclusive) {
85
- var stats = this.getOrCreateMetric(name, scope)
85
+ const stats = this.getOrCreateMetric(name, scope)
86
86
  stats.recordValueInMillis(duration, exclusive)
87
87
  return stats
88
88
  }
@@ -96,7 +96,7 @@ function measureMilliseconds(name, scope, duration, exclusive) {
96
96
  * @return {Stats} The aggregated data related to this metric.
97
97
  */
98
98
  Metrics.prototype.measureBytes = function measureBytes(name, size) {
99
- var stats = this.getOrCreateMetric(name)
99
+ const stats = this.getOrCreateMetric(name)
100
100
  stats.recordValueInBytes(size)
101
101
  return stats
102
102
  }
@@ -110,8 +110,8 @@ Metrics.prototype.measureBytes = function measureBytes(name, size) {
110
110
  * @return {Stats} The aggregated data for that name.
111
111
  */
112
112
  Metrics.prototype.getOrCreateMetric = function getOrCreateMetric(name, scope) {
113
- var resolved = this._resolve(scope)
114
- var stats = resolved[name]
113
+ const resolved = this._resolve(scope)
114
+ let stats = resolved[name]
115
115
  if (!stats) {
116
116
  this.empty = false
117
117
  stats = resolved[name] = new Stats()
@@ -141,14 +141,14 @@ function getOrCreateApdexMetric(name, scope, overrideApdex) {
141
141
  throw new Error('Metrics must be named')
142
142
  }
143
143
 
144
- var resolved = this._resolve(scope)
144
+ const resolved = this._resolve(scope)
145
145
 
146
146
  if (!resolved[name]) {
147
147
  this.empty = false
148
148
 
149
149
  // Only use the given override to create the metric if this is not the
150
150
  // global apdex AND we have a valid value.
151
- var apdexT =
151
+ const apdexT =
152
152
  name !== NAMES.APDEX && overrideApdex > 0 ? overrideApdex * FROM_MILLIS : this.apdexT
153
153
  resolved[name] = new ApdexStats(apdexT)
154
154
  }
@@ -209,12 +209,12 @@ Metrics.prototype.merge = function merge(other, adjustStartTime) {
209
209
  // Loop through all scopes and merge them. Since we know `.scoped` has a `null`
210
210
  // prototype we don't need to worry about own property checks.
211
211
  // eslint-disable-next-line guard-for-in
212
- for (var scope in other.scoped) {
212
+ for (const scope in other.scoped) {
213
213
  _merge(this._resolve(scope), other.scoped[scope])
214
214
  }
215
215
  }
216
216
  function _merge(a, b) {
217
- for (var name in b) {
217
+ for (const name in b) {
218
218
  if (a[name]) {
219
219
  a[name].merge(b[name])
220
220
  } else {
@@ -232,7 +232,7 @@ function _merge(a, b) {
232
232
  * un-scoped metrics if the scope isn't set.
233
233
  */
234
234
  Metrics.prototype._resolve = function _resolve(scope) {
235
- var resolved = this.unscoped
235
+ let resolved = this.unscoped
236
236
 
237
237
  if (scope) {
238
238
  resolved = this.scoped[scope]
@@ -255,7 +255,7 @@ Metrics.prototype._getUnscopedData = function _getUnscopedData(name) {
255
255
  return
256
256
  }
257
257
 
258
- var normalized = this.normalizer.normalize(name)
258
+ const normalized = this.normalizer.normalize(name)
259
259
  if (normalized.ignore || !normalized.value) {
260
260
  return
261
261
  }
@@ -274,7 +274,7 @@ Metrics.prototype._getScopedData = function _getScopedData(name, scope) {
274
274
  return
275
275
  }
276
276
 
277
- var normalized = this.normalizer.normalize(name)
277
+ const normalized = this.normalizer.normalize(name)
278
278
  if (normalized.ignore || !normalized.value) {
279
279
  return
280
280
  }
@@ -287,10 +287,10 @@ Metrics.prototype._getScopedData = function _getScopedData(name, scope) {
287
287
  * for use by toJSON.
288
288
  */
289
289
  Metrics.prototype._toUnscopedData = function _toUnscopedData() {
290
- var metricData = []
290
+ const metricData = []
291
291
 
292
292
  Object.keys(this.unscoped).forEach((name) => {
293
- var data = this._getUnscopedData(name)
293
+ const data = this._getUnscopedData(name)
294
294
  if (data) {
295
295
  metricData.push(data)
296
296
  }
@@ -304,11 +304,11 @@ Metrics.prototype._toUnscopedData = function _toUnscopedData() {
304
304
  * use by toJSON.
305
305
  */
306
306
  Metrics.prototype._toScopedData = function _toScopedData() {
307
- var metricData = []
307
+ const metricData = []
308
308
 
309
309
  Object.keys(this.scoped).forEach(function forEachScope(scope) {
310
310
  Object.keys(this.scoped[scope]).forEach(function forEachMetric(name) {
311
- var data = this._getScopedData(name, scope)
311
+ const data = this._getScopedData(name, scope)
312
312
  if (data) {
313
313
  metricData.push(data)
314
314
  }
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var logger = require('../logger').child({ component: 'mapper' })
8
+ const logger = require('../logger').child({ component: 'mapper' })
9
9
 
10
10
  /**
11
11
  * To tighten up the metrics JSON, the collector will maintain a list of
@@ -41,12 +41,12 @@ MetricMapper.prototype.load = function load(raw) {
41
41
  return
42
42
  }
43
43
 
44
- for (var i = 0; i < raw.length; i++) {
45
- var spec = raw[i][0]
46
- var scope = spec.scope
47
- var name = spec.name
48
- var id = raw[i][1]
49
- var resolved
44
+ for (let i = 0; i < raw.length; i++) {
45
+ const spec = raw[i][0]
46
+ const scope = spec.scope
47
+ const name = spec.name
48
+ const id = raw[i][1]
49
+ let resolved
50
50
 
51
51
  if (scope) {
52
52
  if (!this.scoped[scope]) {
@@ -5,12 +5,12 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var logger = require('../../logger').child({ component: 'normalizer_rule' })
8
+ const logger = require('../../logger').child({ component: 'normalizer_rule' })
9
9
 
10
10
  /**
11
11
  * JavaScript just has to do things slightly differently.
12
12
  */
13
- var replaceReplacer = function replaceReplacer(input) {
13
+ const replaceReplacer = function replaceReplacer(input) {
14
14
  return input.replace(/\\/g, '$')
15
15
  }
16
16
 
@@ -37,7 +37,7 @@ function NormalizerRule(json) {
37
37
  this.ignore = json.ignore || false
38
38
  this.matched = false
39
39
 
40
- var modifiers = 'i'
40
+ let modifiers = 'i'
41
41
  if (this.replaceAll) {
42
42
  modifiers += 'g'
43
43
  }
@@ -78,9 +78,9 @@ NormalizerRule.prototype.getSegments = function getSegments(input) {
78
78
  * @return {bool} - True if this rule matches the given input, otherwise false.
79
79
  */
80
80
  NormalizerRule.prototype.matches = function matches(input) {
81
- var segments = this.getSegments(input)
81
+ const segments = this.getSegments(input)
82
82
 
83
- for (var i = 0; i < segments.length; ++i) {
83
+ for (let i = 0; i < segments.length; ++i) {
84
84
  if (this.pattern.test(segments[i])) {
85
85
  return true
86
86
  }
@@ -118,7 +118,7 @@ NormalizerRule.prototype.apply = function apply(input) {
118
118
  }
119
119
 
120
120
  this.matched = false
121
- var result = this.getSegments(input)
121
+ const result = this.getSegments(input)
122
122
  .map(function applyMap(segment) {
123
123
  // Discussion of why we use `lastIndex` in function documentation to
124
124
  // prevent de-opt due to long function.
@@ -154,9 +154,9 @@ NormalizerRule.prototype.toJSON = function toJSON() {
154
154
  * @return {RegExp} - A regular expression with all the given flags added.
155
155
  */
156
156
  function _addRegExpFlags(re, flags) {
157
- var foundMissing = false
158
- var reFlags = re.flags
159
- for (var i = 0; i < flags.length; ++i) {
157
+ let foundMissing = false
158
+ let reFlags = re.flags
159
+ for (let i = 0; i < flags.length; ++i) {
160
160
  if (reFlags.indexOf(flags[i]) === -1) {
161
161
  foundMissing = true
162
162
  reFlags += flags[i]
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict'
7
7
 
8
- var logger = require('../../logger').child({ component: 'tx_segment_normalizer' })
8
+ const logger = require('../../logger').child({ component: 'tx_segment_normalizer' })
9
9
 
10
10
  module.exports = TxSegmentNormalizer
11
11
 
@@ -33,21 +33,21 @@ function TxSegmentNormalizer() {
33
33
  * @return {NormalizationResults} - The results of normalizing the given path.
34
34
  */
35
35
  TxSegmentNormalizer.prototype.normalize = function normalize(path) {
36
- var currentTerm
37
- var prefix
38
- for (var i = 0; i < this.terms.length; i++) {
36
+ let currentTerm
37
+ let prefix
38
+ for (let i = 0; i < this.terms.length; i++) {
39
39
  currentTerm = this.terms[i]
40
40
  prefix = currentTerm.prefix
41
41
  if (path.lastIndexOf(prefix, 0) === -1) {
42
42
  continue
43
43
  }
44
- var fragment = path.slice(prefix.length)
45
- var parts = fragment.split('/')
46
- var result = []
47
- var prev
44
+ const fragment = path.slice(prefix.length)
45
+ const parts = fragment.split('/')
46
+ const result = []
47
+ let prev
48
+ let segment
48
49
 
49
- var segment
50
- for (var j = 0; j < parts.length; j++) {
50
+ for (let j = 0; j < parts.length; j++) {
51
51
  segment = parts[j]
52
52
 
53
53
  if (segment === '' && j + 1 === parts.length) {
@@ -87,10 +87,10 @@ TxSegmentNormalizer.prototype.load = function load(json) {
87
87
  }
88
88
 
89
89
  function filterRules(rules) {
90
- var map = Object.create(null)
90
+ const map = Object.create(null)
91
91
 
92
- for (var i = 0, l = rules.length; i < l; ++i) {
93
- var prefix = rules[i].prefix
92
+ for (let i = 0, l = rules.length; i < l; ++i) {
93
+ let prefix = rules[i].prefix
94
94
 
95
95
  if (!prefix || typeof prefix !== 'string') {
96
96
  continue
@@ -101,7 +101,7 @@ function filterRules(rules) {
101
101
  rules[i].prefix = prefix
102
102
  }
103
103
 
104
- var segments = prefix.split('/')
104
+ const segments = prefix.split('/')
105
105
  if (segments.length !== 3 || !segments[0] || !segments[1] || segments[3]) {
106
106
  continue
107
107
  }
@@ -111,10 +111,10 @@ function filterRules(rules) {
111
111
  }
112
112
  }
113
113
 
114
- var keys = Object.keys(map)
115
- var filtered = new Array(keys.length)
114
+ const keys = Object.keys(map)
115
+ const filtered = new Array(keys.length)
116
116
 
117
- for (i = 0, l = keys.length; i < l; ++i) {
117
+ for (let i = 0, l = keys.length; i < l; ++i) {
118
118
  filtered[i] = map[keys[i]]
119
119
  }
120
120