Skip to content

Commit d0c3b96

Browse files
committed
refactor: Moved relevant nextjs instrumentation and rely on agent commons
1 parent bfdc9a5 commit d0c3b96

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+262
-2896
lines changed

.eslintrc.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ module.exports = {
3434
parserOptions: {
3535
ecmaVersion: 2022
3636
},
37-
ignorePatterns: ['test/versioned-external'],
37+
ignorePatterns: [
38+
'test/versioned-external',
39+
'test/versioned/nextjs/app',
40+
'test/versioned/nextjs/app-dir'
41+
],
3842
overrides: [
3943
{
4044
files: ['**/*.mjs'],

README.md

+31
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,37 @@ If you cannot control how your program is run, you can load the `newrelic` modul
6161
/* ... the rest of your program ... */
6262
```
6363

64+
## Next.js instrumentation
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+
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).
68+
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+
71+
72+
### Setup
73+
Typically you are running a Next.js app with the `next` cli and you must load the agent via `NODE_OPTIONS`:
74+
75+
```sh
76+
NODE_OPTIONS='-r newrelic' next start
77+
```
78+
79+
If you are having trouble getting the `newrelic` package to instrument Next.js, take a look at our [FAQs](./documentation/nextjs/faqs/README.md).
80+
81+
### Next.js example projects
82+
The following example applications show how to load the `newrelic` instrumentation, inject browser agent, and handle errors:
83+
84+
* [Pages Router example](https://github.com/newrelic/newrelic-node-examples/tree/58f760e828c45d90391bda3f66764d4420ba4990/nextjs-legacy)
85+
* [App Router example](https://github.com/newrelic/newrelic-node-examples/tree/58f760e828c45d90391bda3f66764d4420ba4990/nextjs-app-router)
86+
87+
### Custom Next.js servers
88+
89+
If you are using next as a [custom server](https://nextjs.org/docs/advanced-features/custom-server), you're probably not running your application with the `next` CLI. In that scenario we recommend running the Next.js instrumentation as follows.
90+
91+
```sh
92+
node -r newrelic your-program.js
93+
```
94+
6495
## ECMAScript Modules
6596

6697
If your application is written with `import` and `export` statements in javascript, you are using [ES Modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules) and must bootstrap the agent in a different way.

THIRD_PARTY_NOTICES.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1284,7 +1284,7 @@ This product includes source derived from [@aws-sdk/client-s3](https://github.co
12841284

12851285
### @aws-sdk/s3-request-presigner
12861286

1287-
This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.616.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.616.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.616.0/LICENSE):
1287+
This product includes source derived from [@aws-sdk/s3-request-presigner](https://github.com/aws/aws-sdk-js-v3) ([v3.614.0](https://github.com/aws/aws-sdk-js-v3/tree/v3.614.0)), distributed under the [Apache-2.0 License](https://github.com/aws/aws-sdk-js-v3/blob/v3.614.0/LICENSE):
12881288

12891289
```
12901290
Apache License
@@ -3110,7 +3110,7 @@ THE SOFTWARE.
31103110

31113111
### eslint-plugin-jsdoc
31123112

3113-
This product includes source derived from [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) ([v48.8.3](https://github.com/gajus/eslint-plugin-jsdoc/tree/v48.8.3)), distributed under the [BSD-3-Clause License](https://github.com/gajus/eslint-plugin-jsdoc/blob/v48.8.3/LICENSE):
3113+
This product includes source derived from [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) ([v48.7.0](https://github.com/gajus/eslint-plugin-jsdoc/tree/v48.7.0)), distributed under the [BSD-3-Clause License](https://github.com/gajus/eslint-plugin-jsdoc/blob/v48.7.0/LICENSE):
31143114

31153115
```
31163116
Copyright (c) 2018, Gajus Kuizinas (http://gajus.com/)
File renamed without changes.

merged/nextjs/docs/faqs/cloud-providers.md documentation/nextjs/faqs/cloud-providers.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Deploy Next.js to Cloud Provider
22

3-
Q: Can `@newrelic/next` work when deploying to [Vercel](https://vercel.com/frameworks/nextjs), [AWS Amplify](https://aws.amazon.com/amplify/), [Netlify](https://www.netlify.com/with/nextjs/), [Azure Static Sites](https://azure.microsoft.com/en-us/products/app-service/static), etc?
3+
Q: Can Next.js instrumentation work when deploying to [Vercel](https://vercel.com/frameworks/nextjs), [AWS Amplify](https://aws.amazon.com/amplify/), [Netlify](https://www.netlify.com/with/nextjs/), [Azure Static Sites](https://azure.microsoft.com/en-us/products/app-service/static), etc?
44

5-
A: The short answer is no. Most of these cloud providers lack the ability to control run options to load `@newrelic/next`. Also, most of these cloud providers execute code in a Function as a Service(FaaS) environment. Our agent requires a different setup and then additional processes to load the telemetry. Our recommendation is to rely on OpenTelemetry and load the telemetry via our OTLP endpoint.
5+
A: The short answer is no. Most of these cloud providers lack the ability to control run options to load the New Relic Node.js agent. Also, most of these cloud providers execute code in a Function as a Service(FaaS) environment. Our agent requires a different setup and then additional processes to load the telemetry. Our recommendation is to rely on OpenTelemetry and load the telemetry via our OTLP endpoint.
66

77
## OpenTelemetry setup with New Relic
88

merged/nextjs/docs/faqs/error-handling.md documentation/nextjs/faqs/error-handling.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Injecting Browser Agent
22

3-
Q: How can I get `@newrelic/next` to log errors to [New Relic Errors Inbox](https://docs.newrelic.com/docs/errors-inbox/errors-inbox/)?
3+
Q: How can I get the Next.js instrumentation to log errors to [New Relic Errors Inbox](https://docs.newrelic.com/docs/errors-inbox/errors-inbox/)?
44

55
A: The Node.js agent has an API to log errors `newrelic.noticeError`. Next.js has an error page that can be used to add the API call.
66

merged/nextjs/docs/faqs/instrument-third-party-libraries.md documentation/nextjs/faqs/instrument-third-party-libraries.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ A: Typically the New Relic Node.js agent auto-instruments all supported [3rd par
99
To externalize all supported 3rd party libraries, add the following to `next.config.js`:
1010

1111
```js
12-
const nrExternals = require('@newrelic/next/load-externals')
12+
const nrExternals = require('newrelic/load-externals')
1313

1414
module.exports = {
1515
// In order for newrelic to effectively instrument a Next.js application,
File renamed without changes.

merged/nextjs/lib/next-server.js lib/instrumentation/nextjs/next-server.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const {
1111
MIN_MW_SUPPORTED_VERSION,
1212
MAX_MW_SUPPORTED_VERSION
1313
} = require('./utils')
14+
const { RecorderSpec } = require('../../shim/specs')
1415
const SPAN_PREFIX = 'Nodejs/Nextjs'
1516
const GET_SERVER_SIDE_PROP_VERSION = '13.4.5'
1617

@@ -35,8 +36,8 @@ module.exports = function initialize(shim, nextServer) {
3536
semver.gte(nextVersion, GET_SERVER_SIDE_PROP_VERSION) &&
3637
components.getServerSideProps
3738
) {
38-
shim.record(components, 'getServerSideProps', function recordGetServerSideProps(shim) {
39-
return new shim.specs.RecorderSpec({
39+
shim.record(components, 'getServerSideProps', function recordGetServerSideProps() {
40+
return new RecorderSpec({
4041
inContext(segment) {
4142
segment.addSpanAttributes({ 'next.page': pathname })
4243
assignCLMAttrs(config, segment, {
@@ -81,7 +82,7 @@ module.exports = function initialize(shim, nextServer) {
8182
Server.prototype,
8283
'renderHTML',
8384
function renderHTMLRecorder(shim, renderToHTML, name, [, , page]) {
84-
return new shim.specs.RecorderSpec({
85+
return new RecorderSpec({
8586
inContext(segment) {
8687
segment.addSpanAttributes({ 'next.page': page })
8788
assignCLMAttrs(config, segment, {
@@ -106,7 +107,7 @@ module.exports = function initialize(shim, nextServer) {
106107

107108
shim.record(Server.prototype, 'runMiddleware', function runMiddlewareRecorder(shim) {
108109
const middlewareName = 'middleware'
109-
return new shim.specs.RecorderSpec({
110+
return new RecorderSpec({
110111
type: shim.MIDDLEWARE,
111112
name: `${shim._metrics.MIDDLEWARE}${shim._metrics.PREFIX}/${middlewareName}`,
112113
inContext(segment) {
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2022 New Relic Corporation. All rights reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
'use strict'
7+
const InstrumentationDescriptor = require('../../instrumentation-descriptor')
8+
9+
// TODO: Remove once we update agent instrumentation to not rely on full required path within Node.js
10+
// When running Next.js app as a standalone server this is how the next-server is getting loaded
11+
module.exports = [
12+
{
13+
type: InstrumentationDescriptor.TYPE_WEB_FRAMEWORK,
14+
moduleName: 'next/dist/server/next-server',
15+
onRequire: require('./next-server')
16+
},
17+
{
18+
type: InstrumentationDescriptor.TYPE_WEB_FRAMEWORK,
19+
moduleName: './next-server',
20+
onRequire: require('./next-server')
21+
}
22+
]
File renamed without changes.

lib/instrumentations.js

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ module.exports = function instrumentations() {
3434
'memcached': { type: InstrumentationDescriptor.TYPE_DATASTORE },
3535
'mongodb': { type: InstrumentationDescriptor.TYPE_DATASTORE },
3636
'mysql': { module: './instrumentation/mysql' },
37+
'next': { module: './instrumentation/nextjs' },
3738
'openai': { type: InstrumentationDescriptor.TYPE_GENERIC },
3839
'pg': { type: InstrumentationDescriptor.TYPE_DATASTORE },
3940
'pino': { module: './instrumentation/pino' },

merged/nextjs/load-externals.js load-externals.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
'use strict'
7-
const instrumentedLibraries = require('newrelic/lib/instrumentations')() || {}
7+
const instrumentedLibraries = require('./lib/instrumentations')() || {}
88
const libNames = Object.keys(instrumentedLibraries)
99
module.exports = function loadExternals(config) {
1010
if (config.target.includes('node')) {

merged/nextjs/.c8rc.json

-5
This file was deleted.

merged/nextjs/.eslintignore

-1
This file was deleted.

merged/nextjs/.eslintrc.js

-13
This file was deleted.

merged/nextjs/.github/ISSUE_TEMPLATE/bug_report.md

-41
This file was deleted.

merged/nextjs/.github/ISSUE_TEMPLATE/config.yml

-5
This file was deleted.

merged/nextjs/.github/ISSUE_TEMPLATE/feature_request.md

-24
This file was deleted.

merged/nextjs/.github/PULL_REQUEST_TEMPLATE.md

-27
This file was deleted.

merged/nextjs/.github/dependabot.yml

-13
This file was deleted.

merged/nextjs/.github/workflows/add-to-board.yml

-14
This file was deleted.

0 commit comments

Comments
 (0)