winston
?_ 3.1.0winston@2
winston@3
_ node -v
выходы:_ v8.11.3
_Операционная система?_ Linux
logger.error
, вызванный с экземпляром Error
, не использует поля message
и stack
, вместо этого регистрирует test error
.
Пример кода:
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);
}
Зарегистрировано хотя бы фактическое сообщение об ошибке. В идеале - со стеком.
Это не зависит от форматтера printf
, simple
дает тот же результат. Событие без форматера возвращает пустое сообщение.
Вероятно, связанная проблема № 1422
Была такая же проблема, мне пришлось самому реализовать logger.error
:
logger.error = err => {
if (err instanceof Error) {
logger.log({ level: 'error', message: `${err.stack || err}` });
} else {
logger.log({ level: 'error', message: err });
}
};
@gtsec на самом деле я сделал почти то же самое, просто использовал новое имя метода .exception
.
Это может быть вызвано wintson-transport
, см. https://github.com/winstonjs/winston-transport/issues/31 для проблемы и https://github.com/winstonjs/winston-transport/pull/ 34 для ПР.
В примере репозитория , где я тестирую перенос winston-graylog2
на использование winston@3x
, я реализовал преобразование ошибок в качестве пользовательского средства форматирования.
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;
});
Однако для согласованности было бы полезно, если бы эта обработка выполнялась внутри метода ошибки регистратора, а не полагалась на пользовательские средства форматирования (несовместимые от проекта к проекту) или повторно реализовывала/переписывала методы библиотеки (супер небезопасные и хакерские ).
Собственно, я только сейчас заметил, что у объекта формата winston по умолчанию есть обработчик ошибок, поэтому его просто нужно прикрепить как форматтер.
Пример?
Итак, оказывается, я был неправ насчет форматирования ошибок. Его еще нет в Winston, но он есть в [email protected] , и вы должны использовать его в сочетании с форматировщиками metadata
и json
.
Так что, да, много предостережений, чтобы заставить его работать. Было бы лучше, если бы вы могли просто использовать его отдельно, но это лучше, чем ничего.
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));
Изящный обходной путь @jeremy-j-ackso
Предлагаю закрыть это из-за # 1576.
Можно использовать форматтеры.
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'));
Да, ошибки наконец-то должны быть хорошо зарегистрированы для людей, которые хотят включить эту функцию!
Хотя этот подход в основном работает, похоже, он не обеспечивает простого способа регистрации ошибок в текстовом формате, таком как simple(). Это кажется очень распространенным вариантом использования, и было бы замечательно, если бы существовал стандартный, простой и самоуверенный способ сделать это.
Я ценю стремление к единому формату, который подходит всем, делай все для меня, сделай это волшебным, не заставляй меня думать. В эту ловушку легко попасть, поэтому winston@2 и предыдущие выпуски имели такую ужасную производительность по сравнению с другими библиотеками протоколирования. Он просто пытался сделать слишком много по умолчанию, чтобы удовлетворить потребности большого количества пользователей с разными мнениями и вкусами.
Как проект winston@3 воплощает новое мнение: перевести сложное форматирование в несвязанные одноцелевые форматы и сделать их объединение простым для пользователей.
Я признаю, что еще предстоит проделать работу над документацией, наряду с высокоуровневыми объяснениями и отладкой форматов.
Все сказанное о предложенном формате ошибок отражает мнение проекта: можно ли это реализовать как пользовательский формат?
@DABH , почему ты закрыл этот вопрос? Использование средства форматирования, предложенного @jeremy-j-ackso, не работает без средства форматирования format.json()
. Это даже не обходной путь.
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"
Проверено на [email protected]
.
Да, я согласен с @nosuchip - не похоже, что есть хорошее решение, если вы хотите использовать формат simple()
. На самом деле нам нужны оба для работы в проекте, который у меня есть. Я закончил тем, что создал собственный форматтер, который работает, но немного взломан. Этот код дает мне стек в json при использовании этого формата и стек в необработанном тексте при использовании простого формата:
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
})
Так есть _все еще_ не решение этой проблемы?
@cogscape, к сожалению, нет. Только что протестировал последнюю версию Winston, и ни одно решение, найденное в Интернете, не дало выходного сообщения об ошибке и стека. Кроме пользовательского метода, конечно.
Для TypeScript я использую следующий фрагмент, чтобы избежать ввода предупреждений:
...
// 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;
Он работает с любыми другими форматтерами.
Причина: попытка внедрить текущий форматер всегда завершается ошибкой, так как info
передается форматтеру никогда не instanceof Error
.
Я не могу зарегистрировать какую-либо значимую ошибку:
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,
]
});
Он регистрирует только этот грустный бит:
{"level":"error","metadata":{}}
просто использовать simple почти лучше, так как он дает двойную информацию:
error: undefined
Что мне нужно:
TypeError: Cannot read property 'check' of undefined
at Object.updateSession (U:\Users\muj\endpoint\src\services\cookieService.ts:88:23)
Есть ли способ получить через winston информацию, которую узел печатает автоматически, когда обнаруживает необработанную ошибку?
Любые обновления?
Я заметил, что причина в том, что Object.assign({}, info)
не копирует свойство стека по адресу:
так что в основном, если я хочу трассировку стека, я должен либо
На дворе 2021 год, а для экземпляров Error все еще не работает. Я перестал использовать это.
Это повышение, так как я думаю, что это следует учитывать.
Я обновил winston с 2 до 3, но теперь из-за этого понижаю до 2.
Пожалуйста , @DABH повторно откройте этот вопрос
Хотя спасибо за вашу работу
Это очень критическая проблема для нашего приложения, мы используем Winston, и когда возникают ошибки, нет возможности увидеть стек, не возясь с .error
Это очень критическая проблема для нашего приложения, мы используем Winston, и когда возникают ошибки, нет возможности увидеть стек, не возясь с
.error
У меня точно такая же проблема
Привет, ребята!
Я сделал исправление для этого в формате errors
.
https://github.com/winstonjs/logform/pull/118
Самый полезный комментарий
Итак, оказывается, я был неправ насчет форматирования ошибок. Его еще нет в Winston, но он есть в [email protected] , и вы должны использовать его в сочетании с форматировщиками
metadata
иjson
.Так что, да, много предостережений, чтобы заставить его работать. Было бы лучше, если бы вы могли просто использовать его отдельно, но это лучше, чем ничего.