Как создать собственный форматировщик json для регистратора winston @ 3?

Я пытаюсь создать собственный форматировщик json для Winston v3.

Вот единственный файл с демонстрацией:

const { createLogger, format, transports } = require("winston")
const { combine, timestamp, prettyPrint } = format

const logger = createLogger({
  format: combine(timestamp(), prettyPrint())
})

logger.add(new transports.Console())

logger.info("test message", { data: { a: 1, b: [1, 2, 3, 4], d: new Date() } })

try {
  throw new Error("I'm an error!")
} catch (err) {
  logger.error(err)
}

Он печатает:

{ data: { a: 1, b: [ 1, 2, 3, 4 ], d: 2018-07-21T08:59:27.958Z },
  level: 'info',
  message: 'test message',
  timestamp: '2018-07-21T08:59:27.959Z',
  [Symbol(level)]: 'info',
  [Symbol(splat)]:
   [ { data: { a: 1, b: [ 1, 2, 3, 4 ], d: 2018-07-21T08:59:27.958Z } } ] }
{ Error: I'm an error!
    at Object.<anonymous> (/Users/max7z/projects/test/t32__test__winston__pretty-print_symbol/index.js:13:9)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
    at startup (internal/bootstrap/node.js:266:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:596:3)
  level: 'error',
  timestamp: '2018-07-21T08:59:27.962Z',
  [Symbol(level)]: 'error' }

Я бы хотел получить почти такой же результат, но без некоторых полей: [Символ (уровень)], [Символ (знак)].

Можно ли удалить поля [Symbol] из prettyPrint форматтера?

Или как я могу создать свой собственный форматировщик json с трассировкой стека ошибок, как у prettyPrint?


person Max Block    schedule 21.07.2018    source источник


Ответы (4)


Я протестировал образец с помощью winston v3.3.3 и добавил настраиваемое средство форматирования для строкового преобразования объекта data:

const winston = require('winston');

const myFormatter = winston.format((info) => {
  const {message} = info;

  if (info.data) {
    info.message = `${message} ${JSON.stringify(info.data)}`;
    delete info.data; // We added `data` to the message so we can delete it
  }
  
  return info;
})();

const logger = winston.createLogger({
  format: winston.format.combine(
    winston.format.timestamp({
      format: 'YYYY-MM-DD HH:mm:ss',
    }),
    myFormatter,
    winston.format.simple(),
  ),
  transports: [
    new winston.transports.Console(),
  ],
});

Я выполнил команды из вопроса и получил желаемый результат.

Выполнение:

logger.info('test message', {data: {a: 1, b: [1, 2, 3, 4], d: new Date()}});

try {
  throw new Error(`I'm an error!`);
} catch (err) {
  logger.error(err);
}

Вывод:

info: тестовое сообщение {a: 1, b: [1,2,3,4], d: 2020-09-09T09: 41: 22.525Z} {timestamp: 2020-09-09 11:41:22}

ошибка: я ошибаюсь! {timestamp: 2020-09-09 11:41:22}

Объект JSON также может быть напечатан с табуляцией и переносом строки при использовании winston.format.prettyPrint() вместо winston.format.simple().

person Benny Neugebauer    schedule 09.09.2020

Узнайте, как создавать собственные форматы. Затем используйте исходный код prettyPrint в качестве основы для создания модифицированная версия, основанная на ваших потребностях.

Winstons использует triple-beam для определений различных Symbol, поэтому вы также можете использовать этот пакет для их удаления. .

person Lucas S.    schedule 21.07.2018
comment
Не могли бы вы привести пример, как удалить поля [Symbol] из prettyPrint вывода? Я прочитал ваши ссылки, но до сих пор не знаю, как это сделать. - person Max Block; 22.07.2018
comment
Вы удаляете эти поля так же, как и любое другое поле с помощью delete. - person Lucas S.; 22.07.2018
comment
Я согласен, @ max7z документы очень запутанные. Я не использую splat, но я продолжаю видеть splat в некоторых вызовах console.debug, и мне кажется, что я не могу добавить поле к выходным данным в нужном мне формате. Эта штука чертовски сбивает с толку из-за того, что она является наиболее часто используемым регистратором :( - person SomethingOn; 18.10.2018

Обратитесь к формату Winston.

require('winston-daily-rotate-file');
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, label, printf, prettyPrint, splat, simple } = format;


const myFormat = printf(info => {
    // you can get splat attribue here as info[Symbol.for("splat")]
    // if you custome splat please rem splat() into createLogger()
    return `${info.timestamp} [${info.label}] ${info.level}: ${info.message}`;
});

const logger = createLogger({
  format: combine(
    label({ label: 'keaz.co' }),
    timestamp(),
    splat(),
    myFormat
  ),
  transports: [
      new transports.Console(),
      new transports.File({
        filename: "info.log",
        level: 'info'
      }),
      new transports.File({
        filename: "error.log",
        level: 'error'
      })
    ]
})

logger.info("test message %o", { data: { a: 1, b: [1, 2, 3, 4], d: new Date() } });

module.exports = logger;
person Tan Nguyen    schedule 15.01.2019

Я столкнулся с подобной проблемой и нашел решение в здесь. Я использую Node.js и Socket.IO, я использовал логгер в Socket.IO. В качестве примера:

Node.js

io.on('connection',function(socket){
  var date = new Date();
  socket.on('',function(data){
    logger.log('info', {IP: ip, Date: date, Path: '', Data: data.req_data});

Winston.js (регистратор)

const app_root = require('app-root-path');
const { createLogger, format, transports } = require('winston');


var logger = createLogger({
  level: 'info',
  format: format.combine(
    format(function(info, opts){
        console.log(`[${info.IP}]-[${info.Date}]-[${info.Path}]-[${info.Data}]`);
        return info;
    })(),
    format.json()

  ),

  transports: [
    new transports.File({filename: `${app_root}/logs/info.log`})
  ]
});

module.exports = logger;

Насколько я понимаю, мы можем использовать случайные переменные (ip, дату, птицу, мяч и т. Д.), Как захотим. Я думаю, что после небольшой договоренности вы можете использовать это и для ошибок. Удачи!

person PhiloSophia    schedule 16.04.2019