์‚ฌ์šฉ์ค‘์ธ ์˜คํ”ˆ์†Œ์Šค์˜ ๋ฒ„๊ทธ ์ˆ˜์ •ํ•˜๊ธฐ

youngki
  • #wonderwall
  • #fromm
  • #nestjs
  • #nestjs-pino
  • #pino-http
  • #logger
  • #opensource

๋“ค์–ด๊ฐ€๋ฉฐ

์•ˆ๋…•ํ•˜์„ธ์š”. ๋…ธ๋จธ์Šค์—์„œ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์„ ํ•˜๊ณ  ์žˆ๋Š” JetBrains์„ ์ข‹์•„ํ•˜๋Š” ์œ ์˜๊ธฐ์ž…๋‹ˆ๋‹ค.

ํŠน๋ณ„ํžˆ JetBrains ์–ธ๊ธ‰ํ•œ ์ด์œ ๋Š” ์ด๋ฒˆ์— ๊ธฐ์—ฌํ•˜๊ฒŒ๋œ https://github.com/pinojs/pino-http/pull/288 ์™€ ๊นŠ์€ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
์‚ฌ์šฉ์ค‘์ธ ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๊ธฐ๋Œ€์™€ ๋‹ค๋ฅธ ๋™์ž‘์„ ํ•  ๋•Œ, WebStorm(JetBrains)์„ ํ†ตํ•ด node_modules ํƒํ—˜ํ•˜๊ธฐ ์ข‹์Šต๋‹ˆ๋‹ค.
(๋‹ค๋ฅธ IDE๋„ Debug ๊ธฐ๋Šฅ์ด ์—†๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ, break๋ฅผ ์žก๊ธฐ๊นŒ์ง€ ํ™˜๊ฒฝ์„ค์ •์— ๋งŽ์€ ์‹œ๊ฐ„์„ ์จ์•ผ ํ•ฉ๋‹ˆ๋‹ค.)

์ž…์‚ฌ ์ดˆ ์˜จ๋ณด๋”ฉ ์‹œ๊ธฐ

๋…ธ๋จธ์Šค๋Š” Serverless + NestJS + TypeORM ๋“ฑ์˜ ๊ธฐ์ˆ  ์Šคํƒ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐœ๋ฐœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ์ž…์‚ฌ ์ดˆ๋ฐ˜์— NestJS ๊ด€๋ จ ์‚ฌ์šฉ์ค‘์ธ ์—ฌ๋Ÿฌ ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ดํŽด๋ณด๊ฒŒ ๋˜์—ˆ๊ณ , ๊ทธ์ค‘ ์—๋Ÿฌ์™€ ๋กœ๊ทธ ๊ด€๋ จ ํŒจํ‚ค์ง€๋ฅผ ๋ณด๋˜ ์ค‘์—, nestjs-pino์˜ ์ด๋ฆ„์ด ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.
nestjs-pino๋Š” pino๋ฅผ ๋ฐ”๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, pino-http๋ฅผ nestjs module๋กœ ๋งŒ๋“  ๊ฒƒ์ด๋ผ, nestjs-pino ๋ณด๋‹ค๋Š” nestjs-pino-http๊ฐ€ ๋” ์ ํ•ฉํ•ด ๋ณด์˜€์Šต๋‹ˆ๋‹ค.

https://www.npmjs.com/package/nestjs-pino ์—์„œ๋„ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์น˜ ๊ฐ€์ด๋“œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

npm i nestjs-pino pino-http

๋ฒ„๊ทธ ๋ฐœ๊ฒฌ

@Module({
  imports: [
    ...
    LoggerModule.forRoot({
      pinoHttp: {
        customProps: (req, res) => ({
          context: 'HTTP',
        }),
      },
    }),
    ...
  ],
  ...
})
export class AppModule {}

nestjs-pino์˜ ๋ณธ์ฒด๊ฐ€ pino-http๋ผ๋Š” ์ทจ์ง€๋กœ ์œ„์™€ ๊ฐ™์ด customProps๋ฅผ ์ถ”๊ฐ€ํ•˜์˜€๋”๋‹ˆ, context๊ฐ€ ๋ฐ˜๋ณต๋˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , ๊ตฌ๊ธ€๋ง์„ ํ•ด๋ณธ ๊ฒฐ๊ณผ https://github.com/pinojs/pino-http/issues/216, 1๋…„ ์ด์ƒ๋œ ์˜ค๋ž˜๋œ ์ด์Šˆ๋กœ ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ์ด์Šˆ๋งŒ ์ œ๊ธฐํ•˜๊ณ  ์žˆ๋Š” ์ƒํƒœ์˜€์Šต๋‹ˆ๋‹ค.

์‹ฌ์ง€์–ด, maintainer๋„ ๊ณ ์น˜์ง€ ์•Š๊ณ  ์žˆ๋Š” ์ƒํ™ฉ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฒ„๊ทธ ์ˆ˜์ •

pino-http repository์˜ example.js ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์•ฝ๊ฐ„ ์ˆ˜์ •ํ•˜์—ฌ, ๋ฐ”๋กœ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.


์ด์Šˆ ์ˆ˜์ • ์ „ ์ฝ”๋“œ์—์„œ 2๋ฒˆ์งธ customProps์„ ์‚ฝ์ž…ํ•˜๋ ค๋Š” ์‹œ์ ์— break ์žก์€ ์žฅ๋ฉด์ž…๋‹ˆ๋‹ค.

์ด ๋ถ€๋ถ„์„ ์—ฌ๋Ÿฌ๋ฒˆ ์‹คํ–‰ํ•˜๋ฉด์„œ ๊ด€์ฐฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.

meta์ ์œผ๋กœ ํ•ด๊ฒฐํ•ด ๋ณด๋ ค๋Š” ์‹œ๋„๋ฅผ ๋จผ์ € ํ•˜์˜€๋Š”๋ฐ, pino-http ๊ตฌ์กฐ์ƒ ์–ด๋ ค์› ๊ณ ,
์ด์Šˆ์˜ ํ•ต์‹ฌ์ ์ธ ๋‚ด์šฉ์€ context ๊ฐ’์„ meta๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๊ณ , req, res ๊ฐ๊ฐ ๋ฐ”๋กœ stringifyํ•˜์—ฌ, chindingsSym property์— ์ €์žฅํ•ด ๋†“๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.
2๋ฒˆ์งธ customProps์„ ์ถ”๊ฐ€ํ•˜๋ ค๋Š” ์‹œ์ ์— chindingsSym์— customProps๊ฐ€ ๋“ค์–ด์žˆ๋Š”์ง€ ์ฒดํฌํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.

https://github.com/pinojs/pino-http/pull/288/files

ํ…Œ์ŠคํŠธ ์ž‘์„ฑ

๊ทธ๋ ‡๊ฒŒ ์ด์Šˆ๋Š” ์ˆ˜์ •ํ•˜์˜€์ง€๋งŒ, ๋ฐ˜์‘์ด ๋ฐ”๋กœ ์žˆ์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ, ์—ฌ๋Ÿฌ ๊ฐœ๋ฐœ์ž์˜ ํ•„์š”๋Š” ์žˆ์—ˆ๋Š”์ง€, PR์— ์™€์„œ, ์—„์ง€์ฒ™ ํ•˜๋Š” ์‚ฌ๋žŒ๋„ ์žˆ๊ณ ,

์ถ”๊ฐ€๋กœ github issue์— ์ด์Šˆ ์ˆ˜์ •์„ ํ˜ธ์†Œ ํ•˜๋Š” ๋ถ„๋„ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.


์žŠ๊ณ  ์ง€๋‚ด๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, 1๋‹ฌ ๋ฐ˜์ฏค ์ง€๋‚ฌ์„ ๋ฌด๋ ต maintainer์˜ ์š”์ฒญ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋•Œ๋Š” BEST fromm FRIEND ๋ผ๋Š” ํšŒ์‚ฌ ํ”„๋กœ์ ํŠธ๊ฐ€ ํ•œ์ฐฝ ์ง„ํ–‰์ค‘์ผ ๋•Œ๋ผ, ์‹ฌ์  ์—ฌ์œ ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฌดํƒˆํ•˜๊ฒŒ ํ”„๋กœ์ ํŠธ๋ฅผ ์ž˜ ๋งˆ๋ฌด๋ฆฌ ํ•˜๊ณ , ์–ด๋Š ๋‚  ๋ฐค ์ด ์ด์Šˆ๊ฐ€ ์ƒ๊ฐ๋‚˜ ๋‚จ์€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋„ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” stream์„ ๊ธฐ๋ฐ˜์œผ๋กœ 'data' ์ด๋ฒคํŠธ์—์„œ ๋ฐ์ดํƒ€๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ ๋™์•ˆ ์ด์Šˆ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š์€ ์ด์œ ๋Š” ํ•ญ์ƒ JSON.parse๋ฅผ ๋™๋ฐ˜ํ•œ ์ƒํƒœ์˜ stream์„ ๊ฐ€์ง€๊ณ  ํ…Œ์ŠคํŠธ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ์Šต๋‹ˆ๋‹ค.
(JSON.parse์—์„œ ๋™์ผํ•œ key๊ฐ€ ์žˆ๋‹ค๋ฉด, overwrite ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐ™์€ key๊ฐ€ 2๊ฐœ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.)
ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ๋ถ„์„์€ ์ด์Šˆ ํ•ด๊ฒฐ๊ณผ์ • ๋ชป์ง€ ์•Š๊ฒŒ ์˜ค๋ž˜ ์‚ดํŽด ๋ณด์•„์•ผ ํ–ˆ์ง€๋งŒ, JSON.parse ์—†๋Š” stream์„ ์ƒ๊ฐํ•ด ๋‚ด๊ณ , ์ฝ”๋“œ๋Š” ๋ฐ”๋กœ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊นŒ์ง€ ์ž‘์„ฑํ•˜๊ณ , Request Changes์— ์ถ”๊ฐ€๋กœ ํ•œ๋ถ„ ๋” reviewer๋กœ ์ฐธ์—ฌ ํ•˜์…จ๋Š”๋ฐ,
์žฌ ์š”์ฒญํ•œ ์ฝ”๋“œ ๋ฆฌ๋ทฐ์—์„œ๋Š” ํ•˜๋ฃจ๋ฅผ ๋„˜๊ธฐ์ง€ ์•Š๊ณ , ๋ฆฌ๋ทฐํ•ด ์ฃผ์…จ์Šต๋‹ˆ๋‹ค.

์ด PR์€ v8.4.0๋กœ ๋ฆด๋ฆฌ์ฆˆ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ˆ˜์ • ์ด๋ ฅ

๋งˆ์น˜๋ฉฐ

์•„๋ฌด๋ž˜๋„ ์กฐ์ง์˜ ๊ตฌ์„ฑ์›์œผ๋กœ์„œ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ๋Š” ํ”„๋กœ์ ํŠธ๊ฐ€ ์šฐ์„ ์‹œ๋˜์ง€๋งŒ, ์‚ฌ์šฉ์ค‘์ธ ์˜คํ”ˆ์†Œ์Šค์— ์ด์ƒํ•œ ์ ์„ ๋ฐœ๊ฒฌ ํ–ˆ์„ ๋•Œ, ์ง€๋‚˜์น˜์ง€ ๋งˆ์‹œ๊ณ  ์—ฌ์œ  ์žˆ๋Š” ์‹œ๊ฐ„์— ์ฐธ์—ฌํ•ด ๋ณด์„ธ์š”!
ํŠนํžˆ, Debugger๋ฅผ ํ†ตํ•ด, ํ‰์†Œ ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ์ฝ”๋“œ๋ฅผ ๋ถ„์„(read)ํ•  ๋•Œ๋Š” ๋ฌผ๋ก , ์ต์ˆ™ํ•œ ์ฝ”๋“œ์˜ ๊ฐœ๋ฐœ(write) ์†๋„ ์ธก๋ฉด์—์„œ๋„ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. IDE์—์„œ Debugger๋ฅผ Enable ํ•ด๋ณด์‹œ์ฃ !

์ด๋ ‡๊ฒŒ ๋˜ ํ•˜๋‚˜์˜ ๋กœ๊ทธ(์˜คํ”ˆ์†Œ์Šค ์ปค๋ฐ‹, ๋ธ”๋กœ๊ทธ)๊ฐ€ ์Œ“์—ฌ์ ธ ๊ฐ‘๋‹ˆ๋‹ค.

โ† ๋ชฉ๋ก์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ

Art Changes Life

๋…ธ๋จธ์Šค์™€ ํ•จ๊ป˜ ์—”ํ„ฐํ…Œํฌ ์‚ฐ์—…์„ ํ˜์‹ ํ•ด๋‚˜๊ฐˆ ๋ฉค๋ฒ„๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

์ฑ„์šฉ ์ค‘์ธ ๊ณต๊ณ  ๋ณด๊ธฐ