winston
версия? _winston@2
winston@3
node -v
выходы: _ v8.11.3
С 3.xx:
const winston = require('winston')
const logger = winston.createLogger({
transports: [new winston.transports.Console()]
})
logger.info('test log', 'with a second parameter')
Выходы:
{"level":"info","message":"test log"}
С 2.xx:
const winston = require('winston')
const logger = new winston.Logger({
transports: [new winston.transports.Console()]
})
logger.info('test log', 'with a second parameter')
Выходы:
info: test log with a second parameter
Он должен выводить:
{"level":"info","message":"test log with a second parameter"}
Сегодня я столкнулся с той же проблемой. Я считаю , что это ошибка , так как документация обновления также пример подобного здесь :
logger.info('transaction ok', { creditCard: 123456789012345 });
В настоящее время, чтобы обойти это, вы можете создать функцию, которая анализирует аргументы перед передачей в winston.
@ mulligan121 Хорошо, но я не хочу заменять каждый оператор журнала в своей кодовой базе ...
@indexzero Это вам
Временное решение:
const wrapper = ( original ) => {
return (...args) => original(args.join(" "));
};
winstonLogger.error = wrapper(winstonLogger.error);
winstonLogger.warn = wrapper(winstonLogger.warn);
winstonLogger.info = wrapper(winstonLogger.info);
winstonLogger.verbose = wrapper(winstonLogger.verbose);
winstonLogger.debug = wrapper(winstonLogger.debug);
winstonLogger.silly = wrapper(winstonLogger.silly);
Для нас это ОГРОМНОЕ переломное изменение. Если это сделано намеренно, об этом следует подробно рассказать в https://github.com/winstonjs/winston/blob/master/UPGRADE-3.0.md.
Итак, после некоторого дополнительного исследования я обнаружил, что вам понадобится средство форматирования splat для печати нескольких аргументов. Я думал, что это было только для интерполяции аргументов (т.е. что-то с% s и т. Д. В нем), но, похоже, вам это нужно просто для выполнения logger.info("something", value)
.
Но для меня это все еще немного странно - я получаю что-то похожее на JSON на выходе с ключом «meta», хотя я не использую формат JSON:
logger.info('Test: %s', 1, 2, 3, 4);
Производит:
info: Test: 1 {"meta":[2,3,4]}
Даже пример в примерах не дает того, что обещает:
https://github.com/winstonjs/winston/blob/master/examples/interpolation.js#L20 -L21
info: test message first, second {"meta":{"number":123}}
Я решил это, используя что-то вроде этих строк:
const { version } = require('../package');
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, colorize, label, printf, align } = format;
const { SPLAT } = require('triple-beam');
const { isObject } = require('lodash');
function formatObject(param) {
if (isObject(param)) {
return JSON.stringify(param);
}
return param;
}
// Ignore log messages if they have { private: true }
const all = format((info) => {
const splat = info[SPLAT] || [];
const message = formatObject(info.message);
const rest = splat.map(formatObject).join(' ');
info.message = `${message} ${rest}`;
return info;
});
const customLogger = createLogger({
format: combine(
all(),
label({ label: version }),
timestamp(),
colorize(),
align(),
printf(info => `${info.timestamp} [${info.label}] ${info.level}: ${formatObject(info.message)}`)
),
transports: [new transports.Console()]
});
Вот общий обходной путь, позволяющий использовать несколько параметров:
https://github.com/rooseveltframework/roosevelt/blob/master/lib/tools/logger.js#L29
Относится к:
https://github.com/winstonjs/winston/issues/1377
Просто слишком много вещей, которые не работают одинаково.
Привет, здесь есть обновления? Спасибо.
Также жду подходящего способа подражать console.log(...args)
в Winston ...
Мы исправили ряд случаев краев / углов вокруг splat
и meta
в 3.2.0
, но, похоже, это все еще проблема (см. Https://github.com / winstonjs / winston / pull / 1576 за CHANGELOG.md
).
Убедимся, что это будет обработано в 3.3.0
. Спасибо за терпение, ребята.
Для меня это было обходным путем:
'use strict';
const { createLogger, format, transports } = require('winston');
const { SPLAT } = require('triple-beam');
const { combine, timestamp, label, printf, colorize } = format;
const formatObject = (param) => {
if (typeof param === 'string') {
return param;
}
if (param instanceof Error) {
return param.stack ? param.stack : JSON.stringify(param, null, 2);
}
return JSON.stringify(param, null, 2);
};
const logFormat = printf((info) => {
const { timestamp: ts, level, message } = info;
const rest = info[SPLAT] || [];
const msg = info.stack ? formatObject(info.stack) : formatObject(message);
let result = `${ts} ${level}: ${msg}`;
if (rest.length) {
result += `\n${rest.map(formatObject).join('\n')}`;
}
return result;
});
const logger = createLogger({
format: combine(
label({ label: 'app' }),
timestamp(),
logFormat,
),
transports: [
new transports.Console({
format: combine(colorize()),
handleExceptions: true,
}),
],
exceptionHandlers: [
new transports.File({ filename: 'exceptions.log' }),
],
});
Когда я пытаюсь войти с аргументами, я получаю странный результат
var s = "Hello"
log.info("asdasda", s)
Получение вывода
{"0":"H","1":"e","2":"l","3":"l","4":"o","service":"XXXX","level":"info","message":"asdasda","timestamp":"2019-04-15 13:58:51"}
Я использовал обычный код быстрого запуска
Я заметил вот что:
Надеюсь, это может / будет исправлено
Примечание: протестировал это с последней выпущенной версией Winston, быстрый взгляд на код, кажется, предполагает, что он все еще такой же в master (который, кажется, имеет другие исправления)
Некоторые улучшения по сравнению с решением @luislobo 👏
%s %d or %j
для сообщений типа logger.info(`hello %s`,'world')
printf
trimEnd
если в сборщике не указаны дополнительные аргументыconst { version } = require('../package');
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, colorize, label, printf, align } = format;
const { SPLAT } = require('triple-beam');
const { isObject,trimEnd } = require('lodash');
function formatObject(param) {
if (isObject(param)) {
return JSON.stringify(param);
}
return param;
}
const all = format((info) => {
const splat = info[SPLAT] || []
const isSplatTypeMessage =
typeof info.message === 'string' &&
(info.message.includes('%s') || info.message.includes('%d') || info.message.includes('%j'))
if (isSplatTypeMessage) {
return info
}
const message = formatObject(info.message)
const rest = splat
.map(formatObject)
.join(' ')
info.message = trimEnd(`${message} ${rest}`)
return info
});
const customLogger = createLogger({
format: combine(
colorize(),
all(),
label({ label: version }),
timestamp(),
align(),
printf(info => `${info.timestamp} [${info.label}] ${info.level}: ${info.message}`)
),
transports: [new transports.Console()]
});
Какие-либо дополнительные обновления к этому, которые я могу пропустить? Кажется, что есть довольно сильная поддержка повторного добавления этой функции, но последний раз это было почти 6 месяцев назад.
Привет, огромный бампер и стоппер, пытаюсь перейти на 3.X, вероятно, какое-то время сохранит 2.x.
Немного разочаровал :(
Вот что сработало для меня:
const { format, createLogger, transports } = require('winston');
const jsonStringify = require('fast-safe-stringify');
const logLikeFormat = {
transform(info) {
const { timestamp, label, message } = info;
const level = info[Symbol.for('level')];
const args = info[Symbol.for('splat')];
const strArgs = args.map(jsonStringify).join(' ');
info[Symbol.for('message')] = `${timestamp} [${label}] ${level}: ${message} ${strArgs}`;
return info;
}
};
const debugFormat = {
transform(info) {
console.log(info);
return info;
}
};
const logger = createLogger({
format: format.combine(
// debugFormat, // uncomment to see the internal log structure
format.timestamp(),
format.label({ label: 'myLabel' }),
logLikeFormat,
// debugFormat, // uncomment to see the internal log structure
),
transports: [
new transports.Console()
]
});
logger.info('foo', 'bar', 1, [2, 3], true, { name: 'John' });
что дает: 2019-07-04T21:30:08.455Z [myLabel] info: foo "bar" 1 [2,3] true {"name":"John"}
Обычно format.combine
устанавливает конвейер для объекта info
. Для каждой функции форматирования вызывается transform
и последнее сообщение журнала должно быть записано в info[Symbol.for('message')]
надеюсь это поможет
Мне нужно решение, которое поддерживает %d
, %o
т. Д., Но по-прежнему по умолчанию включает любые остальные аргументы, так что logger.info('hello %d %j', 42, {a:3}, 'some', 'more', 'arguments')
отображается следующим образом:
hello 42 {"a": 3} some more arguments
Мое решение для этого закончилось использованием символа splat
но ручным вызовом util.format()
непосредственно из printf
, который по умолчанию включает все остальные аргументы:
const {format} = require('util');
const winston = require('winston');
const {combine, timestamp, printf} = winston.format;
const SPLAT = Symbol.for('splat');
const transport = new winston.transports.Console({
format: combine(
timestamp(),
printf(({timestamp, level, message, [SPLAT]: args = []}) =>
`${timestamp} - ${level}: ${format(message, ...args)}`)
)
})
Если вам не нужна printf
вы, конечно, можете вместо этого добавить преобразование, которое просто расширяет аргументы до info.message
, а затем форматирует конечный результат так, как вам нравится:
format: combine(
{
transform(info) {
const {[SPLAT]: args = [], message} = info;
info.message = format(message, ...args);
return info;
}
},
simple()
)
Проблема с использованием format.splat()
заключается в том, что он использует совпадающие аргументы, но, кажется, отбрасывает остальные. Вызвав сам util.format()
я могу изменить это поведение.
Та же проблема, есть какие-нибудь обновления по этому поводу? Я люблю Winston, но меня сводит с ума, когда я не могу распечатать все аргументы, переданные регистратору, что я могу сделать с помощью console.log()
.
@ fr1sk Вы пробовали моё форматирование выше? Это дает console.log()
подобное поведение (внутренняя реализация узла console.log()
использует util.format()
afaik).
Очень жаль, что эта проблема до сих пор не решена, и что моя проблема была заблокирована.
Я работаю со многими разными командами, и все они разделяют разочарование от потери предыдущего DX при переходе на v3.
Я провел целый день, пробуя разные вещи.
Вышеупомянутые решения были близки, но мне не хватало раскраски и разрыва строки дополнительных аргументов.
ИМО, вход в консоль должен быть восхитительным.
Вот моя попытка осуществить это ...
const winston = require('winston');
const chalk = require('chalk');
const logger = new winston.Logger({
transports: [
new winston.transports.Console({
level: 'info',
colorize: true,
prettyPrint: true,
timestamp: true
})
]
});
logger.info({ one: 1, two: 2, three: 3 });
logger.info(chalk.blue('[TEST]:'), { one: 1, two: 2, three: 3 }, [4, 5, 6]);
logger.info(chalk.blue('[TEST]:'), null, undefined, 'one', 2, { 3: 3, 4: '4' });
logger.info(chalk.blue('[TEST]:'), chalk.yellow('Bombastic'), () => {}, /foo/);
logger.error(chalk.blue('[ERR]:'), new Error('Error number 1'));
logger.error(new Error('Error number 2'));
const { createLogger, format, transports } = require('winston');
const { inspect } = require('util');
const chalk = require('chalk');
const hasAnsi = require('has-ansi');
function isPrimitive(val) {
return val === null || (typeof val !== 'object' && typeof val !== 'function');
}
function formatWithInspect(val) {
const prefix = isPrimitive(val) ? '' : '\n';
const shouldFormat = typeof val !== 'string' || !hasAnsi(val);
return prefix + (shouldFormat ? inspect(val, { depth: null, colors: true }) : val);
}
const logger = createLogger({
level: 'info',
format: format.combine(
format.timestamp(),
format.errors({ stack: true }),
format.colorize(),
format.printf(info => {
const msg = formatWithInspect(info.message);
const splatArgs = info[Symbol.for('splat')] || [];
const rest = splatArgs.map(data => formatWithInspect(data)).join(' ');
return `${info.timestamp} - ${info.level}: ${msg} ${rest}`;
})
),
transports: [new transports.Console()]
});
logger.info({ one: 1, two: 2, three: 3 });
logger.info(chalk.blue('[TEST]:'), { one: 1, two: 2, three: 3 }, [4, 5, 6]);
logger.info(chalk.blue('[TEST]:'), null, undefined, 'one', 2, { 3: 3, 4: '4' });
logger.info(chalk.blue('[TEST]:'), chalk.yellow('Bombastic'), () => {}, /foo/);
logger.error(chalk.blue('[ERR]:'), new Error('Error number 1'));
logger.error(new Error('Error number 2'));
chalk
info.message
- это просто строка, а стековый тракт находится в свойстве stack
message
в качестве 1-го аргумента выводит только message
, отбрасывая любые другие свойства.info.message
(которое обычно является значением 1-го аргумента), в результате чего сообщение об ошибке отображается дважды.Игра с форматировщиком errors
не помогла.
Мы можем обрабатывать ошибки форматирования, но это хакерский метод:
function formatWithInspect(val) {
+ if (val instanceof Error) {
+ return '';
+ }
const prefix = isPrimitive(val) ? '' : '\n';
const shouldFormat = typeof val !== 'string' || !hasAnsi(val);
return prefix + (shouldFormat ? inspect(val, { depth: null, colors: true }) : val);
}
...
format.printf((info) => {
const msg = formatWithInspect(info.message);
const splatArgs = info[Symbol.for('splat')] || [];
const rest = splatArgs.map((data) => formatWithInspect(data)).join(' ');
+ const stackTrace = info.stack ? `\n${info.stack}` : '';
return `${info.timestamp} - ${info.level}: ${msg} ${rest}${stackTrace}`;
})
...
это работает для меня, используя info[Symbol.for('splat')]
const logger = winston.createLogger({
level: 'debug',
transports: [
...
],
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf((info: any) => {
const timestamp = info.timestamp.trim();
const level = info.level;
const message = (info.message || '').trim();
const args = info[Symbol.for('splat')];
const strArgs = (args || []).map((arg: any) => {
return util.inspect(arg, {
colors: true
});
}).join(' ');
return `[${timestamp}] ${level} ${message} ${strArgs}`;
})
)
});
Я понимаю, что в основных версиях вносятся критические изменения, но боже мой ...
Ни одно из решений не привело к такому поведению, как winston v2.
Решения от @henhal и @yamadashy имеют одну и отображается в виде строки.
logger.debug(err)
создать сообщение журнала:
debug: Error: ETIMEDOUT
тогда как logger.debug('anystringhere', err)
создает:
debug: anystringhereError: ETIMEDOUT { RequestError: Error: ETIMEDOUT
at new RequestError (/path/to/node_modules/request-promise-core/lib/errors.js:14:15)
<the rest of full error stack here>
Вторая проблема заключается в том, что дополнительные аргументы подавляются при использовании с информационным уровнем - похоже, что Winston v3 обрабатывает это иначе до форматирования.
Третья проблема - отсутствие пробела между двумя сообщениями (обратите внимание на «anystringhereError»).
Моя текущая конфигурация регистратора v3:
const { format } = require('util');
const winston = require("winston");
const logger = winston.createLogger({
transports: [
new winston.transports.Console({
level: 'debug'
format: winston.format.combine(
winston.format.colorize(),
winston.format.align(),
winston.format.printf(
({level, message, [Symbol.for('splat')]: args = []}) => `${level}: ${format(message, ...args)}`
)
)
}),
]
});
module.exports = logger;
Мне этого достаточно, и я вернусь к Winston v2 с помощью всего этого:
const Winston = require("winston");
const logger = new Winston.Logger({
transports: [
new Winston.transports.Console({
level: 'debug',
handleExceptions: true,
json: false,
colorize: true,
})
],
});
module.exports = logger;
Эта конфигурация v2 не имеет вышеупомянутых проблем.
Я хочу поделиться своей настройкой Winston:
const util = require('util');
const { createLogger, format, transports } = require('winston');
const { combine, colorize, timestamp, printf, padLevels} = format;
const myFormat = printf(({ level, message, label, timestamp, ...rest }) => {
const splat = rest[Symbol.for('splat')];
const strArgs = splat ? splat.map((s) => util.formatWithOptions({ colors: true, depth: 10 }, s)).join(' ') : '';
return `${timestamp} ${level} ${util.formatWithOptions({ colors: true, depth: 10}, message)} ${strArgs}`;
});
const logger = createLogger({
level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
format: combine(
colorize(),
timestamp({
format: 'YYYY-M-DD HH:mm:ss',
}),
padLevels(),
myFormat
),
transports: [new transports.Console()],
});
logger.info('test info');
logger.error('test error');
logger.debug('test debug');
Вот общий обходной путь, позволяющий использовать несколько параметров:
https://github.com/rooseveltframework/roosevelt/blob/master/lib/tools/logger.js#L29
вот обновленная ссылка на предлагаемое решение
https://github.com/rooseveltframework/roosevelt/blob/0.13.0/lib/tools/logger.js
Мой вариант отличных предложений @alexilyaev :
const { omit } = require('lodash');
const hasAnsi = require('has-ansi');
function isPrimitive(val) {
return val === null || (typeof val !== 'object' && typeof val !== 'function');
}
function formatWithInspect(val) {
if (val instanceof Error) {
return '';
}
const shouldFormat = typeof val !== 'string' && !hasAnsi(val);
const formattedVal = shouldFormat
? inspect(val, { depth: null, colors: true })
: val;
return isPrimitive(val) ? formattedVal : `\n${formattedVal}`;
}
// Handles all the different log formats for console
function getDomainWinstonLoggerFormat(format) {
return format.combine(
format.timestamp(),
format.errors({ stack: true }),
format.colorize(),
format.printf((info) => {
const stackTrace = info.stack ? `\n${info.stack}` : '';
// handle single object
if (!info.message) {
const obj = omit(info, ['level', 'timestamp', Symbol.for('level')]);
return `${info.timestamp} - ${info.level}: ${formatWithInspect(obj)}${stackTrace}`;
}
const splatArgs = info[Symbol.for('splat')] || [];
const rest = splatArgs.map(data => formatWithInspect(data)).join('');
const msg = formatWithInspect(info.message);
return `${info.timestamp} - ${info.level}: ${msg}${rest}${stackTrace}`;
}),
);
}
для журналов типа:
logger.info({
joe: 'blow',
});
logger.info('Single String');
logger.info('With Func ', () => {}, /foo/);
logger.info('String One ', 'String Two');
logger.info('String One ', 'String Two ', 'String Three');
logger.info('Single Object ', {
test: 123,
});
logger.info(
'Multiple Objects ',
{
test: 123,
},
{
martin: 5555,
},
);
logger.error('Error: ', new Error('Boom!'));
Он выводит примерно так - что хорошо для всех моих сценариев:
Привет, я начинаю с Winston, никогда не использовал v2, поэтому я на v3.2.1
Я просто пытался сделать:
import winston, { format } from 'winston';
winston.format(format.combine(format.splat(), format.simple()));
winston.info('buildFastify dataPath %s', opts.dataPath);
И надеемся, что интерполяция строк сработает; но нет.
{"level":"info","message":"buildFastify dataPath %s"}
Когда я ожидал
{"level":"info","message":"buildFastify dataPath /My/Data/Path"}
Этот вопрос как-то тоже самое? Или я вынужден использовать вместо этого функцию logger.log('info', .....)
?
Событие, пытающееся это сделать, не работает.
winston.log('info', 'buildFastify dataPath %s', opts.dataPath);
вывод:
{"level":"info","message":"buildFastify dataPath %s"}
Спасибо, кто разместил предложения выше.
Черт, я выбросил один день только для того, чтобы интегрировать Winston 3 в свой проект: /
Этот поразил меня сегодня - я понял, что мой новый модный регистратор выбрасывает все мои ...rest
аргументы. Это может не сработать для всех или для каждого варианта использования, но в моем случае я счел приемлемым просто обернуть все, что я хотел, зарегистрировать в виде массива. Это не самый красивый вариант, но он легче, чем некоторые [очень умные] обходные пути, требующие большего количества кода. Надеюсь, это поможет кому-то другому!
logger.info(["Something happened!", foo, bar]);
Очень обидно, что они решили внести такое серьезное изменение, и ВСЕ ЕЩЕ не упомянули об этом ни в руководстве по миграции, ни в документации.
Несмотря на это, я хотел поделиться своим решением, которое я нашел довольно компактным, и следует, как node js реализует console.log с помощью util.format
const winstonLogger= createLogger(...);
const writeLogType = (logLevel) => {
return function () {
const args = Array.from(arguments);
winstonLogger[logLevel](util.format(...args));
};
};
const logger = {
silly: writeLogType('silly'),
debug: writeLogType('debug'),
verbose: writeLogType('verbose'),
info: writeLogType('info'),
warn: writeLogType('warn'),
error: writeLogType('error'),
};
Я хотел бы присоединиться и попросить добавить эту функцию в ядро Winston. В настоящее время я использую специальный форматировщик с splat
для достижения этой функциональности, что, честно говоря, кажется очень хакерским. Было бы неплохо иметь функциональность, которая соответствует console.log
Любые обновления?
Помимо описанного выше поведения для v3, я также хочу добавить это:
logger.info('param 1', { propInJson1: 'propInJson 1', propInJson2: 'propInJson 2' });
произведет это
{"propInJson1":"propInJson 1","propInJson2":"propInJson 2","level":"info","message":"param 1"}
версия, которую я использую: (v3.2.1)
Конфиги:
winstonLogger.add(new winston.transports.Console());
Я до сих пор не понимаю, как выводить несколько значений в Winston.
Я просто хотел заменить console.log('Hello', var1, '!')
на logger.log('Hello', var1, '!')
.
Честно говоря, попытки использовать Winston всегда приводили к потере времени и неожиданным проблемам с логированием.
Очень обидно, что они решили внести такое серьезное изменение, и ВСЕ ЕЩЕ не упомянули об этом ни в руководстве по миграции, ни в документации.
Несмотря на это, я хотел поделиться своим решением, которое я нашел довольно компактным, и следует, как node js реализует console.log с помощью
util.format
const winstonLogger= createLogger(...); const writeLogType = (logLevel) => { return function () { const args = Array.from(arguments); winstonLogger[logLevel](util.format(...args)); }; }; const logger = { silly: writeLogType('silly'), debug: writeLogType('debug'), verbose: writeLogType('verbose'), info: writeLogType('info'), warn: writeLogType('warn'), error: writeLogType('error'), };
Кроме того, используйте util.formatWithOptions({ colors: true }, ...args);
чтобы получить цветную печать, как при обычном console.log
У меня это работает. combineMessageAndSplat
который объединяет сообщение и знак с использованием util.format
const winston = require("winston");
const util = require('util');
const combineMessageAndSplat = () => {
return {transform: (info, opts) => {
//combine message and args if any
info.message = util.format(info.message, ...info[Symbol.for('splat')] || [] )
return info;
}
}
}
const logger = winston.createLogger({
format:
winston.format.combine(
combineMessageAndSplat(),
winston.format.simple()
)
});
logger.add(new winston.transports.Console({
level: 'info'
})
);
logger.info("string"); // info: string
logger.info({a:1,b:[{c:[1]}]}); // info: { a: 1, b: [ { c: [Array] } ] }
logger.info("1","2",{a:1}); // info: 1 2 { a: 1 }
logger.info([{},""]); // info: [ {}, '' ]
logger.error(new Error()); // error: Error ... at Object.<anonymous>
Пришлось соответствовать методам console. *, Ориентируясь на все вышесказанное, и ...
Но: Вывод файла должен отображать детали объекта.
В итоге я получил:
// make File and FileList parseable // from: https://stackoverflow.com/a/51939522/1644202
File.prototype.toObject = function () {
return Object({
name: String(this.name),
path: String(this.path),
lastModified: parseInt(this.lastModified),
lastModifiedDate: String(this.lastModifiedDate),
size: parseInt(this.size),
type: String(this.type)
});
};
FileList.prototype.toArray = function () {
return Array.from(this).map(function (file) {
return file.toObject()
});
};
// this fixes: winston console transport to use the original console functions and all the colorization/folding/etc that comes with it
const Transport = require('winston-transport');
class WebDeveloperConsole extends Transport {
constructor(opts) {
super(opts);
}
log(info, callback) {
(window.console[info.level] || window.console.log).apply(window.console, [info.timestamp, ...info.message]);
callback();
}
};
// Electron app console output
class AppConsole extends Transport {
constructor(opts) {
super(opts);
const { remote } = require('electron');
this.electronConsole = remote.getGlobal('console');
}
log(info, callback) {
(this.electronConsole[info.level] || this.electronConsole.log).apply(this.electronConsole, [info.timestamp, ...info.message]);
callback();
}
};
const util = require('util');
const {
createLogger,
transports,
format
} = require('winston');
let logger = createLogger({
level: 'trace',
levels: {
error: 0,
warn: 1,
info: 2,
//http: 3, no console.* methods
//verbose: 4,
debug: 3,
trace: 4
},
format: format.combine(
format.prettyPrint(),
format.timestamp({
format: 'DD-MM-YYYY hh:mm:ss A'
}),
{
transform(info) {
const { timestamp, message } = info;
const level = info[Symbol.for('level')];
const args = [message, ...(info[Symbol.for('splat')] || [])]; // join the args back into one arr
info.message = args; // for all custom transports (mainly the console ones)
let msg = args.map(e => {
if (e.toString() == '[object FileList]')
return util.inspect(e.toArray(), true, 10);
else if (e.toString() == '[object File]')
return util.inspect(e.toObject(), true, 10);
else if (e.toString() == '[object Object]') {
return util.inspect(e, true, 5);
}
else if (e instanceof Error)
return e.stack
else
return e;
}).join(' ');
info[Symbol.for('message')] = `${timestamp} - ${level}: ${msg}`; // for inbuild transport / file-transport
return info;
}
},
),
transports: [
//new transports.Console(),
new WebDeveloperConsole(),
new AppConsole(),
...
],
...
});
@indexzero Вам было интересно, планируете ли вы решить эту проблему в какой-то момент?
Я изучаю Winston для использования в моем проекте, теперь интересно, стоит ли рисковать, поскольку эта проблема открыта уже более 2 лет. для меня это похоже на базовую функцию для любого фреймворка журналирования
Самый полезный комментарий
Для нас это ОГРОМНОЕ переломное изменение. Если это сделано намеренно, об этом следует подробно рассказать в https://github.com/winstonjs/winston/blob/master/UPGRADE-3.0.md.