Добавить имя модуля в записи журнала winston

Есть ли возможность сохранить текущее имя модуля, чтобы оно автоматически печаталось в записях журнала winston при они называются позже?

В настоящее время, когда я хочу напечатать имя модуля в журналах, мне нужно добавить его вручную:

var logHeader = 'mymodule'

log.info(logHeader + 'Hello')

Например, с помощью debug вы можете сделать (пока игнорируйте функцию формата журнала %s):

var debug = require('debug')('http')
  , name = 'My App'

debug('booting %s', name);

Это напечатает префикс http перед журналом:

http загрузка моего приложения

Можно ли это сделать в винстоне? Я искал в документации, но я не мог найти ничего подходящего.


person Alexandru Irimiea    schedule 17.03.2017    source источник


Ответы (4)


Я нашел лучший способ сделать это.

Я добавил дополнительный слой поверх регистратора winston, в данном случае функцию, которая сохраняет имя модуля для каждого модуля, которому требуется регистратор. Таким образом, когда модуль require использует мой новый регистратор, он фактически вызывает экспортированную функцию с именем модуля, в данном случае __filename.

log.js

var winston = require('winston')

var winstonLogger = new (winston.Logger)({
    transports: [
        new (winston.transports.File) ({
            filename: 'MyLogs.txt',
            handleExceptions: true,
            humanReadableUnhandledException: true,
            level: 'info',
            timestamp: true,
            json: false
        }),
        new (winston.transports.Console) ({
            level: 'info',
            prettyPrint: true,
            colorize: true,
            timestamp: true
        })
    ]
})

module.exports = function(fileName) {    
    var myLogger = {
        error: function(text) {
            winstonLogger.error(fileName + ': ' + text)
        },
        info: function(text) {
            winstonLogger.info(fileName + ': ' + text)
        }
    }

    return myLogger
}

модуль1.js

var log = require('log')(__filename)

log.info('Info log example')

информация: C:\Users\user1\project\module1.js: пример информационного журнала

модуль2.js

var log = require('log')(__filename)

log.error('Error log example')

ошибка: C:\Users\user1\project\module2.js: пример журнала ошибок

Кроме того, таким образом мне не нужно было нигде менять способ отправки текстового журнала; log.info('text') остается точно таким же, как раньше.

person Alexandru Irimiea    schedule 23.03.2017
comment
Спасибо. Я подумал об этом решении и попытался выяснить, сделал ли это кто-нибудь еще, и ваше решение намного лучше, чем то, что я думал. - person refaelio; 02.04.2018

Для этого и нужны дочерние регистраторы. Они могли быть недоступны, когда был задан этот вопрос, но для дальнейшего использования вы можете создать свой основной экземпляр регистратора, а затем экспортировать функцию, которая создает дочерний регистратор с некоторыми параметрами по умолчанию.

// logging.js
const winston = require('winston') 

const logger = winston.createLogger({
  transports: [
    new winston.transports.Console({
      format: winston.format.printf(options => {
        // you can pass any custom variable in options by calling
        // logger.log({level: 'debug', message: 'hi', moduleName: 'my_module' })
        return `[${options.moduleName}] ${options.level}: ${options.message}$`;
      })
    })
  ]
});

module.exports = function(name) {
  // set the default moduleName of the child
  return logger.child({moduleName: name});
}

Затем в верхней части каждого модуля импортируйте дочерний элемент, используя:

// my_module.js
const logger = require('./logging.js')('my_module_name');

logger.error('computer says no');
// output:
// [my_module_name] error: computer says no
person Papooch    schedule 11.01.2021

Вы можете указать пользовательский формат журнала с помощью Winston-

var moduleName = 'myModule';

var logger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)({
      formatter: function(options) {
        // Return string will be passed to logger. 
        return moduleName + ' - ' + (options.message ? options.message : '')
      }
    })
  ]
});


logger.info('This is a log message');

Это напечатает -

myModule - This is a log message

Таким образом, имя вашего модуля будет добавлено к каждому сообщению журнала.

person Jyotman Singh    schedule 17.03.2017
comment
Если я правильно понимаю, это добавит строку ко всем сообщениям журнала. Я спрашиваю о добавлении имени модуля для регистрации сообщений из этого модуля. - person Alexandru Irimiea; 17.03.2017
comment
Да, поэтому вам нужно будет создать уникальный регистратор для каждого из ваших модулей, подобно тому, как вы делаете это для модуля debug. - person Jyotman Singh; 17.03.2017
comment
Создание регистратора для каждого из модулей никогда не было хорошей идеей. Скорее 1-й ответ лучше. - person Shobhit Mishra; 03.12.2018

В winston v3.3.3 это можно сделать с помощью winston.format.label и настройки winston.format.printf:

const winston = require('winston');

const logger = winston.createLogger({
  format: winston.format.combine(
    winston.format.label({label: 'mymodule'}),
    winston.format.printf(({label, message}) => {
      return `${label}: ${message}`;
    })
  ),
  transports: [
    new winston.transports.Console(),
  ],
});

logger.info('Hello, World!'); // prints "mymodule: Hello, World!"
person Benny Neugebauer    schedule 13.09.2020