Winston: Метод регистрации ошибок неправильно регистрирует экземпляр ошибки

Созданный на 9 окт. 2018  ·  29Комментарии  ·  Источник: winstonjs/winston

Расскажите, пожалуйста, о вашей среде:

  • _ Версия winston ?_ 3.1.0

    • [ ] winston@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);
}

Что вы ожидаете вместо этого?

Зарегистрировано хотя бы фактическое сообщение об ошибке. В идеале - со стеком.

Самый полезный комментарий

Итак, оказывается, я был неправ насчет форматирования ошибок. Его еще нет в 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));

Все 29 Комментарий

Это не зависит от форматтера 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 по умолчанию есть обработчик ошибок, поэтому его просто нужно прикрепить как форматтер.

https://github.com/winstonjs/logform#errors

Пример?

Итак, оказывается, я был неправ насчет форматирования ошибок. Его еще нет в 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) не копирует свойство стека по адресу:

https://github.com/shrinktofit/editor-3d/blob/5afb36943c4f4fd9a145d82cd4bd44cd6b188242/app/node_modules/winston-transport/index.js#L91

так что в основном, если я хочу трассировку стека, я должен либо

  1. использовать средство форматирования ошибок с форматированием json и meta и получить журнал форматирования json
  2. или реализовать мой собственный форматировщик, чтобы дать мне простой вывод текстового журнала
    Я прав или я что-то пропустил ??

На дворе 2021 год, а для экземпляров Error все еще не работает. Я перестал использовать это.

Это повышение, так как я думаю, что это следует учитывать.
Я обновил winston с 2 до 3, но теперь из-за этого понижаю до 2.
Пожалуйста , @DABH повторно откройте этот вопрос
Хотя спасибо за вашу работу

Это очень критическая проблема для нашего приложения, мы используем Winston, и когда возникают ошибки, нет возможности увидеть стек, не возясь с .error

Это очень критическая проблема для нашего приложения, мы используем Winston, и когда возникают ошибки, нет возможности увидеть стек, не возясь с .error

У меня точно такая же проблема

Привет, ребята!
Я сделал исправление для этого в формате errors .
https://github.com/winstonjs/logform/pull/118

Была ли эта страница полезной?
0 / 5 - 0 рейтинги