newrelic 9.11.0 → 9.12.1
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 +28 -12
- package/README.md +1 -1
- package/api.js +14 -4
- package/lib/errors/error-collector.js +20 -7
- package/lib/errors/helper.js +10 -2
- package/lib/errors/index.js +5 -9
- package/lib/instrumentation/core/http-outbound.js +9 -4
- package/lib/transaction/index.js +1 -1
- package/package.json +2 -2
package/NEWS.md
CHANGED
|
@@ -1,18 +1,34 @@
|
|
|
1
|
-
### v9.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
### v9.12.1 (2023-03-15)
|
|
2
|
+
|
|
3
|
+
* Added ability to mark errors as expected when using `newrelic.noticeError`, by adding an optional boolean:
|
|
4
|
+
* `newrelic.noticeError(error, {customAttributes}, true|false)` when there are custom error attributes.
|
|
5
|
+
* `newrelic.noticeError(error, true|false)` if there are no custom error attributes.
|
|
6
|
+
* `expected` errors do not affect error metrics or Apdex.
|
|
7
|
+
|
|
8
|
+
* Added ability to disable distributed tracing for aws-sdk >= 3.290.0.
|
|
9
|
+
|
|
10
|
+
* Updated README header image to latest OSS office required images
|
|
11
|
+
|
|
12
|
+
* updated @grpc/grpc-js from 1.8.8 to 1.8.9
|
|
13
|
+
|
|
14
|
+
### v9.12.0 (2023-03-13)
|
|
15
|
+
* Release pipeline did not complete.
|
|
16
|
+
|
|
17
|
+
### v9.11.0 (2023-03-08)
|
|
18
|
+
* Added instrumentation for Prisma(`@prisma/client`).
|
|
19
|
+
* Miniumum supported version of `@prisma/client` is 4.0.0.
|
|
20
|
+
* Captures spans for queries.
|
|
5
21
|
* It names them based on the model and action.(i.e. Datastore/statement/Prisma/user/create)
|
|
6
|
-
* For statements and queries using the `$queryRaw`, `$executeRaw`, `$queryRawUnsafe`, and `$executeRawUnsafe` the names will be aligned with the raw SQL.(i.e. Datastore/statement/Prisma/User/select)
|
|
22
|
+
* For statements and queries using the `$queryRaw`, `$executeRaw`, `$queryRawUnsafe`, and `$executeRawUnsafe` the names will be aligned with the raw SQL.(i.e. Datastore/statement/Prisma/User/select)
|
|
7
23
|
* Captures database metrics for all statements and queries.
|
|
8
|
-
* Captures SQL Traces.
|
|
24
|
+
* Captures SQL Traces.
|
|
9
25
|
* Provides connection between application and database server via service maps.
|
|
10
|
-
|
|
11
|
-
Huge shoutout to @osmanmrtacar for the original contribution 🙏🏻
|
|
12
|
-
|
|
13
|
-
* Updated `@grpc/protoloader` from 0.7.4 to 0.7.5.
|
|
14
|
-
* Updated `@grpc/grpc-js` from 1.8.7 to 1.8.8.
|
|
15
|
-
|
|
26
|
+
|
|
27
|
+
Huge shoutout to @osmanmrtacar for the original contribution 🙏🏻
|
|
28
|
+
|
|
29
|
+
* Updated `@grpc/protoloader` from 0.7.4 to 0.7.5.
|
|
30
|
+
* Updated `@grpc/grpc-js` from 1.8.7 to 1.8.8.
|
|
31
|
+
|
|
16
32
|
### v9.10.2 (2023-02-21)
|
|
17
33
|
|
|
18
34
|
* Replaced `request.aborted` with `response.close` in HTTP instrumentation.
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
<a href="https://opensource.newrelic.com/oss-category/#community-plus"><picture><source media="(prefers-color-scheme: dark)" srcset="https://github.com/newrelic/opensource-website/raw/main/src/images/categories/dark/Community_Plus.png"><source media="(prefers-color-scheme: light)" srcset="https://github.com/newrelic/opensource-website/raw/main/src/images/categories/Community_Plus.png"><img alt="New Relic Open Source community plus project banner." src="https://github.com/newrelic/opensource-website/raw/main/src/images/categories/Community_Plus.png"></picture></a>
|
|
2
2
|
|
|
3
3
|
# New Relic's Node.js agent
|
|
4
4
|
[![npm status badge][1]][2] [![Server Smoke Tests][3]][4] [![Node Agent CI][5]][6] [![codecov][7]][8]
|
package/api.js
CHANGED
|
@@ -403,7 +403,8 @@ API.prototype.addCustomSpanAttribute = function addCustomSpanAttribute(key, valu
|
|
|
403
403
|
* } catch (err) {
|
|
404
404
|
* newrelic.noticeError(
|
|
405
405
|
* err,
|
|
406
|
-
* {extraInformation: "error already handled in the application"}
|
|
406
|
+
* {extraInformation: "error already handled in the application"},
|
|
407
|
+
* true
|
|
407
408
|
* );
|
|
408
409
|
* }
|
|
409
410
|
*
|
|
@@ -414,12 +415,21 @@ API.prototype.addCustomSpanAttribute = function addCustomSpanAttribute(key, valu
|
|
|
414
415
|
* The error to be traced.
|
|
415
416
|
* @param {object} [customAttributes]
|
|
416
417
|
* Optional. Any custom attributes to be displayed in the New Relic UI.
|
|
417
|
-
* @
|
|
418
|
+
* @param {boolean} expected
|
|
419
|
+
* Optional. False by default. True if the error is expected, meaning it should be collected
|
|
420
|
+
* for error events and traces, but should not impact error rate.
|
|
421
|
+
* @returns {false|undefined} Returns false when disabled/errored, otherwise undefined
|
|
418
422
|
*/
|
|
419
|
-
API.prototype.noticeError = function noticeError(error, customAttributes) {
|
|
423
|
+
API.prototype.noticeError = function noticeError(error, customAttributes, expected = false) {
|
|
420
424
|
const metric = this.agent.metrics.getOrCreateMetric(NAMES.SUPPORTABILITY.API + '/noticeError')
|
|
421
425
|
metric.incrementCallCount()
|
|
422
426
|
|
|
427
|
+
// let users skip the custom attributes if they want
|
|
428
|
+
if (customAttributes && typeof customAttributes === 'boolean') {
|
|
429
|
+
expected = customAttributes
|
|
430
|
+
customAttributes = null
|
|
431
|
+
}
|
|
432
|
+
|
|
423
433
|
if (!this.agent.config.api.notice_error_enabled) {
|
|
424
434
|
logger.debug('Config.api.notice_error_enabled set to false, not collecting error')
|
|
425
435
|
return false
|
|
@@ -446,7 +456,7 @@ API.prototype.noticeError = function noticeError(error, customAttributes) {
|
|
|
446
456
|
}
|
|
447
457
|
|
|
448
458
|
const transaction = this.agent.tracer.getTransaction()
|
|
449
|
-
this.agent.errors.addUserError(transaction, error, filteredAttributes)
|
|
459
|
+
this.agent.errors.addUserError(transaction, error, filteredAttributes, expected)
|
|
450
460
|
}
|
|
451
461
|
|
|
452
462
|
/**
|
|
@@ -114,19 +114,27 @@ class ErrorCollector {
|
|
|
114
114
|
*
|
|
115
115
|
* @param {Transaction} transaction the collected exception's transaction
|
|
116
116
|
* @param {number} collectedErrors the number of errors we've successfully .collect()-ed
|
|
117
|
-
* @
|
|
117
|
+
* @param {number} expectedErrors the number of errors marked as expected in noticeError
|
|
118
|
+
* @returns {Array.<number>} the updated [collectedErrors, expectedErrors] numbers post-processing
|
|
118
119
|
*/
|
|
119
|
-
_processUserErrors(transaction, collectedErrors) {
|
|
120
|
+
_processUserErrors(transaction, collectedErrors, expectedErrors) {
|
|
120
121
|
if (transaction.userErrors.length) {
|
|
121
122
|
for (let i = 0; i < transaction.userErrors.length; i++) {
|
|
122
123
|
const exception = transaction.userErrors[i]
|
|
123
124
|
if (this.collect(transaction, exception)) {
|
|
124
125
|
++collectedErrors
|
|
126
|
+
// if we could collect it, then check if expected
|
|
127
|
+
if (
|
|
128
|
+
urltils.isExpectedError(this.config, transaction.statusCode) ||
|
|
129
|
+
errorHelper.isExpectedException(transaction, exception, this.config, urltils)
|
|
130
|
+
) {
|
|
131
|
+
++expectedErrors
|
|
132
|
+
}
|
|
125
133
|
}
|
|
126
134
|
}
|
|
127
135
|
}
|
|
128
136
|
|
|
129
|
-
return collectedErrors
|
|
137
|
+
return [collectedErrors, expectedErrors]
|
|
130
138
|
}
|
|
131
139
|
|
|
132
140
|
/**
|
|
@@ -145,7 +153,7 @@ class ErrorCollector {
|
|
|
145
153
|
// if we could collect it, then check if expected
|
|
146
154
|
if (
|
|
147
155
|
urltils.isExpectedError(this.config, transaction.statusCode) ||
|
|
148
|
-
errorHelper.isExpectedException(transaction, exception
|
|
156
|
+
errorHelper.isExpectedException(transaction, exception, this.config, urltils)
|
|
149
157
|
) {
|
|
150
158
|
++expectedErrors
|
|
151
159
|
}
|
|
@@ -196,7 +204,11 @@ class ErrorCollector {
|
|
|
196
204
|
|
|
197
205
|
// errors from noticeError are currently exempt from
|
|
198
206
|
// ignore and exclude rules
|
|
199
|
-
collectedErrors = this._processUserErrors(
|
|
207
|
+
;[collectedErrors, expectedErrors] = this._processUserErrors(
|
|
208
|
+
transaction,
|
|
209
|
+
collectedErrors,
|
|
210
|
+
expectedErrors
|
|
211
|
+
)
|
|
200
212
|
|
|
201
213
|
const isErroredTransaction = urltils.isError(this.config, transaction.statusCode)
|
|
202
214
|
const isIgnoredErrorStatusCode = urltils.isIgnoredError(this.config, transaction.statusCode)
|
|
@@ -276,8 +288,9 @@ class ErrorCollector {
|
|
|
276
288
|
* @param {?Transaction} transaction Transaction associated with the error.
|
|
277
289
|
* @param {*} error The error passed into `API#noticeError()`
|
|
278
290
|
* @param {object} customAttributes custom attributes to add to the error
|
|
291
|
+
* @param {boolean} expected Is the error expected?
|
|
279
292
|
*/
|
|
280
|
-
addUserError(transaction, error, customAttributes) {
|
|
293
|
+
addUserError(transaction, error, customAttributes, expected) {
|
|
281
294
|
if (!error) {
|
|
282
295
|
return
|
|
283
296
|
}
|
|
@@ -289,7 +302,7 @@ class ErrorCollector {
|
|
|
289
302
|
}
|
|
290
303
|
|
|
291
304
|
const timestamp = Date.now()
|
|
292
|
-
const exception = new Exception({ error, timestamp, customAttributes })
|
|
305
|
+
const exception = new Exception({ error, timestamp, customAttributes, expected })
|
|
293
306
|
|
|
294
307
|
if (transaction) {
|
|
295
308
|
transaction.addUserError(exception)
|
package/lib/errors/helper.js
CHANGED
|
@@ -34,10 +34,18 @@ module.exports = {
|
|
|
34
34
|
)
|
|
35
35
|
},
|
|
36
36
|
isExpectedException: function isExpectedException(transaction, exception, config, urltils) {
|
|
37
|
-
|
|
37
|
+
// this is getting JUST the exception.error
|
|
38
|
+
const { type, message } = this.extractErrorInformation(
|
|
39
|
+
transaction,
|
|
40
|
+
exception.error,
|
|
41
|
+
config,
|
|
42
|
+
urltils
|
|
43
|
+
)
|
|
38
44
|
|
|
39
45
|
return (
|
|
40
|
-
|
|
46
|
+
exception._expected ||
|
|
47
|
+
this.isExpectedErrorClass(config, type) ||
|
|
48
|
+
this.isExpectedErrorMessage(config, type, message)
|
|
41
49
|
)
|
|
42
50
|
},
|
|
43
51
|
|
package/lib/errors/index.js
CHANGED
|
@@ -19,11 +19,12 @@ const Transaction = require('../transaction')
|
|
|
19
19
|
const ERROR_EXPECTED_PATH = 'error.expected'
|
|
20
20
|
|
|
21
21
|
class Exception {
|
|
22
|
-
constructor({ error, timestamp, customAttributes, agentAttributes }) {
|
|
22
|
+
constructor({ error, timestamp, customAttributes, agentAttributes, expected }) {
|
|
23
23
|
this.error = error
|
|
24
24
|
this.timestamp = timestamp || 0
|
|
25
25
|
this.customAttributes = customAttributes || {}
|
|
26
26
|
this.agentAttributes = agentAttributes || {}
|
|
27
|
+
this._expected = expected
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
getErrorDetails(config) {
|
|
@@ -34,7 +35,7 @@ class Exception {
|
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
isExpected(config, { type, message }) {
|
|
37
|
-
if (
|
|
38
|
+
if (typeof this._expected === 'undefined') {
|
|
38
39
|
this._expected =
|
|
39
40
|
errorHelper.isExpectedErrorClass(config, type) ||
|
|
40
41
|
errorHelper.isExpectedErrorMessage(config, type, message)
|
|
@@ -103,13 +104,8 @@ function createError(transaction, exception, config) {
|
|
|
103
104
|
|
|
104
105
|
params.stack_trace = maybeAddStackTrace(exception, config)
|
|
105
106
|
|
|
106
|
-
params.intrinsics[ERROR_EXPECTED_PATH] =
|
|
107
|
-
type,
|
|
108
|
-
message,
|
|
109
|
-
transaction,
|
|
110
|
-
config,
|
|
111
|
-
urltils
|
|
112
|
-
)
|
|
107
|
+
params.intrinsics[ERROR_EXPECTED_PATH] =
|
|
108
|
+
exception._expected || errorHelper.isExpected(type, message, transaction, config, urltils)
|
|
113
109
|
|
|
114
110
|
return [0, name, message, type, params]
|
|
115
111
|
}
|
|
@@ -143,7 +143,7 @@ function instrumentRequest(agent, opts, makeRequest, hostname, segment) {
|
|
|
143
143
|
outboundHeaders[NEWRELIC_SYNTHETICS_HEADER] = transaction.syntheticsHeader
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
maybeAddDtCatHeaders(agent, transaction, outboundHeaders,
|
|
146
|
+
maybeAddDtCatHeaders(agent, transaction, outboundHeaders, opts?.headers)
|
|
147
147
|
opts.headers = assignOutgoingHeaders(opts.headers, outboundHeaders)
|
|
148
148
|
|
|
149
149
|
const request = applySegment(opts, makeRequest, hostname, segment)
|
|
@@ -160,13 +160,18 @@ function instrumentRequest(agent, opts, makeRequest, hostname, segment) {
|
|
|
160
160
|
* @param {Agent} agent Node.js agent
|
|
161
161
|
* @param {Transaction} transaction active transaction
|
|
162
162
|
* @param {object} outboundHeaders headers that are getting attached to external http call
|
|
163
|
-
* @param {
|
|
163
|
+
* @param {object} headers headers for http request
|
|
164
164
|
*/
|
|
165
165
|
// TODO: abstract header logic shared with TransactionShim#insertCATRequestHeaders
|
|
166
|
-
function maybeAddDtCatHeaders(agent, transaction, outboundHeaders,
|
|
166
|
+
function maybeAddDtCatHeaders(agent, transaction, outboundHeaders, headers = {}) {
|
|
167
167
|
if (agent.config.distributed_tracing.enabled) {
|
|
168
|
-
if (
|
|
168
|
+
if (!!(headers[symbols.disableDT] || headers['x-new-relic-disable-dt'])) {
|
|
169
169
|
logger.trace('Distributed tracing disabled by instrumentation.')
|
|
170
|
+
// we do not need to remove symbol as it will get implicitly removed
|
|
171
|
+
// when the request is serialized. in fact removing the symbol will cause
|
|
172
|
+
// the same issue that we had to change this to a string header
|
|
173
|
+
// see: https://github.com/newrelic/node-newrelic-aws-sdk/issues/168
|
|
174
|
+
delete headers['x-new-relic-disable-dt']
|
|
170
175
|
} else {
|
|
171
176
|
transaction.insertDistributedTraceHeaders(outboundHeaders)
|
|
172
177
|
}
|
package/lib/transaction/index.js
CHANGED
|
@@ -860,7 +860,7 @@ Transaction.prototype.hasOnlyExpectedErrors = function hasOnlyExpectedErrors() {
|
|
|
860
860
|
const exception = this.exceptions[i]
|
|
861
861
|
// this exception is neither expected nor ignored
|
|
862
862
|
const isUnexpected = !(
|
|
863
|
-
errorHelper.isExpectedException(this, exception
|
|
863
|
+
errorHelper.isExpectedException(this, exception, this.agent.config, urltils) ||
|
|
864
864
|
errorHelper.shouldIgnoreError(this, exception.error, this.agent.config)
|
|
865
865
|
)
|
|
866
866
|
if (isUnexpected) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newrelic",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.12.1",
|
|
4
4
|
"author": "New Relic Node.js agent team <nodejs@newrelic.com>",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"contributors": [
|
|
@@ -179,7 +179,7 @@
|
|
|
179
179
|
"newrelic-naming-rules": "./bin/test-naming-rules.js"
|
|
180
180
|
},
|
|
181
181
|
"dependencies": {
|
|
182
|
-
"@grpc/grpc-js": "^1.8.
|
|
182
|
+
"@grpc/grpc-js": "^1.8.9",
|
|
183
183
|
"@grpc/proto-loader": "^0.7.5",
|
|
184
184
|
"@newrelic/aws-sdk": "^5.0.2",
|
|
185
185
|
"@newrelic/koa": "^7.1.1",
|