Skip to content

Commit

Permalink
Merge pull request #215 from NYPL/DR-3235/new-relic-browser-update
Browse files Browse the repository at this point in the history
DR-3235: New Relic browser update
  • Loading branch information
EdwinGuzman authored Oct 25, 2024
2 parents 6f30a46 + d7f7d2c commit c03f650
Show file tree
Hide file tree
Showing 12 changed files with 401 additions and 817 deletions.
6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ API_CACHE=false # Optional, controls whether or not api responses are cached
DC_URL='' # OR https://qa-digitalcollections.nypl.org OR https://digitalcollections.nypl.org

# Feedback form
CLIENT_ID= # Available in parameter store
CLIENT_SECRET= # Available in parameter store
CLIENT_EMAIL= # Available in parameter store

GOOGLE_SHEETS_PRIVATE_KEY=[YOUR KEY] # Available in parameter store
GOOGLE_SHEETS_CLIENT_EMAIL=[YOUR ACCOUNT EMAIL] # Available in parameter store
SPREADSHEET_ID=[YOU CAN GET THIS ON URL OF YOUR SHEETS] # Available in parameter store

# New Relic
NEW_RELIC_LICENSE_KEY=[NEWRELIC LICENSE KEY] # Available in parameter store
NEW_RELIC_APP_NAME="Facelift QA"

# Adobe Analytics
ADOBE_EMBED_URL=https://assets.adobedtm.com/1a9376472d37/8519dfce636d/launch-bf8436264b01-development.min.js
APP_ENV=development
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

### Updated
- update links in QA to point internally for reverse proxy (DR-3237)

- Updated links in QA to point internally for reverse proxy (DR-3237)
- Updated how env vars are read for New Relic Browser implementation (DR-3235)

## [0.1.15] 2024-10-10

### Updated

- Updated 500 and 404 error page designs, adding link to open feedback box (DR-3203)
Expand Down
8 changes: 7 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@ COPY . .

ENV APP_ENV=${APP_ENV}
ENV NEW_RELIC_LICENSE_KEY=${NEW_RELIC_LICENSE_KEY}
ENV NEW_RELIC_APP_NAME="Facelift ${APP_ENV}"
ENV API_URL=${API_URL}
ENV AUTH_TOKEN=${AUTH_TOKEN}

# Create a `.env.prod` file with the environment variables
# This is a workaround to use environment variables in the `newrelic.js` file
RUN echo "NEW_RELIC_LICENSE_KEY=${NEW_RELIC_LICENSE_KEY}" >> /etc/.env.prod
RUN echo "NEW_RELIC_APP_NAME=${NEW_RELIC_APP_NAME}" >> /etc/.env.prod

# Set environment variables. NODE_ENV is set early because we
# want to use it when running `npm install` and `npm run build`.
ENV PATH /app/node_modules/.bin:$PATH
Expand All @@ -35,4 +41,4 @@ RUN npm run build
EXPOSE 3000

# CMD is the default command when running the docker container.
CMD [ "npm", "start" ]
CMD [ "npm", "run", "start:newrelic" ]
12 changes: 12 additions & 0 deletions ENVIRONMENTVARS.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,15 @@ These environment variables control how certain elements on the page render and
| `GOOGLE_SHEETS_PRIVATE_KEY` | string | "" | |
| `SPREADSHEET_ID` | string | "" | |
| `NEW_RELIC_LICENSE_KEY` | string | "true" | |

## New Relic Variables

The following variables are needed in the global env var scope in order for New
Relic to pick up the values, specifically in the `newrelic.js` file.

These env vars are not picked up by default in Next.js' `.env.local` file. In order for this to work, the `dotenv` package is used to declare these env vars when running either `npm run dev:newrelic` or `npm run start:newrelic`.

| Variable | Type | Value Example | Description |
| ----------------------- | ------ | -------------- | -------------------------------------------------- |
| `NEW_RELIC_LICENSE_KEY` | string | "true" | Private license key. Available in parameter store. |
| `NEW_RELIC_APP_NAME` | string | "Facelift QA" | |
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ You can start editing the page by modifying `pages/index.tsx`. The page auto-upd

The `app/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.

### New Relic Start

If New Relic needs to run locally, run `npm run dev:newrelic`. You must have `NEW_NEW_RELIC_LICENSE_KEY` and `NEW_RELIC_APP_NAME` declared in `.env.local` in order for this to run successfully.

## Environment Variables

A quick note on environment variables
Expand Down
8 changes: 7 additions & 1 deletion app/error.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";
import PageLayout from "./src/components/pageLayout/pageLayout";
import { useEffect } from "react";

import PageLayout from "./src/components/pageLayout/pageLayout";
import ErrorPage from "./src/components/pages/errorPage/errorPage";

export default function Error({
Expand All @@ -10,6 +11,11 @@ export default function Error({
}) {
useEffect(() => {
console.error(error);

// Send error to New Relic
if ((window as any).newrelic) {
(window as any).newrelic.noticeError(error);
}
}, [error]);

return (
Expand Down
28 changes: 25 additions & 3 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import Script from "next/script";
import React from "react";
import newrelic from "newrelic";
import { Metadata } from "next";
import "./globals.css";
import { headers } from "next/headers";
import Script from "next/script";

import "./globals.css";

export const metadata: Metadata = {
title: "NYPL Digital Collections",
Expand Down Expand Up @@ -57,11 +59,24 @@ export async function generateViewport() {
: {};
}

export default function RootLayout({
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
// Not ideal but `any` for now.
const newRelicTyped: any = newrelic;
// Track data for New Relic Browser
if (newRelicTyped?.agent?.collector?.isConnected() === false) {
await new Promise((resolve) => {
newRelicTyped?.agent?.on("connected", resolve);
});
}
const browserTimingHeader = newRelicTyped?.getBrowserTimingHeader({
hasToRemoveScriptWrapper: true,
allowTransactionlessInjection: true,
});

return (
<html lang="en">
<head>
Expand All @@ -84,6 +99,13 @@ export default function RootLayout({
src="https://ds-header.nypl.org/footer.min.js?containerId=nypl-footer"
async
></Script>
<Script
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"
dangerouslySetInnerHTML={{ __html: browserTimingHeader }}
/>
</body>
</html>
);
Expand Down
9 changes: 1 addition & 8 deletions newrelic.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,8 @@
* See lib/config/default.js in the agent distribution for a more complete
* description of configuration variables and their potential values.
*/

exports.config = {
/**
* Array of application names.
*/
app_name: [`Facelift ${process.env.APP_ENV}`],
/**
* Your New Relic license key.
*/
license_key: process.env.NEW_RELIC_LICENSE_KEY,
logging: {
/**
* Level at which to log. 'trace' is most useful to New Relic when diagnosing
Expand Down
19 changes: 19 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
/** @type {import('next').NextConfig} */

const nrExternals = require("@newrelic/next/load-externals");
// This is found in the codebase example but both seem to work and send data
// correctly. Keep the above but can use the bottom for debugging.
// const nrExternals = require('newrelic/load-externals');

const nextConfig = {
experimental: {
// Without this setting, the Next.js compilation step will routinely
// try to import files such as `LICENSE` from the `newrelic` module.
// See https://nextjs.org/docs/app/api-reference/next-config-js/serverComponentsExternalPackages.
serverComponentsExternalPackages: ["newrelic"],
},
reactStrictMode: false,
env: {
DC_URL: process.env.DC_URL,
IIIF_URL: process.env.IIIF_URL,
ADOBE_EMBED_URL: process.env.ADOBE_EMBED_URL,
APP_ENV: process.env.APP_ENV,
NEW_RELIC_LICENSE_KEY: process.env.NEW_RELIC_LICENSE_KEY,
NEW_RELIC_APP_NAME: `${process.env.NEW_RELIC_APP_NAME} ${process.env.APP_ENV}`,
},
images: {
remotePatterns: [
Expand All @@ -22,6 +34,13 @@ const nextConfig = {
],
},
generateEtags: false,
// In order for newrelic to effectively instrument a Next.js application,
// the modules that newrelic supports should not be mangled by webpack. Thus,
// we need to "externalize" all of the modules that newrelic supports.
webpack: (config) => {
nrExternals(config);
return config;
},
};

module.exports = nextConfig;
Loading

0 comments on commit c03f650

Please sign in to comment.