newrelic 12.14.0 → 12.16.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.
Files changed (36) hide show
  1. package/NEWS.md +96 -43
  2. package/README.md +36 -31
  3. package/api.js +2 -0
  4. package/lib/agent.js +5 -5
  5. package/lib/context-manager/async-local-context-manager.js +4 -2
  6. package/lib/context-manager/context.js +15 -48
  7. package/lib/errors/error-collector.js +3 -2
  8. package/lib/feature_flags.js +2 -1
  9. package/lib/instrumentation/kafkajs/consumer.js +1 -1
  10. package/lib/instrumentation/undici.js +2 -1
  11. package/lib/otel/attr-reconciler.js +52 -0
  12. package/lib/otel/constants.js +50 -3
  13. package/lib/otel/context.js +89 -0
  14. package/lib/otel/fake-span.js +28 -0
  15. package/lib/otel/segments/consumer.js +12 -12
  16. package/lib/otel/segments/database.js +1 -0
  17. package/lib/otel/segments/http-external.js +33 -3
  18. package/lib/otel/segments/internal.js +1 -0
  19. package/lib/otel/segments/producer.js +1 -0
  20. package/lib/otel/segments/server.js +7 -2
  21. package/lib/otel/segments/utils.js +30 -0
  22. package/lib/otel/setup.js +7 -8
  23. package/lib/otel/span-key-interceptor.js +30 -0
  24. package/lib/otel/span-processor.js +216 -85
  25. package/lib/otel/trace-propagator.js +12 -16
  26. package/lib/serverless/aws-lambda.js +119 -37
  27. package/lib/shim/message-shim/subscribe-consume.js +0 -1
  28. package/lib/spans/helpers.js +69 -0
  29. package/lib/spans/span-event.js +15 -17
  30. package/lib/spans/streaming-span-event.js +11 -16
  31. package/lib/{sampler.js → system-metrics-sampler.js} +11 -10
  32. package/lib/transaction/index.js +12 -53
  33. package/lib/transaction/trace/segment.js +6 -2
  34. package/lib/transaction/tracecontext.js +13 -6
  35. package/lib/transaction/tracer/index.js +18 -2
  36. package/package.json +1 -1
package/NEWS.md CHANGED
@@ -1,46 +1,99 @@
1
- ### v12.14.0 (2025-02-18)
2
-
3
- #### Features
4
-
5
- * Added support for region-prefixed Bedrock models ([#2947](https://github.com/newrelic/node-newrelic/pull/2947)) ([6acf535](https://github.com/newrelic/node-newrelic/commit/6acf5354d1e7f6786da88c0078699e82a714551d))
6
- * Added attribute reconciliation for message producer spans ([#2942](https://github.com/newrelic/node-newrelic/pull/2942)) ([a9ba396](https://github.com/newrelic/node-newrelic/commit/a9ba39613c78b89c047ca35a218c2eedbb01e3d2))
7
- * Added timeslice metrics for synthesized consumer segments ([#2938](https://github.com/newrelic/node-newrelic/pull/2938)) ([acfe953](https://github.com/newrelic/node-newrelic/commit/acfe953cf7a656fafb69104384c72f94ddc13000))
8
-
9
- #### Bug fixes
10
-
11
- * Fixed queueing of logs from child loggers ([#2945](https://github.com/newrelic/node-newrelic/pull/2945)) ([888cfe8](https://github.com/newrelic/node-newrelic/commit/888cfe84a1ffaf0287682cc9099a2fa762f7a37f))
12
- * Fixed undici/fetch instrumentation to properly assign the parent-id portion of the `traceparent` header on outgoing requests to the active http external span id ([#2951](https://github.com/newrelic/node-newrelic/pull/2951)) ([bc714cf](https://github.com/newrelic/node-newrelic/commit/bc714cfa8fe6754abf25eb556b8f804c9982f986))
13
- * Updated `api.recordLogEvent` to no longer truncate the message key in log event ([#2949](https://github.com/newrelic/node-newrelic/pull/2949)) ([8dd557b](https://github.com/newrelic/node-newrelic/commit/8dd557b4dfca2505b7e9f7f030ab094a6ae8019a))
14
- * Thanks for your contribution @rChaoz 🎉
15
-
16
- #### Documentation
17
-
18
- * Updated compatibility report ([#2948](https://github.com/newrelic/node-newrelic/pull/2948)) ([8e32ed7](https://github.com/newrelic/node-newrelic/commit/8e32ed7d7bc456a0693485e7bdef955c25ead29a))
19
-
20
- ### v12.13.0 (2025-02-12)
21
-
22
- #### Features
23
-
24
- * Added timeslice metrics for synthesized server segments ([#2924](https://github.com/newrelic/node-newrelic/pull/2924)) ([f404585](https://github.com/newrelic/node-newrelic/commit/f4045855a1cdbfb74e3217daf8bfa125aa6fe2e4))
25
- * Added timeslice metrics for synthesized producer segments ([#2939](https://github.com/newrelic/node-newrelic/pull/2939)) ([6832637](https://github.com/newrelic/node-newrelic/commit/68326377dcd23b574abae7c323ff93bc05c525ed))
26
- * Added timeslice metrics for synthesized database segments ([#2922](https://github.com/newrelic/node-newrelic/pull/2922)) ([8606f78](https://github.com/newrelic/node-newrelic/commit/8606f789772b7651d0c46ad50dad3a1da74e5e9c))
27
- * Propagate agent root context when opentelemetry `ROOT_CONTEXT` is passed in to trace propagator.([#2940](https://github.com/newrelic/node-newrelic/pull/2940)) ([b85111c](https://github.com/newrelic/node-newrelic/commit/b85111c46797dfbf399faf973e7a3e0ea6bbdc28))
28
- * Added logic to handle properly naming and ending transactions for server spans.
29
- * Provided ability to disable instrumentation for core Node.js libraries ([#2927](https://github.com/newrelic/node-newrelic/pull/2927)) ([2d232f1](https://github.com/newrelic/node-newrelic/commit/2d232f16c167e5f84b7b7898a6c5410d9cece55e))
30
-
31
- #### Bug fixes
32
-
33
- * Fixed `api.getTraceMetadata` to handle when there is an active transaction but not active segment ([#2944](https://github.com/newrelic/node-newrelic/pull/2944)) ([6db3b4d](https://github.com/newrelic/node-newrelic/commit/6db3b4d53a077a9738dd72d46e1ba1cee0d6af3f))
34
-
35
- #### Documentation
36
-
37
- * Updated compatibility report ([#2920](https://github.com/newrelic/node-newrelic/pull/2920)) ([c7ae8be](https://github.com/newrelic/node-newrelic/commit/c7ae8befafa4c91fab6804cd95e20f5a93546ea4))
38
-
39
- #### Miscellaneous chores
40
-
41
- * Localized OTEL attribute constants ([#2928](https://github.com/newrelic/node-newrelic/pull/2928)) ([965c41b](https://github.com/newrelic/node-newrelic/commit/965c41b3e64805ac14ae4dd36120b018ec5899f4))
42
- * Updated import-in-the-middle version ([#2923](https://github.com/newrelic/node-newrelic/pull/2923)) ([aa2781f](https://github.com/newrelic/node-newrelic/commit/aa2781fd9c7bed08d590e33682729a92f21f43a5))
43
-
1
+ ### v12.16.0 (2025-03-17)
2
+
3
+ #### Features
4
+
5
+ * Added support for response streaming Lambda functions ([#2981](https://github.com/newrelic/node-newrelic/pull/2981)) ([61dbbf9](https://github.com/newrelic/node-newrelic/commit/61dbbf9b4a6cf69f5378387fc9c17c31671e9da4))
6
+ * Added AWS entity linking segment attributes for otel bridge ([#2978](https://github.com/newrelic/node-newrelic/pull/2978)) ([6bf1ccc](https://github.com/newrelic/node-newrelic/commit/6bf1ccc657a955b4064a7a3a473bf24948d4ff56))
7
+ * Added error handling on transactions for otel spans ([#2985](https://github.com/newrelic/node-newrelic/pull/2985)) ([4e61e09](https://github.com/newrelic/node-newrelic/commit/4e61e0935394744345c39f6b581ee86e66d0f82c))
8
+
9
+ #### Code refactoring
10
+
11
+ * Updated span event generation to assign the appropriate `span.kind` based on the segment name ([#2976](https://github.com/newrelic/node-newrelic/pull/2976)) ([697b17e](https://github.com/newrelic/node-newrelic/commit/697b17e0553111aa494d08bc33eb7043cdfa8ca6))
12
+
13
+ #### Documentation
14
+
15
+ * Updated compatibility report ([#2988](https://github.com/newrelic/node-newrelic/pull/2988)) ([ed17a6d](https://github.com/newrelic/node-newrelic/commit/ed17a6df1152a8e54cb8c8570fec0015990a4247)
16
+
17
+ #### Miscellaneous chores
18
+
19
+ * Clarified supported next.js middleware versions in docs ([#2984](https://github.com/newrelic/node-newrelic/pull/2984)) ([15cb454](https://github.com/newrelic/node-newrelic/commit/15cb454f9cc38ccc22089d62aaeea54713159aa7))
20
+ * Clarified system metrics sampler naming ([#2987](https://github.com/newrelic/node-newrelic/pull/2987)) ([8647d43](https://github.com/newrelic/node-newrelic/commit/8647d43f097d6d3d68a372824d9feb325604be96))
21
+ * Refactored loops to be simpler ([#2990](https://github.com/newrelic/node-newrelic/pull/2990)) ([79fb8e9](https://github.com/newrelic/node-newrelic/commit/79fb8e90802954b617c1c00aecc866aa065aee12))
22
+ * Removed unused transaction method ([#2986](https://github.com/newrelic/node-newrelic/pull/2986)) ([cb4e2f7](https://github.com/newrelic/node-newrelic/commit/cb4e2f7a8b84adb6d744a2083b083c92e306fbd5))
23
+ * Reverted restriction in NestJS versioned tests ([#2979](https://github.com/newrelic/node-newrelic/pull/2979)) ([ffddcab](https://github.com/newrelic/node-newrelic/commit/ffddcab6d77bfc10c0df9cbfa724bc1c8f5fb251))
24
+
25
+ #### Tests
26
+
27
+ * Fixed fastify assertions around span kind while running security agent ([#2983](https://github.com/newrelic/node-newrelic/pull/2983)) ([c641645](https://github.com/newrelic/node-newrelic/commit/c6416451f1fa6126b7dfd59f6b9267f9d2188ad0))
28
+
29
+ ### v12.15.0 (2025-03-03)
30
+
31
+ #### Features
32
+
33
+ * Allowed undici error reporting to be disabled with feature flag `undici_error_tracking` ([#2956](https://github.com/newrelic/node-newrelic/pull/2956)) ([6278107](https://github.com/newrelic/node-newrelic/commit/6278107727678c8b45769190c6972c33057067e5))
34
+ * Thanks for your contribution @Voziv :tada:
35
+ * Added ability to propagate traceparent and tracestate on incoming server/consumer spans and outgoing client http and producer spans ([#2958](https://github.com/newrelic/node-newrelic/pull/2958)) ([258ad7d](https://github.com/newrelic/node-newrelic/commit/258ad7de7751df59cf6d68334e342f751bb3a934))
36
+ * Added server span transaction naming fallback to the url.path ([#2966](https://github.com/newrelic/node-newrelic/pull/2966)) ([770bf6f](https://github.com/newrelic/node-newrelic/commit/770bf6fd6ce26642e3fe08b2c1557dd826270516))
37
+ * Updated Context class to ensure bi-directional context propagation with opentelemetry bridge ([#2962](https://github.com/newrelic/node-newrelic/pull/2962)) ([dfeec5a](https://github.com/newrelic/node-newrelic/commit/dfeec5a0443723e7f799db4b9ea7bf4aed5b3bcc))
38
+
39
+ #### Code refactoring
40
+
41
+ * Separated context classes for agent in standard and opentelemetry bridge mode ([#2967](https://github.com/newrelic/node-newrelic/pull/2967)) ([d11c071](https://github.com/newrelic/node-newrelic/commit/d11c071be2504ef442e5aa19fed769ca7a20ceb5))
42
+
43
+ #### Documentation
44
+
45
+ * Updated compatibility report ([#2973](https://github.com/newrelic/node-newrelic/pull/2973)) ([7106c81](https://github.com/newrelic/node-newrelic/commit/7106c818b7add3220d256646cd816dee64efb80a))
46
+
47
+ #### Miscellaneous chores
48
+
49
+ * Added consumer attribute reconciliation ([#2957](https://github.com/newrelic/node-newrelic/pull/2957)) ([8943672](https://github.com/newrelic/node-newrelic/commit/894367239e5e8050da0a38347b81d7186cac0a1f))
50
+ * Added http external span attributes ([#2955](https://github.com/newrelic/node-newrelic/pull/2955)) ([ef697a5](https://github.com/newrelic/node-newrelic/commit/ef697a505ee23f5c2fb2bbe306e90561e66d75c1))
51
+ * Limit nestjs to enable successful CI ([#2972](https://github.com/newrelic/node-newrelic/pull/2972)) ([e9699cf](https://github.com/newrelic/node-newrelic/commit/e9699cf31ff758ff79f44c470bc5f11630117f1c))
52
+ * Refactored otel attribute reconciling ([#2964](https://github.com/newrelic/node-newrelic/pull/2964)) ([1b5ed2c](https://github.com/newrelic/node-newrelic/commit/1b5ed2c2f7c78cb413603124757b9b1c3412ab0a))
53
+
54
+ ### v12.14.0 (2025-02-18)
55
+
56
+ #### Features
57
+
58
+ * Added support for region-prefixed Bedrock models ([#2947](https://github.com/newrelic/node-newrelic/pull/2947)) ([6acf535](https://github.com/newrelic/node-newrelic/commit/6acf5354d1e7f6786da88c0078699e82a714551d))
59
+ * Added attribute reconciliation for message producer spans ([#2942](https://github.com/newrelic/node-newrelic/pull/2942)) ([a9ba396](https://github.com/newrelic/node-newrelic/commit/a9ba39613c78b89c047ca35a218c2eedbb01e3d2))
60
+ * Added timeslice metrics for synthesized consumer segments ([#2938](https://github.com/newrelic/node-newrelic/pull/2938)) ([acfe953](https://github.com/newrelic/node-newrelic/commit/acfe953cf7a656fafb69104384c72f94ddc13000))
61
+
62
+ #### Bug fixes
63
+
64
+ * Fixed queueing of logs from child loggers ([#2945](https://github.com/newrelic/node-newrelic/pull/2945)) ([888cfe8](https://github.com/newrelic/node-newrelic/commit/888cfe84a1ffaf0287682cc9099a2fa762f7a37f))
65
+ * Fixed undici/fetch instrumentation to properly assign the parent-id portion of the `traceparent` header on outgoing requests to the active http external span id ([#2951](https://github.com/newrelic/node-newrelic/pull/2951)) ([bc714cf](https://github.com/newrelic/node-newrelic/commit/bc714cfa8fe6754abf25eb556b8f804c9982f986))
66
+ * Updated `api.recordLogEvent` to no longer truncate the message key in log event ([#2949](https://github.com/newrelic/node-newrelic/pull/2949)) ([8dd557b](https://github.com/newrelic/node-newrelic/commit/8dd557b4dfca2505b7e9f7f030ab094a6ae8019a))
67
+ * Thanks for your contribution @rChaoz 🎉
68
+
69
+ #### Documentation
70
+
71
+ * Updated compatibility report ([#2948](https://github.com/newrelic/node-newrelic/pull/2948)) ([8e32ed7](https://github.com/newrelic/node-newrelic/commit/8e32ed7d7bc456a0693485e7bdef955c25ead29a))
72
+
73
+ ### v12.13.0 (2025-02-12)
74
+
75
+ #### Features
76
+
77
+ * Added timeslice metrics for synthesized server segments ([#2924](https://github.com/newrelic/node-newrelic/pull/2924)) ([f404585](https://github.com/newrelic/node-newrelic/commit/f4045855a1cdbfb74e3217daf8bfa125aa6fe2e4))
78
+ * Added timeslice metrics for synthesized producer segments ([#2939](https://github.com/newrelic/node-newrelic/pull/2939)) ([6832637](https://github.com/newrelic/node-newrelic/commit/68326377dcd23b574abae7c323ff93bc05c525ed))
79
+ * Added timeslice metrics for synthesized database segments ([#2922](https://github.com/newrelic/node-newrelic/pull/2922)) ([8606f78](https://github.com/newrelic/node-newrelic/commit/8606f789772b7651d0c46ad50dad3a1da74e5e9c))
80
+ * Propagate agent root context when opentelemetry `ROOT_CONTEXT` is passed in to trace propagator.([#2940](https://github.com/newrelic/node-newrelic/pull/2940)) ([b85111c](https://github.com/newrelic/node-newrelic/commit/b85111c46797dfbf399faf973e7a3e0ea6bbdc28))
81
+ * Added logic to handle properly naming and ending transactions for server spans.
82
+ * Provided ability to disable instrumentation for core Node.js libraries ([#2927](https://github.com/newrelic/node-newrelic/pull/2927)) ([2d232f1](https://github.com/newrelic/node-newrelic/commit/2d232f16c167e5f84b7b7898a6c5410d9cece55e))
83
+
84
+ #### Bug fixes
85
+
86
+ * Fixed `api.getTraceMetadata` to handle when there is an active transaction but not active segment ([#2944](https://github.com/newrelic/node-newrelic/pull/2944)) ([6db3b4d](https://github.com/newrelic/node-newrelic/commit/6db3b4d53a077a9738dd72d46e1ba1cee0d6af3f))
87
+
88
+ #### Documentation
89
+
90
+ * Updated compatibility report ([#2920](https://github.com/newrelic/node-newrelic/pull/2920)) ([c7ae8be](https://github.com/newrelic/node-newrelic/commit/c7ae8befafa4c91fab6804cd95e20f5a93546ea4))
91
+
92
+ #### Miscellaneous chores
93
+
94
+ * Localized OTEL attribute constants ([#2928](https://github.com/newrelic/node-newrelic/pull/2928)) ([965c41b](https://github.com/newrelic/node-newrelic/commit/965c41b3e64805ac14ae4dd36120b018ec5899f4))
95
+ * Updated import-in-the-middle version ([#2923](https://github.com/newrelic/node-newrelic/pull/2923)) ([aa2781f](https://github.com/newrelic/node-newrelic/commit/aa2781fd9c7bed08d590e33682729a92f21f43a5))
96
+
44
97
  ### v12.12.0 (2025-02-05)
45
98
 
46
99
  #### Features
package/README.md CHANGED
@@ -31,7 +31,7 @@ To use New Relic's Node.js agent entails these three steps, which are described
31
31
 
32
32
  3. Now, add your New Relic license key and application/service name to that file:
33
33
 
34
- ```js
34
+ ```js
35
35
  /* File: newrelic.js */
36
36
  'use strict'
37
37
  /**
@@ -45,30 +45,29 @@ To use New Relic's Node.js agent entails these three steps, which are described
45
45
  license_key: 'your new relic license key',
46
46
  /* ... rest of configuration .. */
47
47
  }
48
- ```
48
+ ```
49
49
 
50
50
  4. Finally, run your program with the `newrelic` module loaded first by using node's `-r/--require` flag.
51
51
 
52
- ```
53
- $ node -r newrelic your-program.js
54
- ```
52
+ ```sh
53
+ $ node -r newrelic your-program.js
54
+ ```
55
55
 
56
- If you cannot control how your program is run, you can load the `newrelic` module _before any other module_ in your program.
56
+ If you cannot control how your program is run, you can load the `newrelic` module _before any other module_ in your program.
57
57
 
58
- ```js
58
+ ```js
59
59
  const newrelic = require('newrelic')
60
60
 
61
61
  /* ... the rest of your program ... */
62
- ```
62
+ ```
63
63
 
64
64
  ## Next.js instrumentation
65
65
  **Note**: The minimum supported Next.js version is [12.0.9](https://github.com/vercel/next.js/releases/tag/v12.0.9). If you are using Next.js middleware the minimum supported version is [12.2.0](https://github.com/vercel/next.js/releases/tag/v12.2.0).
66
66
 
67
- The New Relic Node.js agent provides instrumentation for Next.js The instrumentation provides telemetry for server-side rendering via [getServerSideProps](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props), [middleware](https://nextjs.org/docs/middleware), and New Relic transaction naming for both page and server requests. It does not provide any instrumentation for actions occurring during build or in client-side code. If you want telemetry data on actions occurring on the client (browser), you can [inject the browser agent](./documentation/nextjs/faqs/browser-agent.md).
67
+ The New Relic Node.js agent provides instrumentation for Next.js The instrumentation provides telemetry for server-side rendering via [`getServerSideProps`](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props), [middleware](https://nextjs.org/docs/middleware) (limited to Next.js versions [12.2.0](https://github.com/vercel/next.js/releases/tag/v12.2.0) - [13.4.12](https://github.com/vercel/next.js/releases/tag/v13.4.12)), and New Relic transaction naming for both page and server requests. It does not provide any instrumentation for actions occurring during build or in client-side code. If you want telemetry data on actions occurring on the client (browser), you can [inject the browser agent](./documentation/nextjs/faqs/browser-agent.md).
68
68
 
69
69
  Here are documents for more in-depth explanations about [transaction naming](./documentation/nextjs/transactions.md), and [segments/spans](./documentation/nextjs/segments-and-spans.md).
70
70
 
71
-
72
71
  ### Setup
73
72
  Typically you are running a Next.js app with the `next` cli and you must load the agent via `NODE_OPTIONS`:
74
73
 
@@ -102,15 +101,15 @@ The New Relic Node.js agent includes ***_experimental_*** support for ES Modules
102
101
 
103
102
  1. If you rely on a configuration file to run the agent, you must rename the file from `newrelic.js` to `newrelic.cjs` so it can be properly loaded. All the contents of the configuration file will behave the same once you rename. See [CommonJS modules in ESM](https://nodejs.org/api/modules.html#enabling) for more details.
104
103
 
105
- ```sh
106
- $ mv newrelic.js newrelic.cjs
107
- ```
104
+ ```sh
105
+ $ mv newrelic.js newrelic.cjs
106
+ ```
108
107
 
109
108
  2. To use the newrelic ESM loader, start your program with node and use the `--experimental-loader` flag and a path to the loader file, like this:
110
109
 
111
- ```sh
112
- $ node --experimental-loader newrelic/esm-loader.mjs -r newrelic your-program.js
113
- ```
110
+ ```sh
111
+ $ node --experimental-loader newrelic/esm-loader.mjs -r newrelic your-program.js
112
+ ```
114
113
 
115
114
  **Note**: Unlike the CommonJS methods listed above, there are no alternatives to running the agent without the `--experimental-loader` flag.
116
115
 
@@ -122,11 +121,11 @@ The agent supports adding your own custom instrumentation to ES module applicati
122
121
  import newrelic from 'newrelic'
123
122
  newrelic.instrument({ moduleName: 'parse-json', isEsm: true }, function wrap(shim, parseJson, moduleName) {
124
123
  shim.wrap(parseJson.default, function wrapParseJson(shim, orig) {
125
- return function wrappedParseJson() {
126
- const result = orig.apply(this, arguments)
127
- result.instrumented = true
128
- return true
129
- }
124
+ return function wrappedParseJson() {
125
+ const result = orig.apply(this, arguments)
126
+ result.instrumented = true
127
+ return true
128
+ }
130
129
  })
131
130
  })
132
131
  ```
@@ -151,11 +150,11 @@ For more information on getting started, [check the Node.js docs](https://docs.n
151
150
 
152
151
  There are modules that can be installed and configured to accompany the Node.js agent:
153
152
 
154
- * [@newrelic/apollo-server-plugin](https://github.com/newrelic/newrelic-node-apollo-server-plugin): New Relic's official Apollo Server plugin for use with the Node.js agent.
153
+ * [`@newrelic/apollo-server-plugin`](https://github.com/newrelic/newrelic-node-apollo-server-plugin): New Relic's official Apollo Server plugin for use with the Node.js agent.
155
154
 
156
155
  There are modules included within the Node.js agent to add more instrumentation for 3rd party modules:
157
156
 
158
- * [@newrelic/native-metrics](https://github.com/newrelic/node-native-metrics): Provides hooks into the native v8 layer of Node.js to provide metrics to the Node.js agent.
157
+ * [`@newrelic/native-metrics`](https://github.com/newrelic/node-native-metrics): Provides hooks into the native v8 layer of Node.js to provide metrics to the Node.js agent.
159
158
 
160
159
  ## Usage
161
160
 
@@ -164,10 +163,10 @@ There are modules included within the Node.js agent to add more instrumentation
164
163
  The `newrelic` module returns an object with the Node.js agent's API methods attached.
165
164
 
166
165
  ```js
167
- const newrelic = require('newrelic')
166
+ const newrelic = require('newrelic')
168
167
 
169
- /* ... */
170
- newrelic.addCustomAttribute('some-attribute', 'some-value')
168
+ /* ... */
169
+ newrelic.addCustomAttribute('some-attribute', 'some-value')
171
170
  ```
172
171
 
173
172
  You can read more about using the API over on the [New Relic documentation](https://docs.newrelic.com/docs/agents/nodejs-agent/api-guides/guide-using-nodejs-agent-api) site.
@@ -182,12 +181,16 @@ These are the steps to work on core agent features, with more detail below:
182
181
 
183
182
  1. [Fork](https://github.com/newrelic/node-newrelic/fork) and clone this GitHub repository:
184
183
 
184
+ ```sh
185
185
  $ git clone git@github.com:your-user-name/node-newrelic.git
186
186
  $ cd node-newrelic
187
+ ```
187
188
 
188
189
  2. Install the project's dependencies:
189
190
 
191
+ ```sh
190
192
  $ npm install
193
+ ```
191
194
 
192
195
  Then you're all set to start programming.
193
196
 
@@ -199,11 +202,13 @@ Then you're all set to start programming.
199
202
 
200
203
  Available test suites include:
201
204
 
202
- $ npm run unit
203
- $ npm run integration
204
- $ npm run versioned
205
- $ npm run lint
206
- $ npm run smoke
205
+ ```sh
206
+ $ npm run unit
207
+ $ npm run integration
208
+ $ npm run versioned
209
+ $ npm run lint
210
+ $ npm run smoke
211
+ ```
207
212
 
208
213
  ## Further Reading
209
214
 
package/api.js CHANGED
@@ -992,6 +992,7 @@ API.prototype.startWebTransaction = function startWebTransaction(url, handle) {
992
992
  transaction: tx,
993
993
  parent
994
994
  })
995
+ tx.baseSegment.spanKind = 'server'
995
996
  const newContext = context.enterSegment({ transaction: tx, segment: tx.baseSegment })
996
997
  tx.baseSegment.start()
997
998
 
@@ -1101,6 +1102,7 @@ function startBackgroundTransaction(name, group, handle) {
1101
1102
  parent
1102
1103
  })
1103
1104
  const newContext = context.enterSegment({ transaction: tx, segment: tx.baseSegment })
1105
+ tx.baseSegment.spanKind = 'server'
1104
1106
  tx.baseSegment.partialName = group
1105
1107
  tx.baseSegment.start()
1106
1108
 
package/lib/agent.js CHANGED
@@ -21,7 +21,7 @@ const MetricNormalizer = require('./metrics/normalizer')
21
21
  const MetricAggregator = require('./metrics/metric-aggregator')
22
22
  const NAMES = require('./metrics/names')
23
23
  const QueryTraceAggregator = require('./db/query-trace-aggregator')
24
- const sampler = require('./sampler')
24
+ const systemMetricsSampler = require('./system-metrics-sampler')
25
25
  const TransactionTraceAggregator = require('./transaction/trace/aggregator')
26
26
  const TransactionEventAggregator = require('./transaction/transaction-event-aggregator')
27
27
  const Tracer = require('./transaction/tracer')
@@ -334,7 +334,7 @@ Agent.prototype.start = function start(callback) {
334
334
  return process.nextTick(callback)
335
335
  }
336
336
 
337
- sampler.start(agent)
337
+ systemMetricsSampler.start(agent)
338
338
 
339
339
  if (this.config.serverless_mode.enabled) {
340
340
  return this._serverlessModeStart(callback)
@@ -349,7 +349,7 @@ Agent.prototype.start = function start(callback) {
349
349
  this.healthReporter.setStatus(HealthReporter.STATUS_LICENSE_KEY_MISSING)
350
350
 
351
351
  this.setState('errored')
352
- sampler.stop()
352
+ systemMetricsSampler.stop()
353
353
  return process.nextTick(function onNextTick() {
354
354
  agent.healthReporter.stop(() => {
355
355
  callback(new Error('Not starting without license key!'))
@@ -362,7 +362,7 @@ Agent.prototype.start = function start(callback) {
362
362
  if (error || response.shouldShutdownRun()) {
363
363
  agent.healthReporter.setStatus(HealthReporter.STATUS_CONNECT_ERROR)
364
364
  agent.setState('errored')
365
- sampler.stop()
365
+ systemMetricsSampler.stop()
366
366
  callback(error || new Error('Failed to connect to collector'), response && response.payload)
367
367
  return
368
368
  }
@@ -482,7 +482,7 @@ Agent.prototype.stop = function stop(callback) {
482
482
 
483
483
  this.harvester.stop()
484
484
 
485
- sampler.stop()
485
+ systemMetricsSampler.stop()
486
486
 
487
487
  this.healthReporter.setStatus(HealthReporter.STATUS_AGENT_SHUTDOWN)
488
488
  this.healthReporter.stop(() => {
@@ -7,6 +7,7 @@
7
7
 
8
8
  const { AsyncLocalStorage } = require('async_hooks')
9
9
  const Context = require('./context')
10
+ const OtelContext = require('../otel/context')
10
11
 
11
12
  /**
12
13
  * Class for managing state in the agent.
@@ -18,7 +19,8 @@ const Context = require('./context')
18
19
  * @class
19
20
  */
20
21
  class AsyncLocalContextManager {
21
- constructor() {
22
+ constructor(isOtelBridgeMode) {
23
+ this.isOtelBridgeMode = isOtelBridgeMode
22
24
  this._asyncLocalStorage = new AsyncLocalStorage()
23
25
  }
24
26
 
@@ -28,7 +30,7 @@ class AsyncLocalContextManager {
28
30
  * @returns {object} The current active context.
29
31
  */
30
32
  getContext() {
31
- return this._asyncLocalStorage.getStore() || new Context()
33
+ return this._asyncLocalStorage.getStore() || (this.isOtelBridgeMode ? new OtelContext() : new Context())
32
34
  }
33
35
 
34
36
  /**
@@ -4,13 +4,11 @@
4
4
  */
5
5
 
6
6
  'use strict'
7
- const { otelSynthesis } = require('../symbols')
8
7
 
9
8
  module.exports = class Context {
10
- constructor(transaction, segment, parentContext) {
9
+ constructor(transaction, segment) {
11
10
  this._transaction = transaction
12
11
  this._segment = segment
13
- this._otelCtx = parentContext ? new Map(parentContext) : new Map()
14
12
  }
15
13
 
16
14
  get segment() {
@@ -21,58 +19,27 @@ module.exports = class Context {
21
19
  return this._transaction
22
20
  }
23
21
 
24
- enterSegment({ segment, transaction = this._transaction }) {
25
- return new this.constructor(transaction, segment)
26
- }
27
-
28
- enterTransaction(transaction) {
29
- return new this.constructor(transaction, transaction.trace.root)
30
- }
31
-
32
- /**
33
- * Required for bridging OTEL data into the agent.
34
- *
35
- * @param {string} key Stored entity name to retrieve.
36
- *
37
- * @returns {*} The stored value.
38
- */
39
- getValue(key) {
40
- return this._otelCtx.get(key)
41
- }
42
-
43
22
  /**
44
- * Required for bridging OTEL data into the agent.
23
+ * Constructs a new context from segment about to be bound to context manager
24
+ * along with the current transaction.
45
25
  *
46
- * @param {string} key Name for stored value.
47
- * @param {*} value Value to store.
48
- *
49
- * @returns {object} The context manager object.
26
+ * @param {object} params to function
27
+ * @param {TraceSegment} params.segment segment to bind to context
28
+ * @param {Transaction} params.transaction active transaction
29
+ * @returns {Context} a newly constructed context
50
30
  */
51
- setValue(key, value) {
52
- let ctx
53
-
54
- if (value[otelSynthesis] && value[otelSynthesis].segment && value[otelSynthesis].transaction) {
55
- const { segment, transaction } = value[otelSynthesis]
56
- segment.start()
57
- ctx = new this.constructor(transaction, segment, this._otelCtx)
58
- } else {
59
- ctx = new this.constructor(this._transaction, this._segment, this._otelCtx)
60
- }
61
-
62
- ctx._otelCtx.set(key, value)
63
- return ctx
31
+ enterSegment({ segment, transaction = this._transaction }) {
32
+ return new this.constructor(transaction, segment)
64
33
  }
65
34
 
66
35
  /**
67
- * Required for bridging OTEL data into the agent.
68
- *
69
- * @param {string} key Named value to remove from the store.
36
+ * Constructs a new context from transaction about to be bound to context manager.
37
+ * It uses the trace root segment as the segment in context.
70
38
  *
71
- * @returns {object} The context manager object.
39
+ * @param {Transaction} transaction transaction to bind to context
40
+ * @returns {Context} a newly constructed context
72
41
  */
73
- deleteValue(key) {
74
- const ctx = new this.constructor(this._transaction, this._segment, this._otelCtx)
75
- ctx._otelCtx.delete(key)
76
- return ctx
42
+ enterTransaction(transaction) {
43
+ return new this.constructor(transaction, transaction.trace.root)
77
44
  }
78
45
  }
@@ -215,8 +215,9 @@ class ErrorCollector {
215
215
  * @param {?Transaction} transaction Transaction associated with the error.
216
216
  * @param {Error} error The error to be traced.
217
217
  * @param {?object} customAttributes Custom attributes associated with the request (optional).
218
+ * @param {object} segment The segment associated with the error (optional). Only used in otel bridge.
218
219
  */
219
- add(transaction, error, customAttributes) {
220
+ add(transaction, error, customAttributes, segment) {
220
221
  if (!error) {
221
222
  return
222
223
  }
@@ -236,7 +237,7 @@ class ErrorCollector {
236
237
  const exception = new Exception({ error, timestamp, customAttributes })
237
238
 
238
239
  if (transaction) {
239
- transaction.addException(exception)
240
+ transaction.addException(exception, segment)
240
241
  } else {
241
242
  this.collect(transaction, exception)
242
243
  }
@@ -14,7 +14,8 @@ exports.prerelease = {
14
14
  promise_segments: false,
15
15
  reverse_naming_rules: false,
16
16
  unresolved_promise_cleanup: true,
17
- kafkajs_instrumentation: false
17
+ kafkajs_instrumentation: false,
18
+ undici_error_tracking: true
18
19
  }
19
20
 
20
21
  // flags that are no longer used for released features
@@ -42,7 +42,7 @@ function wrapConsumer(shim, orig) {
42
42
  consumer,
43
43
  'run',
44
44
  new MessageSubscribeSpec({
45
- name: `${SEGMENT_PREFIX}#run`,
45
+ name: `${SEGMENT_PREFIX}run`,
46
46
  destinationType: shim.TOPIC,
47
47
  promise: true,
48
48
  consumer: shim.FIRST,
@@ -192,6 +192,7 @@ function requestHeadersHook(shim, { request, response }) {
192
192
  * @param {Error} params.error error from undici request
193
193
  */
194
194
  function endAndRestoreSegment(shim, { request, error }) {
195
+ const { config } = shim.agent
195
196
  const activeSegment = request[symbols.segment]
196
197
  const parentSegment = request[symbols.parentSegment]
197
198
  const tx = request[symbols.transaction]
@@ -199,7 +200,7 @@ function endAndRestoreSegment(shim, { request, error }) {
199
200
  activeSegment.end()
200
201
  }
201
202
 
202
- if (error && tx) {
203
+ if (error && tx && config.feature_flag.undici_error_tracking === true) {
203
204
  handleError(shim, tx, error)
204
205
  }
205
206
 
@@ -0,0 +1,52 @@
1
+ /*
2
+ * Copyright 2025 New Relic Corporation. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ 'use strict'
7
+
8
+ const urltils = require('../util/urltils')
9
+ const constants = require('./constants')
10
+
11
+ const hostKeys = [
12
+ constants.ATTR_NET_HOST_NAME,
13
+ constants.ATTR_NET_PEER_NAME,
14
+ constants.ATTR_SERVER_ADDRESS
15
+ ]
16
+
17
+ class AttributeReconciler {
18
+ #agent
19
+
20
+ constructor({ agent }) {
21
+ this.#agent = agent
22
+ }
23
+
24
+ #resolveHost(hostname) {
25
+ if (urltils.isLocalhost(hostname)) {
26
+ return this.#agent.config.getHostnameSafe(hostname)
27
+ }
28
+ return hostname
29
+ }
30
+
31
+ #isHostnameKey(key) {
32
+ return hostKeys.includes(key)
33
+ }
34
+
35
+ reconcile({ segment, otelSpan, mapper = {} }) {
36
+ for (const [key, srcValue] of Object.entries(otelSpan.attributes)) {
37
+ let value = srcValue
38
+
39
+ if (this.#isHostnameKey(key) === true) {
40
+ value = this.#resolveHost(srcValue)
41
+ }
42
+
43
+ if (Object.prototype.hasOwnProperty.call(mapper, key) === true) {
44
+ mapper[key](value)
45
+ } else {
46
+ segment.addAttribute(key, value)
47
+ }
48
+ }
49
+ }
50
+ }
51
+
52
+ module.exports = AttributeReconciler