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.
- package/NEWS.md +222 -1
- package/api.js +24 -11
- package/bin/compare-bench-results.js +167 -0
- package/bin/run-bench.js +87 -44
- package/bin/travis-setup.sh +18 -7
- package/index.js +16 -8
- package/lib/collector/remote-method.js +12 -0
- package/lib/config/default.js +5 -0
- package/lib/config/env.js +2 -1
- package/lib/config/index.js +5 -0
- package/lib/db/tracer.js +17 -6
- package/lib/environment.js +1 -1
- package/lib/errors/index.js +1 -1
- package/lib/instrumentation/bluebird.js +35 -45
- package/lib/instrumentation/core/async_hooks.js +8 -8
- package/lib/instrumentation/core/child_process.js +41 -34
- package/lib/instrumentation/core/crypto.js +9 -14
- package/lib/instrumentation/core/dns.js +9 -13
- package/lib/instrumentation/core/domain.js +10 -12
- package/lib/instrumentation/core/fs.js +47 -38
- package/lib/instrumentation/core/globals.js +12 -17
- package/lib/instrumentation/core/http.js +3 -3
- package/lib/instrumentation/core/inspector.js +8 -7
- package/lib/instrumentation/core/net.js +62 -66
- package/lib/instrumentation/core/timers.js +79 -40
- package/lib/instrumentation/core/zlib.js +22 -8
- package/lib/instrumentation/mongodb.js +158 -115
- package/lib/instrumentations.js +3 -2
- package/lib/priority-queue.js +5 -2
- package/lib/shim/constants.js +6 -0
- package/lib/shim/datastore-shim.js +1 -1
- package/lib/shim/index.js +9 -5
- package/lib/shim/message-shim.js +5 -4
- package/lib/shim/promise-shim.js +563 -0
- package/lib/shim/shim.js +90 -11
- package/lib/shim/specs/index.js +8 -5
- package/lib/shimmer.js +70 -28
- package/lib/transaction/dt-payload.js +16 -0
- package/lib/transaction/handle.js +1 -1
- package/lib/transaction/index.js +22 -8
- package/lib/transaction/trace/aggregator.js +3 -3
- package/lib/transaction/trace/index.js +30 -37
- package/lib/util/codec.js +4 -1
- package/package.json +10 -4
package/NEWS.md
CHANGED
|
@@ -1,3 +1,150 @@
|
|
|
1
|
+
### 4.9.0 (2018-10-01):
|
|
2
|
+
|
|
3
|
+
* Updated DT payload creation to use `primary_application_id` from connect response.
|
|
4
|
+
|
|
5
|
+
* Added protection against functions with modified prototypes in `shim.applySegment`.
|
|
6
|
+
|
|
7
|
+
* Replaced SQL ID hash generation algorithm with SHA1 instead of MD5 to allow usage
|
|
8
|
+
in FIPS compliant environments.
|
|
9
|
+
|
|
10
|
+
* Leveraged 16 hex digits for creation of SQL ID.
|
|
11
|
+
|
|
12
|
+
* Fixed `codec.decode()` callback bug that would re-call a callback with an error
|
|
13
|
+
thrown within the callback.
|
|
14
|
+
|
|
15
|
+
* Added `superagent` as built-in instrumentation.
|
|
16
|
+
|
|
17
|
+
This instrumentation just maintains transaction state when using the `superagent`
|
|
18
|
+
module to make HTTP requests with either callbacks or promises.
|
|
19
|
+
|
|
20
|
+
* Updated `noticeError` API method to be partially functional in High Security Mode.
|
|
21
|
+
|
|
22
|
+
In HSM, any custom attributes will be ignored, but the error will still be tracked.
|
|
23
|
+
This brings the Node agent in line with the behavior of other language agents.
|
|
24
|
+
|
|
25
|
+
* Upgraded ejs module to get rid of Github security warnings. The ejs module was
|
|
26
|
+
only used for tests and not in main agent code.
|
|
27
|
+
|
|
28
|
+
* Fixed bug requiring Cross Application Tracing (CAT) to be enabled for Distributed
|
|
29
|
+
Tracing (DT) `createDistributedTracePayload` and `acceptDistributedTracePayload`
|
|
30
|
+
APIs to function. DT configuration will no longer consider CAT configuration.
|
|
31
|
+
|
|
32
|
+
* Changes DT payload configuration log messages to debug level as it is not uncommon
|
|
33
|
+
for calls to occur before server configuration has been retrieved.
|
|
34
|
+
|
|
35
|
+
* Converted `net` instrumentation to use shim api.
|
|
36
|
+
|
|
37
|
+
* Converted child_process instrumentation to newer shim style.
|
|
38
|
+
|
|
39
|
+
* Converted Timers instrumentation to newer shim style.
|
|
40
|
+
|
|
41
|
+
* Fixed bug in wrap() that would fail to wrap callbacks if the callback index was 0.
|
|
42
|
+
|
|
43
|
+
* Added `PromiseShim` class for instrumenting promise libraries.
|
|
44
|
+
|
|
45
|
+
* Support for setting `transaction_tracer.transaction_threshold` to 0 has been added.
|
|
46
|
+
|
|
47
|
+
* The agent now respects `NEW_RELIC_TRACER_THRESHOLD`.
|
|
48
|
+
|
|
49
|
+
Previously, this environment variable was stored as a string. The environment
|
|
50
|
+
variable is now stored as a float.
|
|
51
|
+
|
|
52
|
+
* Converted zlib instrumentation to use shim API.
|
|
53
|
+
|
|
54
|
+
### 4.8.1 (2018-08-27):
|
|
55
|
+
|
|
56
|
+
* Converted File System instrumentation to use newer shim style.
|
|
57
|
+
|
|
58
|
+
* Agent instrumentation will no longer interfere with promisification of core
|
|
59
|
+
methods.
|
|
60
|
+
|
|
61
|
+
Some core methods expose pre-promisified versions of the methods as a reference
|
|
62
|
+
on the method itself. When instrumenting these methods, it neglected to forward
|
|
63
|
+
these references onto the wrapper function. Now the instrumentation will properly
|
|
64
|
+
forward property look ups to the original method.
|
|
65
|
+
|
|
66
|
+
* Converted DNS instrumentation to newer shim style.
|
|
67
|
+
|
|
68
|
+
* Added tracking of callbacks to DNS instrumentation.
|
|
69
|
+
|
|
70
|
+
* Converted crypto instrumentation to newer shim style.
|
|
71
|
+
|
|
72
|
+
* Updated domains instrumentation to use an instrumentation shim.
|
|
73
|
+
|
|
74
|
+
* Refactored the global instrumentation to use the shim API.
|
|
75
|
+
|
|
76
|
+
* Ported inspector instrumentation to use an instrumentation shim.
|
|
77
|
+
|
|
78
|
+
* Ported async_hooks based promise instrumentation over to using shims.
|
|
79
|
+
|
|
80
|
+
* Added shim types for core instrumentations.
|
|
81
|
+
|
|
82
|
+
* Fixed outbound https call to use example.com to resolve integration test issue.
|
|
83
|
+
|
|
84
|
+
* Fixed tests for ioredis 4.0.0 and above.
|
|
85
|
+
|
|
86
|
+
* Improved benchmark comparison output.
|
|
87
|
+
|
|
88
|
+
* Added `http` benchmark tests.
|
|
89
|
+
|
|
90
|
+
### 4.8.0 (2018-08-13):
|
|
91
|
+
|
|
92
|
+
* Added JSON-formatted output to benchmarks to enable automated benchmark comparison.
|
|
93
|
+
|
|
94
|
+
* Updated the benchmark runner to measure specifically userland CPU overhead.
|
|
95
|
+
|
|
96
|
+
* Added DatastoreShim benchmarks.
|
|
97
|
+
|
|
98
|
+
* Fixed MongoDB instrumentation for driver versions greater than 3.0.6.
|
|
99
|
+
|
|
100
|
+
Mongo 3.0.6 removed metadata the Agent relied upon to instrument the driver. This
|
|
101
|
+
fixes that by going back to the old method of manually listing all objects and
|
|
102
|
+
methods to instrument.
|
|
103
|
+
|
|
104
|
+
* Implemented enforcement of `max_payload_size_in_bytes` config value.
|
|
105
|
+
|
|
106
|
+
Any payload during the harvest sequence that exceeds the configured limit will
|
|
107
|
+
be discarded.
|
|
108
|
+
|
|
109
|
+
* Updated MySQL versioned tests to run against the latest release.
|
|
110
|
+
|
|
111
|
+
### 4.7.0 (2018-07-31):
|
|
112
|
+
|
|
113
|
+
* Added support for distributed tracing.
|
|
114
|
+
|
|
115
|
+
Distributed tracing lets you see the path that a request takes as it travels
|
|
116
|
+
through your distributed system. By showing the distributed activity through a
|
|
117
|
+
unified view, you can troubleshoot and understand a complex system better than
|
|
118
|
+
ever before.
|
|
119
|
+
|
|
120
|
+
Distributed tracing is available with an APM Pro or equivalent subscription.
|
|
121
|
+
To see a complete distributed trace, you need to enable the feature on a set of
|
|
122
|
+
neighboring services. Enabling distributed tracing changes the behavior of some
|
|
123
|
+
New Relic features, so carefully consult the [transition guide](https://docs.newrelic.com/docs/transition-guide-distributed-tracing) before
|
|
124
|
+
you enable this feature.
|
|
125
|
+
|
|
126
|
+
To enable distributed tracing, set `distributed_tracing.enabled` to `true` in
|
|
127
|
+
your `newrelic.js` file, or set `NEW_RELIC_DISTRIBUTED_TRACING_ENABLED` in your
|
|
128
|
+
environment.
|
|
129
|
+
|
|
130
|
+
* Added a warning for too-new versions of Node.js during agent startup.
|
|
131
|
+
|
|
132
|
+
* Appropriately obfuscated SQL statements will now be included in all transaction
|
|
133
|
+
traces.
|
|
134
|
+
|
|
135
|
+
Previously, the agent would only include the SQL statements if the corresponding
|
|
136
|
+
query was sufficiently slow.
|
|
137
|
+
|
|
138
|
+
* Added ability to execute instrumentation functions in the context of the segment
|
|
139
|
+
the segment descriptor is describing.
|
|
140
|
+
|
|
141
|
+
All `record*` methods supplied by all instrumentation shim classes now allow for
|
|
142
|
+
a function to be executed under the context of the segment the record call will
|
|
143
|
+
produce. This may be done by supplying a function in the `inContext` key for the
|
|
144
|
+
segment descriptor passed to the record method.
|
|
145
|
+
|
|
146
|
+
* Reservoirs will now respect setting their size to 0.
|
|
147
|
+
|
|
1
148
|
### 4.6.0 (2018-07-24):
|
|
2
149
|
|
|
3
150
|
* Added full support for Node v10.
|
|
@@ -11,6 +158,8 @@
|
|
|
11
158
|
* Updated tests to use `asyncResource.runInAsyncScope` instead of `emitBefore` and
|
|
12
159
|
`emitAfter`
|
|
13
160
|
|
|
161
|
+
* Pulled `distributed_tracing` config value from behind `feature_flag`.
|
|
162
|
+
|
|
14
163
|
### 4.5.1 (2018-07-18):
|
|
15
164
|
|
|
16
165
|
- The agent will now properly remerge event data on collection failure.
|
|
@@ -33,6 +182,12 @@
|
|
|
33
182
|
|
|
34
183
|
* Updated Hapi v17 instrumentation to wrap `server` export, in addition to `Server`.
|
|
35
184
|
|
|
185
|
+
* `ROOT` segment no longer turns into a span event.
|
|
186
|
+
|
|
187
|
+
* Fixed span collection when transactions are `sampled=false`.
|
|
188
|
+
|
|
189
|
+
* Removed `grandparentId` from spans.
|
|
190
|
+
|
|
36
191
|
### 4.4.0 (2018-07-12):
|
|
37
192
|
|
|
38
193
|
* Added config `utilization` env vars to the `BOOLEAN_VARS` set.
|
|
@@ -44,6 +199,29 @@
|
|
|
44
199
|
|
|
45
200
|
* Added node v10 to the test matrix.
|
|
46
201
|
|
|
202
|
+
* Converted distributed trace `x-newrelic-trace` header name to `newrelic`.
|
|
203
|
+
|
|
204
|
+
* Added support for different transport types in distributed tracing.
|
|
205
|
+
|
|
206
|
+
* Added more tests around priority/sampled attributes on traces and events.
|
|
207
|
+
|
|
208
|
+
* Lazily calculate transaction priority only when needed.
|
|
209
|
+
|
|
210
|
+
* Transaction priority is now truncated to 6 decimal places on generation.
|
|
211
|
+
|
|
212
|
+
* Adaptive sampling now uses the `sampling_target` and
|
|
213
|
+
`sampling_target_period_in_seconds` configuration values.
|
|
214
|
+
|
|
215
|
+
With these configurations, the adaptive sampling window is separated from the
|
|
216
|
+
harvest window.
|
|
217
|
+
|
|
218
|
+
* Removed `nr.tripId` attribute from distributed trace intrinsics.
|
|
219
|
+
|
|
220
|
+
* Default span events to enabled.
|
|
221
|
+
|
|
222
|
+
These are still protected behind `feature_flag.distributed_tracing` which defaults
|
|
223
|
+
to `false`.
|
|
224
|
+
|
|
47
225
|
### 4.3.0 (2018-07-09):
|
|
48
226
|
|
|
49
227
|
* Added `nonce` option for `newrelic.getBrowserTimingHeader()`
|
|
@@ -65,7 +243,7 @@
|
|
|
65
243
|
|
|
66
244
|
* Fixed issue with tracking external requests to default ports.
|
|
67
245
|
|
|
68
|
-
|
|
246
|
+
Special thanks to Ryan King for pinpointing the cause of this issue.
|
|
69
247
|
|
|
70
248
|
* Added extra check for handling arrays of functions when wrapping middleware
|
|
71
249
|
mounters.
|
|
@@ -103,6 +281,25 @@
|
|
|
103
281
|
|
|
104
282
|
* No longer download gcc on test suites that do not require it.
|
|
105
283
|
|
|
284
|
+
* Added `url` parameter to `http` external segments.
|
|
285
|
+
|
|
286
|
+
* Renamed request parameters on external segments.
|
|
287
|
+
|
|
288
|
+
Previously these were named just the parameter name (e.g. `/foo?bar=baz` would
|
|
289
|
+
become the parameter `"bar": "baz"`). Now they are prefixed with
|
|
290
|
+
`request.parameter`. (e.g. `"request.parameter.bar": "baz"`).
|
|
291
|
+
|
|
292
|
+
* Added `EventAggregator` base class.
|
|
293
|
+
|
|
294
|
+
The `ErrorAggregator` class was refactored and most generic event aggregation
|
|
295
|
+
logic was moved to the new `EventAggregator` class.
|
|
296
|
+
|
|
297
|
+
* Added `SpanEvent` and `SpanAggregator` classes.
|
|
298
|
+
|
|
299
|
+
* Added Span event generation to the trace `end` method.
|
|
300
|
+
|
|
301
|
+
* Added Span events to harvest cycle steps.
|
|
302
|
+
|
|
106
303
|
### 4.1.5 (2018-06-11):
|
|
107
304
|
|
|
108
305
|
* Make `require()` statements explicitly reference `package.json` as a `.json` file.
|
|
@@ -145,6 +342,11 @@
|
|
|
145
342
|
result in a false `uninstrumented` status, because the agent would interpret
|
|
146
343
|
`redis.js` as the module itself.
|
|
147
344
|
|
|
345
|
+
* Moved `computeSampled` call to `Transaction` constructor.
|
|
346
|
+
|
|
347
|
+
Previously it was only called in `createDistributedTracePayload`, but this
|
|
348
|
+
gives all transactions a `sampled` value, and potentially a boosted priority.
|
|
349
|
+
|
|
148
350
|
### 4.1.4 (2018-06-04):
|
|
149
351
|
|
|
150
352
|
* Transaction stubs are now created properly in `api#getTransaction`
|
|
@@ -168,6 +370,25 @@
|
|
|
168
370
|
|
|
169
371
|
* Modularlized configuration constants to improve readability.
|
|
170
372
|
|
|
373
|
+
* Added `distributed_tracing` feature flag.
|
|
374
|
+
|
|
375
|
+
* Added `acceptDistributedTracePayload` method to `Transaction`.
|
|
376
|
+
|
|
377
|
+
* Added `createDistributedTracePayload` method to `Transaction`.
|
|
378
|
+
|
|
379
|
+
* Updated `Agent#recordSupportability` to not include `Nodejs/` in the default metric name.
|
|
380
|
+
|
|
381
|
+
* Added distributed tracing methods to `TransactionHandle`.
|
|
382
|
+
|
|
383
|
+
* Added distributed tracing cases for `http` and `other` metric recorders.
|
|
384
|
+
|
|
385
|
+
* Implemented `_addDistributedTraceInstrinsics` on `Transaction`.
|
|
386
|
+
|
|
387
|
+
If the `distributed_tracing` feature flag is enabled, the agent will ignore old
|
|
388
|
+
CAT attributes in favor of distributed trace–related ones.
|
|
389
|
+
|
|
390
|
+
* Added integration tests around better CAT functionality.
|
|
391
|
+
|
|
171
392
|
### 4.1.2 (2018-05-22):
|
|
172
393
|
|
|
173
394
|
* Fixed access to properties on promisified methods.
|
package/api.js
CHANGED
|
@@ -397,29 +397,35 @@ API.prototype.setIgnoreTransaction = function setIgnoreTransaction(ignored) {
|
|
|
397
397
|
* Optional. Any custom attributes to be displayed in the New Relic UI.
|
|
398
398
|
*/
|
|
399
399
|
API.prototype.noticeError = function noticeError(error, customAttributes) {
|
|
400
|
-
|
|
400
|
+
const metric = this.agent.metrics.getOrCreateMetric(
|
|
401
401
|
NAMES.SUPPORTABILITY.API + '/noticeError'
|
|
402
402
|
)
|
|
403
403
|
metric.incrementCallCount()
|
|
404
404
|
|
|
405
|
-
|
|
406
|
-
if (this.agent.config.high_security === true) {
|
|
407
|
-
logger.warnOnce(
|
|
408
|
-
'Notice Error',
|
|
409
|
-
'Notice error API is disabled by high security mode.'
|
|
410
|
-
)
|
|
411
|
-
return false
|
|
412
|
-
} else if (!this.agent.config.api.notice_error_enabled) {
|
|
405
|
+
if (!this.agent.config.api.notice_error_enabled) {
|
|
413
406
|
logger.debug(
|
|
414
407
|
'Config.api.notice_error_enabled set to false, not collecting error'
|
|
415
408
|
)
|
|
416
409
|
return false
|
|
417
410
|
}
|
|
418
411
|
|
|
412
|
+
// If high security mode is on or custom attributes are disabled,
|
|
413
|
+
// noticeError does not collect custom attributes.
|
|
414
|
+
if (this.agent.config.high_security === true) {
|
|
415
|
+
logger.debug(
|
|
416
|
+
'Passing custom attributes to notice error API is disabled in high security mode.'
|
|
417
|
+
)
|
|
418
|
+
} else if (!this.agent.config.api.custom_attributes_enabled) {
|
|
419
|
+
logger.debug(
|
|
420
|
+
'Config.api.custom_attributes_enabled set to false, ' +
|
|
421
|
+
'ignoring custom error attributes.'
|
|
422
|
+
)
|
|
423
|
+
}
|
|
424
|
+
|
|
419
425
|
if (typeof error === 'string') {
|
|
420
426
|
error = new Error(error)
|
|
421
427
|
}
|
|
422
|
-
|
|
428
|
+
const transaction = this.agent.tracer.getTransaction()
|
|
423
429
|
|
|
424
430
|
this.agent.errors.addUserError(transaction, error, customAttributes)
|
|
425
431
|
}
|
|
@@ -702,6 +708,13 @@ function createTracer(name, callback) {
|
|
|
702
708
|
return arity.fixArity(callback, tracer.bindFunction(callback, segment, true))
|
|
703
709
|
}
|
|
704
710
|
|
|
711
|
+
/**
|
|
712
|
+
* @callback startSegmentCallback
|
|
713
|
+
* @param {function} cb
|
|
714
|
+
* The function to time with the created segment.
|
|
715
|
+
* @return {Promise=} Returns a promise if cb returns a promise.
|
|
716
|
+
*/
|
|
717
|
+
|
|
705
718
|
/**
|
|
706
719
|
* Wraps the given handler in a segment which may optionally be turned into a
|
|
707
720
|
* metric.
|
|
@@ -720,7 +733,7 @@ function createTracer(name, callback) {
|
|
|
720
733
|
* up on the transaction breakdown table and server breakdown graph. Segments
|
|
721
734
|
* just show up in transaction traces.
|
|
722
735
|
*
|
|
723
|
-
* @param {
|
|
736
|
+
* @param {startSegmentCallback} handler
|
|
724
737
|
* The function to track as a segment.
|
|
725
738
|
*
|
|
726
739
|
* @param {function} [callback]
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
|
|
4
|
+
const async = require('async')
|
|
5
|
+
const fs = require('fs')
|
|
6
|
+
|
|
7
|
+
if (process.argv.length !== 4) {
|
|
8
|
+
console.log('Usage: %s %s <baseline> <upstream>', process.argv[0], process.argv[1])
|
|
9
|
+
console.log(' <baseline> JSON file containing benchmark results for upstream')
|
|
10
|
+
console.log(' upstream comparison.')
|
|
11
|
+
console.log(' <downstream> JSON file containing benchmark results from')
|
|
12
|
+
console.log(' downstream branch to compare against base.')
|
|
13
|
+
process.exit(1)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async.map(process.argv.slice(2), (file, cb) => {
|
|
17
|
+
fs.readFile(file, {encoding: 'utf8'}, (err, data) => {
|
|
18
|
+
if (err) {
|
|
19
|
+
return cb(err)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let parsed = null
|
|
23
|
+
try {
|
|
24
|
+
parsed = JSON.parse(data)
|
|
25
|
+
} catch (parseError) {
|
|
26
|
+
return cb(parseError)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
cb(null, parsed)
|
|
30
|
+
})
|
|
31
|
+
}, (err, resultFiles) => {
|
|
32
|
+
if (err) {
|
|
33
|
+
console.log('Failed to load files.')
|
|
34
|
+
console.log(err)
|
|
35
|
+
process.exit(2)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const baseline = resultFiles[0]
|
|
39
|
+
const downstream = resultFiles[1]
|
|
40
|
+
|
|
41
|
+
const baselineFiles = Object.keys(baseline)
|
|
42
|
+
const downstreamFiles = Object.keys(downstream)
|
|
43
|
+
const warnings = []
|
|
44
|
+
|
|
45
|
+
diffArrays(baselineFiles, downstreamFiles).forEach((file) => {
|
|
46
|
+
warnings.push(`- **WARNING**: File "${file}" in base but not branch.`)
|
|
47
|
+
})
|
|
48
|
+
diffArrays(downstreamFiles, baselineFiles).forEach((file) => {
|
|
49
|
+
warnings.push(`- **NOTE**: File "${file}" in branch but not base.`)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
let allPassing = true
|
|
53
|
+
const details = baselineFiles.sort().map((testFile) => {
|
|
54
|
+
const base = baseline[testFile]
|
|
55
|
+
const down = downstream[testFile]
|
|
56
|
+
|
|
57
|
+
if (!down) {
|
|
58
|
+
return [
|
|
59
|
+
'<details>',
|
|
60
|
+
`<summary>${testFile} file missing from branch</summary>`,
|
|
61
|
+
'',
|
|
62
|
+
'</details>'
|
|
63
|
+
].join('\n')
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let filePassing = true
|
|
67
|
+
const baseTests = Object.keys(base)
|
|
68
|
+
const downTests = Object.keys(down)
|
|
69
|
+
|
|
70
|
+
diffArrays(baseTests, downTests).forEach((test) => {
|
|
71
|
+
warnings.push(`- **WARNING**: Test "${test}" in base but not branch.`)
|
|
72
|
+
})
|
|
73
|
+
diffArrays(downTests, baseTests).forEach((test) => {
|
|
74
|
+
warnings.push(`- **NOTE**: Test "${test}" in branch but not base.`)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
const results = baseTests.sort().map((test) => {
|
|
78
|
+
const passes = compareResults(base[test], down[test])
|
|
79
|
+
filePassing = filePassing && passes
|
|
80
|
+
|
|
81
|
+
return [
|
|
82
|
+
'<details>',
|
|
83
|
+
`<summary>${test}: ${passMark(passes)}</summary>`,
|
|
84
|
+
'',
|
|
85
|
+
formatResults(base[test], down[test]),
|
|
86
|
+
'</details>',
|
|
87
|
+
''
|
|
88
|
+
].join('\n')
|
|
89
|
+
}).join('\n')
|
|
90
|
+
allPassing = allPassing && filePassing
|
|
91
|
+
|
|
92
|
+
return [
|
|
93
|
+
'<details>',
|
|
94
|
+
`<summary>${testFile}: ${passMark(filePassing)}</summary>`,
|
|
95
|
+
'',
|
|
96
|
+
results,
|
|
97
|
+
'',
|
|
98
|
+
'-----------------------------------------------------------------------',
|
|
99
|
+
'</details>'
|
|
100
|
+
].join('\n')
|
|
101
|
+
}).join('\n\n')
|
|
102
|
+
|
|
103
|
+
if (warnings.length) {
|
|
104
|
+
console.log('### WARNINGS')
|
|
105
|
+
console.log(warnings.join('\n'))
|
|
106
|
+
console.log('')
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
console.log(`### Benchmark Results: ${passMark(allPassing)}`)
|
|
110
|
+
console.log('')
|
|
111
|
+
console.log('### Details')
|
|
112
|
+
console.log('_Lower is better._')
|
|
113
|
+
console.log(details)
|
|
114
|
+
|
|
115
|
+
if (!allPassing) {
|
|
116
|
+
process.exitCode = -1
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
function diffArrays(a, b) {
|
|
121
|
+
return a.filter((elem) => !b.includes(elem))
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function compareResults(base, down) {
|
|
125
|
+
const delta = down.mean - base.mean
|
|
126
|
+
const deltaPercent = delta / base.mean
|
|
127
|
+
if (Math.abs(delta) < 0.1) {
|
|
128
|
+
return deltaPercent < 100
|
|
129
|
+
}
|
|
130
|
+
return deltaPercent < 2
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function passMark(passes) {
|
|
134
|
+
return passes ? '✔' : '✘'
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function formatResults(base, down) {
|
|
138
|
+
return [
|
|
139
|
+
'Field | Upstream (ms) | Downstream (ms) | Delta (ms) | Delta (%)',
|
|
140
|
+
'----- | ------------: | --------------: | ---------: | --------:',
|
|
141
|
+
formatField('numSamples'),
|
|
142
|
+
formatField('mean'),
|
|
143
|
+
formatField('stdDev'),
|
|
144
|
+
formatField('max'),
|
|
145
|
+
formatField('min'),
|
|
146
|
+
formatField('5thPercentile'),
|
|
147
|
+
formatField('95thPercentile'),
|
|
148
|
+
formatField('median')
|
|
149
|
+
].join('\n')
|
|
150
|
+
|
|
151
|
+
function formatField(field) {
|
|
152
|
+
const baseValue = base[field]
|
|
153
|
+
const downValue = down[field]
|
|
154
|
+
const diffValue = downValue - baseValue
|
|
155
|
+
const diffPercent = (100 * diffValue / baseValue).toFixed(2)
|
|
156
|
+
const prefix = diffValue >= 0 ? '+' : ''
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
`${field} | ${fixValue(baseValue)} | ${fixValue(downValue)} |` +
|
|
160
|
+
` ${fixValue(diffValue)} | ${prefix}${diffPercent}%`
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function fixValue(value) {
|
|
165
|
+
return value % 1 ? value.toFixed(5) : value
|
|
166
|
+
}
|
|
167
|
+
}
|
package/bin/run-bench.js
CHANGED
|
@@ -36,54 +36,97 @@ if (tests.length === 0 && globs.length === 0) {
|
|
|
36
36
|
)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
class ConsolePrinter {
|
|
40
|
+
/* eslint-disable no-console */
|
|
41
|
+
addTest(name, child) {
|
|
42
|
+
console.log(name)
|
|
43
|
+
child.stdout.on('data', (d) => process.stdout.write(d))
|
|
44
|
+
child.stderr.on('data', (d) => process.stderr.write(d))
|
|
45
|
+
child.once('exit', () => console.log(''))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
finish() {
|
|
49
|
+
console.log('')
|
|
50
|
+
}
|
|
51
|
+
/* eslint-enable no-console */
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
class JSONPrinter {
|
|
55
|
+
constructor() {
|
|
56
|
+
this._tests = Object.create(null)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
addTest(name, child) {
|
|
60
|
+
let output = ''
|
|
61
|
+
this._tests[name] = null
|
|
62
|
+
child.stdout.on('data', (d) => output += d.toString())
|
|
63
|
+
child.stdout.on('end', () => this._tests[name] = JSON.parse(output))
|
|
64
|
+
child.stderr.on('data', (d) => process.stderr.write(d))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
finish() {
|
|
68
|
+
/* eslint-disable no-console */
|
|
69
|
+
console.log(JSON.stringify(this._tests, null, 2))
|
|
70
|
+
/* eslint-enable no-console */
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
run()
|
|
75
|
+
|
|
76
|
+
function run() {
|
|
77
|
+
const printer = opts.json ? new JSONPrinter() : new ConsolePrinter()
|
|
44
78
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return cb(err)
|
|
79
|
+
a.series([
|
|
80
|
+
function resolveGlobs(cb) {
|
|
81
|
+
if (!globs.length) {
|
|
82
|
+
return cb()
|
|
50
83
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
84
|
+
|
|
85
|
+
a.map(globs, glob, function afterGlobbing(err, resolved) {
|
|
86
|
+
if (err) {
|
|
87
|
+
console.error('Failed to glob:', err)
|
|
88
|
+
process.exitCode = -1
|
|
89
|
+
return cb(err)
|
|
90
|
+
}
|
|
91
|
+
resolved.forEach(function mergeResolved(files) {
|
|
92
|
+
files.forEach(function mergeFile(file) {
|
|
93
|
+
if (tests.indexOf(file) === -1) {
|
|
94
|
+
tests.push(file)
|
|
95
|
+
}
|
|
96
|
+
})
|
|
56
97
|
})
|
|
98
|
+
cb()
|
|
57
99
|
})
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
100
|
+
},
|
|
101
|
+
function runBenchmarks(cb) {
|
|
102
|
+
tests.sort()
|
|
103
|
+
a.eachSeries(tests, function spawnEachFile(file, cb) {
|
|
104
|
+
var test = path.relative(benchpath, file)
|
|
105
|
+
|
|
106
|
+
var args = [file]
|
|
107
|
+
if (opts.inspect) {
|
|
108
|
+
args.unshift('--inspect-brk')
|
|
109
|
+
}
|
|
110
|
+
var child = cp.spawn('node', args, {cwd: cwd, stdio: 'pipe'})
|
|
111
|
+
printer.addTest(test, child)
|
|
112
|
+
|
|
113
|
+
child.on('error', cb)
|
|
114
|
+
child.on('exit', function onChildExit(code) {
|
|
115
|
+
if (code) {
|
|
116
|
+
return cb(new Error('Benchmark exited with code ' + code))
|
|
117
|
+
}
|
|
118
|
+
cb()
|
|
119
|
+
})
|
|
120
|
+
}, function afterSpawnEachFile(err) {
|
|
121
|
+
if (err) {
|
|
122
|
+
console.error('Spawning failed:', err)
|
|
123
|
+
process.exitCode = -2
|
|
124
|
+
return cb(err)
|
|
77
125
|
}
|
|
78
126
|
cb()
|
|
79
127
|
})
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
cb()
|
|
87
|
-
})
|
|
88
|
-
}
|
|
89
|
-
])
|
|
128
|
+
}
|
|
129
|
+
], () => {
|
|
130
|
+
printer.finish()
|
|
131
|
+
})
|
|
132
|
+
}
|
package/bin/travis-setup.sh
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#! /bin/bash
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
local
|
|
6
|
-
|
|
3
|
+
|
|
4
|
+
function get_version {
|
|
5
|
+
local num='[[:digit:]][[:digit:]]*' # Grep doesn't have `+` operator.
|
|
6
|
+
local version=`$1 --version 2>/dev/null | grep -o "$num\.$num\.$num" | head -1`
|
|
7
|
+
echo $version | grep -o "$num" | head -1
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
TOOLCHAIN_ADDED="false"
|
|
@@ -15,15 +16,25 @@ function add_toolchain {
|
|
|
15
16
|
TOOLCHAIN_ADDED="true"
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
# Only upgrade GCC if we need to.
|
|
19
19
|
|
|
20
20
|
if [ "$SUITE" = "versioned" ]; then
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
# GCC 5 is the lowest version of GCC we can use.
|
|
23
|
+
if [ "$(get_version gcc)" == "4" ]; then
|
|
22
24
|
echo " --- upgrading GCC --- "
|
|
23
25
|
add_toolchain
|
|
24
26
|
./bin/travis-install-gcc5.sh > /dev/null
|
|
25
27
|
else
|
|
26
|
-
echo " --- not upgrading GCC --- "
|
|
28
|
+
echo " --- not upgrading GCC ($(gcc --version)) --- "
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# npm 2 has an issue installing correctly for the superagent versioned tests.
|
|
32
|
+
# TODO: Remove this check when deprecating Node <5.
|
|
33
|
+
if [ "$(get_version npm)" == "2" ]; then
|
|
34
|
+
echo " -- upgrading npm --- "
|
|
35
|
+
npm install -g npm@3
|
|
36
|
+
else
|
|
37
|
+
echo " --- not upgrading npm ($(npm --version)) --- "
|
|
27
38
|
fi
|
|
28
39
|
|
|
29
40
|
echo " --- installing $SUITE requirements --- "
|