やりたいこと 参考 関連記事 1. ライブラリインストール 2. ロガーのモジュールを追加 全ての環境でJSON出力のみする場合 ローカル起動時だけJSON出力しない場合 3. main.tsでロガーを使うように修正 4. アプリケーションコードでロガーを使う pino-prettyを入れた場合 まとめ
やりたいこと
- ログをJSON形式で出力する
- リクエスト、レスポンスのログを自動で詳細に出力する(リクエストパラメータやリクエストヘッダー、レスポンスのステータスコードなどを自動出力する)
参考
関連記事
1. ライブラリインストール
pnpm add nestjs-pino pino-http pino-pretty -
nestjs-pino:NestJS用のpinoライブラリ -
pino-http:リクエスト、レスポンスログを自動出力する -
pino-pretty:JSON形式は人間には見づらいので、人間に見やすい形式で出力する(ローカル環境のみ)
2. ロガーのモジュールを追加
全ての環境でJSON出力のみする場合
// app.module.ts
import { LoggerModule } from 'nestjs-pino';
@Module({
imports: [LoggerModule.forRoot()],
})
class AppModule {} ローカル起動時だけJSON出力しない場合
// app.module.ts
import { LoggerModule } from 'nestjs-pino';
@Module({
imports: [
LoggerModule.forRoot({
pinoHttp: {
transport:
process.env.NODE_ENV === 'local'
? {
target: 'pino-pretty',
}
: undefined,
},
}),
],
})
export class AppModule {}
NODE_ENV = 'local'のときのみ、 pino-prettyを使うことで
ローカル起動時のみJSONをではなく人間が見やすい形式で表示するようにしている。
特に不要な場合は
3. main.tsでロガーを使うように修正
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Logger } from 'nestjs-pino';
async function bootstrap() {
// これを追加
const app = await NestFactory.create(AppModule, { bufferLogs: true });
app.useLogger(app.get(Logger));
await app.listen(process.env.PORT ?? 3000);
}
bootstrap(); 4. アプリケーションコードでロガーを使う
Loggerのimport先を迷うかもしれないが、 @nestjs/common からインポートしたLoggerを使えばOK。
// NestJS standard built-in logger.
// Logs will be produced by pino internally
import { Logger } from '@nestjs/common';
export class MyService {
private readonly logger = new Logger(MyService.name);
foo() {
// All logger methods have args format the same as pino, but pino methods
// `trace` and `info` are mapped to `verbose` and `log` to satisfy
// `LoggerService` interface of NestJS:
this.logger.verbose({ foo: 'bar' }, 'baz %s', 'qux');
this.logger.debug('foo %s %o', 'bar', { baz: 'qux' });
this.logger.log('foo');
}
} pino-prettyを入れた場合
通常JSONで出力される情報が、このように出力される。
今回細かい設定はしていないが、リクエストとレスポンスに関する情報( reqと res)が自動で出力されていることがわかる。
[14:33:45.881] INFO (74716): アカウント情報を取得します
req: {
"id": 1,
"method": "GET",
"url": "/v1/accounts/1",
"query": {},
"params": {
"path": [
"v1",
"accounts",
"1"
]
},
"headers": {
"host": "localhost:3000",
"user-agent": "curl/8.7.1",
"accept": "*/*",
"x-request-id": "hoge"
},
"remoteAddress": "::1",
"remotePort": 59523
}
context: "AccountUseCase"
[14:33:45.895] INFO (74716): request completed
req: {
"id": 1,
"method": "GET",
"url": "/v1/accounts/1",
"query": {},
"params": {
"path": [
"v1",
"accounts",
"1"
]
},
"headers": {
"host": "localhost:3000",
"user-agent": "curl/8.7.1",
"accept": "*/*",
"x-request-id": "hoge"
},
"remoteAddress": "::1",
"remotePort": 59523
}
res: {
"statusCode": 200,
"headers": {
"x-powered-by": "Express",
"cache-control": "public",
"content-type": "application/json; charset=utf-8",
"content-length": "31",
"etag": "W/\"1f-hFT6eWnlTD2HzutSzS+2TpBuyhw\""
}
}
responseTime: 16
まとめ
- NestJSにpinoを入れる場合は
nestjs-pinoを使えばOK -
pino-httpは導入するだけでリクエストとレスポンスに関するログを自動出力してくれるので、ぜひ入れておきたい - ローカル起動時は
pino-prettyを使って見やすくしておくのがおすすめ