Node.js - регистрация/использование morgan и winston

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

var morgan  = require('morgan');
morgan('combined');
// a format string
morgan(':remote-addr :method :url :uuid');
// a custom function
morgan(function (req, res) {
  return req.method + ' ' + req.url + ' ' + req.uuid;
})

Кроме того, мы используем winston для регистрации других наших журналов:

var winston = require('winston');
var logger = new (winston.Logger)({
  transports: [
         new (winston.transports.Console)({ level: 'info' }),
          new (winston.transports.File)({ filename: '/var/log/log-file.log' })
  ]
});

Есть ли способ объединить два регистратора вместе? Ситуация теперь такова, что morgan записывает в мой стандартный вывод, когда winston пишет в /var/log/log-file.log.

Я хотел бы, чтобы файл регистратора был объединен из информации экспресс-преобразования и из другой информации, которую я хочу (logger.info())..

Ответ 1

Эта статья отлично подходит для того, что вы хотите сделать.

http://tostring.it/2014/06/23/advanced-logging-with-nodejs/

Для вашего конкретного кода вам, вероятно, понадобится что-то вроде этого:

var logger = new winston.Logger({
    transports: [
        new winston.transports.File({
            level: 'info',
            filename: './logs/all-logs.log',
            handleExceptions: true,
            json: true,
            maxsize: 5242880, //5MB
            maxFiles: 5,
            colorize: false
        }),
        new winston.transports.Console({
            level: 'debug',
            handleExceptions: true,
            json: false,
            colorize: true
        })
    ],
    exitOnError: false
}),

logger.stream = {
    write: function(message, encoding){
        logger.info(message);
    }
};

app.use(require("morgan")("combined", { "stream": logger.stream }));

Это установит Winston для записи журнала на консоль, а также в файл. Затем вы можете использовать последнее выражение для передачи вывода из промежуточного программного обеспечения morgan в winston.

Ответ 2

В Typescript:

let logger = new (winston.Logger)({
    exitOnError: false,
    level: 'info',
    transports: [
        new (winston.transports.Console)(),
        new (winston.transports.File)({ filename: 'app.log'})
    ]
})

class MyStream {
    write(text: string) {
        logger.info(text)
    }
}
let myStream = new MyStream()
app.use(morgan('tiny', { stream: myStream }));

Ответ 3

Обновить последнюю строку для удаления предупреждения

app.use(require("morgan")("combined", { stream: logger.stream }));

Ответ 4

У Моргана плохая привычка заканчивать сообщение \n поэтому, чтобы упорядочить ситуацию, вы можете захотеть удалить это, прежде чем писать его Уинстону.

Это можно сделать разными способами, например, на стороне формата в winston, или обновив ваш поток, чтобы не записывать \n

class MyStream {
    write(text: string) {
        logger.info(text.replace(/\n$/, '');
    }
}
let myStream = new MyStream()
app.use(morgan('tiny', { stream: myStream }));

Ответ 5

для Typescript еще один способ сделать это без необходимости создавать класс

let logger = new (winston.Logger)({
    exitOnError: false,
    level: 'info',
    transports: [
        new (winston.transports.Console)(),
        new (winston.transports.File)({ filename: 'app.log'})
    ]
})

const myStream = {
    write: (text: string) => {
        logger.info(text)
    }
}

app.use(morgan('combined', { stream: myStream }));

Это решение было найдено на этой странице Github https://github.com/winstonjs/winston/issues/1385. Однако важно отметить, что между нашими кодами есть небольшая разница. Вместо:

app.use(morgan('combined', { myStream }));

Я использую:

app.use(morgan('combined', { stream: myStream }));

Это помогло мне, так как я не слишком хорош в создании классов.