winston
Winston是一个Node.js的日志记录库,它可以帮助开发人员记录应用程序中的重要日志信息并进行分析。Winston支持多种日志记录级别,包括调试、信息、警告和错误,并提供多种输出选项,例如控制台输出、文件输出和数据库输出等。Winston还支持自定义日志格式和传输方式,可以与各种日志分析工具和第三方服务集成。因此,它被广泛用于开发Node.js应用程序的日志记录和分析。
winston-daily-rotate-file
winston-daily-rotate-file是Winston的一个扩展,它为Winston提供了一个方便的daily rotating file transport(日志文件轮转传输器)。简单来说,就是每当达到指定时间(通常是每日零点)或者文件大小超过限制时,它会创建一个新的日志文件,从而避免单个日志文件过大,便于管理和长期存储大量日志数据。
安装插件
# 安装日志库
pnpm add winston nest-winston
# 安装winston-daily-rotate-file
pnpm add winston-daily-rotate-file
自定义日志服务
@@filename(logger.service.ts)
import { Injectable } from '@nestjs/common'
import { utilities } from 'nest-winston'
import * as winston from 'winston'
import * as WinstonDailyRotateFile from 'winston-daily-rotate-file'
/**
* @description: 自定义日志服务
*/
@Injectable()
export class MyLoggerService {
private logger: winston.Logger
constructor() {
const rotateTransport = new WinstonDailyRotateFile({
// 日志文件名
filename: 'application-%DATE%.log',
// 日志文件名日期格式
datePattern: 'YYYY-MM-DD',
// 日志目录(tip:开发环境logs目录和src同级,生产环境单独设置目录路径)
dirname: 'logs',
zippedArchive: true,
// 日志文件最大大小
maxSize: '20m',
// 日志文件最大保存时间
maxFiles: '14d',
// 日志格式
format: winston.format.combine(
winston.format.timestamp(),
winston.format.ms(),
utilities.format.nestLike('Blog Server Logger...', {
colors: true,
prettyPrint: true,
})
)
})
this.logger = winston.createLogger({
transports: [ rotateTransport, new winston.transports.Console() ],
})
}
public log(message: string) {
this.logger.info(' ==> ' + message)
}
public warn(message: string) {
this.logger.warn(' ==> ' + message)
}
public error(message: string, trace: string) {
this.logger.error(' ==> ' + message, { trace })
}
public debug(message: string) {
this.logger.debug(' ==> ' + message)
}
public verbose(message: string) {
this.logger.verbose(' ==> ' + message)
}
}
使用自定义的日志服务(以UserModule为例)`
user.module.ts
@@filename(user.module.ts)
import { Module } from '@nestjs/common'
import { UserService } from './user.service'
import { UserController } from './user.controller'
import { MyLoggerService } from 'src/libs/logger/logger.service'
/**
* @description 用户模块
*/
@Module({
controllers: [ UserController ],
providers: [ UserService, MyLoggerService ],
exports: [ UserService ]
})
export class UserModule {}
user.service.ts
@@filename(user.service.ts)
import { Injectable } from '@nestjs/common'
import { MyLoggerService } from 'src/libs/logger/logger.service'
/**
* @description 用户服务
*/
@Injectable()
export class UserService {
constructor(
private readonly logger: MyLoggerService,
) {}
async create() {
this.logger.log('用户注册成功')
return 'success'
}
}
执行成功后会在logs
目录下生成两个文件
.83b687ea5651ad72c72a8164984483a0aca9a3a9-audit.json
@@filename(.83b687ea5651ad72c72a8164984483a0aca9a3a9-audit.json)
{
"keep": {
"days": true,
"amount": 14
},
"auditLog": "logs/.83b687ea5651ad72c72a8164984483a0aca9a3a9-audit.json",
"files": [
{
"date": 1715152001987,
"name": "logs/application-2024-05-08.log",
"hash": "c84e5cf08751311bc6ce45228fa6e64c1e77a885ee03a7b2c42384a63ef85c1b"
}
],
"hashType": "sha256"
}
application-2024-05-08.log
[32m[Blog Server Logger...][39m [33mInfo[39m 2024/5/8 19:58:27 [32m 用户注册成功[39m [33m+26s[39m
自定义异常自动写入日志记录
@@filename(http-exception.filter.ts)
import {
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
LoggerService
} from '@nestjs/common'
/**
* @description HTTP异常过滤器, 用于处理HTTP异常
*/
// 固定注解, 用于捕获异常
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
constructor(private logger?: LoggerService) {}
// ExceptionFilter 类中有一个 catch 方法, 这里来进行实现
catch(exception: HttpException, host: ArgumentsHost) {
// host代表nestjs整个进程
const ctx = host.switchToHttp()
const res = ctx.getResponse()
const req = ctx.getRequest()
const status = exception.getStatus()
this.logger.error(`系统错误 =====> ${exception.message}`, exception.stack)
// 响应给用户
res.status(status).json({
status,
timestamp: new Date().toISOString(),
url: req.url,
method: req.method,
message: exception.message || exception.name
})
}
}
使用方式
@@filename(main.ts)
import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
import { NestExpressApplication } from '@nestjs/platform-express'
import { HttpExceptionFilter } from 'src/libs/filters/http-exception/http-exception.filter'
import { MyLoggerService } from 'src/libs/logger/logger.service'
/**
* The bootstrap function is an async function that creates an instance of the Nest application.
*/
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule)
// 异常拦截器
app.useGlobalFilters(new HttpExceptionFilter(new MyLoggerService))
await app.listen(3000)
}
bootstrap().then(_ => _)
个人博客:https://www.linmeimei.top/ 欢迎访问