본문 바로가기
node.js

winston logger에서 날짜 제대로 안찍힐 때

by 루에 2019. 6. 4.
반응형

인터넷에 있는 수많은 예제

function timeFormat(){
	return moment().format('YYYY-MM-DD HH:mm:ss');
}

new (winston.transports.Console)({
	name : 'debug-console',
	colorize : true,
	timestamp : timeFormat(),
	level : 'debug',
	showLevel : true,
	json : false,
	localTime : true
})

이런식으로 되있는데(이거 말고도 수많은 형식이 있는데... 일단 내 case에서는 format이 안되고 그러니 format.printf 등등 도 안되고...) 문제는 timeFormat()을 지정했음에도 망할 아래처럼 출력되었다.

 

2019-06-04T02:40:11.456Z - debug: debug test

한국 시간이 안찍혀! 수도없이 별의별 방법을 시도해보며 블로그며 레퍼런스며 뭐며... 다 안되서 라이브러리 뒤져봤다.

 

var events = require('events'),
    util = require('util'),
    colors = require('colors'),
    common = require('../common'),
    Transport = require('./transport').Transport;

//
// ### function Console (options)
// #### @options {Object} Options for this instance.
// Constructor function for the Console transport object responsible
// for persisting log messages and metadata to a terminal or TTY.
//
var Console = exports.Console = function (options) {
  Transport.call(this, options);
  options = options || {};

  this.json        = options.json        || false;
  this.colorize    = options.colorize    || false;
  this.prettyPrint = options.prettyPrint || false;
  this.timestamp   = typeof options.timestamp !== 'undefined' ? options.timestamp : false;
  this.label       = options.label       || null;

  if (this.json) {
    this.stringify = options.stringify || function (obj) {
      return JSON.stringify(obj, null, 2);
    };
  }
};

//
// Inherit from `winston.Transport`.
//
util.inherits(Console, Transport);

//
// Expose the name of this Transport on the prototype
//
Console.prototype.name = 'console';

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
Console.prototype.log = function (level, msg, meta, callback) {
  if (this.silent) {
    return callback(null, true);
  }

  var self = this,
      output;

  output = common.log({
    colorize:    this.colorize,
    json:        this.json,
    level:       level,
    message:     msg,
    meta:        meta,
    stringify:   this.stringify,
    timestamp:   this.timestamp,
    prettyPrint: this.prettyPrint,
    raw:         this.raw,
    label:       this.label
  });
  
  if (level === 'error' || level === 'debug') {
    process.stderr.write(output + '\n');
  } else {
    process.stdout.write(output + '\n');
  }

  //
  // Emit the `logged` event immediately because the event loop
  // will not exit until `process.stdout` has drained anyway.
  //
  self.emit('logged');
  callback(null, true);

winston 라이브러리의 console.js

 

timestamp값은 정상적으로 입력됨. 보니까 common.log로 보낸다. 여기서 프로토타입 만들어서 보내는 것 같다.

 

//    {
//      level:     'level to add to serialized message',
//      message:   'message to serialize',
//      meta:      'additional logging metadata to serialize',
//      colorize:  false, // Colorizes output (only if `.json` is false)
//      timestamp: true   // Adds a timestamp to the serialized message
//      label:     'label to prepend the message'
//    }
//
exports.log = function (options) {
  var timestampFn = typeof options.timestamp === 'function'
                  ? options.timestamp
                  : exports.timestamp,
      timestamp   = options.timestamp ? timestampFn() : null,
      meta        = options.meta !== undefined || options.meta !== null ? exports.clone(cycle.decycle(options.meta)) : null,
      output;

common.js

 

options.timestamp가 갑자기 boolean값이 되었다. 과정은 모르겠음... 안찾아봄. 분명 console.js로 들어왔을 때는 정상적으로 string값이 들어가있었는데. 어쨋든 boolean값이 들어왔고, function이 아니기 때문에 exports.timestamp로 선택됐다. exports.timestamp를 찍어보니

 

2019-06-04T02:40:11.456Z

범인검거.

 

이러니 별의별 날짜 모듈 등등 써도 저거만 찍혔지... 그래서 다시 내 코드로 돌아와 변경해봄

new winston.transports.Console({
			colorize : true,
			// timestamp : timeFormat(),
			timestamp : () => moment().format('YYYY-MM-DD HH:mm:ss'),
			level : 'debug',
			showLevel : true,
			json : false,
			localTime : true
		}),

기존 string값을 넘겨주던 것을 함수를 넘겨주고 다시 찍어본다.

 

2019-06-04 11:42:32 - debug: debug test

완료 :)

 

왜 레퍼런스의 사용 방법이 안먹히는지, 남들 다 잘되는데 나는 안되는지는 모르겠다. 모듈 버젼은 정상적으로 최신버젼으로 되있는데... 어쨋든 노드의 경우 모듈이 영 안되겠다 싶으면 그냥 라이브러리 뒤져보는게 답이라는걸 깨달았다. 라이브러리 접근도, 수정도 가능하더라.

반응형

댓글