”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 如何使用 New Relic 监控 App Router Next.js 应用程序

如何使用 New Relic 监控 App Router Next.js 应用程序

发布于2024-07-30
浏览:306

Next.js 是一个功能强大的 JavaScript 框架,可为开发和运行时提供优化的速度和性能。随着 Next.js 13 的发布,App Router 已成为在 Next.js 应用程序中处理路由的推荐方式。这款新路由器利用 React 的最新功能,例如服务器组件和流媒体,提供更现代、更高效的方法来构建 Web 应用程序。

在这篇博文中,您将了解如何使用新的 App Router 设置服务器端的应用程序性能监控和前端的浏览器监控,从而为您的 Next.js 应用程序提供全栈可观察性。首先,您需要一个 New Relic 帐户和许可证密钥,两者都是免费提供的。

安装代理和中间件

在 Next.js 项目中运行以下命令来安装 New Relic Node.js APM 代理和 Next.js 的 New Relic 中间件。

npm install newrelic @newrelic/next

命令成功完成后,您将看到 package.json 文件中包含的依赖项。

 "dependencies": {
   "@newrelic/next": "^0.10.0",
   "newrelic": "^11.23.0",
   "next": "14.2.5",
   "react": "^18",
   "react-dom": "^18"
 },

@newrelic/next 包为 New Relic 监控 Next.js 应用程序提供官方工具。它专注于页面和服务器请求的服务器端渲染、中间件和事务命名,确保服务器端活动的全面可观察性。

此软件包单独安装,但与 New Relic Node.js 代理无缝集成,提供代理的所有功能,以增强 Next.js 应用程序中的性能监控和错误跟踪。

虽然它不涵盖客户端操作,但您可以注入 New Relic 浏览器代理以进行客户端遥测(本博客文章后面将详细介绍)。

配置

要使用 New Relic 有效地检测 Next.js 应用程序,您需要修改 next.config.js 文件。此配置确保 New Relic 支持的模块不会被 webpack 破坏,并且它将这些模块外部化。

使用以下内容在项目根目录中创建或更新 next.config.js 文件:

'use strict'

const nrExternals = require('@newrelic/next/load-externals')

module.exports = {
  experimental: {
    serverComponentsExternalPackages: ['newrelic']
  },
  webpack: (config) => {
    nrExternals(config)
    return config
  }
}

接下来,通过修改 package.json 文件的脚本部分来修改您的开发并启动 npm 脚本。允许您的应用程序使用 Node 的 -r 选项运行,这将预加载 @newrelic/next 中间件。

"scripts": {
  "dev": "NODE_OPTIONS='-r @newrelic/next' next",
  "build": "next build",
  "start": "NODE_OPTIONS='-r @newrelic/next' next start",
  "lint": "next lint"
}

在运行应用程序之前,请将 newrelic.js AMP 代理配置文件添加到项目的根目录中。有关详细信息,请参阅 Next.js 应用程序的示例配置文件。

此外,请在 .env 文件中使用 NEW_RELIC_APP_NAME 和 NEW_RELIC_LICENSE_KEY,如应用程序的示例 .env 文件中所示。

在 New Relic 中查看性能数据

运行您的应用程序并转到 New Relic 中的 APM 页面。您将看到应用程序的服务器端数据流入 New Relic。

How to Monitor App Router Next.js Applications with New Relic

前端可观察性

要在使用 App Router 时注入浏览器代理,我们将编辑 app/layout.js(.ts) 文件。

import Script from 'next/script'
import Link from 'next/link'
import newrelic from 'newrelic'
import './style.css'

export default async function RootLayout({ children }) {
  if (newrelic.agent.collector.isConnected() === false) {
    await new Promise((resolve) => {
      newrelic.agent.on("connected", resolve)
    })
  }

  const browserTimingHeader = newrelic.getBrowserTimingHeader({
    hasToRemoveScriptWrapper: true,
    allowTransactionlessInjection: true,
  })

  return (
    
    
      
        
{children} ) }

以下是此过程的步骤:

  1. 如果您尚未使用 npm install newrelic @newrelic/next 命令安装 newrelic npm 软件包。
  2. 添加newrelic.getBrowserTimingHeader方法。

    1. 将 hasToRemoveScriptWrapper: true 作为参数传递给 newrelic.getBrowserTimingHeader,以便返回浏览器脚本而不使用
    2. 将allowTransactionlessInjection: true作为参数传递给newrelic.GetBrowserTimingHeader,以允许不在事务中时注入浏览器代理。
  3. 在 render 方法中,将 New Relic Browser 代理脚本注入到文档

    的末尾。
  4. layout.js(.ts) 文件应位于项目 app 目录的根目录中。

有关示例layout.js(.ts)文件,请访问以下链接。

在 New Relic 中查看浏览器数据

启动应用程序,然后转到 New Relic 中的浏览器监控页面,查看应用程序中流入 New Relic 的客户端数据。

How to Monitor App Router Next.js Applications with New Relic

向 New Relic 发送详细的错误信息

为了捕获 Next.js 应用程序中的详细错误信息,您需要处理客户端和服务器端错误。

客户端错误

对于客户端错误,您可以使用 error.ts(.js) 文件捕获错误详细信息并将其发送到 New Relic。以下是如何实现的示例:

"use client";

import React, { useEffect } from "react";

const Error = ({ error }) => {
  useEffect(() => {
    if (window.newrelic) {
      window.newrelic.noticeError(error);
    }
  }, [error]);

  return 
Something went wrong
; }; export default Error;

在此示例中,useEffect 挂钩用于在发生错误时调用 window.newrelic.noticeError。这会将错误详细信息发送到 New Relic 进行进一步分析。

error.js(.ts) 文件定义路线段的错误 UI 边界。要处理根布局中的错误,请使用 global-error.js(.ts) 并将其放置在根应用程序目录中。

有关 Next.js 中错误处理的更多信息,请参阅 Next.js 文档。

服务器端错误

对于来自后端的错误,@newrelic/next 模块会立即处理它们。您不需要添加任何额外的代码来进行服务器端错误跟踪;模块会自动捕获这些错误并将其报告给 New Relic。

这可确保有效监控客户端和服务器端错误并将其报告给 New Relic,从而为您的 Next.js 应用程序提供全面的错误跟踪。

下一步

您可以在 newrelic-node-examples GitHub 存储库中找到本博客文章中的所有代码示例。您可以在 GitHub 存储库问题部分向我们提供任何反馈。
查看 GitHub 上的 Next.js 集成页面。
注册一个免费的 New Relic 帐户。您的免费帐户包括每月 100 GB 的免费数据摄取、一名免费的完全访问用户和无限制的免费基本用户。

版本声明 本文转载于:https://dev.to/set808/how-to-monitor-app-router-nextjs-applications-with-new-relic-ghp?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 'exec()
    'exec()
    Exec对本地变量的影响: exec function,python staple,用于动态代码执行的python staple,提出一个有趣的Query:它可以在函数中更新局部变量吗? python 3 Dialemma 在Python 3中,以下代码shippet无法更新本地变量,因为人们...
    编程 发布于2025-02-07
  • 为什么我的C ++代码产生“错误LNK2019:未解决的外部符号_Winmain@16”?
    为什么我的C ++代码产生“错误LNK2019:未解决的外部符号_Winmain@16”?
    解决“错误lnk2019:未解决的外部符号_winmain@16在___ tmaincrtstartup中引用的16遇到以下错误:错误lnk2019:未解决的外部符号_winmain@16在函数___ tmaincrtstartup 无法解析未定义的符号_WINMAIN。此符号通常是指Windo...
    编程 发布于2025-02-07
  • 如何克服PHP的功能重新定义限制?
    如何克服PHP的功能重新定义限制?
    克服PHP的函数重新定义限制在PHP中,多次定义一个相同名称的函数是一个no-no。尝试这样做,如提供的代码段所示,将导致可怕的“不能重新列出”错误。 // error:“ coss redeclare foo()” 但是,php工具腰带中有一个隐藏的宝石:runkit扩展。它使您能够灵活地...
    编程 发布于2025-02-07
  • 如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
    插入记录时如何解决“一般错误:2006 MySQL 服务器已消失”介绍:将数据插入 MySQL 数据库有时会导致错误“一般错误:2006 MySQL 服务器已消失”。当与服务器的连接丢失时会出现此错误,通常是由于 MySQL 配置中的两个变量之一所致。解决方案:解决此错误的关键是调整wait_tim...
    编程 发布于2025-02-07
  • 为什么尽管有效代码,为什么在PHP中捕获输入?
    为什么尽管有效代码,为什么在PHP中捕获输入?
    [2 _post ['ss'];?> 的目的是从单击提交按钮时,文本框并显示。但是,输出保持空白。当方法=“ get”无缝工作时,方法=“ post”构成问题。 检查action属性:如果您正在刷新页面,请将操作属性设置为空字符串,例如] action ='&#...
    编程 发布于2025-02-07
  • 如何使用PHP将斑点(图像)正确插入MySQL?
    如何使用PHP将斑点(图像)正确插入MySQL?
    在尝试将image存储在mysql数据库中时,您可能会遇到一个可能会遇到问题。本指南将提供成功存储您的图像数据的解决方案。 easudy values('$ this-> image_id','file_get_contents($ tmp_image)...
    编程 发布于2025-02-07
  • 如何在JavaScript对象中动态设置键?
    如何在JavaScript对象中动态设置键?
    如何为JavaScript对象变量创建动态键,尝试为JavaScript对象创建动态键,使用此Syntax jsObj['key' i] = 'example' 1;将不起作用。正确的方法采用方括号:他们维持一个长度属性,该属性反映了数字属性(索引)和一个数字属性的数量。标准对象没有模仿这...
    编程 发布于2025-02-07
  • 如何在Java列表中有效计算元素的发生?
    如何在Java列表中有效计算元素的发生?
    计数列表中的元素出现在列表 中,在java编程中,列举列表中列举元素出现的任务来自列表。为此,收集框架提供了全面的工具套件。在这种情况下,Batocurrences变量将保持值3,代表动物列表中的“ BAT”出现的数量。 &&& [此方法是简单的,可以得出准确的结果,使其成为计算列表中元素出现的理...
    编程 发布于2025-02-07
  • 对象拟合:IE和Edge中的封面失败,如何修复?
    对象拟合:IE和Edge中的封面失败,如何修复?
    解决此问题,我们采用了一个巧妙的CSS解决方案来解决问题:高度:100%; 高度:auto; 宽度:100%; //对于水平块 ,使用绝对定位将图像定位在中心,以object-fit:object-fit:cover in IE和edge消除了问题。现在,图像将按比例扩展,保持所需的效果而不会失...
    编程 发布于2025-02-07
  • Java是否允许多种返回类型:仔细研究通用方法?
    Java是否允许多种返回类型:仔细研究通用方法?
    在java中的多个返回类型:一个误解介绍,其中foo是自定义类。该方法声明似乎拥有两种返回类型:列表和E。但是,情况确实如此吗?通用方法:拆开神秘 [方法仅具有单一的返回类型。相反,它采用机制,如钻石符号“ ”。分解方法签名: :本节定义了一个通用类型参数,E。它表示该方法接受了扩展foo类的任...
    编程 发布于2025-02-07
  • 如何使用Python的记录模块实现自定义处理?
    如何使用Python的记录模块实现自定义处理?
    使用Python的Loggging Module 确保正确处理和登录对于疑虑和维护的稳定性至关重要Python应用程序。尽管手动捕获和记录异常是一种可行的方法,但它可能乏味且容易出错。解决此问题,Python允许您覆盖默认的异常处理机制,并将其重定向为登录模块。这提供了一种方便而系统的方法来捕获和...
    编程 发布于2025-02-07
  • \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    使用(1)而不是(;;)会导致无限循环的性能差异? 现代编译器,(1)和(;;)之间没有性能差异。 是如何实现这些循环的技术分析在编译器中: perl: S-> 7 8 unstack v-> 4 -e语法ok 在GCC中,两者都循环到相同的汇编代码中,如下所示:。 globl t_时 t_时...
    编程 发布于2025-02-07
  • 如何使用不同数量列的联合数据库表?
    如何使用不同数量列的联合数据库表?
    合并列数不同的表 当尝试合并列数不同的数据库表时,可能会遇到挑战。一种直接的方法是在列数较少的表中,为缺失的列追加空值。 例如,考虑两个表,表 A 和表 B,其中表 A 的列数多于表 B。为了合并这些表,同时处理表 B 中缺失的列,请按照以下步骤操作: 确定表 B 中缺失的列,并将它们添加到表的末...
    编程 发布于2025-02-07
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    在这里工作/},false); 不幸的是,答案是否。除非在Creation中存储对处理程序的引用。要解决此问题,请考虑将事件处理程序存储在中心位置,例如页面的主要对象,请考虑将事件处理程序存储在中心位置,否则无法清理匿名事件处理程序。 。这允许在需要时轻松迭代和清洁处理程序。
    编程 发布于2025-02-07
  • 如何检查对象是否具有Python中的特定属性?
    如何检查对象是否具有Python中的特定属性?
    方法来确定对象属性存在寻求一种方法来验证对象中特定属性的存在。考虑以下示例,其中尝试访问不确定属性会引起错误: >>> a = someClass() >>> A.property Trackback(最近的最新电话): 文件“ ”,第1行, AttributeError:SomeClass实...
    编程 发布于2025-02-07

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3