winston
versión?_ 3.1.0winston@2
winston@3
_ node -v
salidas:_ v8.11.3
_¿Sistema Operativo?_ Linux
logger.error
llamado con la instancia Error
no usa los campos message
y stack
, sino que registra la prueba error
.
Ejemplo de código:
const winston = require('winston');
const alignedWithColorsAndTime = winston.format.combine(
// winston.format.colorize({ all: true }),
// winston.format.timestamp(),
// winston.format.align(),
winston.format.printf((info) => {
const { level, message, ...args } = info;
if (level.indexOf('error') !== -1) {
console.log(typeof message, JSON.stringify(message));
}
return `[${level}]: ${message} ${Object.keys(args).length ? JSON.stringify(args, null, 2) : ''}`;
})
);
const transports = [new winston.transports.Console({
level: 'debug',
format: alignedWithColorsAndTime
})];
const logger = winston.createLogger({
level: 'debug',
transports
});
try {
logger.info('aaaaa');
logger.debug('bbbb');
logger.error('eeee');
throw new Error('Scary error');
} catch (error) {
logger.error(error);
}
Al menos se registró un mensaje de error real. Idealmente, con pila.
No depende del formateador printf
, simple
da el mismo resultado. Evento sin formateador devuelve mensaje vacío.
Problema probablemente relacionado # 1422
Tuve el mismo problema, tuve que implementar logger.error
yo mismo:
logger.error = err => {
if (err instanceof Error) {
logger.log({ level: 'error', message: `${err.stack || err}` });
} else {
logger.log({ level: 'error', message: err });
}
};
@gtsec en realidad hice casi lo mismo, solo usé el nuevo nombre de método .exception
.
Esto podría deberse a wintson-transport
, consulte https://github.com/winstonjs/winston-transport/issues/31 para conocer el problema y https://github.com/winstonjs/winston-transport/pull/ 34 para el PR.
En un repositorio de muestra donde estoy probando la migración winston-graylog2
para usar winston@3x
, terminé implementando la conversión de error como un formateador personalizado.
const errorFormatter = format((info, opts) => {
let formatted = {};
if (info instanceof Error) {
// An error object is not 100% like a normal object, so
// we have to jump through hoops to get needed info out
// of error objects for logging.
formatted = Object.assign(formatted, info);
formatted.message = info.stack;
} else {
formatted = info;
}
return formatted;
});
Sin embargo , para una experiencia consistente, sería beneficioso si este manejo se hiciera dentro del método de error del registrador, en lugar de depender de formateadores personalizados (inconsistentes de un proyecto a otro) o volver a implementar/sobrescribir los métodos de la biblioteca (súper inseguro y pirateado). ).
En realidad, acabo de darme cuenta de que el objeto de formato winston predeterminado tiene un controlador de errores, por lo que solo necesita adjuntarlo como formateador.
¿Ejemplo?
Entonces, resulta que estaba equivocado sobre el formateador de errores. Todavía no está en Winston, pero está en [email protected] , y debe usarlo en combinación con los formateadores metadata
y json
.
Entonces, sí, muchas advertencias para que funcione. Sería mejor si pudieras usarlo solo, pero es mejor que nada.
const winston = require('winston');
const { format } = require('logform');
const logger = winston.createLogger({
format: format.combine(
format.errors({ stack: true }),
format.metadata(),
format.json(),
),
transports: [ new winston.transports.Console() ],
});
logger.error(new Error(FakeError));
Solución ingeniosa @ jeremy-j-ackso
Sugiriendo que esto se cierre debido a # 1576.
Puede utilizar los formateadores.
const winston = require('winston');
const { format } = winston;
const logger = winston.createLogger({
format: format.combine(
format.errors({ stack: true }),
format.metadata(),
format.json(),
),
transports: [ new winston.transports.Console() ],
});
logger.error(new Error('FakeError'));
¡Sí, los errores finalmente deberían poder registrarse de una manera agradable para las personas que desean activar esa funcionalidad!
Si bien este enfoque funciona principalmente, no parece proporcionar una manera fácil de registrar errores en un formato de texto como simple(). Parece un caso de uso muy común, y sería maravilloso si hubiera una forma estándar, libre de problemas y obstinada de hacerlo.
Aprecio el deseo de un formato único para todos, hazlo todo por mí, hazlo mágico, no me hagas pensar. Es una trampa en la que es fácil caer, y es por eso que winston@2 y las líneas de lanzamiento anteriores tuvieron un rendimiento tan terrible en comparación con otras bibliotecas de registro. Simplemente trató de hacer demasiado por defecto para satisfacer las demandas de funciones de un gran conjunto de usuarios con diferentes opiniones y gustos.
Como proyecto, winston@3 encarna una nueva opinión: impulsar el formato complejo en formatos de un solo propósito desacoplados y hacer que la combinación sea fácil para los usuarios.
Admito que todavía queda trabajo por hacer en la documentación, junto con explicaciones de alto nivel y depuración de formatos.
Todo lo dicho, el formato de errores sugerido refleja la opinión del proyecto: ¿Se puede implementar esto como un formato personalizado?
@DABH ¿por qué cerraste este problema? El uso del formateador sugerido por @jeremy-j-ackso no funciona sin el formateador format.json()
. Ni siquiera es una solución.
const winston = require('winston');
const { format } = winston;
const logger = winston.createLogger({
format: format.combine(
format.errors({ stack: true }),
format.metadata()
),
transports: [ new winston.transports.Console() ],
});
function a() {
throw new Error('Error from "a"');
console.log('a()');
}
function b() {
a();
console.log('a() called from b()');
}
function c() {
b();
console.log('b() called from c()');
}
function f() {
try {
c();
console.log('c() called from d()');
} catch(error) {
logger.error(error);
}
}
f();
$ node 1.js
Error from "a"
Probado en [email protected]
.
Sí, estoy de acuerdo con @nosuchip : no parece haber una buena solución si desea usar el formato simple()
. De hecho, necesitamos a ambos para trabajar en un proyecto que tengo. Terminé creando un formateador personalizado que funciona pero es un poco complicado. Este código me da una pila en json cuando uso ese formato y una pila en texto sin procesar cuando uso un formato simple:
const displayStack = winston.format((info) => {
info.message = info.stack ? info.stack : info.message
return info
})
const consoleDebugFormat = winston.format.combine(
displayStack(),
winston.format.simple()
)
const jsonFormat = winston.format.combine(
winston.format.errors({ stack: true }),
winston.format.json()
)
const activeFormat = process.env.LOG_FORMAT === 'simple' ? consoleDebugFormat : jsonFormat
const loggerConsole = new winston.transports.Console()
const logger = winston.createLogger({
transports: [loggerConsole],
format: activeFormat,
exitOnError: false
})
Entonces, ¿todavía no hay una solución para este problema?
@cogscape lamentablemente no. Acabo de probar el último Winston y ninguna solución encontrada en Internet dio un mensaje de error de salida y la pila. Excepto el método personalizado, por supuesto.
Para TypeScript, estoy usando el siguiente fragmento para evitar escribir advertencias:
...
// standard transports and format initialization
export interface BetterLogger extends winston.Logger {
exception: (error: Error, prefix?: string) => BetterLogger;
}
const logger: BetterLogger = winston.createLogger({
level: config.logLevel,
transports,
}) as BetterLogger;
// Monkey patching Winston because it incorrectly logs `Error` instances even in 2020
// Related issue: https://github.com/winstonjs/winston/issues/1498
logger.exception = function (error, prefix?) {
const message = error.message || error.toString();
const stack = error.stack;
prefix = prefix ? `${prefix} ` : '';
return this.error(`${prefix}${message}, stack ${stack}`) as BetterLogger;
};
export default logger;
Funciona con cualquier otro formateador.
Razón: el intento de implementar el formateador actual siempre termina con falla ya que info
pasó al formateador nunca instanceof Error
.
No puedo registrar ningún error significativo:
import winston from 'winston';
const consoleTransport = new winston.transports.Console({
format: winston.format.combine(
winston.format.errors({ stack: true }),
winston.format.metadata(),
winston.format.json(),
)
});
export const logger = winston.createLogger({
transports: [
consoleTransport,
]
});
Solo registra este bit triste:
{"level":"error","metadata":{}}
simplemente usar simple es casi mejor ya que produce el doble de información:
error: undefined
Lo que necesito:
TypeError: Cannot read property 'check' of undefined
at Object.updateSession (U:\Users\muj\endpoint\src\services\cookieService.ts:88:23)
¿Hay alguna forma de obtener a través de Winston la información que el nodo imprime automáticamente cuando detecta un error no controlado?
¿Alguna actualización?
Me di cuenta de que el motivo es que Object.assign({}, info)
no copia la propiedad de la pila en:
así que básicamente, si quiero el seguimiento de la pila, tengo que
Es 2021 y todavía no funcionó para las instancias de error. Dejé de usar esto.
Esto es un up, ya que creo que esto se debe tener en cuenta.
Actualicé winston de 2 a 3, pero ahora estoy bajando a 2 debido a esto.
@DABH vuelve a abrir este problema
gracias por tu trabajo
Este es un problema muy crítico para nuestra aplicación, usamos winston y cuando ocurren errores, no hay forma de ver la pila sin modificar el .error
Este es un problema muy crítico para nuestra aplicación, usamos winston y cuando ocurren errores, no hay forma de ver la pila sin modificar el
.error
Tengo el mismo problema
¡Hola chicos!
Hice una solución para eso en formato errors
.
https://github.com/winstonjs/logform/pull/118
Comentario más útil
Entonces, resulta que estaba equivocado sobre el formateador de errores. Todavía no está en Winston, pero está en [email protected] , y debe usarlo en combinación con los formateadores
metadata
yjson
.Entonces, sí, muchas advertencias para que funcione. Sería mejor si pudieras usarlo solo, pero es mejor que nada.