Отключить ведение журнала Winston при запуске модульных тестов?

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

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

Я использую winston внутри моего модуля, примерно так:

// MyModule.js
var logger = require('winston');
module.exports = function() {
  // does some stuff
  // and logs some stuff like so:
  logger.log('an informational message');
}

// MyModuleTest.js
describe('MyModule', fucntion() {
  it('should do some stuff', function() {
     var myModuleUnderTest = require('MyModule');
     // some tests
  }
}   

person Sk606    schedule 13.07.2016    source источник
comment
stackoverflow.com/questions/22709882/   -  person Vladimir G.    schedule 14.07.2016


Ответы (8)


Транспорты Winston имеют свойство silent, которое вы можете установить, что, вероятно, немного лучше, чем удаление всего транспорта.

Я добавляю названия транспортов, чтобы было немного проще:

var logger = new winston.Logger();

logger.add(winston.transports.Console, {
    name: 'console.info',
    colorize: true,
    showLevel: true,
    formatter: consoleFormatter,
})

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

logger.transports['console.info'].silent = true  // turns off
logger.transports['console.info'].silent = false // logging back on
person Mark    schedule 28.08.2017

Извините, я знаю, что это немного старый вопрос.

То, что я делаю, немного некрасиво, но позволяет мне продолжать использовать параметр Jest --silent в обычном режиме. Я только что установил silent Уинстона на process.argv.indexOf("--silent") >= 0. Например:

const logger = new winston.Logger({
  …,
  transports: [
    new winston.transports.Console({
      …,
      silent: process.argv.indexOf("--silent") >= 0,
    }),
  ],
});
person Rubén Illodo Brea    schedule 13.11.2017
comment
silent: process.env.NODE_ENV === 'testing' тоже вариант - person Palisand; 16.11.2017
comment
Правда. Но тогда вы не можете просто включить или отключить его напрямую с помощью параметра Jest --silent, что меня очень раздражает. - person Rubén Illodo Brea; 17.11.2017
comment
Ах, я должен был сказать, что это будет вариант, только если вы всегда хотите отключить Winston при запуске тестов. - person Palisand; 17.11.2017

Создайте регистратор:

const logger = createLogger({
    level: "info",
    format: format.json(),
    transports: []
});

Отключить все журналы:

logger.transports.forEach((t) => (t.silent = true));
person shusson    schedule 30.05.2018

Если вы используете Jest, вы можете отключить его так:

  1. Установите файлы настройки, которые будут запускаться до того, как jest запустит тест. В 1_:

    {
        "jest": {
            "setupFiles": ["<rootDir>/jest-set-up/index.js"]
        }
    }
    
  2. In jest-set-up/index.js:

    import winston from 'winston'
    winston.remove(winston.transports.Console)
    
person Quan Vuong    schedule 26.02.2017
comment
спасибо за редактирование @Meyer, я попытался использовать 4 пробела, но не уверен, что мой текст не был отформатирован как код - person Quan Vuong; 26.02.2017
comment
Вы знаете, как достичь той же цели с помощью ava? - person aviggiano; 12.06.2017
comment
Я использую ежедневные транспорты Winston, как мне пропустить тестовые случаи для регистрации - person Learner; 31.01.2019
comment
Это здорово! Можете ли вы поделиться каким-либо тестовым файлом? - person TechTurtle; 13.09.2019

Вот моя установка:

const { createLogger, format, transports, config } = require("winston");

let level, silent;
switch (process.env.NODE_ENV) {
  case "production":
    level = "warning";
    silent = false;
    break;
  case "test":
    level = "emerg";
    silent = true;
    break;
  default:
    level = "debug";
    silent = false;
    break;
}

const options = {
  console: {
    level,
    silent,
    handleExceptions: true,
    format: format.combine(
      format.colorize(),
      format.splat(),
      format.printf(
        info => `${new Date().toISOString()} ${info.level}: ${info.message}`,
      ),
    ),
  },
};

const logger = createLogger({
  levels: config.syslog.levels,
  transports: [new transports.Console(options.console)],
  exitOnError: false,
});

module.exports = logger;
person Joel    schedule 19.01.2019
comment
silent - это параметр, который я искал. - person Prabhat Mishra; 13.05.2020

Я понимаю, что это довольно поздно, но я просто хотел поделиться своим решением с помощью jest, так как я не был полностью удовлетворен найденными здесь решениями. Я не могу сказать, что мое решение очень элегантное и может просто скрывать некоторый запах кода, поскольку я все еще изучаю TDD, но оно работает.

В своей работе я часто хочу войти в файл, указанный через winston.transports.File(filename: "<filename>") транспорт. Скажем, мой файл журнала info.log

Конечно, при тестировании я не хочу

  1. журналы, которые будут записаны в этот info.log
  2. info.log будет создан, если он не существует.

Это сделано для того, чтобы избежать побочных эффектов. Ответов выше вместе с издевательством было достаточно, чтобы избежать 1., но по какой-то причине не удалось избежать 2. (почему ниже объясняется).

То, как я настраиваю свои проекты, обычно такое

   src
    ├── app.js
    ├── services
    │   ├── logging
    │   │   ├── logger.js
    │   │   └── logger_utils.js
    │   ├── foo.js
    │   ├── bar.js
    │   └── etc.js
    ├── tests
    │   ├── foo.test.js
    │   ├── bar.test.js
    │   └── etc.test.js
    └── logs
        └── info.log

Сосредоточьтесь в основном на файлах, связанных с журналами. logger.js - это место, где я создаю и затем экспортирую объект Winston Logger. Затем я пишу вспомогательные функции в logger_utils.js для модульности и упрощения тестирования.

Когда появилась моя проблема, logger.js состояла в

problematic_logger.js
const winston = require("winston");
const path = require("path");
// define the log file directory
const log_dir = path.resolve(__dirname, "./../../logs/info.log");
// create logger
const logger = winston.createLogger({
    transports: [
      new winston.transports.File({
        filename: log_dir
      })
    ]
  });
// export it
module.exports = logger;

Затем я потребовал его в logger_utils.js, который, в свою очередь, потребовался бы в сценариях любых других модулей. Итак, при тестировании (помимо тестирования logger_utils.js) мне нужно только имитировать функции, содержащиеся в logger_utils.js, и не нужно беспокоиться о logger.js, поскольку он вызывается только logger_utils.js.

Теперь я не совсем уверен в этом, но я думаю, что 2. определенный выше все еще не удался, несмотря на имитацию и отключение звука, потому что winston.createLogger() все еще вызывается, и я считаю, что это создаст файл, даже если установлен флаг --silent . Я не знаю, правда ли это, но, тем не менее, приведенные выше решения не работали.

Итак, (вдохновленный этим ответом) я решил просто не создавать никаких объектов winston при тестировании . Я сделал это, изменив свой logger.js файл на

fixed_logger.js
const winston = require("winston");
const path = require("path");
// define the log file directory
const log_dir = path.resolve(__dirname, "../../logs/info.log");
// if we are testing, don't create any winston object
if (process.env.NODE_ENV === "test") {
  // export
  module.exports = {};
} else {
  // behave normally otherwise
  // create winston logger
  const logger = winston.createLogger({
    transports: [
      new winston.transports.File({
        filename: log_dir
      })
    ]
  });
  // export it
  module.exports = logger;
}

(NODE_ENV автоматически устанавливается на "тест" при запуске npm test, npm run test:watch и т. Д.)

Нам все еще нужно что-то экспортировать, чтобы logger_utils.js не сломался при тестировании, поэтому мы экспортируем пустой объект. Это нормально, потому что над ним будут издеваться.

В любом случае, это мой первый ответ по поводу stackoverflow. Надеюсь, это было не так уж плохо, дайте мне знать, если кому-то нужны дополнительные подробности.

person thesofakillers    schedule 03.10.2019

мы использовали в тестах свойство silent:

import logger from './my-defined-winston-logger'


//...
beforeAll(() => {
  logger.silent = true;
})
afterAll(() => {
  logger.silent = false;
})
person ya_dimon    schedule 22.04.2021

У меня ничего не получилось, я использую winston v3.1.0, есть новый способ создания логгеров.

С сайта Winston: https://github.com/winstonjs/winston

Рекомендуемый способ использования winston - создать собственный регистратор. Самый простой способ сделать это - использовать winston.createLogger:

const logger = winston.createLogger({
    level: 'info',
    format: winston.format.json(),
    transports: [
      //
      // - Write to all logs with level `info` and below to `combined.log` 
      // - Write all logs error (and below) to `error.log`.
      //
      new winston.transports.File({ filename: 'error.log', level: 'error' }),
      new winston.transports.File({ filename: 'combined.log' })
    ]
  });

  //
  // If we're not in production then log to the `console` with the format:
  // `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
  // 
  if (process.env.NODE_ENV !== 'production') {
    logger.add(new winston.transports.Console({
    format: winston.format.simple()
  }));
}

Итак, я делаю это в своем logger.js

if (process.env.NODE_ENV === 'test') {
    return winston.createLogger({
      transports: [ new winston.transports.Console({ level: 'error'}) ]
    });
}

Это останавливает все сообщения журнала, если у вас нет ошибки, которую я хотел бы увидеть, чтобы помочь с отладкой любых проблем.

Надеюсь это поможет.

person englishPete    schedule 02.11.2018