Next.js Custom Log Record: Capture the unsatisfactory server end abnormal
Next.js itself cannot use a custom log recorder to handle the unsatisfactory and rejection of the server's unsatisfactory side. Although you can use libraries such as next-logger
, it is limited to using Pino. If you want to use other log libraries and even send logs to cloud providers such as DataDog, this method is invalid.
Loglayer log library can solve this problem. It can capture these abnormalities and send them to the log library you choose (such as Pino and DataDog).
View the LOGLAYER website to understand the log recorder and cloud provider that supports support. Install
This guide assumes that you have set up next.js.Set
You need to create a detection file in the project root directory.
<code class="language-bash">npm i loglayer @loglayer/transport-pino pino serialize-error</code>
More information
<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>
Loglayer Next.js Integrated Guide. 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>
The above is the detailed content of Custom logging in Next.js. For more information, please follow other related articles on the PHP Chinese website!