New Relic
Description
Assemble Web is connected to New Relic with both back-end and browser observability.
By default, New Relic is enabled on production builds. On local/development builds, it’s disabled by default with an opt-in option to enable it.
Setup
You can follow the steps described in New Relic’s official blog. Make sure you have your license key ready beforehand.
From New Relic’s dashboard, you want to create a new Node integration using npm. Once the AMP entity is set up, you will then create another integration with Next.js as the technology and connect it to your already instrumented application with AMP.
Configuration File
Assemble has a newrelic.js agent configuration file that needs to be located at the root of the project. Notice that both app_name and license_key are omitted in the file. This is because they are instead being passed as their environment variable equivalent: NEW_RELIC_APP_NAME & NEW_RELIC_LICENSE_KEY.
Although Next.js by default handles multiple environment configuration files such as .env.development and .env.production, the New Relic config file by default is initialized with the environment variables of .env. Because of this, make sure to set both of these variables locally if you want to run the new relic agent in your dev server
NEW_RELIC_APP_NAME=...
NEW_RELIC_LICENSE_KEY=...
These variables are being passed to the CI process via Github Actions. To run the agent locally, start the dev server through the dev:nr script
The script is injected in layout.tsx, with a validation to wait for the Agent API to be connected
if (ENABLE_NEW_RELIC && !newrelic.agent.collector.isConnected()) {
await new Promise((resolve) => {
newrelic.agent.on("connected", resolve);
});
}
const browserTimingHeader = newrelic.getBrowserTimingHeader({
hasToRemoveScriptWrapper: true,
allowTransactionlessInjection: true,
});
// ...
{ENABLE_NEW_RELIC && (
<Script
// We have to set an id for inline scripts.
// See https://nextjs.org/docs/app/building-your-application/optimizing/scripts#inline-scripts
id="nr-browser-agent"
// By setting the strategy to "beforeInteractive" we guarantee that
// the script will be added to the document's `head` element.
strategy="beforeInteractive"
// The body of the script element comes from the async evaluation
// of `getInitialProps`. We use the special
// `dangerouslySetInnerHTML` to provide that element body. Since
// it requires an object with an `__html` property, we pass in an
// object literal.
dangerouslySetInnerHTML={{ __html: browserTimingHeader }}
/>
)}