内置Logger
默认的 nest 控制台日志配置:
const app = await NestFactory.create(AppModule, {
logger: ['error', 'warn', 'log']
});
当然,nest 内部也默认集成了日志模块:
import { Logger } from '@nestjs/common';
const logger = new Logger()
logger.log(`Application is running on: http://localhost:${port}`);
在单个模块下使用:
ts
export class UsersController {
// 可以将一个参数传递给日志对象,一般我们设置为模块名
private readonly logger = new Logger(UsersController.name);
constructor(private readonly usersService: UsersService) {}
@Get()
@Roles(Role.admin)
@ApiOperation({ summary: '获取所有用户' })
@ApiResponse({ status: 200, description: '获取成功' })
findAll() {
this.logger.log('获取所有用户');
return this.usersService.findAll();
}
}

nestjs-pino
pino 有一个特点就是默认会打印日志(无需手动的 logger.log )。而且他很小,很简洁。
默认的打印和 console.log 一样(很丑陋),so 我们可以使用 pino-pretty 这个库来优化样式。这是在开发环境。
如果是生产环境下,我们可以使用 pino-roll 来记录定时记录日志,便于追踪用户行为。

winstom
winston 对于日志的集成度很高。
添加一个模块:
nest g mo logs
logs.module.ts
ts
import { Module } from "@nestjs/common";
import { utilities, WinstonModule } from "nest-winston";
import { ConfigService } from "@nestjs/config";
import * as Winston from "winston";
import * as DailyRotateFile from "winston-daily-rotate-file";
@Module({
imports: [
WinstonModule.forRootAsync({
useFactory: (config: ConfigService) => {
const consoleTransport = new Winston.transports.Console({
level: "info",
format: Winston.format.combine(
Winston.format.timestamp(),
utilities.format.nestLike()
),
});
const dailyTransport = new DailyRotateFile({
level: config.get("LOG_LEVEL") || "info",
filename: "logs/app-%DATE%.log",
datePattern: "YYYY-MM-DD",
zippedArchive: true,
maxSize: "20m",
maxFiles: "14d",
format: Winston.format.combine(
Winston.format.timestamp(),
Winston.format.simple()
),
});
const dailyInfoTransport = new DailyRotateFile({
level: config.get("LOG_LEVEL") || "warn",
filename: "logs/app-info-%DATE%.log",
datePattern: "YYYY-MM-DD",
zippedArchive: true,
maxSize: "20m",
format: Winston.format.combine(
Winston.format.timestamp(),
Winston.format.simple()
),
});
return {
transports: [
consoleTransport,
...(config.get("LOG_ON")
? [dailyTransport, dailyInfoTransport]
: []),
],
};
},
inject: [ConfigService],
}),
],
providers: [],
exports: [],
})
export class LogsModule {}
然后全局替换掉 nest 内置的日志记录:
main.ts
ts
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER))
await app.listen(port);
}
依赖注入使用:
users.controller.ts
ts
import { Controller, Get, Post, Body, Param, Delete, Put, UseGuards, ParseIntPipe, LoggerService, Inject } from '@nestjs/common';
// ....
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
@ApiTags('users')
@Controller('api/users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
constructor(
private readonly usersService: UsersService,
@Inject(WINSTON_MODULE_NEST_PROVIDER)
private readonly logger: LoggerService
) {}
@Get()
findAll() {
this.logger.log('获取所有用户');
return this.usersService.findAll();
}