xzz2021
发布于 2024-02-03 / 3 阅读
0
0

nestjs日志系统winston配置学习

跳过nest内置日志系统主要是希望分类输出日志文件方便进行查询!

使用依赖nest-winston

main.ts文件里替换nest内置的logger

// main.ts 文件
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

// 使用winston替代nest自带日志系统
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; // <-----

async function bootstrap() {
const app = await NestFactory.create(AppModule);
// app.setGlobalPrefix('全局接口前缀')
app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER)) // <-------
await app.listen(3000);
}
bootstrap();

app.module.ts里配置自定义选项,分类输出日志文件

import { WinstonModule } from 'nest-winston';
import * as winston from 'winston';
import { format } from 'winston';
const { combine, timestamp, label, prettyPrint } = format;
//.......
@Module({
imports: [
WinstonModule.forRoot({
// 输出格式
// format: winston.format.json(),
format: combine(
label({ label: '测试' }),
timestamp(),
prettyPrint()
),
transports: [
new winston.transports.Console({
format: winston.format.combine(
winston.format.timestamp(),
),
}),
// 输出文件
new winston.transports.File({ //定义输出日志文件
filename: 'logFile/combined.log',
level: 'info',
// format: winston.format.combine(
// winston.format.timestamp({
// format: 'YYYY-MM-DD HH:mm:ss',
// }),
// winston.format.json(),
// ),
}),
new winston.transports.File({
filename: 'logFile/errors.log',
level: 'error'
}),
new winston.transports.File({
filename: 'logFile/warning.log',
level: 'warning'
}),
],
// 未捕获的异常
exceptionHandlers: [
new winston.transports.File({ filename: 'logFile/exceptions.log' })
]
})
],
controllers: [AppController],
providers: [AppService],
}]

主动输出日志需要到模块controller里inject

import { LoggerService } from '@nestjs/common';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';

@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: LoggerService
) {}

@get()
getData(){
this.logger.warn( {message:'==========='})
}
}

滚动输出日志,需要用到依赖winston-daily-rotate-file,会每小时自动生成新的日志文件

和输出文件一样,配置在module的transport数组中, 既然使用了滚动,那上面的new winston.transports.File就可以注释不用了

// 实测使用typescript方式引入会报错
import 'winston-daily-rotate-file';
//。。。。。
new winston.transports.DailyRotateFile({
level: 'info',
filename: 'logFile/info-%DATE%.log',
datePattern: 'YYYY-MM-DD-HH',
zippedArchive: true,
maxSize: '10m',
maxFiles: '14d'
}),
new winston.transports.DailyRotateFile({
level: 'warn',
filename: 'logFile/warn-%DATE%.log',
datePattern: 'YYYY-MM-DD-HH',
zippedArchive: true,
maxSize: '10m',
maxFiles: '30d'
}),

滚动日志依赖默认没有时间戳,全局配置format会导致日志文件出现undefined的bug 原因是需要配置输出格式 此处参考大神解决方案

原因是forRoot里设置了全局format属性会覆写,所以在全局定义里要再定义下打印输出日志的内容,使用winston.format.printf()

WinstonModule.forRoot({
format: combine(
winston.format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss',
}),
winston.format.printf((info) => { // 定义文件输出内容
return 时间:${info.timestamp},日志类型:${info.level},${info?.context ? 运行背景: ${info.context} : '' },日志信息: ${info.message}
})
})

至此一般运行和主动触发的日志就能自动写入文件里了,关于对请求接口进行日志记录和输出,请看这里


评论