newrelic 12.3.0 → 12.3.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 +21 -0
- package/api.js +50 -49
- package/lib/serverless/api-gateway.js +18 -6
- package/package.json +1 -1
package/NEWS.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
### v12.3.1 (2024-09-04)
|
|
2
|
+
|
|
3
|
+
#### Bug fixes
|
|
4
|
+
|
|
5
|
+
* Fixed detection of REST API type payloads in AWS Lambda ([#2543](https://github.com/newrelic/node-newrelic/pull/2543)) ([adfeebc](https://github.com/newrelic/node-newrelic/commit/adfeebc043161e0e0c35de2cf93989dbde9cb8fa))
|
|
6
|
+
|
|
7
|
+
#### Documentation
|
|
8
|
+
|
|
9
|
+
* Cleaned up formatting of api.js to properly inject example snippets when rendering on API docs site ([#2524](https://github.com/newrelic/node-newrelic/pull/2524)) ([4b34f3d](https://github.com/newrelic/node-newrelic/commit/4b34f3dbab45a55ec447b6e21b69c7621b41e539))
|
|
10
|
+
* Updated compatibility report ([#2523](https://github.com/newrelic/node-newrelic/pull/2523)) ([29784ea](https://github.com/newrelic/node-newrelic/commit/29784ea766b2a9388c050f271ab7190895bc22ed))
|
|
11
|
+
* Updated Next.js Otel cloud provider FAQ ([#2537](https://github.com/newrelic/node-newrelic/pull/2537)) ([6553807](https://github.com/newrelic/node-newrelic/commit/655380760a89193c5b6cd47d3955d1244cd79e7b))
|
|
12
|
+
|
|
13
|
+
#### Tests
|
|
14
|
+
|
|
15
|
+
* Converted db unit tests to node:test ([#2514](https://github.com/newrelic/node-newrelic/pull/2514)) ([bea4548](https://github.com/newrelic/node-newrelic/commit/bea45481a8a04099096929b36532203fbb8b6921))
|
|
16
|
+
* Converted grpc, lib, and utilization tests to `node:test` ([#2532](https://github.com/newrelic/node-newrelic/pull/2532)) ([c207e1e](https://github.com/newrelic/node-newrelic/commit/c207e1e3de75a9c3a2c4a05fa1bc318d3e455ef9))
|
|
17
|
+
* Replaced distributed tracing tests with `node:test` ([#2527](https://github.com/newrelic/node-newrelic/pull/2527)) ([8184c56](https://github.com/newrelic/node-newrelic/commit/8184c5676155b9028c84adc0da3902803ee9d107))
|
|
18
|
+
* Added a match function for tests ([#2541](https://github.com/newrelic/node-newrelic/pull/2541)) ([51e7f34](https://github.com/newrelic/node-newrelic/commit/51e7f34e733202a9c2c024d9d9a7f3c207dfc4b0))
|
|
19
|
+
* Converted `config` to `node:test` ([#2517](https://github.com/newrelic/node-newrelic/pull/2517)) ([1534a73](https://github.com/newrelic/node-newrelic/commit/1534a734995b6800c4cab3b6712f1b6b1329ed5e))
|
|
20
|
+
|
|
21
|
+
|
|
1
22
|
### v12.3.0 (2024-08-27)
|
|
2
23
|
|
|
3
24
|
#### Features
|
package/api.js
CHANGED
|
@@ -304,8 +304,7 @@ API.prototype.addCustomAttribute = function addCustomAttribute(key, value) {
|
|
|
304
304
|
* See documentation for newrelic.addCustomAttribute for more information on
|
|
305
305
|
* setting custom attributes.
|
|
306
306
|
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
307
|
+
* @example
|
|
309
308
|
* newrelic.addCustomAttributes({test: 'value', test2: 'value2'});
|
|
310
309
|
*
|
|
311
310
|
* @param {object} [atts] Attribute object
|
|
@@ -332,7 +331,7 @@ API.prototype.addCustomAttributes = function addCustomAttributes(atts) {
|
|
|
332
331
|
*
|
|
333
332
|
* See documentation for newrelic.addCustomSpanAttribute for more information.
|
|
334
333
|
*
|
|
335
|
-
*
|
|
334
|
+
* @example
|
|
336
335
|
*
|
|
337
336
|
* newrelic.addCustomSpanAttribute({test: 'value', test2: 'value2'})
|
|
338
337
|
*
|
|
@@ -401,21 +400,20 @@ API.prototype.addCustomSpanAttribute = function addCustomSpanAttribute(key, valu
|
|
|
401
400
|
* `Error` or one of its subtypes, but the API will handle strings and objects
|
|
402
401
|
* that have an attached `.message` or `.stack` property.
|
|
403
402
|
*
|
|
404
|
-
* An example of using this function is
|
|
405
|
-
*
|
|
406
|
-
* try {
|
|
407
|
-
* performSomeTask();
|
|
408
|
-
* } catch (err) {
|
|
409
|
-
* newrelic.noticeError(
|
|
410
|
-
* err,
|
|
411
|
-
* {extraInformation: "error already handled in the application"},
|
|
412
|
-
* true
|
|
413
|
-
* );
|
|
414
|
-
* }
|
|
415
|
-
*
|
|
416
403
|
* NOTE: Errors that are recorded using this method do _not_ obey the
|
|
417
404
|
* `ignore_status_codes` configuration.
|
|
418
405
|
*
|
|
406
|
+
* @example
|
|
407
|
+
* try {
|
|
408
|
+
* performSomeTask();
|
|
409
|
+
* } catch (err) {
|
|
410
|
+
* newrelic.noticeError(
|
|
411
|
+
* err,
|
|
412
|
+
* {extraInformation: "error already handled in the application"},
|
|
413
|
+
* true
|
|
414
|
+
* );
|
|
415
|
+
* }
|
|
416
|
+
*
|
|
419
417
|
* @param {Error} error
|
|
420
418
|
* The error to be traced.
|
|
421
419
|
* @param {object} [customAttributes]
|
|
@@ -474,13 +472,12 @@ API.prototype.noticeError = function noticeError(error, customAttributes, expect
|
|
|
474
472
|
* If application log forwarding is disabled in the agent
|
|
475
473
|
* configuration, this function does nothing.
|
|
476
474
|
*
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
*
|
|
483
|
-
* })
|
|
475
|
+
* @example
|
|
476
|
+
* newrelic.recordLogEvent({
|
|
477
|
+
* message: 'cannot find file',
|
|
478
|
+
* level: 'ERROR',
|
|
479
|
+
* error: new SystemError('missing.txt')
|
|
480
|
+
* })
|
|
484
481
|
*
|
|
485
482
|
* @param {object} logEvent The log event object to send. Any
|
|
486
483
|
* attributes besides `message`, `level`, `timestamp`, and `error` are
|
|
@@ -554,20 +551,21 @@ API.prototype.recordLogEvent = function recordLogEvent(logEvent = {}) {
|
|
|
554
551
|
* GUIDs, or timestamps), the rule will generate too many metrics and
|
|
555
552
|
* potentially get your application blocked by New Relic.
|
|
556
553
|
*
|
|
557
|
-
* An example of a good rule with replacements:
|
|
558
|
-
*
|
|
559
|
-
* newrelic.addNamingRule('^/storefront/(v[1-5])/(item|category|tag)',
|
|
560
|
-
* 'CommerceAPI/$1/$2')
|
|
561
554
|
*
|
|
562
|
-
*
|
|
555
|
+
* @example
|
|
556
|
+
* // An example of a good rule with replacements:
|
|
557
|
+
* newrelic.addNamingRule('^/storefront/(v[1-5])/(item|category|tag)',
|
|
558
|
+
* 'CommerceAPI/$1/$2')
|
|
563
559
|
*
|
|
564
|
-
*
|
|
560
|
+
* @example
|
|
561
|
+
* // An example of a bad rule with replacements:
|
|
562
|
+
* newrelic.addNamingRule('^/item/([0-9a-f]+)', 'Item/$1')
|
|
565
563
|
*
|
|
566
|
-
* Keep in mind that the original URL and any query parameters will be sent
|
|
567
|
-
* along with the request, so slow transactions will still be identifiable.
|
|
564
|
+
* // Keep in mind that the original URL and any query parameters will be sent
|
|
565
|
+
* // along with the request, so slow transactions will still be identifiable.
|
|
568
566
|
*
|
|
569
|
-
* Naming rules can not be removed once added. They can also be added via the
|
|
570
|
-
* agent's configuration. See configuration documentation for details.
|
|
567
|
+
* // Naming rules can not be removed once added. They can also be added via the
|
|
568
|
+
* // agent's configuration. See configuration documentation for details.
|
|
571
569
|
*
|
|
572
570
|
* @param {RegExp} pattern The pattern to rename (with capture groups).
|
|
573
571
|
* @param {string} name The name to use for the transaction.
|
|
@@ -591,8 +589,7 @@ API.prototype.addNamingRule = function addNamingRule(pattern, name) {
|
|
|
591
589
|
* distorting an app's apdex or mean response time. Pattern may be a (standard
|
|
592
590
|
* JavaScript) RegExp or a string.
|
|
593
591
|
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
592
|
+
* @example
|
|
596
593
|
* newrelic.addIgnoringRule('^/socket\\.io/')
|
|
597
594
|
*
|
|
598
595
|
* @param {RegExp} pattern The pattern to ignore.
|
|
@@ -929,9 +926,9 @@ API.prototype.startSegment = function startSegment(name, record, handler, callba
|
|
|
929
926
|
* will be ended when {@link TransactionHandle#end} is called in the user's code.
|
|
930
927
|
*
|
|
931
928
|
* @example
|
|
932
|
-
*
|
|
929
|
+
* const newrelic = require('newrelic')
|
|
933
930
|
* newrelic.startWebTransaction('/some/url/path', function() {
|
|
934
|
-
*
|
|
931
|
+
* const transaction = newrelic.getTransaction()
|
|
935
932
|
* setTimeout(function() {
|
|
936
933
|
* // do some work
|
|
937
934
|
* transaction.end()
|
|
@@ -1017,9 +1014,9 @@ API.prototype.startBackgroundTransaction = startBackgroundTransaction
|
|
|
1017
1014
|
* will be ended when {@link TransactionHandle#end} is called in the user's code.
|
|
1018
1015
|
*
|
|
1019
1016
|
* @example
|
|
1020
|
-
*
|
|
1017
|
+
* const newrelic = require('newrelic')
|
|
1021
1018
|
* newrelic.startBackgroundTransaction('Red October', 'Subs', function() {
|
|
1022
|
-
*
|
|
1019
|
+
* const transaction = newrelic.getTransaction()
|
|
1023
1020
|
* setTimeout(function() {
|
|
1024
1021
|
* // do some work
|
|
1025
1022
|
* transaction.end()
|
|
@@ -1478,14 +1475,15 @@ API.prototype.instrumentMessages = function instrumentMessages(moduleName, onReq
|
|
|
1478
1475
|
* Applies an instrumentation to an already loaded CommonJs module.
|
|
1479
1476
|
*
|
|
1480
1477
|
* Note: This function will not work for ESM packages.
|
|
1478
|
+
* @example
|
|
1481
1479
|
*
|
|
1482
|
-
*
|
|
1483
|
-
*
|
|
1484
|
-
*
|
|
1480
|
+
* // oh no, express was loaded before newrelic
|
|
1481
|
+
* const express = require('express')
|
|
1482
|
+
* const newrelic = require('newrelic')
|
|
1485
1483
|
*
|
|
1486
|
-
*
|
|
1487
|
-
*
|
|
1488
|
-
*
|
|
1484
|
+
* // phew, we can use instrumentLoadedModule to make
|
|
1485
|
+
* // sure express is still instrumented
|
|
1486
|
+
* newrelic.instrumentLoadedModule('express', express)
|
|
1489
1487
|
*
|
|
1490
1488
|
* @param {string} moduleName
|
|
1491
1489
|
* The module's name/identifier. Will be normalized
|
|
@@ -1906,11 +1904,14 @@ API.prototype.ignoreApdex = function ignoreApdex() {
|
|
|
1906
1904
|
/**
|
|
1907
1905
|
* Run a function with the passed in LLM context as the active context and return its return value.
|
|
1908
1906
|
*
|
|
1909
|
-
*
|
|
1910
|
-
*
|
|
1911
|
-
*
|
|
1912
|
-
*
|
|
1913
|
-
*
|
|
1907
|
+
* @example
|
|
1908
|
+
* const OpenAI = require('openai')
|
|
1909
|
+
* const client = new OpenAI()
|
|
1910
|
+
* newrelic.withLlmCustomAttributes({'llm.someAttribute': 'someValue'}, async () => {
|
|
1911
|
+
* const response = await client.chat.completions.create({ messages: [
|
|
1912
|
+
* { role: 'user', content: 'Tell me about Node.js.'}
|
|
1913
|
+
* ]})
|
|
1914
|
+
* })
|
|
1914
1915
|
* @param {Object} context LLM custom attributes context
|
|
1915
1916
|
* @param {Function} callback The function to execute in context.
|
|
1916
1917
|
*/
|
|
@@ -97,6 +97,10 @@ function normalizeHeaders(event, lowerCaseKey = false) {
|
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
* Determines if Lambda event appears to be a valid Lambda Proxy event.
|
|
100
|
+
* There are multiple types of events possible. They are described at
|
|
101
|
+
* https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html#services-apigateway-apitypes.
|
|
102
|
+
* Each type of event has its own event payload structure; some types have
|
|
103
|
+
* multiple versions of the payload structure.
|
|
100
104
|
*
|
|
101
105
|
* @param {object} event The event to inspect.
|
|
102
106
|
* @returns {boolean} Whether the given object contains fields necessary
|
|
@@ -106,7 +110,8 @@ function isLambdaProxyEvent(event) {
|
|
|
106
110
|
return isGatewayV1Event(event) || isGatewayV2Event(event)
|
|
107
111
|
}
|
|
108
112
|
|
|
109
|
-
|
|
113
|
+
// See https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
|
|
114
|
+
const restApiV1Keys = [
|
|
110
115
|
'body',
|
|
111
116
|
'headers',
|
|
112
117
|
'httpMethod',
|
|
@@ -118,16 +123,23 @@ const v1Keys = [
|
|
|
118
123
|
'queryStringParameters',
|
|
119
124
|
'requestContext',
|
|
120
125
|
'resource',
|
|
121
|
-
'stageVariables'
|
|
122
|
-
'version'
|
|
126
|
+
'stageVariables'
|
|
123
127
|
].join(',')
|
|
124
128
|
|
|
129
|
+
// See https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
|
|
130
|
+
const httpApiV1Keys = [...restApiV1Keys.split(','), 'version'].join(',')
|
|
131
|
+
|
|
125
132
|
function isGatewayV1Event(event) {
|
|
126
133
|
const keys = Object.keys(event).sort().join(',')
|
|
127
|
-
|
|
134
|
+
if (keys === httpApiV1Keys && event?.version === '1.0') {
|
|
135
|
+
return true
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return keys === restApiV1Keys
|
|
128
139
|
}
|
|
129
140
|
|
|
130
|
-
|
|
141
|
+
// See https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html
|
|
142
|
+
const httpApiV2Keys = [
|
|
131
143
|
'body',
|
|
132
144
|
'cookies',
|
|
133
145
|
'headers',
|
|
@@ -144,7 +156,7 @@ const v2Keys = [
|
|
|
144
156
|
|
|
145
157
|
function isGatewayV2Event(event) {
|
|
146
158
|
const keys = Object.keys(event).sort().join(',')
|
|
147
|
-
return keys ===
|
|
159
|
+
return keys === httpApiV2Keys && event?.version === '2.0'
|
|
148
160
|
}
|
|
149
161
|
|
|
150
162
|
/**
|