newrelic 6.6.0 → 6.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 +81 -0
- package/README.md +2 -0
- package/api.js +31 -25
- package/bin/run-versioned-tests.sh +10 -1
- package/bin/ssl.sh +3 -3
- package/lib/config/default.js +10 -2
- package/lib/config/env.js +4 -2
- package/lib/config/index.js +4 -0
- package/lib/errors/error-collector.js +30 -14
- package/lib/instrumentation/core/http.js +16 -14
- package/lib/metrics/normalizer.js +5 -5
- package/lib/serverless/event-sources.json +1 -1
- package/lib/shim/shim.js +3 -3
- package/lib/spans/create-span-event-aggregator.js +2 -1
- package/lib/spans/span-context.js +13 -0
- package/lib/spans/span-event.js +5 -0
- package/lib/spans/span-streamer.js +85 -51
- package/lib/spans/streaming-span-event-aggregator.js +1 -11
- package/lib/spans/streaming-span-event.js +5 -0
- package/lib/transaction/index.js +44 -13
- package/lib/transaction/trace/segment.js +13 -1
- package/lib/transaction/tracer/index.js +5 -0
- package/package.json +26 -11
- package/.eslintignore +0 -1
- package/.eslintrc.js +0 -67
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -5
- package/.travis.yml +0 -40
package/NEWS.md
CHANGED
|
@@ -1,3 +1,84 @@
|
|
|
1
|
+
### 6.9.0 (2020-06-08):
|
|
2
|
+
|
|
3
|
+
* Added AWS API Gateway V2 Support to lambda instrumentation.
|
|
4
|
+
|
|
5
|
+
* Added 'transaction.name' intrinsic to active span at time transaction name is finalized.
|
|
6
|
+
|
|
7
|
+
This enables finding transaction name for traces that may not have a matching transaction event.
|
|
8
|
+
|
|
9
|
+
* Added 'error.expected' attribute to span active at time expected error was noticed.
|
|
10
|
+
|
|
11
|
+
* Dropped errors earlier during collection when error collection is disabled.
|
|
12
|
+
|
|
13
|
+
Error attributes will no longer show up on spans when error collection has been disabled. Other unnecessary work will also be avoided.
|
|
14
|
+
|
|
15
|
+
* Removed allocation of logging-only objects used by transaction naming when those log levels are disabled.
|
|
16
|
+
|
|
17
|
+
* Upgraded escodegen from 1.12.0 to 1.14.1.
|
|
18
|
+
|
|
19
|
+
* Upgraded readable-stream from 3.4.0 to 3.6.0.
|
|
20
|
+
|
|
21
|
+
* Upgraded @grpc/proto-loader from 0.5.3 to 0.5.4.
|
|
22
|
+
|
|
23
|
+
* Converted facts unit test to use tap API.
|
|
24
|
+
|
|
25
|
+
* Converted transaction 'finalizeName...' unit tests to use tap API.
|
|
26
|
+
|
|
27
|
+
* Added several items to .npmignore to prevent accidental publishing.
|
|
28
|
+
|
|
29
|
+
* Fixed Redis client w/o callback versioned test flicker.
|
|
30
|
+
|
|
31
|
+
Doesn't end transaction until error encountered. Increases wait time for first operation which has to complete for the second operation to be successful.
|
|
32
|
+
|
|
33
|
+
### 6.8.0 (2020-05-21):
|
|
34
|
+
|
|
35
|
+
* Bumped @newrelic/native-metrics to ^5.1.0.
|
|
36
|
+
|
|
37
|
+
Upgraded nan to ^2.14.1 to resolve 'GetContents' deprecation warning with Node 14. This version of the native metrics module is tested against Node 14 and includes a pre-built binary download backup for Node 14.
|
|
38
|
+
|
|
39
|
+
* Added whitespace trimming of license key configuration values.
|
|
40
|
+
|
|
41
|
+
Previously, when a license key was entered with leading or trailing whitespace, it would be used as-is and result in a validation failure. This most commonly occurred with environment variable based configuration.
|
|
42
|
+
|
|
43
|
+
* Moved to GitHub actions for CI.
|
|
44
|
+
|
|
45
|
+
* Updated PR template and added initial issue templates.
|
|
46
|
+
|
|
47
|
+
* Converted most of the collector API unit tests to use the tap API. Split larger test groupings into their own test files.
|
|
48
|
+
|
|
49
|
+
### 6.7.1 (2020-05-14):
|
|
50
|
+
|
|
51
|
+
* Added synthetics headers to transaction event intrinsics for DT
|
|
52
|
+
|
|
53
|
+
* Fixed stale comment documentation with regards to segment recording
|
|
54
|
+
|
|
55
|
+
### 6.7.0 (2020-05-06):
|
|
56
|
+
|
|
57
|
+
* Added a configurable-length span queue to Infinite Tracing:
|
|
58
|
+
infinite_tracing.span_events.queue_size.
|
|
59
|
+
|
|
60
|
+
The queue length can be modified to balance the needs of keeping full traces
|
|
61
|
+
against trade-off of memory usage and CPU overhead in a high-throughput
|
|
62
|
+
application.
|
|
63
|
+
|
|
64
|
+
* Fixed issue where API.instrumentLoadedModule could throw an exception when it
|
|
65
|
+
failed.
|
|
66
|
+
|
|
67
|
+
Error details will now be caught and logged.
|
|
68
|
+
|
|
69
|
+
* Resolved non-proxy minimist security warnings by bumping dependencies.
|
|
70
|
+
|
|
71
|
+
These updates only impact development dependencies. Thank you to @devfreddy for
|
|
72
|
+
the contribution.
|
|
73
|
+
|
|
74
|
+
* Updated minimist sub-deps to resolve most related security warnings.
|
|
75
|
+
* Updated tap to resolve remaining tap security warnings.
|
|
76
|
+
* Updated @newrelic/proxy.
|
|
77
|
+
|
|
78
|
+
* Updated remaining /api unit tests to use tap API.
|
|
79
|
+
|
|
80
|
+
* Updated @grpc/grpc-js to v1.0.3.
|
|
81
|
+
|
|
1
82
|
### 6.6.0 (2020-04-20):
|
|
2
83
|
|
|
3
84
|
* Added support for [Infinite Tracing on New Relic
|
package/README.md
CHANGED
package/api.js
CHANGED
|
@@ -342,13 +342,13 @@ API.prototype.addCustomAttributes = function addCustomAttributes(atts) {
|
|
|
342
342
|
|
|
343
343
|
/**
|
|
344
344
|
* Add custom span attributes in an object to the current segment/span.
|
|
345
|
-
*
|
|
345
|
+
*
|
|
346
346
|
* See documentation for newrelic.addCustomSpanAttribute for more information.
|
|
347
|
-
*
|
|
347
|
+
*
|
|
348
348
|
* An example of setting a custom span attribute:
|
|
349
|
-
*
|
|
349
|
+
*
|
|
350
350
|
* newrelic.addCustomSpanAttribute({test: 'value', test2: 'value2'})
|
|
351
|
-
*
|
|
351
|
+
*
|
|
352
352
|
* @param {object} [atts]
|
|
353
353
|
* @param {string} [atts.KEY] The name you want displayed in the RPM UI.API.
|
|
354
354
|
* @param {string} [atts.KEY.VALUE] The value you want displayed. Must be serializable.
|
|
@@ -396,7 +396,7 @@ API.prototype.addCustomSpanAttribute = function addCustomSpanAttribute(key, valu
|
|
|
396
396
|
}
|
|
397
397
|
|
|
398
398
|
const segment = this.agent.tracer.getSegment()
|
|
399
|
-
|
|
399
|
+
|
|
400
400
|
if (!segment) {
|
|
401
401
|
return logger.debug(
|
|
402
402
|
'Could not add attribute %s. No available span/segment.',
|
|
@@ -1344,31 +1344,37 @@ function instrumentLoadedModule(moduleName, module) {
|
|
|
1344
1344
|
NAMES.SUPPORTABILITY.API + '/instrumentLoadedModule'
|
|
1345
1345
|
)
|
|
1346
1346
|
metric.incrementCallCount()
|
|
1347
|
+
try {
|
|
1348
|
+
const instrumentationName = shimmer.getInstrumentationNameFromModuleName(moduleName)
|
|
1349
|
+
if (!shimmer.registeredInstrumentations[instrumentationName]) {
|
|
1350
|
+
logger.warn("No instrumentation registered for '%s'.", instrumentationName)
|
|
1351
|
+
return false
|
|
1352
|
+
}
|
|
1347
1353
|
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
const instrumentation = shimmer.registeredInstrumentations[instrumentationName]
|
|
1355
|
-
if (!instrumentation.onRequire) {
|
|
1356
|
-
logger.warn("No onRequire function registered for '%s'.", instrumentationName)
|
|
1357
|
-
return false
|
|
1358
|
-
}
|
|
1354
|
+
const instrumentation = shimmer.registeredInstrumentations[instrumentationName]
|
|
1355
|
+
if (!instrumentation.onRequire) {
|
|
1356
|
+
logger.warn("No onRequire function registered for '%s'.", instrumentationName)
|
|
1357
|
+
return false
|
|
1358
|
+
}
|
|
1359
1359
|
|
|
1360
|
-
|
|
1360
|
+
const resolvedName = require.resolve(moduleName)
|
|
1361
1361
|
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1362
|
+
const shim = shims.createShimFromType(
|
|
1363
|
+
instrumentation.type,
|
|
1364
|
+
this.agent,
|
|
1365
|
+
moduleName,
|
|
1366
|
+
resolvedName
|
|
1367
|
+
)
|
|
1368
1368
|
|
|
1369
|
-
|
|
1369
|
+
instrumentation.onRequire(shim, module, moduleName)
|
|
1370
1370
|
|
|
1371
|
-
|
|
1371
|
+
return true
|
|
1372
|
+
} catch (error) {
|
|
1373
|
+
logger.error(
|
|
1374
|
+
'instrumentLoadedModule encountered an error, module not instrumentend: %s',
|
|
1375
|
+
error
|
|
1376
|
+
)
|
|
1377
|
+
}
|
|
1372
1378
|
}
|
|
1373
1379
|
|
|
1374
1380
|
/**
|
|
@@ -21,5 +21,14 @@ fi
|
|
|
21
21
|
|
|
22
22
|
export AGENT_PATH=`pwd`
|
|
23
23
|
|
|
24
|
+
# @koa/router 8.03+ breaks segment naming for nested routes
|
|
25
|
+
skip="koa"
|
|
26
|
+
|
|
27
|
+
# Don't run the aws-sdk tests if we don't have the keys set
|
|
28
|
+
if [[ -z "$AWS_ACCESS_KEY_ID" ]]; then
|
|
29
|
+
skip="${skip},aws-sdk"
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
|
|
24
33
|
# This is meant to be temporary. Remove once new major version with fixes rolled into agent.
|
|
25
|
-
time ./node_modules/.bin/versioned-tests $VERSIONED_MODE -i 2 -s
|
|
34
|
+
time ./node_modules/.bin/versioned-tests $VERSIONED_MODE -i 2 -s $skip ${directories[@]}
|
package/bin/ssl.sh
CHANGED
|
@@ -8,7 +8,7 @@ set -x # be chatty and show the lines we're running
|
|
|
8
8
|
# that are mysterious and not understood, so let
|
|
9
9
|
# bail early if we detect that's the case
|
|
10
10
|
ENGINE_OPENSSL=`openssl version | awk '{print $(1)}'`
|
|
11
|
-
if [ "$ENGINE_OPENSSL"
|
|
11
|
+
if [ "$ENGINE_OPENSSL" = "LibreSSL" ]
|
|
12
12
|
then
|
|
13
13
|
echo "LibreSSL is not supported, please install a stock openssl and \n"
|
|
14
14
|
echo "make sure that openssl binary is in your PATH"
|
|
@@ -25,7 +25,7 @@ CERTIFICATE="test/lib/self-signed-test-certificate.crt"
|
|
|
25
25
|
|
|
26
26
|
# USAGE: ./bin/ssl.sh clear
|
|
27
27
|
# a sub command to remove all the generated files and start over
|
|
28
|
-
if [ "$1"
|
|
28
|
+
if [ "$1" = "clear" ]
|
|
29
29
|
then
|
|
30
30
|
rm $SSLKEY
|
|
31
31
|
rm $CACERT
|
|
@@ -37,7 +37,7 @@ fi
|
|
|
37
37
|
|
|
38
38
|
# if there's already a certificate, then exit, but
|
|
39
39
|
# exit with a success code so build continue
|
|
40
|
-
if [ -
|
|
40
|
+
if [ -e $CERTIFICATE ]; then
|
|
41
41
|
exit 0;
|
|
42
42
|
fi
|
|
43
43
|
|
package/lib/config/default.js
CHANGED
|
@@ -891,16 +891,24 @@ exports.config = () => ({
|
|
|
891
891
|
trace_observer: {
|
|
892
892
|
/**
|
|
893
893
|
* The URI HOST of the observer. Setting this enables infinite tracing.
|
|
894
|
-
*
|
|
894
|
+
*
|
|
895
895
|
* @env NEW_RELIC_INFINITE_TRACING_TRACE_OBSERVER_HOST
|
|
896
896
|
*/
|
|
897
897
|
host: '',
|
|
898
898
|
/**
|
|
899
899
|
* The URI PORT of the observer.
|
|
900
|
-
*
|
|
900
|
+
*
|
|
901
901
|
* @env NEW_RELIC_INFINITE_TRACING_TRACE_OBSERVER_PORT
|
|
902
902
|
*/
|
|
903
903
|
port: '443'
|
|
904
|
+
},
|
|
905
|
+
span_events: {
|
|
906
|
+
/**
|
|
907
|
+
* The amount of spans to hold onto before dropping them
|
|
908
|
+
*
|
|
909
|
+
* @env NEW_RELIC_INFINITE_TRACING_SPAN_EVENTS_QUEUE_SIZE
|
|
910
|
+
*/
|
|
911
|
+
queue_size: 10000
|
|
904
912
|
}
|
|
905
913
|
},
|
|
906
914
|
|
package/lib/config/env.js
CHANGED
|
@@ -157,7 +157,8 @@ const ENV_MAPPING = {
|
|
|
157
157
|
trace_observer: {
|
|
158
158
|
host: 'NEW_RELIC_INFINITE_TRACING_TRACE_OBSERVER_HOST',
|
|
159
159
|
port: 'NEW_RELIC_INFINITE_TRACING_TRACE_OBSERVER_PORT'
|
|
160
|
-
}
|
|
160
|
+
},
|
|
161
|
+
queue_size: 'NEW_RELIC_INFINITE_TRACING_QUEUE_SIZE'
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
|
|
@@ -245,7 +246,8 @@ const FLOAT_VARS = new Set([
|
|
|
245
246
|
|
|
246
247
|
const INT_VARS = new Set([
|
|
247
248
|
'NEW_RELIC_EXPLAIN_THRESHOLD',
|
|
248
|
-
'NEW_RELIC_MAX_SQL_SAMPLES'
|
|
249
|
+
'NEW_RELIC_MAX_SQL_SAMPLES',
|
|
250
|
+
'NEW_RELIC_INFINITE_TRACING_SPAN_EVENTS_QUEUE_SIZE'
|
|
249
251
|
])
|
|
250
252
|
|
|
251
253
|
exports.ENV_MAPPING = ENV_MAPPING
|
package/lib/config/index.js
CHANGED
|
@@ -1323,6 +1323,10 @@ Config.prototype._canonicalize = function _canonicalize() {
|
|
|
1323
1323
|
|
|
1324
1324
|
this.serverless_mode.enabled = this.serverless_mode.enabled
|
|
1325
1325
|
&& this.feature_flag.serverless_mode
|
|
1326
|
+
|
|
1327
|
+
if (this.license_key) {
|
|
1328
|
+
this.license_key = this.license_key.trim()
|
|
1329
|
+
}
|
|
1326
1330
|
}
|
|
1327
1331
|
|
|
1328
1332
|
function _parseCodes(codes) {
|
|
@@ -193,6 +193,12 @@ class ErrorCollector {
|
|
|
193
193
|
return
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
+
const shouldCollectErrors = this._shouldCollectErrors()
|
|
197
|
+
if (!shouldCollectErrors) {
|
|
198
|
+
logger.trace('error_collector.enabled is false, dropping application error.')
|
|
199
|
+
return
|
|
200
|
+
}
|
|
201
|
+
|
|
196
202
|
if (errorHelper.shouldIgnoreError(transaction, error, this.config)) {
|
|
197
203
|
logger.trace('Ignoring error')
|
|
198
204
|
return
|
|
@@ -223,7 +229,15 @@ class ErrorCollector {
|
|
|
223
229
|
* @param {Exception} exception The Exception to be traced.
|
|
224
230
|
*/
|
|
225
231
|
addUserError(transaction, error, customAttributes) {
|
|
226
|
-
if (!error)
|
|
232
|
+
if (!error) {
|
|
233
|
+
return
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const shouldCollectErrors = this._shouldCollectErrors()
|
|
237
|
+
if (!shouldCollectErrors) {
|
|
238
|
+
logger.trace('error_collector.enabled is false, dropping user reported error.')
|
|
239
|
+
return
|
|
240
|
+
}
|
|
227
241
|
|
|
228
242
|
const timestamp = Date.now()
|
|
229
243
|
const exception = new Exception({error, timestamp, customAttributes})
|
|
@@ -270,18 +284,6 @@ class ErrorCollector {
|
|
|
270
284
|
return false
|
|
271
285
|
}
|
|
272
286
|
|
|
273
|
-
// allow enabling & disabling the error tracer at runtime
|
|
274
|
-
// TODO: it would be better to check config in the public add() to prevents collecting
|
|
275
|
-
// errors on the transaction unnecessarily. Should we allow the work above or
|
|
276
|
-
// short-circuit sooner?
|
|
277
|
-
if (
|
|
278
|
-
!this.config.collect_errors ||
|
|
279
|
-
!this.config.error_collector ||
|
|
280
|
-
!this.config.error_collector.enabled
|
|
281
|
-
) {
|
|
282
|
-
return false
|
|
283
|
-
}
|
|
284
|
-
|
|
285
287
|
if (exception.error) {
|
|
286
288
|
logger.trace(exception.error, 'Got exception to trace:')
|
|
287
289
|
}
|
|
@@ -304,7 +306,10 @@ class ErrorCollector {
|
|
|
304
306
|
}
|
|
305
307
|
}
|
|
306
308
|
|
|
307
|
-
|
|
309
|
+
// defaults true in config/index. can be modified server-side
|
|
310
|
+
if (this.config.collect_errors) {
|
|
311
|
+
this.traceAggregator.add(errorTrace)
|
|
312
|
+
}
|
|
308
313
|
|
|
309
314
|
if (this.config.error_collector.capture_events === true) {
|
|
310
315
|
const priority = transaction && transaction.priority || Math.random()
|
|
@@ -328,6 +333,17 @@ class ErrorCollector {
|
|
|
328
333
|
this.seenObjectsByTransaction = Object.create(null)
|
|
329
334
|
}
|
|
330
335
|
|
|
336
|
+
_shouldCollectErrors() {
|
|
337
|
+
const errorCollectorEnabled =
|
|
338
|
+
this.config.error_collector && this.config.error_collector.enabled
|
|
339
|
+
|
|
340
|
+
const shouldCaptureTraceOrEvent =
|
|
341
|
+
this.config.collect_errors || // are traces enabled
|
|
342
|
+
(this.config.error_collector && this.config.error_collector.capture_events)
|
|
343
|
+
|
|
344
|
+
return errorCollectorEnabled && shouldCaptureTraceOrEvent
|
|
345
|
+
}
|
|
346
|
+
|
|
331
347
|
reconfigure(config) {
|
|
332
348
|
this.config = config
|
|
333
349
|
|
|
@@ -117,28 +117,30 @@ function wrapEmitWithTransaction(agent, emit, isHTTPS) {
|
|
|
117
117
|
transaction.queueTime = Date.now() - queueTimeStamp
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
const synthHeader = request.headers[NEWRELIC_SYNTHETICS_HEADER]
|
|
121
|
+
|
|
122
|
+
if (synthHeader && agent.config.trusted_account_ids && agent.config.encoding_key) {
|
|
123
|
+
handleSyntheticsHeader(
|
|
124
|
+
synthHeader,
|
|
125
|
+
agent.config.encoding_key,
|
|
126
|
+
agent.config.trusted_account_ids,
|
|
127
|
+
transaction
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
120
131
|
if (agent.config.distributed_tracing.enabled) {
|
|
121
132
|
// Node http headers are automatically lowercase
|
|
122
133
|
transaction.acceptDistributedTraceHeaders(transport, request.headers)
|
|
123
134
|
} else if (agent.config.cross_application_tracer.enabled) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
cat.handleCatHeaders(incomingCatId, obfTransaction, encKey, transaction)
|
|
135
|
+
const incomingCatId = request.headers[NEWRELIC_ID_HEADER]
|
|
136
|
+
const obfTransaction = request.headers[NEWRELIC_TRANSACTION_HEADER]
|
|
137
|
+
|
|
138
|
+
if (agent.config.encoding_key) {
|
|
139
|
+
cat.handleCatHeaders(incomingCatId, obfTransaction, agent.config.encoding_key, transaction)
|
|
130
140
|
if (transaction.incomingCatId) {
|
|
131
141
|
logger.trace('Got inbound request CAT headers in transaction %s',
|
|
132
142
|
transaction.id)
|
|
133
143
|
}
|
|
134
|
-
if (synthHeader && agent.config.trusted_account_ids) {
|
|
135
|
-
handleSyntheticsHeader(
|
|
136
|
-
synthHeader,
|
|
137
|
-
encKey,
|
|
138
|
-
agent.config.trusted_account_ids,
|
|
139
|
-
transaction
|
|
140
|
-
)
|
|
141
|
-
}
|
|
142
144
|
}
|
|
143
145
|
}
|
|
144
146
|
|
|
@@ -4,7 +4,7 @@ var EventEmitter = require('events').EventEmitter
|
|
|
4
4
|
var util = require('util')
|
|
5
5
|
var logger = require('../logger').child({component: 'metric_normalizer'})
|
|
6
6
|
var deepEqual = require('../util/deep-equal')
|
|
7
|
-
var
|
|
7
|
+
var NormalizerRule = require('./normalizer/rule')
|
|
8
8
|
var NAMES = require('../metrics/names.js')
|
|
9
9
|
|
|
10
10
|
|
|
@@ -82,7 +82,7 @@ MetricNormalizer.prototype.load = function load(json) {
|
|
|
82
82
|
|
|
83
83
|
json.forEach(function cb_forEach(ruleJSON) {
|
|
84
84
|
// no need to add the same rule twice
|
|
85
|
-
var rule = new
|
|
85
|
+
var rule = new NormalizerRule(ruleJSON)
|
|
86
86
|
if (!this.rules.find(deepEqual.bind(null, rule))) {
|
|
87
87
|
this.rules.push(rule)
|
|
88
88
|
logger.trace("Loaded %s normalization rule: %s", this.type, rule)
|
|
@@ -142,9 +142,9 @@ MetricNormalizer.prototype.loadFromConfig = function loadFromConfig() {
|
|
|
142
142
|
: r.precedence > json.eval_order
|
|
143
143
|
})
|
|
144
144
|
if (insert === -1) {
|
|
145
|
-
this.rules.push(new
|
|
145
|
+
this.rules.push(new NormalizerRule(json))
|
|
146
146
|
} else {
|
|
147
|
-
this.rules.splice(insert, 0, new
|
|
147
|
+
this.rules.splice(insert, 0, new NormalizerRule(json))
|
|
148
148
|
}
|
|
149
149
|
}, this)
|
|
150
150
|
}
|
|
@@ -186,7 +186,7 @@ MetricNormalizer.prototype.addSimple = function addSimple(pattern, name) {
|
|
|
186
186
|
json.ignore = true
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
this.rules.unshift(new
|
|
189
|
+
this.rules.unshift(new NormalizerRule(json))
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
/**
|
package/lib/shim/shim.js
CHANGED
|
@@ -989,9 +989,9 @@ function record(nodule, properties, recordNamer) {
|
|
|
989
989
|
})
|
|
990
990
|
|
|
991
991
|
// Apply the function, and (if it returned a stream) bind that too.
|
|
992
|
-
//
|
|
993
|
-
//
|
|
994
|
-
//
|
|
992
|
+
// The reason there is no check for `segment` is because it should
|
|
993
|
+
// be guaranteed by the parent and active transaction check
|
|
994
|
+
// at the beginning of this function.
|
|
995
995
|
var ret = _applyRecorderSegment(segment, this, args, segDesc)
|
|
996
996
|
if (ret) {
|
|
997
997
|
if (segDesc.stream) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
class SpanContext {
|
|
4
|
+
constructor(intrinsicAttributes) {
|
|
5
|
+
this.intrinsicAttributes = intrinsicAttributes || Object.create(null)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
addIntrinsicAttribute(key, value) {
|
|
9
|
+
this.intrinsicAttributes[key] = value
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = SpanContext
|
package/lib/spans/span-event.js
CHANGED
|
@@ -91,6 +91,11 @@ class SpanEvent {
|
|
|
91
91
|
span = new SpanEvent(attributes, customAttributes)
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
const spanContext = segment.getSpanContext()
|
|
95
|
+
for (const [key, value] of Object.entries(spanContext.intrinsicAttributes)) {
|
|
96
|
+
span.intrinsics[key] = value
|
|
97
|
+
}
|
|
98
|
+
|
|
94
99
|
const tx = segment.transaction
|
|
95
100
|
|
|
96
101
|
span.intrinsics.traceId = tx.traceId
|
|
@@ -1,94 +1,128 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const logger = require('../logger').child({component: 'span-streamer'})
|
|
4
|
+
const NAMES = require('../metrics/names').INFINITE_TRACING
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
+
const SPAN_DROP_MSG =
|
|
7
|
+
'Queue full, dropping spans.'
|
|
8
|
+
const SPAN_DROP_INTERVAL = 5
|
|
6
9
|
|
|
7
|
-
const NO_STREAM_WARNING =
|
|
8
|
-
'Attempting to stream spans before connection created. ' +
|
|
9
|
-
'This warning will not appear again this agent run.'
|
|
10
|
-
|
|
11
|
-
const BACK_PRESSURE_WARNING =
|
|
12
|
-
'Back pressure detected in SpanStreamer! Spans will be dropped until the current batch ' +
|
|
13
|
-
'has fully sent. Will not warn again for %s seconds.'
|
|
14
|
-
const BACK_PRESSURE_WARNING_INTERVAL = 60 // in seconds
|
|
15
|
-
|
|
16
|
-
const BACK_PRESSURE_STOP = 'Back pressure has ended, continuing to stream'
|
|
17
10
|
|
|
18
11
|
class SpanStreamer {
|
|
19
|
-
constructor(license_key, connection, metrics) {
|
|
12
|
+
constructor(license_key, connection, metrics, queue_size) {
|
|
20
13
|
this.stream = null
|
|
21
14
|
this.license_key = license_key
|
|
22
15
|
this.connection = connection
|
|
16
|
+
this.queue_size = queue_size
|
|
17
|
+
this.spans = []
|
|
23
18
|
this._metrics = metrics
|
|
24
19
|
this._writable = false
|
|
25
20
|
|
|
26
21
|
// 'connected' indicates a safely writeable stream.
|
|
27
22
|
// May still be mid-connect to gRPC server.
|
|
28
23
|
this.connection.on('connected', (stream) =>{
|
|
24
|
+
logger.info('Span streamer connected')
|
|
29
25
|
this.stream = stream
|
|
30
26
|
this._writable = true
|
|
27
|
+
this.sendQueue()
|
|
31
28
|
})
|
|
32
29
|
|
|
33
30
|
this.connection.on('disconnected', () =>{
|
|
31
|
+
logger.info('Span streamer disconnected')
|
|
34
32
|
this.stream = null
|
|
35
33
|
this._writable = false
|
|
36
34
|
})
|
|
37
35
|
}
|
|
38
36
|
|
|
37
|
+
/* Accepts a span and either writes it to the stream, queues it to be sent,
|
|
38
|
+
* or drops it depending on stream/queue state
|
|
39
|
+
*/
|
|
39
40
|
write(span) {
|
|
40
|
-
|
|
41
|
-
logger.warnOnce(NO_STREAM_WARNING)
|
|
42
|
-
return false
|
|
43
|
-
}
|
|
41
|
+
this._metrics.getOrCreateMetric(NAMES.SEEN).incrementCallCount()
|
|
44
42
|
|
|
43
|
+
// If not writeable (because of backpressure) queue the span
|
|
45
44
|
if (!this._writable) {
|
|
46
|
-
|
|
45
|
+
if (this.spans.length <= this.queue_size) {
|
|
46
|
+
this.spans.push(span)
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// If the queue is full drop the span
|
|
51
|
+
logger.infoOncePer(
|
|
52
|
+
// key for the OncePer
|
|
53
|
+
'SPAN_DROP_MSG',
|
|
54
|
+
// interval in ms
|
|
55
|
+
SPAN_DROP_INTERVAL * 1000,
|
|
56
|
+
// message
|
|
57
|
+
SPAN_DROP_MSG + ' Will not warn again for %s seconds.',
|
|
58
|
+
// variables to put in log message
|
|
59
|
+
SPAN_DROP_INTERVAL
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
return
|
|
47
63
|
}
|
|
48
64
|
|
|
49
65
|
const formattedSpan = span.toStreamingFormat()
|
|
50
66
|
|
|
51
67
|
try {
|
|
52
|
-
|
|
53
|
-
// and future writes should be avoided until drained. written items,
|
|
54
|
-
// including the one that returned false, will still be buffered.
|
|
55
|
-
this._writable = this.stream.write(formattedSpan)
|
|
56
|
-
|
|
57
|
-
if (!this._writable) {
|
|
58
|
-
logger.infoOncePer(
|
|
59
|
-
'BACK_PRESSURE_START',
|
|
60
|
-
BACK_PRESSURE_WARNING_INTERVAL * 1000,
|
|
61
|
-
BACK_PRESSURE_WARNING,
|
|
62
|
-
BACK_PRESSURE_WARNING_INTERVAL
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
const waitDrainStart = Date.now()
|
|
66
|
-
|
|
67
|
-
this.stream.once('drain', () => {
|
|
68
|
-
const drainCompleted = Date.now()
|
|
69
|
-
const drainDurationMs = drainCompleted - waitDrainStart
|
|
70
|
-
|
|
71
|
-
// Metric can be used to see how frequently completing drains
|
|
72
|
-
// as well as average time to drain from when we first notice.
|
|
73
|
-
this._metrics.getOrCreateMetric(NAMES.INFINITE_TRACING.DRAIN_DURATION)
|
|
74
|
-
.recordValue(drainDurationMs / 1000)
|
|
75
|
-
|
|
76
|
-
logger.trace(BACK_PRESSURE_STOP)
|
|
77
|
-
this._writable = true
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// span was added to internal node stream buffer to be sent while draining
|
|
82
|
-
// so we return true even when we should not write anymore afterwards
|
|
83
|
-
return true
|
|
68
|
+
this.send(formattedSpan)
|
|
84
69
|
} catch (err) {
|
|
85
|
-
logger.
|
|
70
|
+
logger.error(err)
|
|
86
71
|
// TODO: something has gone horribly wrong.
|
|
87
72
|
// We may want to log and turn off this aggregator
|
|
88
73
|
// to prevent sending further spans. Maybe even "disable" their creation?
|
|
89
74
|
// or is there a situation where we can recover?
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Sends the span over the stream. Spans are only sent here if the stream is
|
|
80
|
+
* in a writable state. If the stream becomes unwritable after sending the
|
|
81
|
+
* span, a drain event handler is setup to continue writing when possible.
|
|
82
|
+
*/
|
|
83
|
+
send(span) {
|
|
84
|
+
// false indicates the stream has reached the highWaterMark
|
|
85
|
+
// and future writes should be avoided until drained. written items,
|
|
86
|
+
// including the one that returned false, will still be buffered.
|
|
87
|
+
this._writable = this.stream.write(span)
|
|
88
|
+
this._metrics.getOrCreateMetric(NAMES.SENT).incrementCallCount()
|
|
89
|
+
|
|
90
|
+
if (!this._writable) {
|
|
91
|
+
const waitDrainStart = Date.now()
|
|
92
|
+
const onDrain = this.drain.bind(this, waitDrainStart)
|
|
93
|
+
this.stream.once('drain', onDrain)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Drains the span queue that built up when the connection was
|
|
99
|
+
* back-pressured or disconnected. `waitDrainStart` is when the stream
|
|
100
|
+
* initially blocked, used to time how long the stream was blocked. If this
|
|
101
|
+
* is not defined, it is assumed this is being called after a reconnect,
|
|
102
|
+
* and the metric is not used.
|
|
103
|
+
*/
|
|
104
|
+
drain(waitDrainStart) {
|
|
105
|
+
// Metric can be used to see how frequently completing drains as well as
|
|
106
|
+
// average time to drain from when we first notice.
|
|
107
|
+
const drainCompleted = Date.now()
|
|
108
|
+
const drainDurationMs = drainCompleted - waitDrainStart
|
|
109
|
+
this._metrics.getOrCreateMetric(NAMES.DRAIN_DURATION)
|
|
110
|
+
.recordValue(drainDurationMs / 1000)
|
|
111
|
+
|
|
112
|
+
// Once the 'drain' event fires we can begin writing to the stream again
|
|
113
|
+
this._writable = true
|
|
114
|
+
|
|
115
|
+
this.sendQueue()
|
|
116
|
+
}
|
|
90
117
|
|
|
91
|
-
|
|
118
|
+
sendQueue() {
|
|
119
|
+
// Continue sending the spans that were in the queue. _writable is checked
|
|
120
|
+
// so that if a send fails while clearing the queue, this drain handler can
|
|
121
|
+
// finish, and the drain handler setup on the failed send will then attempt
|
|
122
|
+
// to clear the queue
|
|
123
|
+
while (this.spans.length > 0 && this._writable) {
|
|
124
|
+
const nextObject = this.spans.shift()
|
|
125
|
+
this.send(nextObject)
|
|
92
126
|
}
|
|
93
127
|
}
|
|
94
128
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const Aggregator = require('../aggregators/base-aggregator')
|
|
4
4
|
const StreamingSpanEvent = require('./streaming-span-event')
|
|
5
|
-
const NAMES = require('../metrics/names')
|
|
6
5
|
const logger = require('../logger').child({component: 'streaming-span-event-aggregator'})
|
|
7
6
|
|
|
8
7
|
const SEND_WARNING =
|
|
@@ -20,7 +19,6 @@ class StreamingSpanEventAggregator extends Aggregator {
|
|
|
20
19
|
|
|
21
20
|
super(opts, collector)
|
|
22
21
|
|
|
23
|
-
this.metricNames = opts.metricNames || NAMES.INFINITE_TRACING
|
|
24
22
|
this.stream = opts.span_streamer
|
|
25
23
|
this.metrics = metrics
|
|
26
24
|
this.started = false
|
|
@@ -82,16 +80,8 @@ class StreamingSpanEventAggregator extends Aggregator {
|
|
|
82
80
|
return
|
|
83
81
|
}
|
|
84
82
|
|
|
85
|
-
// SEEN/SENT are to understand where we've had to drop spans due back-pressure, errors,
|
|
86
|
-
// reconnects, etc. so moving after start check to avoid logging for a
|
|
87
|
-
// currently unsupported case.
|
|
88
|
-
this.metrics.getOrCreateMetric(this.metricNames.SEEN).incrementCallCount()
|
|
89
|
-
|
|
90
83
|
const span = StreamingSpanEvent.fromSegment(segment, parentId, isRoot)
|
|
91
|
-
|
|
92
|
-
if (this.stream.write(span)) {
|
|
93
|
-
this.metrics.getOrCreateMetric(this.metricNames.SENT).incrementCallCount()
|
|
94
|
-
}
|
|
84
|
+
this.stream.write(span)
|
|
95
85
|
}
|
|
96
86
|
}
|
|
97
87
|
|
|
@@ -112,6 +112,11 @@ class StreamingSpanEvent {
|
|
|
112
112
|
span = new StreamingSpanEvent(traceId, agentAttributes, customAttributes)
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
const spanContext = segment.getSpanContext()
|
|
116
|
+
for (const [key, value] of Object.entries(spanContext.intrinsicAttributes)) {
|
|
117
|
+
span.addIntrinsicAttribute(key, value)
|
|
118
|
+
}
|
|
119
|
+
|
|
115
120
|
span.addIntrinsicAttribute('guid', segment.id)
|
|
116
121
|
span.addIntrinsicAttribute('parentId', parentId)
|
|
117
122
|
span.addIntrinsicAttribute('transactionId', transaction.id)
|
package/lib/transaction/index.js
CHANGED
|
@@ -381,8 +381,10 @@ Transaction.prototype.isIgnored = function getIgnore() {
|
|
|
381
381
|
*/
|
|
382
382
|
Transaction.prototype.finalizeNameFromUri = finalizeNameFromUri
|
|
383
383
|
function finalizeNameFromUri(requestURL, statusCode) {
|
|
384
|
-
logger.
|
|
385
|
-
|
|
384
|
+
if (logger.traceEnabled()) {
|
|
385
|
+
logger.trace({requestURL: requestURL, statusCode: statusCode, transactionId: this.id,
|
|
386
|
+
transactionName: this.name}, 'Setting transaction name')
|
|
387
|
+
}
|
|
386
388
|
|
|
387
389
|
this.url = urltils.scrub(requestURL)
|
|
388
390
|
this.statusCode = statusCode
|
|
@@ -426,11 +428,26 @@ function finalizeNameFromUri(requestURL, statusCode) {
|
|
|
426
428
|
}
|
|
427
429
|
|
|
428
430
|
this.baseSegment && this._markAsWeb(requestURL)
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
431
|
+
|
|
432
|
+
this._copyNameToActiveSpan(this.name)
|
|
433
|
+
|
|
434
|
+
if (logger.traceEnabled()) {
|
|
435
|
+
logger.trace({
|
|
436
|
+
transactionId: this.id,
|
|
437
|
+
transactionName: this.name,
|
|
438
|
+
ignore: this.ignore
|
|
439
|
+
}, 'Finished setting transaction name from Uri')
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
Transaction.prototype._copyNameToActiveSpan = function _copyNameToActiveSpan(name) {
|
|
444
|
+
const spanContext = this.agent.tracer.getSpanContext()
|
|
445
|
+
if (!spanContext) {
|
|
446
|
+
logger.trace('Span context not available, not adding transaction.name attribute for %s', name)
|
|
447
|
+
return
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
spanContext.addIntrinsicAttribute('transaction.name', name)
|
|
434
451
|
}
|
|
435
452
|
|
|
436
453
|
/**
|
|
@@ -490,11 +507,15 @@ Transaction.prototype.finalizeName = function finalizeName(name) {
|
|
|
490
507
|
|
|
491
508
|
this.baseSegment && this.baseSegment.setNameFromTransaction()
|
|
492
509
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
510
|
+
this._copyNameToActiveSpan(this.name)
|
|
511
|
+
|
|
512
|
+
if (logger.traceEnabled()) {
|
|
513
|
+
logger.trace({
|
|
514
|
+
transactionId: this.id,
|
|
515
|
+
transactionName: this.name,
|
|
516
|
+
ignore: this.ignore
|
|
517
|
+
}, 'Finished setting transaction name from string')
|
|
518
|
+
}
|
|
498
519
|
}
|
|
499
520
|
|
|
500
521
|
/**
|
|
@@ -692,11 +713,21 @@ function _linkExceptionToSegment(exception) {
|
|
|
692
713
|
return
|
|
693
714
|
}
|
|
694
715
|
|
|
716
|
+
const config = this.agent.config
|
|
717
|
+
|
|
695
718
|
// Add error attributes to the span
|
|
696
|
-
const details = exception.getErrorDetails(
|
|
719
|
+
const details = exception.getErrorDetails(config)
|
|
697
720
|
segment.addAttribute('error.message', details.message)
|
|
698
721
|
segment.addAttribute('error.class', details.type)
|
|
699
722
|
|
|
723
|
+
const isExpected =
|
|
724
|
+
errorHelper.isExpectedErrorClass(config, details.type) ||
|
|
725
|
+
errorHelper.isExpectedErrorMessage(config, details.type, details.message)
|
|
726
|
+
|
|
727
|
+
if (isExpected) {
|
|
728
|
+
segment.addAttribute('error.expected', isExpected)
|
|
729
|
+
}
|
|
730
|
+
|
|
700
731
|
// Add the span/segment ID to the exception as agent attributes
|
|
701
732
|
exception.agentAttributes.spanId = segment.id
|
|
702
733
|
}
|
|
@@ -8,6 +8,7 @@ const hashes = require('../../util/hashes')
|
|
|
8
8
|
|
|
9
9
|
const {Attributes, MAXIMUM_CUSTOM_ATTRIBUTES} = require('../../attributes')
|
|
10
10
|
const ExclusiveCalculator = require('./exclusive-time-calculator')
|
|
11
|
+
const SpanContext = require('../../spans/span-context')
|
|
11
12
|
|
|
12
13
|
const NAMES = require('../../metrics/names')
|
|
13
14
|
const INSTANCE_UNKNOWN = 'unknown'
|
|
@@ -77,6 +78,17 @@ function TraceSegment(transaction, name, recorder) {
|
|
|
77
78
|
this.probe('new TraceSegment')
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
TraceSegment.prototype.getSpanContext = function getSpanContext() {
|
|
82
|
+
const config = this.transaction.agent.config
|
|
83
|
+
const spansEnabled = config.distributed_tracing.enabled && config.span_events.enabled
|
|
84
|
+
|
|
85
|
+
if (!this._spanContext && spansEnabled) {
|
|
86
|
+
this._spanContext = new SpanContext()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return this._spanContext
|
|
90
|
+
}
|
|
91
|
+
|
|
80
92
|
TraceSegment.prototype.addAttribute =
|
|
81
93
|
function addAttribute(key, value, truncateExempt = false) {
|
|
82
94
|
this.attributes.addAttribute(
|
|
@@ -91,7 +103,7 @@ TraceSegment.prototype.getAttributes = function getAttributes() {
|
|
|
91
103
|
return this.attributes.get(DESTINATIONS.TRANS_SEGMENT)
|
|
92
104
|
}
|
|
93
105
|
|
|
94
|
-
TraceSegment.prototype.addCustomSpanAttribute =
|
|
106
|
+
TraceSegment.prototype.addCustomSpanAttribute =
|
|
95
107
|
function addCustomSpanAttribute(key, value, truncateExempt = false) {
|
|
96
108
|
this.customAttributes.addAttribute(
|
|
97
109
|
DESTINATIONS.SPAN_EVENT,
|
|
@@ -21,6 +21,7 @@ function Tracer(agent) {
|
|
|
21
21
|
|
|
22
22
|
Tracer.prototype.getTransaction = getTransaction
|
|
23
23
|
Tracer.prototype.getSegment = getSegment
|
|
24
|
+
Tracer.prototype.getSpanContext = getSpanContext
|
|
24
25
|
Tracer.prototype.createSegment = createSegment
|
|
25
26
|
Tracer.prototype.addSegment = addSegment
|
|
26
27
|
Tracer.prototype.transactionProxy = transactionProxy
|
|
@@ -61,6 +62,10 @@ function getSegment() {
|
|
|
61
62
|
return this.segment
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
function getSpanContext() {
|
|
66
|
+
return this.segment && this.segment.getSpanContext()
|
|
67
|
+
}
|
|
68
|
+
|
|
64
69
|
function createSegment(name, recorder, _parent) {
|
|
65
70
|
var parent = _parent || this.segment
|
|
66
71
|
if (!parent || !parent.transaction.isActive()) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newrelic",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.9.0",
|
|
4
4
|
"author": "New Relic Node.js agent team <nodejs@newrelic.com>",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"contributors": [
|
|
@@ -83,6 +83,21 @@
|
|
|
83
83
|
"name": "Michael Goin",
|
|
84
84
|
"email": "mgoin@newrelic.com",
|
|
85
85
|
"web": "https://newrelic.com"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"name": "Alan Storm",
|
|
89
|
+
"email": "astorm@newrelic.com",
|
|
90
|
+
"web": "https://newrelic.com"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "Carlo Pearson",
|
|
94
|
+
"email": "cpearson@newrelic.com",
|
|
95
|
+
"web": "https://newrelic.com"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"name": "Nick Tzaperas",
|
|
99
|
+
"email": "ntzaperas@newrelic.com",
|
|
100
|
+
"web": "https://newrelic.com"
|
|
86
101
|
}
|
|
87
102
|
],
|
|
88
103
|
"description": "New Relic agent",
|
|
@@ -108,7 +123,7 @@
|
|
|
108
123
|
"clean": "./bin/clean.sh",
|
|
109
124
|
"docker-env": "./bin/docker-env-vars.sh",
|
|
110
125
|
"docs": "npm ci && jsdoc -c ./jsdoc-conf.json --private -r .",
|
|
111
|
-
"integration": "npm run prepare-test && npm run sub-install && time tap --no-esm test/integration/**/**/*.tap.js --timeout=
|
|
126
|
+
"integration": "npm run prepare-test && npm run sub-install && time tap --no-esm test/integration/**/**/*.tap.js --timeout=180 --no-coverage",
|
|
112
127
|
"prepare-test": "npm ci && npm run ca-gen && npm run ssl && npm run docker-env",
|
|
113
128
|
"lint": "eslint ./*.js lib test",
|
|
114
129
|
"public-docs": "npm ci && jsdoc -c ./jsdoc-conf.json --tutorials examples/shim api.js lib/shim/ lib/transaction/handle.js && cp examples/shim/*.png out/",
|
|
@@ -118,7 +133,7 @@
|
|
|
118
133
|
"ssl": "./bin/ssl.sh",
|
|
119
134
|
"sub-install": "node test/bin/install_sub_deps",
|
|
120
135
|
"test": "npm run integration && npm run unit",
|
|
121
|
-
"unit": "rm -f newrelic_agent.log && time tap --test-regex='(\\/|^test\\/unit\\/.*\\.test\\.js)$' --timeout=
|
|
136
|
+
"unit": "rm -f newrelic_agent.log && time tap --test-regex='(\\/|^test\\/unit\\/.*\\.test\\.js)$' --timeout=180 --no-coverage",
|
|
122
137
|
"update-cross-agent-tests": "./bin/update-cats.sh",
|
|
123
138
|
"versioned-tests": "./bin/run-versioned-tests.sh",
|
|
124
139
|
"versioned": "npm run prepare-test && time ./bin/run-versioned-tests.sh"
|
|
@@ -127,27 +142,27 @@
|
|
|
127
142
|
"newrelic-naming-rules": "./bin/test-naming-rules.js"
|
|
128
143
|
},
|
|
129
144
|
"dependencies": {
|
|
130
|
-
"@grpc/grpc-js": "
|
|
131
|
-
"@grpc/proto-loader": "^0.5.
|
|
145
|
+
"@grpc/grpc-js": "1.0.3",
|
|
146
|
+
"@grpc/proto-loader": "^0.5.4",
|
|
132
147
|
"@newrelic/aws-sdk": "^1.1.1",
|
|
133
148
|
"@newrelic/koa": "^3.0.0",
|
|
134
149
|
"@newrelic/superagent": "^2.0.1",
|
|
135
150
|
"@tyriar/fibonacci-heap": "^2.0.7",
|
|
136
151
|
"async": "^2.1.4",
|
|
137
152
|
"concat-stream": "^2.0.0",
|
|
138
|
-
"escodegen": "^1.
|
|
153
|
+
"escodegen": "^1.14.1",
|
|
139
154
|
"esprima": "^4.0.1",
|
|
140
155
|
"https-proxy-agent": "^4.0.0",
|
|
141
156
|
"json-stringify-safe": "^5.0.0",
|
|
142
|
-
"readable-stream": "^3.
|
|
157
|
+
"readable-stream": "^3.6.0",
|
|
143
158
|
"semver": "^5.3.0"
|
|
144
159
|
},
|
|
145
160
|
"optionalDependencies": {
|
|
146
|
-
"@newrelic/native-metrics": "^5.
|
|
161
|
+
"@newrelic/native-metrics": "^5.1.0"
|
|
147
162
|
},
|
|
148
163
|
"devDependencies": {
|
|
149
|
-
"@newrelic/proxy": "^
|
|
150
|
-
"@newrelic/test-utilities": "^3.
|
|
164
|
+
"@newrelic/proxy": "^2.0.0",
|
|
165
|
+
"@newrelic/test-utilities": "^3.3.0",
|
|
151
166
|
"JSV": "~4.0.2",
|
|
152
167
|
"architect": "*",
|
|
153
168
|
"benchmark": "^2.1.4",
|
|
@@ -173,7 +188,7 @@
|
|
|
173
188
|
"rimraf": "^2.6.3",
|
|
174
189
|
"should": "*",
|
|
175
190
|
"sinon": "^4.5.0",
|
|
176
|
-
"tap": "^14.10.
|
|
191
|
+
"tap": "^14.10.7",
|
|
177
192
|
"temp": "^0.8.1",
|
|
178
193
|
"through": "^2.3.6",
|
|
179
194
|
"when": "*"
|
package/.eslintignore
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
**/node_modules/**
|
package/.eslintrc.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
"env": {
|
|
3
|
-
"es6": true,
|
|
4
|
-
"node": true,
|
|
5
|
-
"browser": false
|
|
6
|
-
},
|
|
7
|
-
"parserOptions": {
|
|
8
|
-
"ecmaVersion": 6
|
|
9
|
-
},
|
|
10
|
-
"ignorePatterns": ["invalid-json/"],
|
|
11
|
-
"rules": {
|
|
12
|
-
"indent": ["warn", 2, {"SwitchCase": 1}],
|
|
13
|
-
"brace-style": "error",
|
|
14
|
-
"comma-dangle": "off",
|
|
15
|
-
"comma-style": ["error", "last"],
|
|
16
|
-
"consistent-return": "off",
|
|
17
|
-
"curly": "off",
|
|
18
|
-
"eol-last": "error",
|
|
19
|
-
"eqeqeq": ["error", "smart"],
|
|
20
|
-
"camelcase": ["off", {"properties": "never"}],
|
|
21
|
-
"dot-notation": "error",
|
|
22
|
-
"func-names": "error",
|
|
23
|
-
"guard-for-in": "error",
|
|
24
|
-
"key-spacing": ["off", { "beforeColon": false }],
|
|
25
|
-
"max-len": ["error", 100, { "ignoreUrls": true }],
|
|
26
|
-
"max-nested-callbacks": ["error", 3],
|
|
27
|
-
"max-params": ["error", 5],
|
|
28
|
-
"new-cap": "error",
|
|
29
|
-
"no-console": "warn",
|
|
30
|
-
"no-debugger": "error",
|
|
31
|
-
"no-else-return": "error",
|
|
32
|
-
"no-floating-decimal": "error",
|
|
33
|
-
"no-lonely-if": "error",
|
|
34
|
-
"no-mixed-requires": "error",
|
|
35
|
-
"no-multiple-empty-lines": "error",
|
|
36
|
-
"no-multi-spaces": ["off", { "ignoreEOLComments": true }],
|
|
37
|
-
"no-new": "error",
|
|
38
|
-
"no-new-func": "warn",
|
|
39
|
-
"no-shadow": ["warn", {"allow": ["shim"]}],
|
|
40
|
-
"no-undef": "error",
|
|
41
|
-
"no-unused-vars": "error",
|
|
42
|
-
"no-use-before-define": ["off", {"functions": false}],
|
|
43
|
-
"one-var": ["off", "never"],
|
|
44
|
-
"padded-blocks": ["error", "never"],
|
|
45
|
-
"radix": "error",
|
|
46
|
-
"semi": ["error", "never"],
|
|
47
|
-
"space-before-function-paren": ["error", "never"],
|
|
48
|
-
"keyword-spacing": "error",
|
|
49
|
-
"space-before-blocks": "error",
|
|
50
|
-
"space-infix-ops": "error",
|
|
51
|
-
"spaced-comment": "error",
|
|
52
|
-
"space-unary-ops": "error",
|
|
53
|
-
"strict": "error",
|
|
54
|
-
"quote-props": [ "off", "consistent-as-needed" ],
|
|
55
|
-
"quotes": ["off", "single"],
|
|
56
|
-
"use-isnan": "error",
|
|
57
|
-
"wrap-iife": "error"
|
|
58
|
-
},
|
|
59
|
-
"overrides": [
|
|
60
|
-
{
|
|
61
|
-
"files": ["test/integration/*.tap.js", "test/integration/*/*.tap.js", "test/integration/core/exec-me.js"],
|
|
62
|
-
"rules": {
|
|
63
|
-
"no-console": ["off"]
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
]
|
|
67
|
-
}
|
package/.travis.yml
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
language: generic
|
|
2
|
-
env:
|
|
3
|
-
global:
|
|
4
|
-
- MONGODB=2.6.11
|
|
5
|
-
matrix:
|
|
6
|
-
# NODE 8
|
|
7
|
-
- NR_NODE_VERSION=8 SUITE=smoke
|
|
8
|
-
- NR_NODE_VERSION=8 SUITE=unit
|
|
9
|
-
- NR_NODE_VERSION=8 SUITE=integration
|
|
10
|
-
- NR_NODE_VERSION=8 SUITE=versioned
|
|
11
|
-
# NODE 10
|
|
12
|
-
- NR_NODE_VERSION=10 SUITE=smoke
|
|
13
|
-
- NR_NODE_VERSION=10 SUITE=unit
|
|
14
|
-
- NR_NODE_VERSION=10 SUITE=integration
|
|
15
|
-
- NR_NODE_VERSION=10 SUITE=versioned
|
|
16
|
-
# NODE 12 --
|
|
17
|
-
- NR_NODE_VERSION=12 SUITE=smoke
|
|
18
|
-
- NR_NODE_VERSION=12 SUITE=unit
|
|
19
|
-
- NR_NODE_VERSION=12 SUITE=integration
|
|
20
|
-
- NR_NODE_VERSION=12 SUITE=lint
|
|
21
|
-
- NR_NODE_VERSION=12 SUITE=versioned
|
|
22
|
-
services:
|
|
23
|
-
- memcached
|
|
24
|
-
- mysql
|
|
25
|
-
- redis
|
|
26
|
-
- postgresql
|
|
27
|
-
- rabbitmq
|
|
28
|
-
addons:
|
|
29
|
-
apt:
|
|
30
|
-
packages:
|
|
31
|
-
- rabbitmq-server
|
|
32
|
-
before_install:
|
|
33
|
-
- source ./bin/travis-node.sh
|
|
34
|
-
- ./bin/travis-setup.sh
|
|
35
|
-
install: if [ "$SUITE" != "smoke" ]; then npm ci; fi
|
|
36
|
-
cache:
|
|
37
|
-
directories:
|
|
38
|
-
- "$HOME/.npm"
|
|
39
|
-
script: npm run $SUITE
|
|
40
|
-
after_script: find /home/travis/.npm/_logs -type f -exec cat '{}' +
|