@newskit-render/core 4.13.9 → 4.14.0-alpha.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.
Files changed (40) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/Dockerfile.withNewRelic +15 -0
  3. package/config/environment.ts +4 -2
  4. package/helpers/__tests__/logger.test.ts +62 -0
  5. package/helpers/logger/getWinstonLogger.ts +19 -0
  6. package/helpers/logger/index.ts +20 -0
  7. package/helpers/logger/replaceConsoleWithLogger.ts +14 -0
  8. package/infrastructure/.circleci/config.yml +5 -1
  9. package/newrelic.js +6 -1
  10. package/package.json +10 -5
  11. package/pages/[section]/[articleId]/[articleSlug].tsx +2 -2
  12. package/pages/[section]/[articleId]/relatedArticles.tsx +2 -2
  13. package/pages/[section]/index.tsx +2 -2
  14. package/pages/_app.tsx +0 -7
  15. package/pages/_document.tsx +9 -10
  16. package/pages/_error.tsx +1 -6
  17. package/pages/account/add/[field].tsx +2 -2
  18. package/pages/account/cancellation/index.tsx +2 -2
  19. package/pages/account/dream-team/index.tsx +2 -2
  20. package/pages/account/edit/[field].tsx +2 -2
  21. package/pages/account/holiday-stop/index.tsx +2 -2
  22. package/pages/account/holiday-stop/previous-holiday-stops.tsx +2 -2
  23. package/pages/account/holiday-stop/upcoming-holiday-stops.tsx +2 -2
  24. package/pages/account/index.tsx +2 -2
  25. package/pages/account/newsletters-and-alerts/index.tsx +2 -2
  26. package/pages/account/payment/[paymentMethod].tsx +2 -2
  27. package/pages/account/payment/index.tsx +2 -2
  28. package/pages/account/payment-methods/index.tsx +2 -2
  29. package/pages/account/subscription-and-billing/index.tsx +2 -2
  30. package/pages/help-hub/article/[title]/index.tsx +3 -4
  31. package/pages/help-hub/error.tsx +2 -4
  32. package/pages/help-hub/index.tsx +3 -4
  33. package/pages/help-hub/results.tsx +2 -2
  34. package/pages/index.tsx +2 -5
  35. package/scripts/nr-exports.sh +7 -0
  36. package/temp/_app.tsx +0 -7
  37. package/temp/_document.tsx +13 -12
  38. package/helpers/__tests__/getCircularReplacer.test.ts +0 -17
  39. package/helpers/getCircularReplacer.ts +0 -12
  40. package/helpers/logger.ts +0 -24
package/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [4.13.9](https://github.com/newscorp-ghfb/ncu-newskit-render/compare/@newskit-render/core@4.13.9-alpha.1...@newskit-render/core@4.13.9) (2023-08-16)
7
+
8
+ **Note:** Version bump only for package @newskit-render/core
9
+
10
+
11
+
12
+
13
+
6
14
  ## [4.13.8](https://github.com/newscorp-ghfb/ncu-newskit-render/compare/@newskit-render/core@4.13.8-alpha.0...@newskit-render/core@4.13.8) (2023-08-02)
7
15
 
8
16
  **Note:** Version bump only for package @newskit-render/core
@@ -0,0 +1,15 @@
1
+ FROM node:18.17-buster
2
+
3
+ WORKDIR /app
4
+
5
+ ENV NEXT_TELEMETRY_DISABLED 1
6
+
7
+ RUN npm install @newrelic/next
8
+ COPY .next/standalone ./standalone
9
+ COPY public ./standalone/public
10
+ COPY .next/static ./standalone/.next/static
11
+
12
+ EXPOSE 3000
13
+ ENV PORT 3000
14
+
15
+ CMD ["node", "-r", "@newrelic/next", "./standalone/server.js"]
@@ -27,7 +27,8 @@ export const getSanitizedConfig = () => {
27
27
  sitemapFirstPublicationDate: process.env
28
28
  .SITEMAP_FIRST_PUBLICATION_DATE as string,
29
29
  sitemapPublicationName: process.env.SITEMAP_PUBLICATION_NAME as string,
30
- newRelicEnabled: process.env.NEW_RELIC_ENABLED as string,
30
+ winstonEnabled: process.env.WINSTON_ENABLED as string,
31
+ winstonLogLevel: process.env.WINSTON_LOG_LEVEL as string,
31
32
  experimentationWeb: process.env.EXPERIMENTATION_WEB as string,
32
33
  sourcepointAccountId: process.env.SOURCEPOINT_ACCOUNT_ID as string,
33
34
  sourcepointPropertyHref: process.env.SOURCEPOINT_PROPERTY_HREF as string,
@@ -58,7 +59,8 @@ export const {
58
59
  optimizelysdkKey,
59
60
  sitemapFirstPublicationDate,
60
61
  sitemapPublicationName,
61
- newRelicEnabled,
62
+ winstonEnabled,
63
+ winstonLogLevel,
62
64
  experimentationWeb,
63
65
  sourcepointAccountId,
64
66
  sourcepointPropertyHref,
@@ -0,0 +1,62 @@
1
+ import { replaceConsoleWithLogger } from '../logger'
2
+
3
+ describe('logger', () => {
4
+ const { window } = global
5
+
6
+ const loggerMock = {
7
+ debug: jest.fn(),
8
+ warn: jest.fn(),
9
+ info: jest.fn(),
10
+ error: jest.fn(),
11
+ }
12
+
13
+ beforeEach(() => {
14
+ delete global.window
15
+ jest.resetAllMocks()
16
+ })
17
+ afterEach(() => {
18
+ global.window = window
19
+ })
20
+
21
+ it('should not replace console.log with Wintson', () => {
22
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'false')
23
+ replaceConsole()
24
+ console.log('test')
25
+ expect(loggerMock.info).not.toBeCalledWith('test')
26
+ })
27
+
28
+ it('should replace console.log with Wintson', () => {
29
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'true')
30
+ replaceConsole()
31
+ console.log('test')
32
+ expect(loggerMock.info).toBeCalledWith('test')
33
+ })
34
+
35
+ it('should replace console.info with Wintson', () => {
36
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'true')
37
+ replaceConsole()
38
+ console.info('test')
39
+ expect(loggerMock.info).toBeCalledWith('test')
40
+ })
41
+
42
+ it('should replace console.warn with Wintson', () => {
43
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'true')
44
+ replaceConsole()
45
+ console.warn('test')
46
+ expect(loggerMock.warn).toBeCalledWith('test')
47
+ })
48
+
49
+ it('should replace console.error with Wintson', () => {
50
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'true')
51
+ replaceConsole()
52
+ console.error('test')
53
+ expect(loggerMock.error).toBeCalledWith('test')
54
+ })
55
+
56
+ it('should replace console.debug with Wintson', () => {
57
+ const replaceConsole = replaceConsoleWithLogger(loggerMock, 'true')
58
+ replaceConsole()
59
+ console.debug('test')
60
+ expect(loggerMock.debug).toBeCalledWith('test')
61
+ })
62
+ })
@@ -0,0 +1,19 @@
1
+ import winston, { Logger } from 'winston'
2
+ import newrelicFormatter from '@newrelic/winston-enricher'
3
+
4
+ const newrelicWinstonFormatter = newrelicFormatter(winston)
5
+
6
+ export const getWinstonLogger = (winstonLogLevel?: string): Logger =>
7
+ winston.createLogger({
8
+ level: winstonLogLevel || 'info',
9
+ format: winston.format.json(),
10
+ transports: [
11
+ new winston.transports.Console({
12
+ format: winston.format.combine(
13
+ winston.format.timestamp({ format: 'DD-MM-YYYY T hh:mm:ss.sss A' }),
14
+ winston.format.json(),
15
+ newrelicWinstonFormatter()
16
+ ),
17
+ }),
18
+ ],
19
+ })
@@ -0,0 +1,20 @@
1
+ import newrelic from 'newrelic'
2
+ import { winstonEnabled, winstonLogLevel } from '../../config'
3
+ import { getWinstonLogger } from './getWinstonLogger'
4
+ import { replaceConsoleWithLogger } from './replaceConsoleWithLogger'
5
+
6
+ const logger = getWinstonLogger(winstonLogLevel)
7
+ const replaceConsole = replaceConsoleWithLogger(logger, winstonEnabled)
8
+
9
+ const replaceConsoleAndSetTransactionName = (transactionName: string) => {
10
+ replaceConsole()
11
+
12
+ newrelic.setTransactionName(transactionName)
13
+ }
14
+
15
+ export {
16
+ logger,
17
+ replaceConsoleWithLogger,
18
+ replaceConsole,
19
+ replaceConsoleAndSetTransactionName,
20
+ }
@@ -0,0 +1,14 @@
1
+ import { Logger } from 'winston'
2
+
3
+ export const replaceConsoleWithLogger =
4
+ (logger: Logger, winstonEnabled?: string) => () => {
5
+ if (winstonEnabled === 'true') {
6
+ console.log = (...message: any[]) => logger.info.call(logger, ...message)
7
+ console.info = (...message: any[]) => logger.info.call(logger, ...message)
8
+ console.warn = (...message: any[]) => logger.warn.call(logger, ...message)
9
+ console.error = (...message: any[]) =>
10
+ logger.error.call(logger, ...message)
11
+ console.debug = (...message: any[]) =>
12
+ logger.debug.call(logger, ...message)
13
+ }
14
+ }
@@ -503,6 +503,9 @@ jobs:
503
503
  description: Project name that will be used to tag docker images i.e ncu-newskit-render
504
504
  type: string
505
505
  default: <% PROJECT_NAME >
506
+ dockerfile:
507
+ type: string
508
+ default: "Dockerfile.withNewRelic"
506
509
  working_directory: ~/project
507
510
  executor: node
508
511
  steps:
@@ -536,7 +539,7 @@ jobs:
536
539
  <% PACKAGE_DOCKER_BUILD >
537
540
 
538
541
  echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin
539
- docker build -t << parameters.project >> .
542
+ docker build -f << parameters.dockerfile >> -t << parameters.project >> .
540
543
  $(aws ecr get-login --no-include-email)
541
544
  for tag in $TAGS; do
542
545
  docker tag << parameters.project >> $DOCKER_REGISTRY_URL/<< parameters.project >>:$tag;
@@ -879,6 +882,7 @@ workflows:
879
882
  <<: *only_on_pr_branch
880
883
  context: <% PROJECT_NAME >-dev
881
884
  name: publish_docker
885
+ dockerfile: "Dockerfile"
882
886
  requires:
883
887
  - install_deps
884
888
  - aws_oidc
package/newrelic.js CHANGED
@@ -28,7 +28,12 @@ exports.config = {
28
28
  *
29
29
  * @env NEW_RELIC_DISTRIBUTED_TRACING_ENABLED
30
30
  */
31
- enabled: false,
31
+ enabled: true,
32
+ },
33
+ application_logging: {
34
+ forwarding: {
35
+ enabled: true,
36
+ },
32
37
  },
33
38
  logging: {
34
39
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newskit-render/core",
3
- "version": "4.13.9",
3
+ "version": "4.14.0-alpha.1",
4
4
  "description": "Newskit Render - Core package",
5
5
  "author": "",
6
6
  "license": "UNLICENSED",
@@ -11,7 +11,9 @@
11
11
  "scripts": {
12
12
  "build": "next build",
13
13
  "start": "NODE_OPTIONS=--max_old_space_size=8192 next dev",
14
+ "dev:nr": "NODE_OPTIONS='-r @newrelic/next' next dev",
14
15
  "start:prod": "next build && next start",
16
+ "start:prod:nr": "next build && NODE_OPTIONS='-r @newrelic/next' next start",
15
17
  "clean": "rm -rf node_modules & rm -f package-lock.json & rm -f yarn.lock & rm -rf .next",
16
18
  "test:unit": "jest --coverage --verbose --silent --i",
17
19
  "test:unit:ci": "JEST_JUNIT_OUTPUT_NAME=core.xml node --max_old_space_size=4096 --expose-gc ./node_modules/.bin/jest --ci --coverage --reporters=default --reporters=jest-junit --runInBand --logHeapUsage",
@@ -38,26 +40,29 @@
38
40
  "@emotion-icons/material-outlined": "3.14.0",
39
41
  "@emotion/react": "11.9.3",
40
42
  "@emotion/styled": "11.9.3",
43
+ "@newrelic/next": "0.5.2",
44
+ "@newrelic/winston-enricher": "4.0.1",
41
45
  "@newskit-render/api": "^1.8.0",
42
46
  "@newskit-render/auth": "^1.7.1",
43
47
  "@newskit-render/checkout": "^3.7.4",
44
48
  "@newskit-render/feature-flags": "^1.6.0",
45
49
  "@newskit-render/feed": "^1.8.1",
46
- "@newskit-render/my-account": "^7.2.0",
50
+ "@newskit-render/my-account": "^7.2.1-alpha.0",
47
51
  "@newskit-render/shared-components": "^4.1.0",
48
52
  "@newskit-render/standalone-components": "^3.16.4",
49
53
  "@newskit-render/validation": "^1.12.1",
50
54
  "cross-fetch": "3.1.5",
51
55
  "graphql": "16.6.0",
52
56
  "lodash.get": "4.4.2",
53
- "newrelic": "7.1.0",
57
+ "newrelic": "10.6.1",
54
58
  "newskit": "7.4.0",
55
59
  "next": "13.4.4",
56
60
  "react": "18.2.0",
57
61
  "react-dom": "18.2.0",
58
62
  "react-helmet": "6.1.0",
59
63
  "sharp": "0.32.4",
60
- "swr": "1.3.0"
64
+ "swr": "1.3.0",
65
+ "winston": "3.10.0"
61
66
  },
62
67
  "devDependencies": {
63
68
  "@apollo/react-testing": "4.0.0",
@@ -69,7 +74,7 @@
69
74
  "@percy/cypress": "3.1.2",
70
75
  "@testing-library/jest-dom": "5.16.5",
71
76
  "@testing-library/react": "13.4.0",
72
- "@types/newrelic": "7.0.0",
77
+ "@types/newrelic": "9.14.0",
73
78
  "@types/react": "18.0.26",
74
79
  "@types/react-dom": "18.0.10",
75
80
  "@types/react-helmet": "6.1.0",
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import newrelic from 'newrelic'
2
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
3
3
  import {
4
4
  createApolloClient,
5
5
  ClientTypes,
@@ -66,7 +66,7 @@ export async function getServerSideProps(context) {
66
66
  params: { articleId, section, articleSlug },
67
67
  } = context
68
68
 
69
- newrelic.setTransactionName(
69
+ replaceConsoleAndSetTransactionName(
70
70
  `Article: /${section}/${articleId}/${articleSlug}`
71
71
  )
72
72
 
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import newrelic from 'newrelic'
2
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
3
3
  import { getAcsCookie, ClientTypes, Config } from '@newskit-render/api'
4
4
  import {
5
5
  RecommendedArticleList,
@@ -65,7 +65,7 @@ const RelatedArticlesPage: React.FC<RelatedArticles> = ({
65
65
  }
66
66
 
67
67
  export async function getServerSideProps(context) {
68
- newrelic.setTransactionName('RelatedArticlesPage')
68
+ replaceConsoleAndSetTransactionName('RelatedArticlesPage')
69
69
  console.warn('context:')
70
70
  console.warn(context.req && context.req.headers)
71
71
  const {
@@ -1,4 +1,4 @@
1
- import newrelic from 'newrelic'
1
+ import { replaceConsoleAndSetTransactionName } from '../../helpers/logger'
2
2
  import {
3
3
  createApolloClient,
4
4
  getAcsCookie,
@@ -24,7 +24,7 @@ export async function getServerSideProps(context) {
24
24
  ? getAcsCookie(ClientTypes.main, context.req.headers.cookie)
25
25
  : ''
26
26
  const siteHost = getHost(context.req)
27
- newrelic.setTransactionName(`Section: ${section}`)
27
+ replaceConsoleAndSetTransactionName(`Section: ${section}`)
28
28
 
29
29
  let data
30
30
  let user
package/pages/_app.tsx CHANGED
@@ -4,7 +4,6 @@ import Head from 'next/head'
4
4
  import { ThemeProvider, Global, styled } from 'newskit'
5
5
  import { Publisher } from '@newskit-render/api'
6
6
  import { AppContextProvider, AppContext } from '../context/app-context'
7
- import { logger } from '../helpers/logger'
8
7
  import { InstrumentationContextProvider } from '../app-context/InstrumentationContextProvider'
9
8
  import { getTenant } from '../helpers/multiTenancy'
10
9
  import { GlobalStyling } from '../css'
@@ -23,12 +22,6 @@ import {
23
22
  graphik,
24
23
  } from '../assets/fontFamily'
25
24
 
26
- if (!process.browser) {
27
- // eslint-disable-next-line global-require
28
- require('newrelic')
29
- logger()
30
- }
31
-
32
25
  const PageContainer = styled.div`
33
26
  position: relative;
34
27
  min-height: 100vh;
@@ -11,7 +11,6 @@ import Document, {
11
11
  import { ExperimentationWeb, Consent, Tealium } from 'newskit'
12
12
  import Helmet from 'react-helmet'
13
13
  import newrelic from 'newrelic'
14
- import { getSubStringBetween } from '../components/utils'
15
14
  import {
16
15
  experimentationWeb,
17
16
  sourcepointAccountId,
@@ -25,9 +24,15 @@ import {
25
24
  export default class MyDocument extends Document {
26
25
  static async getInitialProps(ctx: DocumentContext) {
27
26
  const { html, head } = await ctx.renderPage()
27
+
28
+ const browserTimingHeader = newrelic.getBrowserTimingHeader({
29
+ hasToRemoveScriptWrapper: true,
30
+ })
31
+
28
32
  return {
29
33
  html,
30
34
  head,
35
+ browserTimingHeader,
31
36
  }
32
37
  }
33
38
 
@@ -44,18 +49,12 @@ export default class MyDocument extends Document {
44
49
  <Html lang="en">
45
50
  <Head>
46
51
  <>
47
- <Script
48
- id="browser-script"
52
+ <script
49
53
  type="text/javascript"
50
- data-attribute="nr-browser"
51
54
  dangerouslySetInnerHTML={{
52
- __html: getSubStringBetween(
53
- "<script type='text/javascript' defer>",
54
- '</script>',
55
- newrelic.getBrowserTimingHeader()
56
- ),
55
+ // @ts-ignore
56
+ __html: this.props.browserTimingHeader,
57
57
  }}
58
- strategy="lazyOnload"
59
58
  />
60
59
  {experimentationWeb &&
61
60
  featureFlags &&
package/pages/_error.tsx CHANGED
@@ -1,7 +1,6 @@
1
1
  import React from 'react'
2
2
  import { NotFound, GenericError } from '@newskit-render/my-account'
3
3
  import Error from 'next/error'
4
- import { getCircularReplacer } from '../helpers/getCircularReplacer'
5
4
  import ErrorPage from '../components/ErrorPage/ErrorPage'
6
5
  import ErrorPageHelpHub from '../pages/help-hub/error'
7
6
 
@@ -61,11 +60,7 @@ CustomError.getInitialProps = ({ res, err, asPath }) => {
61
60
  const statusCode = res ? res.statusCode : err ? err.statusCode : 404
62
61
 
63
62
  // Logging the error for being captured by New Relic
64
- console.error(
65
- `An ${statusCode} error has occurred ${
66
- err ? `:${JSON.stringify(err, getCircularReplacer())}` : ''
67
- }`
68
- )
63
+ console.error(`An ${statusCode} error has occurred`, err)
69
64
 
70
65
  return { statusCode, asPath }
71
66
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import newrelic from 'newrelic'
2
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
3
3
  import { AddField, addComponentMap } from '@newskit-render/my-account'
4
4
  import validation from '../../../validation'
5
5
  import { DynamicPage } from '@newskit-render/my-account'
@@ -20,7 +20,7 @@ export const getServerSideProps = async (context) => {
20
20
  params: { field },
21
21
  } = context
22
22
  const doesAddpageExist = Object.keys(addComponentMap).includes(field)
23
- newrelic.setTransactionName(`Account: add ${field}`)
23
+ replaceConsoleAndSetTransactionName(`Account: add ${field}`)
24
24
 
25
25
  if (!doesAddpageExist) {
26
26
  context.res.statusCode = 404
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
  import { Cancellation, getProviderProps } from '@newskit-render/my-account'
3
- import newrelic from 'newrelic'
3
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
4
4
  import { initAndGetFeatureFlag } from '@newskit-render/feature-flags' /* cra-effected */
5
5
  import { optimizelysdkKey } from '../../../config' /* cra-effected */
6
6
  import validation from '../../../validation'
@@ -12,7 +12,7 @@ const AccountCancellation = (props) => (
12
12
  export default AccountCancellation
13
13
 
14
14
  export const getServerSideProps = async (context) => {
15
- newrelic.setTransactionName('Account: Cancellation')
15
+ replaceConsoleAndSetTransactionName('Account: Cancellation')
16
16
  /* start cra-effected */
17
17
  const featureFlags = await initAndGetFeatureFlag(optimizelysdkKey)
18
18
  /* end cra-effected */
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
  import { DreamTeam, getProviderProps } from '@newskit-render/my-account'
3
- import newrelic from 'newrelic'
3
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
4
4
  import { initAndGetFeatureFlag } from '@newskit-render/feature-flags' /* cra-effected */
5
5
  import { optimizelysdkKey } from '../../../config' /* cra-effected */
6
6
 
@@ -9,7 +9,7 @@ const AccountNewslettersAndAlerts = (props) => <DreamTeam {...props} />
9
9
  export default AccountNewslettersAndAlerts
10
10
 
11
11
  export const getServerSideProps = async (context) => {
12
- newrelic.setTransactionName('Account: Dream Team')
12
+ replaceConsoleAndSetTransactionName('Account: Dream Team')
13
13
  /* start cra-effected */
14
14
  const featureFlags = await initAndGetFeatureFlag(optimizelysdkKey)
15
15
  /* end cra-effected */
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import newrelic from 'newrelic'
2
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
3
3
  import {
4
4
  EditField,
5
5
  getProviderProps,
@@ -28,7 +28,7 @@ export const getServerSideProps = async (context) => {
28
28
  } = context
29
29
  const doesEditPageExist = Object.keys(editComponentMap).includes(field)
30
30
 
31
- newrelic.setTransactionName(`Account: edit ${field}`)
31
+ replaceConsoleAndSetTransactionName(`Account: edit ${field}`)
32
32
 
33
33
  if (!doesEditPageExist) {
34
34
  context.res.statusCode = 404
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
  import { getProviderProps, HolidayStop } from '@newskit-render/my-account'
3
- import newrelic from 'newrelic'
3
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
4
4
  import { initAndGetFeatureFlag } from '@newskit-render/feature-flags' /* cra-effected */
5
5
  import { optimizelysdkKey } from '../../../config' /* cra-effected */
6
6
 
@@ -9,7 +9,7 @@ const AccountHolidayStop = (props) => <HolidayStop {...props} />
9
9
  export default AccountHolidayStop
10
10
 
11
11
  export const getServerSideProps = async (context) => {
12
- newrelic.setTransactionName('Account: Book a Holiday Stop')
12
+ replaceConsoleAndSetTransactionName('Account: Book a Holiday Stop')
13
13
  /* start cra-effected */
14
14
  const featureFlags = await initAndGetFeatureFlag(optimizelysdkKey)
15
15
  /* end cra-effected */
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
  import { getProviderProps, HolidayStopList } from '@newskit-render/my-account'
3
- import newrelic from 'newrelic'
3
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
4
4
  import { holidayStopListContextOverrides } from '../../../context/app-context/holidayStopListContextOverrides'
5
5
 
6
6
  const AccountPreviousHolidayStops = (props) => (
@@ -14,6 +14,6 @@ const AccountPreviousHolidayStops = (props) => (
14
14
  export default AccountPreviousHolidayStops
15
15
 
16
16
  export const getServerSideProps = async (context) => {
17
- newrelic.setTransactionName('Account: Previous Holiday Stops')
17
+ replaceConsoleAndSetTransactionName('Account: Previous Holiday Stops')
18
18
  return getProviderProps({ ...context, provider: 'HolidayStop' })
19
19
  }
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
  import { getProviderProps, HolidayStopList } from '@newskit-render/my-account'
3
- import newrelic from 'newrelic'
3
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
4
4
  import { holidayStopListContextOverrides } from '../../../context/app-context/holidayStopListContextOverrides'
5
5
 
6
6
  const AccountUpcomingHolidayStops = (props) => (
@@ -14,6 +14,6 @@ const AccountUpcomingHolidayStops = (props) => (
14
14
  export default AccountUpcomingHolidayStops
15
15
 
16
16
  export const getServerSideProps = async (context) => {
17
- newrelic.setTransactionName('Account: Upcoming Holiday Stops')
17
+ replaceConsoleAndSetTransactionName('Account: Upcoming Holiday Stops')
18
18
  return getProviderProps({ ...context, provider: 'HolidayStop' })
19
19
  }
@@ -1,9 +1,9 @@
1
1
  import React from 'react'
2
- import newrelic from 'newrelic'
3
2
  import { PersonalDetails, getProviderProps } from '@newskit-render/my-account'
4
3
  import { initAndGetFeatureFlag } from '@newskit-render/feature-flags' /* cra-effected */
5
4
  import { optimizelysdkKey } from '../../config' /* cra-effected */
6
5
  import { AccountDropdown } from '../../components/AccountDropdown' /* cra-disabled */
6
+ import { replaceConsoleAndSetTransactionName } from '../../helpers/logger'
7
7
 
8
8
  const AccountPersonalDetails = (props) => (
9
9
  <>
@@ -22,7 +22,7 @@ export const getServerSideProps = async (context) => {
22
22
  /* start cra-effected */
23
23
  const featureFlags = await initAndGetFeatureFlag(optimizelysdkKey)
24
24
  /* end cra-effected */
25
- newrelic.setTransactionName('Account: Personal details')
25
+ replaceConsoleAndSetTransactionName('Account: Personal details')
26
26
  return getProviderProps(
27
27
  { ...context, provider: 'PersonalDetails' },
28
28
  { featureFlags } /* cra-effected */
@@ -3,7 +3,7 @@ import {
3
3
  NewslettersAndAlerts,
4
4
  getProviderProps,
5
5
  } from '@newskit-render/my-account'
6
- import newrelic from 'newrelic'
6
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
7
7
  import { initAndGetFeatureFlag } from '@newskit-render/feature-flags' /* cra-effected */
8
8
  import { optimizelysdkKey } from '../../../config' /* cra-effected */
9
9
 
@@ -14,7 +14,7 @@ const AccountNewslettersAndAlerts = (props) => (
14
14
  export default AccountNewslettersAndAlerts
15
15
 
16
16
  export const getServerSideProps = async (context) => {
17
- newrelic.setTransactionName('Account: Newsletters and Alerts')
17
+ replaceConsoleAndSetTransactionName('Account: Newsletters and Alerts')
18
18
  /* start cra-effected */
19
19
  const featureFlags = await initAndGetFeatureFlag(optimizelysdkKey)
20
20
  /* end cra-effected */
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import newrelic from 'newrelic'
2
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
3
3
  import {
4
4
  getProviderProps,
5
5
  Payment,
@@ -23,7 +23,7 @@ const PaymentPage = (props) => {
23
23
  export default PaymentPage
24
24
 
25
25
  export const getServerSideProps = async (context) => {
26
- newrelic.setTransactionName('Payment method')
26
+ replaceConsoleAndSetTransactionName('Payment method')
27
27
  /* start cra-effected */
28
28
  const featureFlags = await initAndGetFeatureFlag(optimizelysdkKey)
29
29
  /* end cra-effected */
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import newrelic from 'newrelic'
2
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
3
3
  import { Payment, getProviderProps } from '@newskit-render/my-account'
4
4
  import { initAndGetFeatureFlag } from '@newskit-render/feature-flags' /* cra-effected */
5
5
  import { optimizelysdkKey } from '../../../config' /* cra-effected */
@@ -9,7 +9,7 @@ const AccountPayment = (props) => <Payment {...props} />
9
9
  export default AccountPayment
10
10
 
11
11
  export const getServerSideProps = async (context) => {
12
- newrelic.setTransactionName('Edit Payment method')
12
+ replaceConsoleAndSetTransactionName('Edit Payment method')
13
13
  /* start cra-effected */
14
14
  const featureFlags = await initAndGetFeatureFlag(optimizelysdkKey)
15
15
  /* end cra-effected */
@@ -1,9 +1,9 @@
1
1
  import React from 'react'
2
2
  import { getProviderProps, PaymentMethods } from '@newskit-render/my-account'
3
- import newrelic from 'newrelic'
4
3
  import { initAndGetFeatureFlag } from '@newskit-render/feature-flags' // create-render-app effected
5
4
  import { optimizelysdkKey } from '../../../config' // create-render-app effected
6
5
  import { paymentMethodContext } from '../../../context/app-context/paymentMethodContext'
6
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
7
7
 
8
8
  const AccountPaymentMethods = (props) => (
9
9
  <PaymentMethods {...props} context={paymentMethodContext} />
@@ -12,7 +12,7 @@ const AccountPaymentMethods = (props) => (
12
12
  export default AccountPaymentMethods
13
13
 
14
14
  export const getServerSideProps = async (context) => {
15
- newrelic.setTransactionName('Account: Payment Methods')
15
+ replaceConsoleAndSetTransactionName('Account: Payment Methods')
16
16
  const featureFlags = await initAndGetFeatureFlag(optimizelysdkKey) // create-render-app effected
17
17
  return getProviderProps(
18
18
  { ...context, provider: 'PaymentMethods' },
@@ -3,9 +3,9 @@ import {
3
3
  SubscriptionAndBilling,
4
4
  getProviderProps,
5
5
  } from '@newskit-render/my-account'
6
- import newrelic from 'newrelic'
7
6
  import { initAndGetFeatureFlag } from '@newskit-render/feature-flags' /* cra-effected */
8
7
  import { optimizelysdkKey } from '../../../config' /* cra-effected */
8
+ import { replaceConsoleAndSetTransactionName } from '../../../helpers/logger'
9
9
 
10
10
  const AccountSubscriptionAndBilling = (props) => (
11
11
  <SubscriptionAndBilling {...props} />
@@ -14,7 +14,7 @@ const AccountSubscriptionAndBilling = (props) => (
14
14
  export default AccountSubscriptionAndBilling
15
15
 
16
16
  export const getServerSideProps = async (context) => {
17
- newrelic.setTransactionName('Account: Subscription and Billing')
17
+ replaceConsoleAndSetTransactionName('Account: Subscription and Billing')
18
18
  /* start cra-effected */
19
19
  const featureFlags = await initAndGetFeatureFlag(optimizelysdkKey)
20
20
  /* end cra-effected */
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import newrelic from 'newrelic'
2
+ import { replaceConsoleAndSetTransactionName } from '../../../../helpers/logger'
3
3
  import {
4
4
  AlgoliaCredentials,
5
5
  HelpHubArticlePage,
@@ -17,9 +17,8 @@ const ArticlePage: React.FC<{
17
17
  export default ArticlePage
18
18
 
19
19
  export const getServerSideProps = async (context) => {
20
- newrelic.setTransactionName('HelpHubArticlePage')
21
- console.warn('context:')
22
- console.warn(context.req && context.req.headers)
20
+ replaceConsoleAndSetTransactionName('HelpHubArticlePage')
21
+
23
22
  addCacheHeaders(context.res)
24
23
 
25
24
  return helpHubArticleProvider(context)
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import newrelic from 'newrelic'
2
+ import { replaceConsoleAndSetTransactionName } from '../../helpers/logger'
3
3
  import {
4
4
  HelpHubErrorPage,
5
5
  helpHubErrorPageProvider,
@@ -14,9 +14,7 @@ const ErrorPageHelpHub: React.FC<{
14
14
  }
15
15
 
16
16
  export const getServerSideProps = async (context) => {
17
- newrelic.setTransactionName('HelpHubErrorPage')
18
- console.warn('context:')
19
- console.warn(context.req && context.req.headers)
17
+ replaceConsoleAndSetTransactionName('HelpHubErrorPage')
20
18
 
21
19
  addCacheHeaders(context.res)
22
20
  return helpHubErrorPageProvider()
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import newrelic from 'newrelic'
2
+ import { replaceConsoleAndSetTransactionName } from '../../helpers/logger'
3
3
  import {
4
4
  AlgoliaCredentials,
5
5
  HelpHubLandingPage,
@@ -43,9 +43,8 @@ const LandingPage: React.FC<{
43
43
  export default LandingPage
44
44
 
45
45
  export const getServerSideProps = async (context) => {
46
- newrelic.setTransactionName('HelpHubLandingPage')
47
- console.warn('context:')
48
- console.warn(context.req && context.req.headers)
46
+ replaceConsoleAndSetTransactionName('HelpHubLandingPage')
47
+
49
48
  addCacheHeaders(context.res)
50
49
 
51
50
  return helpHubLandingPageProvider()
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import newrelic from 'newrelic'
2
+ import { replaceConsoleAndSetTransactionName } from '../../helpers/logger'
3
3
  import {
4
4
  HelpHubResultsPage,
5
5
  AlgoliaCredentials,
@@ -16,7 +16,7 @@ const ResultsPage: React.FC<{
16
16
  export default ResultsPage
17
17
 
18
18
  export const getServerSideProps = async (context) => {
19
- newrelic.setTransactionName('HelpHubResultsPage')
19
+ replaceConsoleAndSetTransactionName('HelpHubResultsPage')
20
20
  console.warn('context:')
21
21
  console.warn(context.req && context.req.headers)
22
22
  addCacheHeaders(context.res)
package/pages/index.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import newrelic from 'newrelic'
1
+ import { replaceConsoleAndSetTransactionName } from '../helpers/logger'
2
2
  import {
3
3
  createApolloClient,
4
4
  getAcsCookie,
@@ -14,10 +14,7 @@ import { getAccountQueryUrl } from '../constants'
14
14
  import { addCacheHeaders } from '../helpers/addCacheHeaders'
15
15
 
16
16
  export async function getServerSideProps(context) {
17
- newrelic.setTransactionName('Homepage')
18
- console.warn('config:')
19
- console.warn('context:')
20
- console.warn(context.req && context.req.headers)
17
+ replaceConsoleAndSetTransactionName('Homepage')
21
18
 
22
19
  const apolloClient = await createApolloClient(ClientTypes.nkapi)
23
20
  const acsCookie = context.req.headers.cookie
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+
3
+ # to run New Relic locally add values here and run . ./scripts/nr-exports.sh
4
+ # never commit to repo with license key value
5
+
6
+ export NEW_RELIC_LICENSE_KEY=""
7
+ export NEW_RELIC_APP_NAME=""
package/temp/_app.tsx CHANGED
@@ -6,13 +6,6 @@ import { bitter, poppins, dmSans } from '../assets/fontFamily'
6
6
  import { GlobalStyling } from '../css'
7
7
  <% MODULE >
8
8
 
9
-
10
-
11
- if (!process.browser) {
12
- // eslint-disable-next-line global-require
13
- require('newrelic')
14
- }
15
-
16
9
  const PageContainer = styled.div`
17
10
  position: relative;
18
11
  min-height: 100vh;
@@ -17,9 +17,15 @@ import { getSubStringBetween } from '../components/utils'
17
17
  export default class MyDocument extends Document {
18
18
  static async getInitialProps(ctx: DocumentContext) {
19
19
  const { html, head } = await ctx.renderPage()
20
+
21
+ const browserTimingHeader = newrelic.getBrowserTimingHeader({
22
+ hasToRemoveScriptWrapper: true,
23
+ })
24
+
20
25
  return {
21
26
  html,
22
27
  head,
28
+ browserTimingHeader,
23
29
  }
24
30
  }
25
31
 
@@ -31,18 +37,13 @@ export default class MyDocument extends Document {
31
37
  <Html lang="en">
32
38
  <Head>
33
39
  <>
34
- <Script
35
- id="browser-script"
36
- type="text/javascript"
37
- data-attribute="nr-browser"
38
- dangerouslySetInnerHTML={{
39
- __html: getSubStringBetween(
40
- "<script type='text/javascript' >",
41
- '</script>',
42
- newrelic.getBrowserTimingHeader()
43
- ),
44
- }}
45
- />
40
+ <script
41
+ type="text/javascript"
42
+ dangerouslySetInnerHTML={{
43
+ // @ts-ignore
44
+ __html: this.props.browserTimingHeader,
45
+ }}
46
+ />
46
47
  <% OPTIMIZELY_WEB >
47
48
  {helmet.script.toComponent()}
48
49
  <% SOURCEPOINT >
@@ -1,17 +0,0 @@
1
- import { getCircularReplacer } from '../getCircularReplacer'
2
-
3
- describe('getCircularReplacer', () => {
4
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
- const mockObject: any = { value: 'test' }
6
- mockObject.self = mockObject
7
- it('should throw error', () => {
8
- expect(() => JSON.stringify(mockObject)).toThrowError(
9
- /Converting circular structure to JSON/
10
- )
11
- })
12
- it('should remove cyclic object value and not throw error', () => {
13
- expect(JSON.stringify(mockObject, getCircularReplacer())).toEqual(
14
- JSON.stringify({ value: 'test' })
15
- )
16
- })
17
- })
@@ -1,12 +0,0 @@
1
- export const getCircularReplacer = () => {
2
- const seen = new WeakSet()
3
- return (_key, value) => {
4
- if (typeof value === 'object' && value !== null) {
5
- if (seen.has(value)) {
6
- return undefined
7
- }
8
- seen.add(value)
9
- }
10
- return value
11
- }
12
- }
package/helpers/logger.ts DELETED
@@ -1,24 +0,0 @@
1
- import { newRelicEnabled } from '../config'
2
-
3
- export const logger = () => {
4
- if (newRelicEnabled === 'true') {
5
- // Format Output logs to be properly logged for NewRelic
6
- const { log, error, warn, info } = console
7
-
8
- console.error = (...args) => {
9
- error.call(console, JSON.stringify(args))
10
- }
11
-
12
- console.log = (...args) => {
13
- log.call(console, JSON.stringify(args))
14
- }
15
-
16
- console.info = (...args) => {
17
- info.call(console, JSON.stringify(args))
18
- }
19
-
20
- console.warn = (...args) => {
21
- warn.call(console, JSON.stringify(args))
22
- }
23
- }
24
- }