Menu

instrumentation

instrumentation 是使用代码将监控和日志工具集成到应用程序中的过程。这允许你跟踪应用程序的性能和行为,并在生产环境中调试问题。

约定

要设置 instrumentation,请在项目的根目录中创建 instrumentation.ts|js 文件 (如果使用 src 文件夹,则在其中创建)。

然后,在文件中导出一个 register 函数。当新的 Next.js 服务器实例初始化时,这个函数将被调用一次

例如,要将 Next.js 与 OpenTelemetry@vercel/otel 一起使用:

instrumentation.ts
import { registerOTel } from "@vercel/otel";
 
export function register() {
  registerOTel("next-app");
}
instrumentation.js
import { registerOTel } from "@vercel/otel";
 
export function register() {
  registerOTel("next-app");
}

请参阅 Next.js 与 OpenTelemetry 示例 以获取完整的实现。

值得注意的是

  • 这个功能是实验性的。要使用它,你必须在 next.config.js 中明确选择启用,方法是定义 experimental.instrumentationHook = true;
  • instrumentation 文件应该位于项目的根目录,而不是在 apppages 目录内。如果你使用 src 文件夹,那么将文件放在 src 中,与 pagesapp 并列。
  • 如果你使用 pageExtensions 配置选项 添加后缀,你还需要更新 instrumentation 文件名以匹配。

示例

导入具有副作用的文件

有时,由于文件会产生的副作用,在代码中导入文件可能会很有用。例如,你可能会导入一个定义了一组全局变量的文件,但在代码中从不显式使用导入的文件。你仍然可以访问该包声明的全局变量。

我们建议在 register 函数中使用 JavaScript import 语法导入文件。以下示例演示了在 register 函数中使用 import 的基本用法:

instrumentation.ts
export async function register() {
  await import("package-with-side-effect");
}
instrumentation.js
export async function register() {
  await import("package-with-side-effect");
}

值得注意的是

我们建议在 register 函数内部导入文件,而不是在文件顶部导入。这样做可以将所有副作用集中在代码的一个地方,并避免在文件顶部全局导入可能带来的任何意外后果。

导入特定运行时的代码

Next.js 在所有环境中调用 register,因此重要的是要有条件地导入不支持特定运行时的代码 (例如 Edge 或 Node.js)。你可以使用 NEXT_RUNTIME 环境变量来获取当前环境:

instrumentation.ts
export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs") {
    await import("./instrumentation-node");
  }
 
  if (process.env.NEXT_RUNTIME === "edge") {
    await import("./instrumentation-edge");
  }
}
instrumentation.js
export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs") {
    await import("./instrumentation-node");
  }
 
  if (process.env.NEXT_RUNTIME === "edge") {
    await import("./instrumentation-edge");
  }
}