2013-09-15 4 views
58

У меня есть полный, развернутый, экспресс-проект с множеством инструкций console.log() и console.error(). Проект работает навсегда, направляя stdout и stderr в 2 отдельных файла.Добавление временных меток ко всем сообщениям консоли

Все это работает очень хорошо, но теперь мне не хватает временных меток - точно знать, когда произошли ошибки.

Я могу выполнить какой-либо поиск/замену в течение всего моего кода или использовать некоторый модуль npm, который переопределяет консоль в каждом файле, но я не хочу касаться каждого файла модели/маршрута, если только мне это не нужно.

Есть ли способ, возможно, промежуточное программное обеспечение Express, которое позволит мне добавить временную метку для каждого сделанного вызова или мне нужно вручную добавить его?

+0

тесно связаны: [Можно ли привязать дату/время, чтобы журнал консоли?] (http://stackoverflow.com/questions/18410119/is-it-possible-to-bind-a-date-time-to-a-console-log) и [console.log ti mestamps в Chrome?] (http://stackoverflow.com/questions/12008120/console-log-timestamps-in-chrome) –

ответ

78

Оказывается, вы можете переопределить функции консоли в верхней части app.js файла, и он вступит в силу в любом другом модуле. Я получил смешанные результаты, потому что один из моих модулей раздвоен как child_process. Как только я скопировал строку вверху этого файла, все работает.

Для записи, я установил модуль консольного-штамп (npm install console-stamp --save), и добавили эту строку в верхней части app.js и childProcess.js:

// add timestamps in front of log messages 
require('console-stamp')(console, '[HH:MM:ss.l]'); 

Моя проблема сейчас в том, что формат :date в журнале подключений используется формат UTC, а не тот, который я использую в других консольных вызовах. Это было легко исправить, зарегистрировав свой собственный формат времени (и, как побочный эффект, требующий dateformat модуль, который console stamp поставляется с, а не установка другой):

// since logger only returns a UTC version of date, I'm defining my own date format - using an internal module from console-stamp 
express.logger.format('mydate', function() { 
    var df = require('console-stamp/node_modules/dateformat'); 
    return df(new Date(), 'HH:MM:ss.l'); 
}); 
app.use(express.logger('[:mydate] :method :url :status :res[content-length] - :remote-addr - :response-time ms')); 

Теперь мои файлы журнала выглядят организованной (а еще лучше , распознаваем):

[15:09:47.746] staging server listening on port 3000 
[15:09:49.322] connected to database server xxxxx successfully 
[15:09:52.743] GET /product 200 - - 127.0.0.1 - 214 ms 
[15:09:52.929] GET /stylesheets/bootstrap-cerulean.min.css 304 - - 127.0.0.1 - 8 ms 
[15:09:52.935] GET /javascripts/vendor/require.js 304 - - 127.0.0.1 - 3 ms 
[15:09:53.085] GET /javascripts/product.js 304 - - 127.0.0.1 - 2 ms 
... 
+2

Я не мог найти документы для него, но кажется, что «: mm» будет ссылаться на месяц, а «: MM» - это формат, который вы на самом деле хотите использовать. –

+2

вы shoud меняете часть минут в соответствии с тем, что говорит @ пользователь603124. Для минут строка: **: MM ** (https://github.com/starak/node-console-stamp) – sucotronic

+0

Спасибо за комментарий. Исправленный! –

1

Это не прямой ответ, но вы заглянули в winston.js? Он имеет более тонкие параметры ведения журнала, включая ведение журнала в json-файле или базе данных. По умолчанию они всегда имеют отметки времени. Просто мысль.

+0

Я изучил многие вещи, прямо сейчас, я хотел бы добавить что-то к существующему , развернутый проект - не затрагивая слишком много кода. –

17

Создайте файл со следующим:

var log = console.log; 

console.log = function(){ 
    log.apply(console, [Date.now()].concat(arguments)); 
}; 

Требовать его в приложение, прежде чем войти что-нибудь. Сделайте то же самое для console.error, если необходимо.

Обратите внимание, что это решение уничтожит переменную вставку (console.log("he%s", "y") // "hey"), если вы используете это. Если вам нужно, просто войти в метку времени первым:

log.call(console, Date.now()); 
log.apply(console, arguments); 
+0

Это все еще требует 'require'ment в каждом файле, который использует консоль ... –

+2

Нет, если это одно и то же приложение/процесс. Консоль - это глобальный объект, поэтому, если вы захватите одну из своих функций, как это, он будет удержаться за все файлы, которые разделяют этот глобальный объект. –

+0

Так что это/должно быть помещено в файл app.js? –

8

Вы также можете воспользоваться пакетом log-timestamp. Это довольно просто и настраивается.

8

Если вам требуется решение без другой внешней зависимости, но вы хотите сохранить все функции консоли.войти (несколько параметров, переменная вставки), можно использовать следующий код:

var log = console.log; 

console.log = function() { 
    var first_parameter = arguments[0]; 
    var other_parameters = Array.prototype.slice.call(arguments, 1); 

    function formatConsoleDate (date) { 
     var hour = date.getHours(); 
     var minutes = date.getMinutes(); 
     var seconds = date.getSeconds(); 
     var milliseconds = date.getMilliseconds(); 

     return '[' + 
       ((hour < 10) ? '0' + hour: hour) + 
       ':' + 
       ((minutes < 10) ? '0' + minutes: minutes) + 
       ':' + 
       ((seconds < 10) ? '0' + seconds: seconds) + 
       '.' + 
       ('00' + milliseconds).slice(-3) + 
       '] '; 
    } 

    log.apply(console, [formatConsoleDate(new Date()) + first_parameter].concat(other_parameters)); 
}; 

Вы можете изменить функцию formatConsoleDate для форматирования даты, как вы хотите.

Этот код должен быть записан только один раз поверх основного файла JavaScript.

console.log("he%s", "y") напечатает что-то вроде этого:

[12:22:55.053] hey 
+1

Спасибо, этот ответ «без зависимостей» был именно тем, что мне нужно. – RdR

+0

Не будет работать с console.log ({a: 1, b: 2}) –

0

Эта реализация проста, поддерживает оригинальные функциональные возможности console.log (проходящее один объект, и замены переменных), не использует внешние модули и печатает все в одном звонке на console.log:

var origlog = console.log; 

console.log = function(obj, ...placeholders){ 
    if (typeof obj === 'string') 
     placeholders.unshift(Date.now() + " " + obj); 
    else 
    { 
     // This handles console.log(object) 
     placeholders.unshift(obj); 
     placeholders.unshift(Date.now() + " %j"); 
    } 

    origlog.apply(this, placeholders); 
}; 
Смежные вопросы