2013-11-24 2 views
1

Я использую winston для создания самозапуска, что позволяет мне добавлять отметки времени и номер строки в журнале. Код может выполнять функциональные возможности каждый, но в сочетании они не работают должным образом.Временные метки исчезают при добавлении конфигурации номера строки в node.js winston для ведения журнала

// **help to add timestamp** 
var logger = new (winston.Logger)({ 
    transports : [new (winston.transports.Console)({ 
    json : false, 
    timestamp : true, 
    colorize: true 
    }), new winston.transports.File({ 
    filename : __dirname + '/debug.log', 
    json : true 
    })] 
    ,exitOnError : false 
}); 

// **help me to add line number** 
var logger_info_old = winston.info; 
logger.info = function(msg) { 
    var fileAndLine = traceCaller(1); 
    return logger_info_old.call(this, fileAndLine + ":" + msg); 
} 

Однако при добавлении конфигурации номера строки временная метка для ведения журнала исчезнет.

Например, перед добавлением конфигурации номера строки.

logger.info("abc"); 
2013-11-24T09:49:15.914Z - info:339:abc 

при добавлении конфигурации номер строки

logger.info("abc"); 
info: (H:\Dropbox\node\fablab\utils\logging.js:85:abc 

Оптимальный результат я хочу, как

logger.info("abc"); 
2013-11-24T09:49:15.914Z - info: (H:\Dropbox\node\fablab\app.js:339:abc 

Могу ли я исправить это?

ответ

3

Я получил это, чтобы работать, и вот как я это сделал.

var transports = [ 
    new(winston.transports.Console)({ 
    colorize: true, 
    prettyPrint: true, 
    timestamp : true, 
    level: 'debug', 
    }) 
]; 

var log = new(winston.Logger)({ 
    "transports": transports 
}); 

for (var func in winston.levels) { 
    var oldFunc = log[func]; 

    log[func] = function() { 
    var args = Array.prototype.slice.call(arguments); 
    args.unshift(traceCaller(1)); 
    oldFunc.apply(log, args); 
    } 
} 

С этим я получил как метку времени, так и файл. (примечание traceCaller (1) взято из этого вопроса stackoverflow: I want to display the file Name in the log statement). Я сделал цикл for над winston.levels, поэтому я бы взял все функции, а не только информацию.

Причина, по которой ваша работа не работала, была ваша logger_info_old из winston, а не из регистратора. Так

var logger_info_old = winston.info; 

должен был

var logger_info_old = logger.info; 
+0

Просто сделал бенчмарк. Будьте предупреждены, что добавление трассировки стека намного, намного медленнее. Выполняя 10 000 журналов, время шло от 71 мс без номера файла и линии до 4666 мс. Это в 65 раз медленнее. traceCaller, возможно, неэффективен, но я предполагаю, что большую часть времени на самом деле принимается при создании трассировки стека: (новая ошибка) .stack –

+0

согласен, traceCaller неэффективен, но он будет использоваться для отладки, так что это нормально. Большое спасибо, jeff – user824624

+0

Должно быть закрытие для захвата 'oldFunc', в противном случае вся функция журнала будет заменена последней (' error() 'в настройках по умолчанию). Кроме того, почему вы используете 'winston.levels' вместо' logger.levels'? – leesei

3

Я обновленный @ ответа JEFF-Уайтинг (в закрывающем использовании и зафиксировать для интерполяции строк) и сделать его единственной функцией.
Передайте существующий регистратор, чтобы добавить информацию о вызывающем абоненте в свои функции уровня.
Примечание logger.log() не изменяется, только logger.{level}() изменены.

// add callsite info to winston logger instance 
function addCallSite(logger) { 
    // WARNING: traceCaller is slow 
    // http://stackoverflow.com/a/20431861/665507 
    // http://stackoverflow.com/a/13411499/665507 
    /** 
    * examines the call stack and returns a string indicating 
    * the file and line number of the n'th previous ancestor call. 
    * this works in chrome, and should work in nodejs as well. 
    * 
    * @param n : int (default: n=1) - the number of calls to trace up the 
    * stack from the current call. `n=0` gives you your current file/line. 
    * `n=1` gives the file/line that called you. 
    */ 
    function traceCaller(n) { 
    if(isNaN(n) || n<0) n=1; 
    n+=1; 
    var s = (new Error()).stack 
     , a=s.indexOf('\n',5); 
    while(n--) { 
     a=s.indexOf('\n',a+1); 
     if(a<0) { a=s.lastIndexOf('\n',s.length); break;} 
    } 
    b=s.indexOf('\n',a+1); if(b<0) b=s.length; 
    a=Math.max(s.lastIndexOf(' ',b), s.lastIndexOf('/',b)); 
    b=s.lastIndexOf(':',b); 
    s=s.substring(a+1,b); 
    return s; 
    } 

    // assign to `logger.{level}()` 
    for (var func in logger.levels) { 
    (function (oldFunc) { 
     logger[func] = function() { 
     var args = Array.prototype.slice.call(arguments); 
     if (typeof args[0] === 'string') { 
      args[0] = traceCaller(1) + ' ' + args[0]; 
     } 
     else { 
      args.unshift(traceCaller(1)); 
     } 
     oldFunc.apply(logger, args); 
     }; 
    })(logger[func]); 
    }; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^