首頁 > web前端 > js教程 > 定制登錄Next.js

定制登錄Next.js

Patricia Arquette
發布: 2025-01-28 10:30:09
原創
237 人瀏覽過

Next.js自定義日誌記錄:捕獲未捕獲的服務器端異常

Next.js本身無法使用自定義日誌記錄器來處理服務器端未捕獲的異常和拒絕。雖然可以使用next-logger之類的庫,但它僅限於使用Pino。如果您想使用其他日誌庫,甚至將日誌發送到DataDog等雲提供商,則此方法無效。

LogLayer日誌庫可以解決這個問題。它可以捕獲這些異常並將它們發送到您選擇的日誌庫(例如Pino和DataDog)中。

查看LogLayer網站以了解支持的日誌記錄器和雲提供商。

安裝

本指南假設您已設置好Next.js。

首先,安裝所需的軟件包。您可以使用任何您喜歡的傳輸方式 - 此示例中我們將使用Pino:

<code class="language-bash">npm i loglayer @loglayer/transport-pino pino serialize-error</code>
登入後複製

設置

您需要在項目根目錄下創建一個檢測文件。

<code class="language-typescript">// instrumentation.ts
import { LogLayer, type ILogLayer } from 'loglayer';
import { PinoTransport } from "@loglayer/transport-pino";
import pino from "pino";
import { serializeError } from "serialize-error";

/**
 * 去除字符串中的ANSI代码,这是Next.js喜欢注入的内容。
 */
function stripAnsiCodes(str: string): string {
  return str.replace(
    /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=>/,
    ''
  );
}

function createConsoleMethod(log: ILogLayer, method: string) {
  const mappedMethod = method === "error" ? "errorOnly" : method;
  return (...args: unknown[]): void => {
    const data: Record<string, unknown> = {};
    let hasData = false;
    let error: Error | null = null;
    const messages: string[] = [];

    for (const arg of args) {
      if (arg instanceof Error) {
        error = arg;
        continue;
      }

      if (typeof arg === "object" && arg !== null) {
        Object.assign(data, arg);
        hasData = true;
        continue;
      }

      if (typeof arg === "string") {
        messages.push(arg);
      }
    }

    let finalMessage = stripAnsiCodes(messages.join(" ")).trim();

    // next.js在错误对象时使用“x”作为错误消息
    if (finalMessage === "⨯" && error) {
      finalMessage = error?.message || "";
    }

    if (error && hasData && messages.length > 0) {
      log.withError(error).withMetadata(data)[mappedMethod](finalMessage);
    } else if (error && messages.length > 0) {
      log.withError(error)[mappedMethod](finalMessage);
    } else if (hasData && messages.length > 0) {
      log.withMetadata(data)[mappedMethod](finalMessage);
    } else if (error && hasData && messages.length === 0) {
      log.withError(error).withMetadata(data)[mappedMethod]("");
    } else if (error && messages.length === 0) {
      log.errorOnly(error);
    } else if (hasData && messages.length === 0) {
      log.metadataOnly(data);
    } else {
      log[mappedMethod](finalMessage);
    }
  };
}

export async function register() {
  const logger = new LogLayer({
    errorSerializer: serializeError,
    transport: [
      new PinoTransport({
        logger: pino(),
      }),
    ]
  });

  if (process.env.NEXT_RUNTIME === "nodejs") {
    console.error = createConsoleMethod(logger, "error");
    console.log = createConsoleMethod(logger, "log");
    console.info = createConsoleMethod(logger, "info");
    console.warn = createConsoleMethod(logger, "warn");
    console.debug = createConsoleMethod(logger, "debug");
  }
}</code>
登入後複製

測試

如果您從page.tsx拋出一個未捕獲的錯誤,您應該在終端中看到以下內容:

<code class="language-json">{"err":{"type":"Object","message":"test","stack":"Error: test\n    at Page (webpack-internal:///(rsc)/./src/app/page.tsx:12:11)","digest":"699232626","name":"Error"},"msg":"test"}</code>
登入後複製

更多信息

  • LogLayer
  • LogLayer Next.js集成指南。

Custom logging in Next.js

以上是定制登錄Next.js的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板