在nestjs中自定义logger
孙泽辉 Lv5

记录日志很重要,正如Apache软件基金会所说:没有错误日志的任何问题的故障排除就像闭着眼睛开车一样。

nodejs中主流日志记录插件,如log4js,winston,pino,试了log4js,有些问题没能解决,最终听从群友建议,使用pino。理由是:配置方便,美化日志好看!

安装

nestjs-pino 是基于pino封装的nest模块,可以拿来即用!

1
2
3
yarn add nestjs-pino
# pino 日志美化工具
yarn add -D pino-pretty

main.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { NestFactory } from '@nestjs/core';
import { TransformInterceptor } from './core/interceptor/transform.interceptor';
import { AppModule } from './app.module';

import { ConfigService } from '@nestjs/config';
import { Logger } from 'nestjs-pino';
async function bootstrap() {
// 关闭默认logger
const app = await NestFactory.create(AppModule, {
bufferLogs: true,
logger: false,
});
app.useLogger(app.get(Logger));

const configService = app.get(ConfigService);
await app.listen(configService.get('port'));
return configService;
}
bootstrap().then((configService) => {
console.log(
`应用程序接口地址: http://localhost:${configService.get<number>('port')}`,
);
console.log('🚀 服务应用已经成功启动!');
});

main.ts中引入nestjs-pino,将默认Logger替换

继续在app.module.ts中配置nest-pino

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

import { LoggerModule } from 'nestjs-pino';
import { pinoHttpOption } from './logger.config';

@Module({
imports: [
LoggerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => {
return { pinoHttp: pinoHttpOption(configService.get('NODE_ENV')) };
},
}),
// ...
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

使用useFactory为其注入原生pino的配置信息,为方便整理,将pinoHttp的配置信息拎出去了

logger.config.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { Request, Response } from 'express';
import {
SerializedError,
SerializedRequest,
SerializedResponse,
} from 'pino-std-serializers';
export function pinoHttpOption(envDevMode = 'development') {
return {
customAttributeKeys: {
req: '请求信息',
res: '响应信息',
err: '错误信息',
responseTime: '响应时间(ms)',
},
level: envDevMode !== 'production' ? 'debug' : 'info',
customLogLevel(_: Request, res: Response) {
if (res.statusCode <= 300) return 'info';
return 'error';
},
serializers: {
// 自定义请求日志
req(_req: SerializedRequest) {
const santizedReq = {
method: _req.method,
url: _req.url,
params: (_req.raw as Request).params,
query: (_req.raw as Request).query,
body: (_req.raw as Request).body,
};
return santizedReq;
},
res(_res: SerializedResponse) {
const santizedRes = {
status: _res.statusCode,
};
return santizedRes;
},
// 自定义错误日志
err(_err: SerializedError) {
const santizedErr = {
..._err,
};
return santizedErr;
},
},
transport: {
target: 'pino-pretty',
// 美化插件配置
options:
envDevMode === 'development'
? {
colorize: true, // 带颜色输出
levelFirst: true,
// 转换时间格式
translateTime: 'yyyy-mm-dd HH:MM:ss.l o',
}
: {
colorize: false,
levelFirst: true,
translateTime: 'yyyy-mm-dd HH:MM:ss.l o',
// 保存日志到文件
destination: './log/combined.log',
mkdir: true,
},
},
};
}

注意:保存到文件时一定要把colorize关掉,不然有些控制字符在文件里,大概是控制颜色的字符。

插件仓库:

iamolegga/nestjs-pino: Platform agnostic logger for NestJS based on Pino with REQUEST CONTEXT IN EVERY LOG (github.com)

pinojs/pino-pretty: 🌲Basic prettifier for Pino log lines (github.com)

pinojs/pino: 🌲 super fast, all natural json logger (github.com)

nestjs-pino是pino的封装,一般它文档缺少的可以去看一下pino的,就这样。

效果

效果还ok,我的需求能看清请求信息就可以了

成功响应:

image

失败响应

image

参考:

(88条消息) NestJS 7.x 折腾记: (3) 采用nestjs-pino作为Nest logger_crper的博客-CSDN博客

 Comments
Comment plugin failed to load
Loading comment plugin
Powered by Hexo & Theme Keep
Total words 85.5k