Предупреждение
Я думаю, что предполагаемое использование winston состоит в том, чтобы в первую очередь регистрировать строковые сообщения и (при необходимости) дополнительную метаинформацию. Более того, я не совсем понимаю, почему вы хотите регистрировать всю коллекцию, возвращенную из монго, а не, скажем, только _id
s (при условии, что docs
может быть довольно большим).
вступление
Я просмотрел исходный код winston
и вот соответствующие части:
winston/logger.js
Logger.prototype.log = function (level) {
var self = this,
args = Array.prototype.slice.call(arguments, 1);
...
var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null,
meta = typeof args[args.length - 1] === 'object' ? args.pop() : {},
msg = util.format.apply(null, args);
...
}
По сути, один аргумент типа object
интерпретируется как мета. Консольный транспортный уровень (по умолчанию) в основном определяется в winston/common.js, и вот как обрабатывается мета:
... if (Object.keys(meta).length > 0) {
output += ' ' + (
options.prettyPrint
? ('\n' + util.inspect(meta, false, null, options.colorize))
: exports.serialize(meta)
);
}
Метод serialize перебирает (рекурсивно) все ключи объекта для формирования конечной строки (вместо вызова .toString
или аналогичного).
Предлагаемые решения
Оба решения вынуждают winston интерпретировать единственный аргумент объекта не как метаданные, а как строку сообщения.
Если вы хотите поддерживать разные транспортные уровни, их необходимо изменить.
Изменить исходный код winston
Просто разветвите репозиторий и внесите соответствующие изменения в исходный код. Существует множество способов добиться этого. Одним из уродливых может быть:
meta = args.length === 1 ? {} :
(typeof args[args.length - 1] === 'object' ? args.pop() : {}),
Но гораздо лучше было бы добавить особый случай в метод .serialize
, сделать специальную обработку, если объект является моделью мангуса, очень наивной и неправильной:
else if ('_doc' in obj && 'save' in obj){
var result = [];
msg += '{'
for(var key in obj['_doc']){
result.push (key + ':' + obj['_doc'][key]);
}
msg += result.join(', ');
msg += '}';
}
(К сожалению, с этим подходом есть проблема, так как winston копирует метаданные, и все методы, определенные выше в цепочке прототипов, теряются — в противном случае это было бы так же просто, как вызвать obj.toJSON
, и наверняка это было бы самое элегантное и надежное решение)
Переопределить поведение winston по умолчанию
var original = winston.log;
winston.log = function(){
if(arguments.length === 2){
original.call(winston, arguments[0], arguments[1], {});
}
else {
original.apply(winston, arguments);
}
}
Объяснение: arguments[0]
определяет уровень, поэтому arguments[1]
является фактическим объектом для регистрации.
person
artur grzesiak
schedule
17.10.2014