NextJs中如果使用Route Handlers来编写Restful API接口,可以使用winston来将日志存储到文件。
winston
Winston是一个Node.js的日志记录库,它可以帮助开发人员记录应用程序中的重要日志信息并进行分析。Winston支持多种日志记录级别,包括调试、信息、警告和错误,并提供多种输出选项,例如控制台输出、文件输出和数据库输出等。Winston还支持自定义日志格式和传输方式,可以与各种日志分析工具和第三方服务集成。因此,它被广泛用于开发Node.js应用程序的日志记录和分析。
NextJS中使用winston
1. 安装winston
# 安装winston库
npm install winston --save
# 安装插件
npm install winston-daily-rotate-file --save
winston-daily-rotate-file 是 Winston 日志库的一个插件,它提供了日志文件的按日轮换功能。它可以根据用户设置的时间间隔(如每天、每小时、每周等)自动将日志文件按日期轮换,以防止单个日志文件过大,影响读写性能。同时,它还可以设置日志文件的最大数量,当超过最大数量时,将删除最旧的日志文件。winston-daily-rotate-file 插件使用简单,并且与 Winston 日志库的其他插件兼容,可以很方便地集成到现有的 Node.js 应用程序中。
2. 创建winston-logger.ts
const { createLogger, format, transports } = require("winston");
require("winston-daily-rotate-file");
const customFormat = format.combine(
format.timestamp({ format: "MMM-DD-YYYY HH:mm:ss" }),
format.align(),
format.printf((i: { level: any; timestamp: any; message: any; }) => `${i.level}: ${[i.timestamp]}: ${i.message}`)
);
const defaultOptions = {
format: customFormat,
datePattern: "YYYY-MM-DD",
zippedArchive: true,
maxSize: "20m",
maxFiles: "14d",
frequency: "1m",
//format: format.json()
};
const globalLogger = createLogger({
format: customFormat,
transports: [
new transports.Console(),
new transports.DailyRotateFile({
filename: "logs/info-%DATE%.log",
level: "info",
...defaultOptions,
}),
new transports.DailyRotateFile({
filename: "logs/error-%DATE%.log",
level: "error",
...defaultOptions,
}),
],
exitOnError: false,
exceptionHandlers: [
new transports.DailyRotateFile({
filename: "logs/exceptions.log",
}),
]
});
module.exports = {
globalLogger: globalLogger,
};
2. 创建logger.ts日志工具类
const { globalLogger } = require("./winston-logger");
export class Logger {
public static error(e: Error) {
globalLogger.error(e.stack)
}
public static info(message: any) {
globalLogger.info(message)
}
public static warn(message: any) {
globalLogger.warn(message)
}
public static debug(message: any) {
globalLogger.debug(message)
}
}
3. Route Handlers中使用日志类
app/api/test/route.ts文件
import { Logger } from '@/lib/logger'
import { PrismaClient } from '@prisma/client'
import { NextRequest } from 'next/server'
async function delChapter(docId: number, chapterId: bigint) {
prisma操作数据库...
}
export async function GET(request: NextRequest) {
try {
const searchParams = request.nextUrl.searchParams;
const docId = Number(searchParams.get('docId') as string);
const chapterId = BigInt(searchParams.get('chapterId') as string);
let res = await delChapter(docId, chapterId).finally(async () => await prisma.$disconnect())
return res
}
catch(e) {
Logger.error(e as Error)
return new Response((e as Error).message, { status: 500, statusText: (e as Error).name })
}
}
nextjs13中暂时没有找到更好的方式来处理异常的统一记录,现阶段需要在每个api中try catch捕捉。