Winston: process.exit (0) ํ˜ธ์ถœ์‹œ ํŒŒ์ผ์— ๋กœ๊น…์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2013๋…„ 03์›” 25์ผ  ยท  87์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: winstonjs/winston

ํŒŒ์ผ์— ๊ธฐ๋กํ•˜๋„๋ก winston์„ ๊ตฌ์„ฑํ•˜๊ณ  ์ฝ”๋“œ์—์„œ process.exit (0)์„ ํ˜ธ์ถœํ•˜๋ฉด winston์€ ๋กœ๊ทธ ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ํŒŒ์ผ์— ๋กœ๊ทธ ๋ฉ”์‹œ์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์™„๋ฒฝํ•œ ์„ธ์ƒ์—์„œ winston์€์ด ์—ฃ์ง€ ์ผ€์ด์Šค๋ฅผ ๊ธฐ๊บผ์ด ์ฒ˜๋ฆฌํ•˜๊ณ  ํŒŒ์ผ์— ์“ธ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ˆ˜๋™์œผ๋กœ ํŒŒ์ผ์— ํ”Œ๋Ÿฌ์‹œ๋ฅผ ๊ฐ•์ œํ•˜๊ธฐ ์œ„ํ•ด ๋กœ๊ฑฐ ์ธ์Šคํ„ด์Šค์—์„œ ํ”Œ๋Ÿฌ์‹œ๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์ˆ˜๋™์œผ๋กœ 'ํ”Œ๋Ÿฌ์‹œ'ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์ด์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ ์‹ค์ œ๋กœ ๋กœ๊ทธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋กœ๊ฑฐ ์ธ์Šคํ„ด์Šค ๋˜๋Š” ๋‚ด๋ถ€ ์ŠคํŠธ๋ฆผ์„ ์ˆ˜๋™์œผ๋กœ ๋‹ซ๊ฑฐ๋‚˜ ์ข…๋ฃŒ / ํŒŒ๊ดดํ•˜๋Š” ๋ฐ ์šด์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ์— ๊ธฐ๋ก๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค ..

var winston = require('winston');
var logger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)(),
    new (winston.transports.File)({ filename: 'winston.log' })
  ]
});

logger.info('info logged');
logger.error('error logged');

process.exit(0);
// the two logs get written out to console, but not to the winston.log file/
bug important winston-file

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@danielweck ์•„๋‹ˆ์š”, ๊ณ ์žฅ

6 ๋…„, ์ฆ‰ _important_๋กœ ํ‘œ์‹œ๋œ ๋ฒ„๊ทธ์˜ ๊ฒฝ์šฐ 6 ๋…„์ž…๋‹ˆ๋‹ค. ์ธ์ƒ์ ์ธ ๊ฒฝ๊ณ„์„ ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  87 ๋Œ“๊ธ€

๋…ธ๋“œ์—์„œ console. * ๋ฉ”์†Œ๋“œ๋Š” ๋น„๋™๊ธฐ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ํŒŒ์ผ ์ „์†ก์€ ๋น„๋™๊ธฐ์ž…๋‹ˆ๋‹ค. ๋…ธ๋“œ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์“ฐ๊ธฐ ์ „์— ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹ซ์Šต๋‹ˆ๋‹ค.

2013 ๋…„ 3 ์›” 25 ์ผ ์›”์š”์ผ 19:45์— Yuri Zapuchlak์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

ํŒŒ์ผ์— ๊ธฐ๋กํ•˜๋„๋ก winston์„ ๊ตฌ์„ฑํ•˜๊ณ  ์ฝ”๋“œ์—์„œ process.exit (0)์„ ํ˜ธ์ถœํ•˜๋ฉด winston์€ ๋กœ๊ทธ ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ํŒŒ์ผ์— ๋กœ๊ทธ ๋ฉ”์‹œ์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์™„๋ฒฝํ•œ ์„ธ์ƒ์—์„œ winston์€์ด ์—ฃ์ง€ ์ผ€์ด์Šค๋ฅผ ๊ธฐ๊บผ์ด ์ฒ˜๋ฆฌํ•˜๊ณ  ํŒŒ์ผ์— ์“ธ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ˆ˜๋™์œผ๋กœ ํŒŒ์ผ์— ํ”Œ๋Ÿฌ์‹œ๋ฅผ ๊ฐ•์ œํ•˜๊ธฐ ์œ„ํ•ด ๋กœ๊ฑฐ ์ธ์Šคํ„ด์Šค์—์„œ ํ”Œ๋Ÿฌ์‹œ๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ˜„์žฌ ์ˆ˜๋™์œผ๋กœ 'ํ”Œ๋Ÿฌ์‹œ'ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์ด์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ ์‹ค์ œ๋กœ ๋กœ๊ทธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋กœ๊ฑฐ ์ธ์Šคํ„ด์Šค ๋˜๋Š” ๋‚ด๋ถ€ ์ŠคํŠธ๋ฆผ์„ ์ˆ˜๋™์œผ๋กœ ๋‹ซ๊ฑฐ๋‚˜ ์ข…๋ฃŒ / ํŒŒ๊ดดํ•˜๋Š” ๋ฐ ์šด์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ์— ๊ธฐ๋ก๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค ..
var winston = require ( 'winston'); var logger = new (winston.Logger) ({transports : [new (winston.transports.Console) (), new (winston.transports.File) ({filename : 'winston.log'})]}); logger.info ( '์ •๋ณด ๊ธฐ๋ก๋จ'); logger.error ( '์˜ค๋ฅ˜ ๊ธฐ๋ก๋จ'); process.exit (0); // ๋‘ ๋กœ๊ทธ๋Š” ์ฝ˜์†”์— ๊ธฐ๋ก๋˜์ง€๋งŒ winston.log ํŒŒ์ผ์—๋Š” ๊ธฐ๋ก๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

โ€”
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ํšŒ์‹ ํ•˜๊ฑฐ๋‚˜ GitHub (https://github.com/flatiron/winston/issues/228)์—์„œ ํ™•์ธํ•˜์„ธ์š”.

ํ . ์ด ๊ฒฝ์šฐ ๋…ธ๋“œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ฃฝ์—ฌ์•ผํ•˜์ง€๋งŒ ์ฃฝ์ด๊ธฐ ์ง์ „์— ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ, ์ถฉ๋ถ„ํžˆ ๊ธด ์‹œ๊ฐ„์„ ๊ฐ€์ง„ setTimeout () ์•ˆ์— process.exit ()๋ฅผ ๋„ฃ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. winston์ด ์‹ค์ œ๋กœ ๋กœ๊ทธ ํŒŒ์ผ์— ๋ฉ”์‹œ์ง€๋ฅผ ์”๋‹ˆ๊นŒ?

๋ช…ํ™•์„ฑ์„ ์œ„ํ•ด console.log ๋ฐ ์นœ๊ตฌ ๋Š” ๋™๊ธฐ์‹ ์ž…๋‹ˆ๋‹ค.

@yzapuchlak ๋‚˜๋Š” ์‹ค์ œ๋กœ ํ…Œ์ŠคํŠธํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ๊ทธ๊ฒŒ ๋‚˜๋„ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค.

@yzapuchlak setTimeout์€ ๋ฌธ์ œ์—†์ด _probably_ ์ž‘๋™ํ•˜์ง€๋งŒ, ๋Œ€์‹  ์„ ํƒ์  ์ฝœ๋ฐฑ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ˜„๋ช…ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

2000 ๋˜๋Š” 5000์˜ setTimeout์€ ๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ์—์„œ ์ž‘๋™ํ•˜์ง€๋งŒ ์‹ค์ œ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•  ๋•Œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ž ์žฌ์  ์ธ ์ˆ˜์ •์ด ์–ผ๋งˆ๋‚˜ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์„ ํƒ์  ์ฝœ๋ฐฑ ํ”„๋ŸฐํŠธ์— ์šด์ด ์—†์œผ๋ฉด ๋‚˜์ค‘์— ๊ทธ ๋ฌธ์ œ๋ฅผ ํŒŒํ—ค์น  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@dtex ๋ฐฉ๊ธˆ ์„ ํƒ์  ์ฝœ๋ฐฑ (๋‹ค์Œ ์˜ˆ์ œ ์ฝ”๋“œ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Œ)์„ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ๋กœ๊ทธ๊ฐ€ ํŒŒ์ผ์— ๊ธฐ๋ก๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ํŒŒ์ผ์€ ์‹ค์ œ๋กœ ์ƒ์„ฑ๋˜์ง€๋งŒ ๋กœ๊ทธ๋Š” ๊ธฐ๋ก๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

var winston = require('winston');
var logger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)(),
    new (winston.transports.File)({ filename: 'winston.log' })
  ]
});

logger.info('winston - info logged');
logger.error('winston - error logged');

logger.info('winston - exiting now', { seriously: true }, function(err, level, msg, meta) {
  console.log('console - CALLING PROCESS EXIT');
  process.exit(0);
});

logger.warn('winston - I probably should only appear in console, not the log file?');

@yzaouchiak Curious, ๋ฒ„์ „ 0.6.2์ž…๋‹ˆ๊นŒ?

โ””โ”€โ”ฌ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ””โ”€โ”€ [email protected]

์ง€๊ธˆ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํ”„๋กœ์„ธ์Šค๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ๋กœ๊ทธ ํŒŒ์ผ์— ๋ฉ”๋ชจ๋ฅผ ์ž‘์„ฑํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์‹œ์ง€๊ฐ€ ์ž‘์„ฑ๋œ ํ›„์— ๋งŒ โ€‹โ€‹ํ”„๋กœ์„ธ์Šค๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” ์ฝœ๋ฐฑ ์˜ต์…˜์ด ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด ์ด๋ฏธ ์กด์žฌํ•ฉ๋‹ˆ๊นŒ?

Winston 0.7.2์—์„œ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
์„ฑ๊ณตํ•˜์ง€ ์•Š๊ณ  setTimeout ๋ฐ ์ฝœ๋ฐฑ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ํ…Œ์ŠคํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ # 288 ๋ฐ log4js-node ๋ฌธ์ œ (https://github.com/nomiddlename/log4js-node/issues/148)์™€ ๋™์ผํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” process.exit ์ฝœ๋ฐฑ์ด ์™„๋ฃŒ๋˜๋ฉด ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ณด๋ฅ˜์ค‘์ธ ๋น„๋™๊ธฐ ํ˜ธ์ถœ (์˜ˆ : ํŒŒ์ผ ์“ฐ๊ธฐ)์ด ์‹คํ–‰๋  ๊ธฐํšŒ๋ฅผ ์–ป์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๋‚˜๋ฅผ ํ‹€๋ ธ๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•˜๊ณ  ํ•ด๊ฒฐ์ฑ…์„ ์ œ์‹œ ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋งค์šฐ ๊ธฐ์  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค๋ฉด์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์„ ํ• ์• ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฃผ์š” ๋ฌธ์ œ๋Š” WritableStreams๊ฐ€ process.exit () ๋˜๋Š” ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ์˜ˆ์™ธ์— ๋Œ€ํ•œ ํ”Œ๋Ÿฌ์‹œ๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€์ฒด ์†”๋ฃจ์…˜์„ ์กฐ์‚ฌ ํ–ˆ์Šต๋‹ˆ๊นŒ? WritableStream์ด ์†Œ๋ชจ ๋  ๋•Œ๊นŒ์ง€ ๋กœ๊ทธ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์บ์‹œ ํ•  ์ˆ˜์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ process.exit ๋˜๋Š” ํฌ์ฐฉ๋˜์ง€ ์•Š์€ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋“œ๋ ˆ์ธ๋˜์ง€ ์•Š์€ ๋กœ๊ทธ๋ฅผ ๋™ ๊ธฐ์ ์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์ค‘๋ณต ๋กœ๊ทธ๊ฐ€ ์ƒ์„ฑ ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์ ์–ด๋„ ๋กœ๊ทธ ์†์‹ค์€ ๋ฐฉ์ง€๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒฌ์žˆ๋Š” ์‚ฌ๋žŒ?

# 288๊ณผ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ~ 0.9.0 ์—ฌ์ „ํžˆ ์‹คํŒจ

์˜ˆ, ์ด์ „์— @yzapuchlak์—์„œ ์–ธ๊ธ‰ ํ•œ setTimeout () ํ•ดํ‚น์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด์จŒ๋“  ๋‚˜๋Š” ์ด๊ฒƒ์„ ์œˆ์Šคํ„ด์˜ ๋ฒ„๊ทธ๋กœ ๋ณด์ง€ ์•Š๋Š”๋‹ค. ๋•Œ ๋‹น์‹ ์—๊ฒŒ process.exit ๋‹น์‹ ์ด ์•„์ง ์™„์ „ํžˆ ์ฒ˜๋ฆฌ์—์„œ ์‹คํ–‰์ค‘์ธ ๋ชจ๋“  ๊ฒƒ์„ ์ฃฝ์ผํ•˜๊ธฐ๋กœ ๊ฒฐ์ •์„ ํ•œ ์ฝ”๋“œ์—์„œ. ์—ฌ์ „ํžˆ ์‹คํ–‰์ค‘์ธ HTTP ์š”์ฒญ์ด์žˆ๋Š” ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ์š”์ฒญ์ด ์‘๋‹ต ๋  ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜์ง€ ์•Š๋Š”๋ฐ, ๋กœ๊ทธ ๋ฉ”์‹œ์ง€๊ฐ€ ๋กœ๊ทธ์— ๋๋‚  ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ๋…ธ๋“œ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ฝœ๋ฐฑ ๋˜๋Š” setTimeout ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ setTimeout์ด ์™„๋ฃŒ๋˜๊ฑฐ๋‚˜ ์ฝœ๋ฐฑ์ด ํ˜ธ์ถœ๋˜๊ธฐ ์ง์ „์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‹ค๋ฅธ ํ–‰์„ ๊ธฐ๋กํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉํ•ดํ•˜๋Š” ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ๋™๊ธฐ ๋กœ๊น…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ ์š”์ฒญ์„ ์ฒ˜๋ฆฌ ํ•  ๋•Œ ๋น„๋™๊ธฐ ์‹œ์Šคํ…œ์„ ๊ฐ„๋‹จํ•œ ๋กœ๊ทธ ๋ฌธ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๋ชฉ์ ์„ ๋ฌด๋ ฅํ™”ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋‚ด๊ฐ€ ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์€์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ์•Š๊ณ  ๋‹ซ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋กœ๊ทธ ๋ฉ”์‹œ์ง€๋ฅผ ๋†“์น˜์ง€ ์•Š์œผ๋ ค๋ฉด process.exit๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ •๋ฆฌํ•˜๊ณ  ์ข…๋ฃŒํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

ํŽธ์ง‘ ๋˜ํ•œ ๋ชจ๋“  setTimeout ํ•ดํ‚น์€ ๊ฒฐํ•จ์ด ์žˆ์œผ๋ฉฐ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ์šด์˜ ์ฒด์ œ์— ๊ธฐ๋ก๋˜๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„๊ณผ ๋””์Šคํฌ ๋˜๋Š” SSD๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋Š” ์†๋„๋ฅผ ์•Œ์ง€ ๋ชปํ•˜๋ฏ€๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ์—ฌ๊ธฐ์„œ ์œ ์ผํ•˜๊ฒŒ ์ ์ ˆํ•œ ํ•ด๊ฒฐ์ฑ…์€ ์ŠคํŠธ๋ฆผ์˜ drain ์ด๋ฒคํŠธ๋ฅผ ๋“ฃ๊ณ  ํ”„๋กœ์„ธ์Šค๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ๊ณ„์† ๋กœ๊น…ํ•˜๋Š” ๊ฒฝ์šฐ ์˜ค๋žœ ๊ธฐ๊ฐ„ ๋™์•ˆ ํ˜ธ์ถœ๋˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ข…๋ฃŒํ•˜๊ธฐ ์ „์— ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์ œ๋Œ€๋กœ ์ข…๋ฃŒํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ ๋˜ ๋‹ค๋ฅธ ํ•ดํ‚น ์ผ๋ฟ์ž…๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ํ˜„์žฌ ๋กœ๊ทธ๊ฐ€ ํ”Œ๋Ÿฌ์‹œ ๋  ๋•Œ๊นŒ์ง€ (์ฝœ๋ฐฑ / ์•ฝ์† / ๋ฌด์—‡์ด๋“ ) ๊ธฐ๋‹ค๋ฆด ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ๋™๊ธฐํ™” ๋กœ๊น…์„ ๊ฐ•์ œํ•˜๋ฉด process.on('exit') ๋กœ๊ทธ๋ฅผ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ์ˆ˜๋ช… ๋™์•ˆ ๋น„๋™๊ธฐ ๋กœ๊น…์„ ์‚ฌ์šฉํ•˜๊ณ  process.exit ๋™์•ˆ ๋™๊ธฐํ™” ๋กœ๊น…์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์“ฐ๊ธฐ๋ฅผ ๋™๊ธฐํ™”ํ•˜๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ํŒŒ์ผ ๊ตฌํ˜„์œผ๋กœ ์ƒˆ winston ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์–ธ์ œ ํ”Œ๋Ÿฌ์‹œ๋˜๋Š”์ง€ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ์ŠคํŠธ๋ฆผ์˜ ๋“œ๋ ˆ์ธ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๊ณ ๋งˆ์›Œ์š”!

๊ทธ๋งŒํ•œ ๊ฐ€์น˜๋ฅผ ์œ„ํ•ด setTimeout ์„ ํ”ผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ _stream ๋ฅผ ๊ฐ€์ ธ์™€์•ผํ•ฉ๋‹ˆ๋‹ค.

// log then exit(1)
logger.error("The thing to log", function(err) {
  var numFlushes = 0;
  var numFlushed = 0;
  Object.keys(logger.transports).forEach(function(k) {
    if (logger.transports[k]._stream) {
      numFlushes += 1;
      logger.transports[k]._stream.once("finish", function() {
        numFlushed += 1;
        if (numFlushes === numFlushed) {
          process.exit(1);
        }
      });
      logger.transports[k]._stream.end();
    }
  });
  if (numFlushes === 0) {
    process.exit(1);
  }
});

์œ„์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋Š” ํŒŒ์ผ์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ”Œ๋Ÿฌ์‹œ๋˜๋„๋ก _ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค _. ์ด๊ฒƒ์€ ๋‚˜์—๊ฒŒ ๋ฒ„๊ทธ์ฒ˜๋Ÿผ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค.

winston์˜ flush ๋˜๋Š” closed ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ์‹ค์ œ๋กœ finish ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. https://nodejs.org/api/stream.html#stream_event_finish ๊ทธ๊ฒƒ๋„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ธฐ๋กํ•˜๊ธฐ์—๋Š” ๋ถˆ์ถฉ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค : /

์ด๊ฑธ๋กœ ํ•ด๋ด. ์ œ ๊ฒฝ์šฐ์—๋Š” ๊ฝค ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. process.exit ์ง์ ‘ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹  ๋กœ๊ทธ๋ฅผ ํ”Œ๋Ÿฌ์‹œ ํ•œ ํ›„ ๋กœ๊ฑฐ๊ฐ€ process.exit ํ˜ธ์ถœํ•˜๋„๋กํ•ฉ๋‹ˆ๋‹ค.

logger.js :

var winston = require('winston');

winston.loggers.add('my-logger', {
    console: {
        level: 'debug',
        colorize: true,
        timestamp: true,
        handleExceptions: true
    },
    file: {
        level: 'info',
        colorize: false,
        timestamp: true,
        filename: 'file.log',
        handleExceptions: true
    }
});

var logger = winston.loggers.get('my-logger');


/* ******* *
 * EXPORTS
 * ******* */

exports.exitAfterFlush = function(code) {
    logger.transports.file.on('flush', function() {
        process.exit(code);
    });
};

exports.info = function() {
    logger.info.apply(this, arguments);
};

exports.warn = function() {
    logger.info.apply(this, arguments);
};

exports.error = function() {
    logger.info.apply(this, arguments);
};

๊ท€ํ•˜์˜ ์ฝ”๋“œ์—์„œ :

var logger = require('./logger.js');
logger.exitAfterFlush(0);
logger.info('Done!');

NodeJS v4.1.2 ๋ฐ winston 1.1.0์—์„œ ํ…Œ์ŠคํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@ da-mkay์™€ ๋น„์Šทํ•œ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

function closeAllLoggersAndDisconnect() {
    "use strict";

    let openCount = 0;

    Object.keys(loggerInstance.transports).forEach((key) => {

        let transportInstance = loggerInstance.transports[key];

        if (typeof transportInstance.close === "function") {
            transportInstance.close();
            openCount++;
        }

        transportInstance.on("closed", () => {
            openCount--;
        });

        setInterval(() => {
            if (openCount === 0) {
                if (process.connected) {
                    process.disconnect();
                }
            }
        }, 100);
    });
}

๊ท€ํ•˜์˜ ์ฝ”๋“œ์—์„œ :

winston.error("Error Occured", err, () => {
    closeAllLoggersAndDisconnect();
});

์ด์ƒ์ ์œผ๋กœ๋Š” ๋‚œ ๊ทธ๋ƒฅ ์ „ํ™”๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์€ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค close ์˜จ ๋ฐฉ๋ฒ• loggerInstance ํ•˜์ง€๋งŒ ๋ฐฉ์ถœ ์ดํ›„ closed ์ด๋ฒคํŠธ ๊ณง ํ˜ธ์ถœ์„ ์™„๋ฃŒ ํ•œ close ๋ฉ”์„œ๋“œ๋Š” ์‹ค์ œ๋กœ ๋‹ซ์€ ํ›„๊ฐ€ ์•„๋‹ˆ๋ผ ๊ธฐ๋ณธ ์ „์†ก์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์ „์†ก์ด ์™„์ „ํžˆ ๋‹ซํžˆ์ง€ ์•Š๊ณ  ๋กœ๊ฑฐ๋ฅผ ๋‹ซ์„ ์ˆ˜์žˆ๋Š” ๊ฒƒ์€ ๋ฒ„๊ทธ ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@Kegsay ๋ฅผ ์‚ฌ์šฉ

๋˜ํ•œ @Kegsay ์˜ ๋‹จ๊ณ„๋ฅผ ์„ฑ๊ณต์œผ๋กœ ์‚ฌ์šฉ ... ๋‚ด ์ž์‹ ์˜ ๊ธฐ๋Šฅ์— ์‹ธ์—ฌ ์žˆ์Šต๋‹ˆ๋‹ค.

2.2.0 ๋ฒ„์ „์—์„œ ์—ฌ์ „ํžˆ์ด ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„์ง ๊ตฌํ˜„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๊นŒ? 3 ์„ธ ์ด์ƒ. ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜์ง€๋งŒ ๋ช…์‹œ ์ ์œผ๋กœ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ์ข…๋ฃŒ ๋  ์ˆ˜ ์žˆ๋„๋ก ํŒŒ์ผ์— ๋Œ€ํ•œ ๋ชจ๋“  ์“ฐ๊ธฐ๋ฅผ ์™„๋ฃŒํ•˜๊ณ  ์—ด๋ ค์žˆ๋Š” ๋ชจ๋“  ํ•ญ๋ชฉ์„ ๋‹ซ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๋•์…˜ ์‹œ์Šคํ…œ์—์„œ ๊ทธ๋Ÿฐ ๊ฒƒ๋“ค์„ ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ์ •๋ง๋กœ ์œˆ์Šคํ„ด ์ธก์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์ƒ๊ธฐ์‹œํ‚จ๋‹ค. ๊ทธ๊ฒƒ์ด ๋™๊ธฐ์‹ ํŒŒ์ผ ์ „์†ก์„ ์ œ๊ณตํ•˜๋“  Winston์„ '์•ˆ์ „ํ•˜๊ฒŒ'์ข…๋ฃŒํ•˜๊ธฐ ์œ„ํ•ด ์ข…๋ฃŒ ํ›„ํฌ๋ฅผ ์ œ๊ณตํ•˜๋“  ์ƒ๊ด€ ์—†์ง€๋งŒ ๋‚˜์—๊ฒŒ ๋งŒ์กฑ์Šค๋Ÿฌ์šด ์†”๋ฃจ์…˜์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์•„๋ฌด๊ฒƒ๋„ ๊ฐ€์ง€์ง€ ์•Š์œผ๋ฉด ๋กœ๊ทธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์ข…๋ฃŒํ•˜๊ณ  ์‹ค์ œ๋กœ ๊ธฐ๋ก ๋  ๊ฒƒ์ด๋ผ๋Š” ํ™•์‹ ์„ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋™๊ธฐ ์ „์†ก์˜ ๊ฒฝ์šฐ IO๊ฐ€ ์™„๋ฃŒ ๋  ๋•Œ๊นŒ์ง€ ์ฝ”๋“œ ์‹คํ–‰์ด ์ฐจ๋‹จ๋˜์–ด ์„ฑ๋Šฅ์ด ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ ์“ฐ๊ธฐ๋ฅผ ์ฐจ๋‹จ ์“ฐ๊ธฐ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ผ๋‹จ ๋กœ๊ทธ์— ๋น„๋™๊ธฐ ์“ฐ๊ธฐ๋ฅผํ•˜๋ฉด NodeJS๊ฐ€ ์ ‘๊ทผ ํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผํ•˜๋ฉฐ ๊ทธ๋™์•ˆ ๋‹ค๋ฅธ JS ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด์— ํ”„๋ผ ๋ฏธ์Šค๋Š” ๋™๊ธฐ์‹์œผ๋กœ ์ทจ์†Œ ํ•  ์ˆ˜ ์žˆ๊ณ , ์‹œ๊ฐ„ ์ดˆ๊ณผ๋Š” ๋™๊ธฐ์‹์œผ๋กœ ์ง€์šธ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํŒŒ์ผ ๋ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์€ ๋™๊ธฐ์‹์œผ๋กœ ๋‹ซ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋” ๋‚˜์€ (๋” ๋‚˜์€ ์„ฑ๋Šฅ) ์†”๋ฃจ์…˜์€ ์ทจ์†Œ / ์ง€์›Œ์•ผํ•˜๋Š” ํ•ญ๋ชฉ์„ ์ถ”์ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. winston.log_and_exit() ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ธฐ ๋˜๋Š” winston.log_and_exit() ๋Œ€ํ•œ ์„ ํƒ์  ์ฝœ๋ฐฑ์—์„œ ๋‹ซ๊ณ  ๋‹ซ์Šต๋‹ˆ๋‹ค.

๋ฌผ๋ก  Winston์ด ์˜ค๋ฅ˜ ๋ฐœ์ƒ์‹œ ๋‹ซ์•„์•ผํ•˜๋Š” ๋ชจ๋“  ์‚ฌํ•ญ์„ ์ถ”์ ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋Ÿฌํ•œ ์ž‘์—… ๊ด€๋ฆฌ์ž๋Š” ๊ทธ ์ž์ฒด๋กœ ์œ ์šฉํ•œ ๊ฒƒ์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ณ„๋„์˜ ํ”„๋ ˆ์ž„ ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•  ๊ฐ€์น˜๊ฐ€์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. Curley์˜ ๋ฒ•์น™).

์—ฌ๊ธฐ์„œ ์„ฑ๋Šฅ์ด ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. winston์€ IMO๋ฅผ ํ–‰๋ณตํ•˜๊ฒŒ ์ฐจ๋‹จํ•  ์ˆ˜์žˆ๋Š” ์ตœ์ข… ๋กœ๊ทธ ๋ผ์ธ์— ๋Œ€ํ•œ ๋ถ€๊ธฐ ๋งŒ ์ˆ˜ํ–‰ํ•˜๋ฉด๋ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๊ฐ€ ์–ผ๋งˆ๋‚˜ ์˜ค๋ž˜๋˜์—ˆ๊ณ  ์ด์— ๋Œ€ํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊ฐ์•ˆํ•  ๋•Œ ์–ธ์ œ๋ผ๋„ winston์—์„œ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์‚ฌ๋žŒ์„ ์ •ํ™•ํžˆ์ง€์ง€ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

๋‹น์‹ ๊ณผ ๋‚ด๊ฐ€ ๋ชฉ์ ์„๋‘๊ณ  ์ด์•ผ๊ธฐ (์“ฐ๊ธฐ)ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ํŒŒ์ผ์— ์ตœ์ข… ๋ฉ”์‹œ์ง€๋ฅผ ๋™๊ธฐ์‹์œผ๋กœ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ๊ด€์‹ฌ์ด์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฌ์ง€๋งŒ ์ œ ๊ด€์‹ฌ์‚ฌ๋Š” ์˜ค๋ฅ˜ ์ง์ „์— ๋น„๋™๊ธฐ์‹์œผ๋กœ ์ž‘์„ฑ๋œ ๋กœ๊ทธ๊ฐ€ ํŒŒ์ผ์— ์ž‘์„ฑ๋˜๋„๋กํ•˜๋Š” ๊ฒƒ์ด ์—ˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋ฅ˜ ์ง์ „์— ๋ฐœ์ƒํ•œ ํŒŒ์ผ์— ๋ฉ”์‹œ์ง€๋ฅผ ๋™ ๊ธฐ์ ์œผ๋กœ ๊ธฐ๋กํ•˜๋ ค๋ฉด ๋ชจ๋“  ๋ฉ”์‹œ์ง€๊ฐ€ ๋™ ๊ธฐ์ ์œผ๋กœ ๊ธฐ๋ก๋˜์–ด์•ผํ•˜๋ฉฐ ์ด๊ฒƒ์ด ์„ฑ๋Šฅ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ํ›„ ๋งˆ์ง€๋ง‰ ๋กœ๊ทธ๊ฐ€ ํŒŒ์ผ์— ๊ธฐ๋ก๋˜๊ธฐ ์ „์— ๋‹ค๋ฅธ JS ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋„๋กํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์šฐ๋ คํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ์‚ฌ๋žŒ์˜ ์š”๊ตฌ๋ฅผ ๋งŒ์กฑ์‹œํ‚ฌ ์ˆ˜์žˆ๋Š” ์˜ต์…˜์€ ๋น„๋™๊ธฐ ์ ์œผ๋กœ ์“ฐ๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ์ „์†ก ์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ, ์•„์ง ํŒŒ์ผ์— ๊ธฐ๋ก (ํ”Œ๋Ÿฌ์‹œ) ๋œ ๊ฒƒ์œผ๋กœ ํ™•์ธ๋˜์ง€ ์•Š์€ ๋ฉ”์‹œ์ง€์˜ ๋ฒ„ํผ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. , NodeJS๊ฐ€ ์ด๋ฏธ ํŒŒ์ผ ์“ฐ๊ธฐ๋ฅผ ์™„๋ฃŒํ–ˆ์ง€๋งŒ ํ”Œ๋Ÿฌ์‹œ ๋œ ์ด๋ฒคํŠธ๊ฐ€ ์•„์ง ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ...).

๋ฐ˜ํ™˜ ๋ฐ / ๋˜๋Š” ์ฝœ๋ฐฑ์„ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ๋ชจ๋“  ๊ฒƒ์ด ํ”Œ๋Ÿฌ์‹œ ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ข…๋ฃŒ ํ›„ํฌ๋ฅผ ํ˜ธ์ถœ์— ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์‹ค์ œ๋กœ ์–ด๋ ต์Šต๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ๊ฑฐ์˜ ๋ชจ๋“  ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ํ•ด๊ฒฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋™๊ธฐ ๋กœ๊ทธ์— ๊ด€์‹ฌ์ด์—†๋Š” ์ด์œ  ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•ด์„œ๋„ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ. ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐ 1 ~ 2 ์ดˆ๊ฐ€ ๋” ๊ฑธ๋ฆฌ๋Š”์ง€ ์ƒ๊ด€ ์—†์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ๊ฐ€ ๊ฒฐ์ •์ ์ด์ง€ ์•Š์€์ง€ ์—ฌ๋ถ€๋Š” ๋…ธ๋“œ๊ฐ€ ์ข…๋ฃŒํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜๋Š” ์†๋„์— ๋”ฐ๋ผ ๊ธฐ๋ก ๋  ์ˆ˜๋„ ์žˆ๊ณ  ๊ธฐ๋ก๋˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‚˜์˜๋‹ค . ๋น„๋™๊ธฐ๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์ด์–ด์•ผํ•œ๋‹ค๋Š” ์ ์— ์ง„์‹ฌ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ๋‚ด๋ถ€ ๋…ธ๋“œ ์ž์ฒด์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๊ณ ๋ คํ•  ๋•Œ ์ด๊ฒƒ์ด ์œ ์ผํ•œ ์˜ต์…˜์ด์–ด์•ผํ•œ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@mscharley ์ด๊ฒƒ์ด log4js.shutdown ํ•จ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝœ๋ฐฑ์„ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ๋ชจ๋“  ์–ด ํŽœ๋” (winston์ด ํŠธ๋žœ์Šค ํฌํŠธ๋ผ๊ณ  ๋ถ€๋ฆ„)๊ฐ€ ์ž‘์„ฑ์„ ์™„๋ฃŒํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ๋‹ค๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚ด ์‚ฌ์šฉ์ž์—๊ฒŒ ์ž˜ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ข…๋ฃŒ ํ˜ธ์ถœ์— ์‘๋‹ต ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ž‘์„ฑํ•ด์•ผํ•œ๋‹ค๋Š” ์ ์—์„œ ์–ด ํŽœ๋”์˜ ์ง€์›์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” log4js๋ฅผ ํ™๋ณดํ•˜๊ฑฐ๋‚˜ ์œˆ์Šคํ„ด๋ณด๋‹ค ๋‚ซ๋‹ค๊ณ  ๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ์ด ์ ‘๊ทผ ๋ฐฉ์‹์ด ํšจ๊ณผ๊ฐ€์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ง€์ ํ•ฉ๋‹ˆ๋‹ค. ์ตœ์„ ์˜ ๋ฐฉ๋ฒ•์ด ์•„๋‹ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ winston.log_and_exit() ๋Š” ์ผ์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. log4js.shutdown() ๋Š” ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ์ŠคํŠธ๋ฆผ ( appenders.filter(a => a.shutdown).forEach(a => a.shutdown(complete)); )์„ ๊ธฐ๋ฐ˜์œผ๋กœํ•˜๋Š” ์ถ”๊ฐ€์˜ ๊ฒฝ์šฐ writable.end(complete) ์— ์ข…์†๋˜๋ฉฐ ์—ฌ์ „ํžˆ ๋น„๋™๊ธฐ์‹ ์ข…๋ฃŒ์ž…๋‹ˆ๋‹ค.

@mscharley ์˜ ์˜๊ฒฌ๊ณผ ๊ด€๋ จํ•˜์—ฌ ์žฅ์ ์€ fileSync appender๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. shutdown() ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋…ธ๋“œ๊ฐ€ ํŒŒ์ผ์— ๊ธฐ๋ก ๋  ๋•Œ ์ „์ฒด ๋กœ๊ทธ๋ฅผ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค ...

์˜ˆ, fileSync ์ „์†ก์„ ์‚ฌ์šฉํ•˜๋ฉด ์ˆœ ์„ฑ๋Šฅ์ด ์ €ํ•˜ ๋˜๋”๋ผ๋„ ์ผ๋ถ€ ์ƒํ™ฉ์—์„œ ์œ ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@jdthorpe ์ข…๋ฃŒํ•˜๊ธฐ ์ „์— ๊นจ๋—ํ•˜๊ฒŒ ๋‹ซ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ์•„์ด๋””์–ด๋Š” ์ข‹์€ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๋ชจ๋“  ๊ฒƒ์„ ๋””์Šคํฌ์— ํ”Œ๋Ÿฌ์‹œ ํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด winston์—์„œ ์ฑ…์ž„์„ ์˜ฎ๊ธฐ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค (์ฆ‰, ์ž์ฒด๋ฅผ ๋‹ซ๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์ œ๊ณต) ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด๋Ÿฌํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ close ๋ฉ”์„œ๋“œ๋ฅผ ์ง‘๊ณ„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํ‹ฐ์ผ“์€ ์ตœ์†Œํ•œ ๋ฌธ์„œ๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ํ˜„์žฌ ์ง€์›๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์—์„œ seriously ๋ฅผ ๊ฒ€์ƒ‰ ํ•  ๋•Œ ์ง€์›ํ•œ๋‹ค๊ณ  ์ฃผ์žฅํ•˜๋Š” ์ด ๋ฌธ์ œ๋ฅผ ๋””๋ฒ„๊น…ํ•˜๋Š” ๋ฐ 30 ๋ถ„์„ ๋ณด๋ƒˆ์Šต๋‹ˆ๋‹ค. README ์ด๊ฒƒ์€ ์ง€์›๋˜์ง€ ์•Š๋Š” ๊ธฐ๋Šฅ์ด๋‚˜ ๋ฒ„๊ทธ์ฒ˜๋Ÿผ ๋ณด์ด๋ฉฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์‹ค์ œ๋กœ ๋„ˆ๋ฌด ๋ง›์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ์–ธ์ œ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ์ง€๊ธˆ๊นŒ์ง€ 3 ๋…„ ๋™์•ˆ ์กด์žฌํ–ˆ์œผ๋ฉฐ ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์ ์–ด๋„ ์‹ค์ œ๋กœ ์ž‘๋™ํ•˜๋Š” ๋กœ๊ฑฐ์— ์ฝœ๋ฐฑ์„ ๋„ฃ์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ์‚ฌ๋žŒ์„์œ„ํ•œ ์ผ๋ฐ˜ shutdown() ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์œผ๋กœ ์ž‘์„ฑํ–ˆ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ์ด ๊ธฐ๋Šฅ์€ ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ ์ด๊ฒƒ์€ ๋งค์šฐ, ๋งค์šฐ ์ค‘์š”ํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์— ๋Œ€ํ•œ +1

์†”์งํžˆ shutdown(callback) ๊ฒƒ์ด ์ ์ ˆ ํ•ด ๋ณด์ด์ง€๋งŒ ์šด์†ก ์ˆ˜๋‹จ์ด์ด๋ฅผ ์ ๊ทน์ ์œผ๋กœ ์ง€์›ํ•ด์•ผํ•œ๋‹ค๋Š” ๊ฒฝ๊ณ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ์ „์†ก์€ ๊ธฐ๋ณธ ์ถœ๋ ฅ ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ๋Œ€ํ•œ "์ •๋ณด ์ „๋ฌธ๊ฐ€"์ž…๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ๊ทธ๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์™„์ „ํžˆ ์ข…๋ฃŒ๋˜์–ด์•ผํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๊ฐ€์žฅ ๋งŽ์€ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

winston ์ฝ”์–ด๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…, ๊ทธ๋ฆฌ๊ณ  ๊ฐ€์žฅ ํ™•์‹คํ•˜๊ฒŒ ์‚ฌ์šฉ์ž ์˜์—ญ์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์—๋Š” ์œ ์ถœ ํ•  ์ „์†ก์˜ ๊ตฌํ˜„ ์„ธ๋ถ€ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ winston ๊ฐ€ ์ž‘์—… ์„ ์ˆ˜ํ–‰ ํ•  ํ•„์š”๋Š” ์—†์ง€๋งŒ

์•„๋ž˜ ์š”์ ์„ ์„ค๋ช…ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ์˜์‚ฌ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

```js
shutdown (callback) {
var transportCount = transports.length
var finished = 0;
// ๊ฐ ์ „์†ก์— ๋Œ€ํ•ด
if (transport.shutdown) {
transport.shutdown (function () {
// ์™„๋ฃŒ ํšŸ์ˆ˜๋ฅผ ๋Š˜๋ฆฝ๋‹ˆ๋‹ค.
// ๋ชจ๋‘ ์™„๋ฃŒ๋˜๋ฉด ์›๋ž˜ ์ฝœ๋ฐฑ์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
});
} else {
// ์ „์†ก์€ (์•„์ง) ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
// ์™„๋ฃŒ๋œ ์นด์šดํ„ฐ ์ฆ๊ฐ€
}
}

v3.x์—์„œ ์ˆ˜์ • ๋œ ๊ฒƒ์„๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋‚ด ์†”๋ฃจ์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค ( async / await ๋ฅผ ์ง€์›ํ•˜๋Š” ํ™˜๊ฒฝ ๊ฐ€์ •)


๋‹จ์ผ ์ „์†ก์˜ ๊ฒฝ์šฐ :

const logTransport = new winston.transports.File({filename: '/log/app.log'})

global.log = winston.createLogger({transports: [logTransport]})

// helper to exit with a given return code, but only after the logger is finished
// this will return a Promise that will never resolve, thus halting execution
log.exit = (exit = 5) => {
  return new Promise(() => {
    logTransport.on('finished', () => process.exit(exit))
  })
}



๋‹ค์ค‘ ์ „์†ก์˜ ๊ฒฝ์šฐ (๋ฏธ์ •) :

```js
const logTransports = [์ƒˆ winston.transports.File ({ํŒŒ์ผ ์ด๋ฆ„ : '/log/app.log'})]

global.log = winston.createLogger ({transports : [logTransport]})

// ์ฃผ์–ด์ง„ ๋ฐ˜ํ™˜ ์ฝ”๋“œ๋กœ ์ข…๋ฃŒํ•˜๋Š” ๋„์šฐ๋ฏธ์ด์ง€๋งŒ ๋กœ๊ฑฐ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„์— ๋งŒ
// ํ•ด๊ฒฐ๋˜์ง€ ์•Š๋Š” Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ์‹คํ–‰์ด ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค.
log.exit = (exit = 5) => {
return new Promise (() => {
Promise.all (
logTransports.map (transport => new Promise (resolve => transport.on ( 'finished', resolve)))
) .then (() => process.exit (exit))
})
}

</details>
<br>
Then, call with `await` like:

```js
try {
  something()
} catch(e) {   
  //do something with the error
  await log.exit(5) // <--- nothing will happen past this line as the promise will never resolve!
  // <--- process will have exited before it reaches here
  trySomethingElse() // <--- this will never be called, and control wont return to the calling code
}

๊ธฐ๋ก์ด ๊นจ์ง€๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ winston-log-and-exit ๋„์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๋งค์šฐ ๊ตฌ์ฒด์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€์—๋งŒ ํ•ด๋‹น๋ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋˜์ง€ ์•Š๋Š” AWS Lambda์—์„œ๋Š” winston-log-and-exit์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์—ˆ์ง€๋งŒ ์‹คํ–‰ ์‚ฌ์ด์— ๋™๊ฒฐ๋˜๋ฏ€๋กœ ๋กœ๊ทธ๊ฐ€ ์—ฌ์ „ํžˆ ์†์‹ค๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์„ฑ๊ณต์ ์ธ ์‹คํ–‰ ๊ฒฝ๋กœ์—์„œ ํ•ญ์ƒ ๊ทธ๋ ‡์ง€๋Š” ์•Š์€ ๋งˆ์ง€๋ง‰ ๋ฉ”์‹œ์ง€๊ฐ€ ์–ด๋–ค ๋ฉ”์‹œ์ง€์ธ์ง€ ์•Œ๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

@mscharley ์œ„์˜ await ์†”๋ฃจ์…˜์ด ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ ํ•ฉํ•ฉ๋‹ˆ๊นŒ? ์•„๋งˆ๋„ log.exit() ๋Œ€์‹ ์— ๋” ๋‚˜์€ API๋Š” await log.finish() ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ชจ๋“  ํŠธ๋žœ์Šค ํฌํŠธ๊ฐ€ ์“ฐ๊ธฐ๋ฅผ ๋งˆ์น  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๋ฌด์—‡์ด๋“  ํ•  ์ˆ˜์žˆ๊ฒŒํ•ฉ๋‹ˆ๋‹ค ( process.exit ํ˜ธ์ถœ, ๋žŒ๋‹ค ํ˜ธ์ถœ done ์ฝœ๋ฐฑ ๋“ฑ)

๊ทธ๊ฒƒ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ ์œˆ์Šคํ„ด ๋‚ด๋ถ€๋ฅผ ์ œ์™ธํ•˜๊ณ ๋Š” ์ด๋ฒˆ ํ˜ธ์—์„œ ์ถ”์ง„ํ•ด์˜จ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ ์ธ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋” ์ž์ฃผ ๋“ฑ์žฅํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ํ•˜๋Š” ์ผ์ด ํŠน๋ณ„ํ•œ ์ผ์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ํ”„๋กœ์ ํŠธ์—์„œ์ด ๋ฒฝ์„ ์ณค์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ๊ฒฐ๊ตญ Winston์—์„œ ๋ฉ€์–ด์กŒ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๊ฐ€์žฅ ๋†’์€ ํ”„๋กœ์„ธ์Šค ๋์—์„œ ๋กœ๊ทธ๋ฅผ ์žƒ๋Š” ๊ฒƒ์€ ์ ์–ด๋„ ์œ„ํ—˜ ํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.

log4js-node๋Š” ๋ชจ๋“  ์ „์†ก์„ ํ”Œ๋Ÿฌ์‹œํ•˜๊ณ  process.exit() ์™€ ๊ฐ™์€ ์ฝœ๋ฐฑ์„๋ฐ›๋Š” ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ ๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. winston์— ์ด์™€ ๊ฐ™์€ ๊ฒƒ์„ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

log4js-node๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋ฌธ์ œ๋Š” ๋งค์šฐ ์‹ค์ œ์ ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  ๋กœ๊น… ์‹œ์Šคํ…œ์˜ ๊ฒฝ์šฐ ๋ฏธ์ ๋ถ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๋กœ๊ทธ๊ฐ€ ๋ฐ˜๋“œ์‹œ ์žˆ์–ด์•ผํ•˜๊ณ  ๋Š๋ฆฐ ์‘๋‹ต ์‹œ๊ฐ„์— ๋Œ€ํ•œ ๋น„์šฉ์„ ์ง€๋ถˆ ํ•  ์˜ํ–ฅ์ด์žˆ๋Š” ๊ฒฝ์šฐ ๋™๊ธฐ์‹ ๋กœ๊ฑฐ๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.
  • process.exit() ์ง์ ‘ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ ๋ฒ„ํผ๋ง ๋œ ๋ฉ”์‹œ์ง€๊ฐ€ ์ง€์›Œ์งˆ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์‹ญ์‹œ์˜ค. winston์˜ ๊ฒฝ์šฐ winston-log-and-exit ํŒจํ‚ค์ง€๊ฐ€์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹ค๋ฅธ ์ฝ”๋“œ๊ฐ€ process.exit() ํ˜ธ์ถœํ•˜๊ณ  ํ”Œ๋žซํผ์— on-exit ํ›„ํฌ๊ฐ€์žˆ๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ํ›„ํฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ฒ„ํผ๋ง ๋œ ๋ฉ”์‹œ์ง€๊ฐ€ ์ง€์›Œ์งˆ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์‹ญ์‹œ์˜ค. winston-log-and-exit ๋„ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • on-exit ํ›„ํฌ๊ฐ€์—†๋Š” AWS Lambda์™€ ๊ฐ™์€ ํ”Œ๋žซํผ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ ์†์‹ค ์œ„ํ—˜์— ๋Œ€ํ•ด ํ”Œ๋žซํผ์˜ ์ด์ ์„ ๊ฑฐ๋ž˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ถ€์ˆ˜์ ์œผ๋กœ @ begin-again log_and_exit() ๋ฉ”์„œ๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ log-4js์˜ shutdown() ๋ฉ”์„œ๋“œ์™€ ๋™์ผํ•˜๋ฉฐ ์ œ๊ณต๋œ ๋กœ๊ทธ ๋ฉ”์‹œ์ง€๊ฐ€ ๊ธฐ๋ก๋œ๋‹ค๋Š” ์ถ”๊ฐ€ ๋ณด์žฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@jdthorpe ํ•˜์ง€๋งŒ winston-log-and-exit ์€ winston 3์—์„œ ์‰ฝ๊ฒŒ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@VRuzhentsov ์•„, ๊ทธ๊ฒŒ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์ •๋ง๋กœ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋ญ”๊ฐ€๋ฅผํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

@jdthorpe๋กœ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

const transport = new Transport();
const logger = createLogger({
  transports: [
    transport 
  ]
})

logger.finish = (exitCode) => {
  transport.on('finish', () => process.exit(exitCode));
  transport.close();
};

const shutDown = (exitCode) => {
  logger.info('Shutting down');
  logger.finish(exitCode);
};

shutDown(1);

๋‹ค์Œ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

logger.info('winston - info logged');
logger.error('winston - error logged');
process.nextTick(() => {
    process.exit(0)
})

@ redhat-raptor. ๋Œ€๋ถ€๋ถ„ ์˜ ๊ฒฝ์šฐ ์ž‘๋™ํ•˜์ง€๋งŒ ํ•ญ์ƒ ์ž‘๋™ํ•œ๋‹ค๊ณ  ๋ณด์žฅ ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. nextTick ()์ด ํ˜ธ์ถœ ๋  ๋•Œ ๋ฒ„ํผ๊ฐ€ ์ง€์›Œ์กŒ์ง€๋งŒ ๋กœ๊ฑฐ๊ฐ€ ์˜์กดํ•˜๋Š” ์—ฐ๊ฒฐ์— ๋”ฐ๋ผ ์‰ฝ๊ฒŒ ๋ฉ”์‹œ์ง€๊ฐ€ ์†์‹ค ๋  ์ˆ˜

์ด ์ฝ”๋“œ๋Š” ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค.

            logger.error(`No value specified for ${value} variable! Node will exit now...`);
            logger._flush(() => {
                process.exit(1);
            })

v3์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›๋˜์ง€ ์•Š๋‚˜์š”?

https://github.com/winstonjs/winston/blob/master/README.md#awaiting -logs-to-be-written-in-winston

@danielweck ์•„๋‹ˆ์š”, ๊ณ ์žฅ

6 ๋…„, ์ฆ‰ _important_๋กœ ํ‘œ์‹œ๋œ ๋ฒ„๊ทธ์˜ ๊ฒฝ์šฐ 6 ๋…„์ž…๋‹ˆ๋‹ค. ์ธ์ƒ์ ์ธ ๊ฒฝ๊ณ„์„ ์ž…๋‹ˆ๋‹ค.

waitForWinston() ์•ฝ์†์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

const winston = require('winston');

const fileTransport = new winston.transports.File({ name: 'file', filename: FILE_PATH });
const consoleTransport = new winston.transports.Console({ name: 'console', stderrLevels: ['error'] });
const transports = [
    fileTransport,
    consoleTransport
];
winston.configure({
    level: 'verbose',
    transports,
    format: winston.format.cli()
});
winston.log('info', 'TEST MSG');
try {
    await waitForWinston();
} catch (err) {
    console.log(err);
}
process.exit(0);
const waitForWinston = async () => {
    return new Promise(async (resolve, _reject) => {
        for (const transport of transports) {
            try {
                await closeWinstonTransportAndWaitForFinish(transport);
            } catch (err) {
                console.log(err);
            }
        }
        resolve();
    });
};
const closeWinstonTransportAndWaitForFinish = async (transport) => {
    if (!transport.close) {
        // e.g. transport.name === 'console'
        return Promise.resolve();
    }
    // e.g. transport.name === 'file'

    return new Promise(async (resolve, _reject) => {
        transport._doneFinish = false;
        function done() {
            if (transport._doneFinish) {
                return; // avoid resolving twice, for example timeout after successful 'finish' event
            }
            transport._doneFinish = true;
            resolve();
        }
        setTimeout(() => { // TODO: use a cancellable setInterval instead
            done();
        }, 5000); // just in case the 'finish' event never occurs
        const finished = () => {
            done();
        };

/* Update: `stream.end()` does not flush pending writes, so this solution is inadequate.  For some reason, in recent tests `transport.close();` + `transport.once('finish', ...);` works just fine ... not sure why this works now though! (it used to fail!) */

/*
        if (transport._stream) {
            transport._stream.once('finish', finished);
            transport._stream.end();
        }
*/
            transport.once('finish', finished);
            transport.close();
    });  
};

์—…๋ฐ์ดํŠธ : stream.end() ๋Š” ๋ณด๋ฅ˜์ค‘์ธ ์“ฐ๊ธฐ๋ฅผ ํ”Œ๋Ÿฌ์‹œํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ์ด ์†”๋ฃจ์…˜์€ ๋ถ€์ ์ ˆํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ์ด์œ ๋กœ ์ตœ๊ทผ ํ…Œ์ŠคํŠธ์—์„œ transport.close(); + transport.once('finish', ...); ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค ... ์™œ ์ง€๊ธˆ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค! (์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค!)

์œ„์˜ ์ž‘์—… ์†”๋ฃจ์…˜์—์„œ ํ•ต์‹ฌ์€ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
transport._stream.once('finish', finished); transport._stream.end();
๋Œ€์‹ ์—:
transport.once('finish', finished); transport.close();
(์ถ”๊ฐ€ ๋œ ์‹œ๊ฐ„ ์ œํ•œ ์ „๋žต์€ ๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋ฉฐ ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ์—๋Š” ์„ ํƒ ์‚ฌํ•ญ / ์ค‘๋ณต ์ผ ์ˆ˜ ์žˆ์Œ)

๋” ์‰ฌ์šด ๋ฐฉ๋ฒ• :

logger.error(`No value specified for ${missing_vars.join(',')} variable! Node will exit now...`, () => {
            process.exit(1);
        });

@danielweck ์ด๊ฒƒ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๊นŒ? ์ตœ๊ทผ์— Winston 3.x๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ–ˆ์ง€๋งŒ 2.x๋กœ ๋Œ์•„๊ฐ€๊ฑฐ๋‚˜ ์—ฌ๊ธฐ์—์„œ ์†”๋ฃจ์…˜์ด์—†๋Š” ๋‹ค๋ฅธ ๋กœ๊ฑฐ๋ฅผ ์ฐพ์•„์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@matttowerssonos , IIRC, ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋Š” ๋ชจ๋‘ Winston @ 2 ์™€ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค

BTW, Winston @ 3 ์—์„œ ๋กœ๊ทธ ์†์‹ค ๋ฌธ์ œ๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ƒˆ ๋ฌธ์ œ์— ๊ตฌ์„ฑ์„ ํฌํ•จํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@cjbarth ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  process.on(type as any, (err: ErrorExtended) => {
    const processLogger: Logger = loggers.get('processLogger');

    processLogger.error(errorFormatter(err, type));

    processLogger.on('finish', function () {
      processLogger.end();
      console.log('never reaches here');
      process.exit(1);
    });
  });

processExit('uncaughtException');
// log and exit for unhandledRejection events.
processExit('unhandledRejection');

@stephanoparaskeva ์‹ค์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด processLogger.end() ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— finish ์ด๋ฒคํŠธ๊ฐ€ processLogger ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด Winston์ด ๋กœ๊น…์„ ์™„๋ฃŒํ•˜๋ฉด finish ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด process.disconnect() ๋Œ€์‹  process.exit() ๋“œ๋ ˆ์ธ ๋Œ€๊ธฐ์—ด์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๊ธฐ์—ด์ด ๋น„์›Œ์ง€๋ฉด ์ž๋™์œผ๋กœ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

@stephanoparaskeva ์‹ค์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด processLogger.end() ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— finish ์ด๋ฒคํŠธ๊ฐ€ processLogger ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด Winston์ด ๋กœ๊น…์„ ์™„๋ฃŒํ•˜๋ฉด finish ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด process.disconnect() ๋Œ€์‹  process.exit() ๋“œ๋ ˆ์ธ ๋Œ€๊ธฐ์—ด์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๊ธฐ์—ด์ด ๋น„์›Œ์ง€๋ฉด ์ž๋™์œผ๋กœ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

์•Œ์•˜์–ด์š”, ์ด๋ ‡๊ฒŒ ๋ญ”๊ฐ€์š”?

process.on(type as any, (err: ErrorExtended) => {
  const processLogger: Logger = loggers.get('processLogger');

  processLogger.error(errorFormatter(err, type));
  processLogger.end()

  processLogger.on('finish', function () {
    process.disconnect();
  });
});

// log and exit for uncaughtException events.
processExit('uncaughtException');
// log and exit for unhandledRejection events.
processExit('unhandledRejection');

@stephanoparaskeva ๋” ์ข‹์•„ ๋ณด์ธ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ processLogger.end() ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๊ธฐ๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜์ง€๋งŒ finish ์ด๋ฒคํŠธ๋Š” ์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ๋ฐ”์ธ๋”ฉ๋˜๋Š” ์‹œ๊ฐ„์— ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ์ „ํ™˜ ๋œ ํ›„์— ๋งŒ โ€‹โ€‹๋ฐœ์ƒํ•ด์•ผํ•˜๋ฏ€๋กœ ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ๋จผ์ € ๋ฐ”์ธ๋”ฉ๋˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์ž‘์„ฑํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ฟก๋ฟก
์˜ค, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๊นŒ?
๊ทธ๋Ÿด๊นŒ์š”?

processLogger.on('finish', () => {
    this.process.disconnect();
  });

@stephanoparaskeva ๋„ค. ์ด๊ฒƒ์ด ํ•จ์ˆ˜ ๋ฐ”์ธ๋”ฉ์„์œ„ํ•œ ์˜ฌ๋ฐ”๋ฅธ ๊ตฌ๋ฌธ์ž…๋‹ˆ๋‹ค.

{
  this.process.disconnect();
}

processLogger ๊ฐœ์ฒด์— ์˜ํ•ด ์ƒ์„ฑ ๋œ finish ์ด๋ฒคํŠธ์—.

๋‚˜๋ฅผ ์œ„ํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค : https://stackoverflow.com/a/59260151

process.exit๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  ๋ชจ๋“  ์—ฐ๊ฒฐ์„ ๋‹ซ๊ณ  ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ๋ฐฐ์ˆ˜ ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆผ์œผ๋กœ์จ ์ ์ ˆํ•œ ์ข…๋ฃŒ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

@deedf ๊ฐ€ ๋ฌด์—‡์„ ํ•˜๋ ค๋ฉด https://stackoverflow.com/a/37592669 ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ์ด ์กฐ์–ธ์— ๋”ฐ๋ผ ์ €๋„์ด ๋ฌธ์ œ๋ฅผ ์™„ํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ข…๋ฃŒ ์ด๋ฒคํŠธ๊ฐ€ ๋ช‡ ๋…„์ด ์ง€๋‚œ ํ›„์—๋„ ์—ฌ์ „ํžˆ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์€์ด ์‹œ์ ์—์„œ ๋‹นํ™ฉ ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๋กœ๊ฑฐ๋ฅผ ์ „ํ™˜ํ•˜๊ณ  ๋ชจ๋“  ์‚ฌ์šฉ์ž ์ง€์ • ์ „์†ก์„ ๋‹ค์‹œ ์ž‘์„ฑํ•ด์•ผํ•˜๋Š” ๊ฒƒ์€ ๊ณ ํ†ต ์Šค๋Ÿฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด winston์— ์˜ํ•ด ์•„์ง ํ•ด๊ฒฐ๋˜์ง€ ์•Š์€ ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ์ฝ”๋“œ์˜ ์ฒซ ๋ฒˆ์งธ ๋กœ๊ฑฐ ๋งŒ Logstash์— ๊ธฐ๋ก๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค (winston-elasticsearch๋„ ์‚ฌ์šฉ). logger.end ()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ๊ธฐ๋ก๋˜์ง€๋งŒ ํ”„๋กœ๊ทธ๋žจ์ด ๋„ˆ๋ฌด ์ผ์ฐ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์œ„์˜ ๋ชจ๋“  ์†”๋ฃจ์…˜์„ ์‚ฌ์šฉํ•ด ๋ณด์•˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
๋‚œ ์ •๋ง ๋ฌด๋ ฅ ํ•ด

๋‚˜๋Š” ์ด๊ฒƒ์ด winston์— ์˜ํ•ด ์•„์ง ํ•ด๊ฒฐ๋˜์ง€ ์•Š์€ ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ์ฝ”๋“œ์˜ ์ฒซ ๋ฒˆ์งธ ๋กœ๊ฑฐ ๋งŒ Logstash์— ๊ธฐ๋ก๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค (winston-elasticsearch๋„ ์‚ฌ์šฉ). logger.end ()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ๊ธฐ๋ก๋˜์ง€๋งŒ ํ”„๋กœ๊ทธ๋žจ์ด ๋„ˆ๋ฌด ์ผ์ฐ ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์œ„์˜ ๋ชจ๋“  ์†”๋ฃจ์…˜์„ ์‚ฌ์šฉํ•ด ๋ณด์•˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
๋‚œ ์ •๋ง ๋ฌด๋ ฅ ํ•ด

์ด๊ฑฐ ํ•ด๋ดค ์–ด?

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด์ด "๋ฌธ์ œ"๊ฐ€ "ํ•ด๊ฒฐ"๋˜์ง€ ์•Š์•˜ ์Œ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค. exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ ์ ˆํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด์ด "๋ฌธ์ œ"๊ฐ€ "ํ•ด๊ฒฐ"๋˜์ง€ ์•Š์•˜ ์Œ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค. exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ ์ ˆํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์€ process.exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด์ด "๋ฌธ์ œ"๊ฐ€ "ํ•ด๊ฒฐ"๋˜์ง€ ์•Š์•˜ ์Œ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค. exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ ์ ˆํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์€ process.exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ, nodejs์—์„œ๋Š” ํ•ญ์ƒ ๋‚˜์œ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค. https://stackoverflow.com/a/37592669๋ฅผ ์ฐธ์กฐ

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด์ด "๋ฌธ์ œ"๊ฐ€ "ํ•ด๊ฒฐ"๋˜์ง€ ์•Š์•˜ ์Œ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค. exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ ์ ˆํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์€ process.exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ, nodejs์—์„œ๋Š” ํ•ญ์ƒ ๋‚˜์œ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค. https://stackoverflow.com/a/37592669๋ฅผ ์ฐธ์กฐ

๊ฐœ์ธ์ ์œผ๋กœ process.exit๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” uncaughtException ๋ฐ unhandledRejection์„ ๋“ฃ๊ณ  ๋ชจ๋“  ์ „์†ก์— ๊ธฐ๋กํ•œ ๋‹ค์Œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด์ด "๋ฌธ์ œ"๊ฐ€ "ํ•ด๊ฒฐ"๋˜์ง€ ์•Š์•˜ ์Œ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค. exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ ์ ˆํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ exit ()๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๊ณ  ์–ด๋””์—์„œ ๋ณด์•˜์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด์ด "๋ฌธ์ œ"๊ฐ€ "ํ•ด๊ฒฐ"๋˜์ง€ ์•Š์•˜ ์Œ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค. exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ ์ ˆํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ exit ()๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๊ณ  ์–ด๋””์—์„œ ๋ณด์•˜์Šต๋‹ˆ๊นŒ?

๋‹น์‹ ์˜ ์ฝ๊ธฐ์™€ ์ดํ•ด ๋Šฅ๋ ฅ์ด์ด ๋ฒ„๊ทธ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ œ๋ชฉ์„ ๋‹ค์‹œ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด์ด "๋ฌธ์ œ"๊ฐ€ "ํ•ด๊ฒฐ"๋˜์ง€ ์•Š์•˜ ์Œ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค. exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ ์ ˆํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ exit ()๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๊ณ  ์–ด๋””์—์„œ ๋ณด์•˜์Šต๋‹ˆ๊นŒ?

๋‹น์‹ ์˜ ์ฝ๊ธฐ์™€ ์ดํ•ด ๋Šฅ๋ ฅ์ด์ด ๋ฒ„๊ทธ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ œ๋ชฉ์„ ๋‹ค์‹œ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

8 ๋…„ ๋™์•ˆ ์—ด๋ ค ์žˆ๊ณ  ์ ์ ˆํ•œ ๋„์›€์„ ์ „ํ˜€ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๋ฉด ๋„ˆ๋ฌด ๋ฐ”๋น ์•ผํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด์ด "๋ฌธ์ œ"๊ฐ€ "ํ•ด๊ฒฐ"๋˜์ง€ ์•Š์•˜ ์Œ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค. exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ ์ ˆํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์€ process.exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ, nodejs์—์„œ๋Š” ํ•ญ์ƒ ๋‚˜์œ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค. https://stackoverflow.com/a/37592669๋ฅผ ์ฐธ์กฐ

๊ฐœ์ธ์ ์œผ๋กœ process.exit๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” uncaughtException ๋ฐ unhandledRejection์„ ๋“ฃ๊ณ  ๋ชจ๋“  ์ „์†ก์— ๊ธฐ๋กํ•œ ๋‹ค์Œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ํ•œ๋™์•ˆ winston์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ์–ด์จŒ๋“  ๊ธฐ๋กํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋กœ๊น… ํ›„ ์˜ค๋ฅ˜๊ฐ€ ๋‹ค์‹œ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด์ด "๋ฌธ์ œ"๊ฐ€ "ํ•ด๊ฒฐ"๋˜์ง€ ์•Š์•˜ ์Œ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค. exit ()๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ์ ์ ˆํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ exit ()๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๊ณ  ์–ด๋””์—์„œ ๋ณด์•˜์Šต๋‹ˆ๊นŒ?

๋‹น์‹ ์˜ ์ฝ๊ธฐ์™€ ์ดํ•ด ๋Šฅ๋ ฅ์ด์ด ๋ฒ„๊ทธ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ œ๋ชฉ์„ ๋‹ค์‹œ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

8 ๋…„ ๋™์•ˆ ์—ด๋ ค ์žˆ๊ณ  ์ ์ ˆํ•œ ๋„์›€์„ ์ „ํ˜€ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๋ฉด ๋„ˆ๋ฌด ๋ฐ”๋น ์•ผํ•ฉ๋‹ˆ๋‹ค.

์ ์–ด๋„ ๋‚˜๋Š” ์ž๊ฒฉ์„ ๊ฐ–์ถ˜ ๋…€์„์ฒ˜๋Ÿผ ์ง•์ง• ๋Œ€์ง€ ์•Š๊ณ  ๋‚ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰