winston
versión? _winston@2
winston@3
node -v
salidas: _ v8.11.3
Con 3.xx:
const winston = require('winston')
const logger = winston.createLogger({
transports: [new winston.transports.Console()]
})
logger.info('test log', 'with a second parameter')
Salidas:
{"level":"info","message":"test log"}
Con 2.xx:
const winston = require('winston')
const logger = new winston.Logger({
transports: [new winston.transports.Console()]
})
logger.info('test log', 'with a second parameter')
Salidas:
info: test log with a second parameter
Debería generar:
{"level":"info","message":"test log with a second parameter"}
Hoy me encontré con el mismo problema. Creo que es un error ya que la documentación de actualización también tiene un ejemplo como ese aquí :
logger.info('transaction ok', { creditCard: 123456789012345 });
Actualmente, para evitar esto, puede crear una función que analice los argumentos antes de pasar a winston
@ mulligan121 Está bien, pero no quiero reemplazar cada declaración de registro en mi base de código ...
@indexzero ¿
Solución temporal:
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);
Este es un ENORME cambio radical para nosotros. Si es intencional, debe detallarse en https://github.com/winstonjs/winston/blob/master/UPGRADE-3.0.md
Entonces, después de investigar un poco más, descubrí que necesita el formateador de símbolos para que se impriman varios argumentos. Pensé que era solo para la interpolación de argumentos (es decir, cosas con% s, etc.), pero parece que lo necesitas solo para hacer logger.info("something", value)
.
Pero esto sigue siendo un poco extraño para mí: obtengo algo que se parece a JSON en la salida con una clave "meta", aunque no estoy usando un formato JSON:
logger.info('Test: %s', 1, 2, 3, 4);
Produce:
info: Test: 1 {"meta":[2,3,4]}
Incluso el ejemplo de los ejemplos no produce lo que dice que lo hará:
https://github.com/winstonjs/winston/blob/master/examples/interpolation.js#L20 -L21
info: test message first, second {"meta":{"number":123}}
Lo resolví usando algo como esto:
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()]
});
Aquí hay una solución común para permitir múltiples parámetros:
https://github.com/rooseveltframework/roosevelt/blob/master/lib/tools/logger.js#L29
Relacionado con:
https://github.com/winstonjs/winston/issues/1377
Hay demasiadas cosas que no funcionan igual.
Hola, ¿alguna actualización aquí? Gracias.
También esperando la forma adecuada de emular console.log(...args)
en winston ...
Arreglamos varios casos de borde / esquina alrededor de splat
y meta
en 3.2.0
, pero parece que esto sigue siendo un problema (consulte: https://github.com / winstonjs / winston / pull / 1576 para el CHANGELOG.md
).
Se asegurará de que esto se maneje en 3.3.0
. Gracias por su paciencia amigos.
Esta fue una solución para mí:
'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' }),
],
});
Cuando intento iniciar sesión con argumentos, obtengo un resultado extraño
var s = "Hello"
log.info("asdasda", s)
Obteniendo el resultado
{"0":"H","1":"e","2":"l","3":"l","4":"o","service":"XXXX","level":"info","message":"asdasda","timestamp":"2019-04-15 13:58:51"}
Usé el código de inicio rápido normal
Una cosa que noté es esto:
Espero que esto pueda / será arreglado
Nota: probé esto con la última versión lanzada de Winston, un vistazo rápido al código parece sugerir que todavía es así en el maestro (que parece tener otras correcciones)
Algunas mejoras sobre solución @luislobo 's 👏
%s %d or %j
para mensajes como logger.info(`hello %s`,'world')
printf
trimEnd
si no se proporcionan argumentos de suma en el loogerconst { 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()]
});
¿Alguna actualización adicional de esto que pueda estar perdiendo? Parece que hay un apoyo bastante sólido para que se vuelva a agregar esta función, pero el último compromiso con esto fue hace casi 6 meses.
Hola, enorme Bumper y show stopper, tratando de migrar al 3.X, probablemente mantendrá el 2.x por un tiempo.
Un poco decepcionado :(
Esto es lo que funcionó para mí:
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' });
que da como resultado: 2019-07-04T21:30:08.455Z [myLabel] info: foo "bar" 1 [2,3] true {"name":"John"}
Básicamente, format.combine
establece una canalización para un objeto info
. Para cada función de formato, se llama transform
y el mensaje de registro final debe escribirse en info[Symbol.for('message')]
espero que esto ayude
Quería una solución que admita %d
, %o
, etc., pero aún así, por defecto, incluye cualquier argumento de descanso, de modo que logger.info('hello %d %j', 42, {a:3}, 'some', 'more', 'arguments')
se muestre así:
hello 42 {"a": 3} some more arguments
Mi solución para esto terminó usando el símbolo splat
pero invocando manualmente util.format()
directamente desde printf
, que por defecto incluye cualquier argumento de resto:
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)}`)
)
})
Si no desea printf
, por supuesto, podría agregar una transformación que simplemente expanda los argumentos en info.message
, y luego formatee el resultado final de la manera que desee:
format: combine(
{
transform(info) {
const {[SPLAT]: args = [], message} = info;
info.message = format(message, ...args);
return info;
}
},
simple()
)
El problema con el uso de format.splat()
es que consume los argumentos coincidentes pero parece desechar el resto. Al invocar util.format()
yo mismo, puedo anular ese comportamiento.
El mismo problema, ¿alguna actualización con respecto a este? Amo a Winston, pero me vuelve loco cuando no puedo imprimir todos los argumentos pasados al registrador, lo que puedo hacer con console.log()
.
@ fr1sk ¿ console.log()
comportamiento similar a console.log()
usa internamente util.format()
afaik).
Es decepcionante que este problema aún no se haya resuelto y que mi problema relacionado se haya bloqueado.
Estoy trabajando con muchos equipos diferentes y todos comparten la frustración de perder DX anterior al migrar a v3.
Me he pasado un día entero probando cosas.
Las soluciones anteriores estaban cerca, pero me faltaba la coloración y el salto de línea de los argumentos adicionales.
En mi opinión, iniciar sesión en la consola debería ser una delicia.
Aquí está mi intento de hacerlo realidad ...
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
es solo una cadena y el tracto de pila está en la propiedad stack
message
como primer argumento solo imprime message
, descartando cualquier otra propiedadinfo.message
(que suele ser el valor del primer argumento), lo que da como resultado ver el mensaje de error dos vecesJugar con el formateador errors
no ayudó.
Podemos manejar los errores de formato, pero es un truco:
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}`;
})
...
me funciona usando 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}`;
})
)
});
Entiendo que las versiones principales introducen cambios importantes, pero Dios mío ...
Ninguna de las soluciones me dio el mismo comportamiento que winston v2.
Las soluciones de @henhal y @yamadashy tienen el mismo problema: el valor del mensaje se muestra como la cadena.
logger.debug(err)
crear mensaje de registro:
debug: Error: ETIMEDOUT
mientras que logger.debug('anystringhere', err)
crea:
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>
El segundo problema es que los argumentos adicionales se suprimen cuando se usa con el nivel de información; winston v3 parece manejar eso de la otra manera antes de formatear.
El tercer problema es el espacio que falta entre 2 mensajes (observe "anystringhereError").
Mi configuración actual del registrador 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;
Ya tuve suficiente de eso y volveré a winston v2 con solo esto:
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;
Esta configuración v2 no tiene los problemas mencionados anteriormente.
Quiero compartir mi configuración de 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');
Aquí hay una solución común para permitir múltiples parámetros:
https://github.com/rooseveltframework/roosevelt/blob/master/lib/tools/logger.js#L29
aquí está el enlace actualizado a la solución propuesta
https://github.com/rooseveltframework/roosevelt/blob/0.13.0/lib/tools/logger.js
La mía es una variación de las grandes sugerencias de
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}`;
}),
);
}
para registros como:
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!'));
Produce así, lo cual es bueno para todos mis escenarios:
Oye, estoy comenzando con Winston, nunca usé v2, así que estoy en v3.2.1
Estaba tratando de hacer simplemente:
import winston, { format } from 'winston';
winston.format(format.combine(format.splat(), format.simple()));
winston.info('buildFastify dataPath %s', opts.dataPath);
Y esperando que la interpolación de cuerdas funcione; pero no.
{"level":"info","message":"buildFastify dataPath %s"}
Cuando estaba esperando
{"level":"info","message":"buildFastify dataPath /My/Data/Path"}
¿Este problema es lo mismo de alguna manera? ¿O me veo obligado a usar la función logger.log('info', .....)
lugar?
El evento que intenta esto no funciona.
winston.log('info', 'buildFastify dataPath %s', opts.dataPath);
producción:
{"level":"info","message":"buildFastify dataPath %s"}
Gracias a quien publicó las sugerencias anteriores.
Maldita sea, he desperdiciado un día solo para integrar Winston 3 en mi proyecto: /
Este me golpeó hoy: me di cuenta de que mi nuevo y elegante registrador estaba lanzando todos mis argumentos ...rest
. Es posible que esto no funcione para todos o para todos los casos de uso, pero en mi caso me pareció aceptable simplemente envolver todo lo que quería que se registrara como una matriz. No es el más bonito, pero es más ligero que algunas de las soluciones alternativas [muy inteligentes] que requieren más código. ¡Espero que esto ayude a alguien más!
logger.info(["Something happened!", foo, bar]);
Realmente molesto que decidieron hacer un cambio tan importante y TODAVÍA no lo han mencionado en la guía de migración o en la documentación.
Independientemente, quería compartir mi solución que encontré bastante compacta y sigue cómo el nodo js implementa console.log usando 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'),
};
Me gustaría intervenir y solicitar que esta función se agregue al núcleo de Winston. Actualmente, estoy usando el formateador personalizado con splat
para lograr esta funcionalidad, que honestamente se siente muy mal. Sería bueno tener una funcionalidad que coincida con console.log
¿Alguna actualización?
Además de los comportamientos anteriores para v3, también quiero agregar esto:
logger.info('param 1', { propInJson1: 'propInJson 1', propInJson2: 'propInJson 2' });
producirá esto
{"propInJson1":"propInJson 1","propInJson2":"propInJson 2","level":"info","message":"param 1"}
la versión que estoy usando: (v3.2.1)
Las configuraciones:
winstonLogger.add(new winston.transports.Console());
Todavía no entiendo cómo generar varios valores en Winston.
Solo quería reemplazar console.log('Hello', var1, '!')
con logger.log('Hello', var1, '!')
.
Para ser honesto, intentar usar Winston siempre conduce a una gran pérdida de tiempo y a problemas sorprendentes con el registro.
Realmente molesto que decidieron hacer un cambio tan importante y TODAVÍA no lo han mencionado en la guía de migración o en la documentación.
Independientemente, quería compartir mi solución que encontré bastante compacta y sigue cómo el nodo js implementa console.log usando
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'), };
Además, use util.formatWithOptions({ colors: true }, ...args);
para obtener resultados impresos en color como con console.log
normales
Esto funciona para mi. combineMessageAndSplat
que combina mensaje y splat usando 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>
Tuve que ajustarme a los métodos de la consola. *, Orientándome en todo lo anterior, y ...
Pero: la salida del archivo debe mostrar detalles del objeto.
Así que terminé con:
// 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 ¿Se preguntaba si todavía planeaba abordar esto en algún momento?
Estoy explorando winston para usarlo en mi proyecto, ahora me pregunto si vale la pena correr el riesgo, ya que este problema está abierto durante más de 2 años. para mí, esto parece una función básica para cualquier marco de registro
Comentario más útil
Este es un ENORME cambio radical para nosotros. Si es intencional, debe detallarse en https://github.com/winstonjs/winston/blob/master/UPGRADE-3.0.md