Node.js - logowanie / Użyj morgan i winston


102

używamy morgando rejestrowania naszej ekspresowej transformacji:

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;
})

Ponadto używamy winstondo rejestrowania innych danych logowania:

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' })
  ]
});

Czy jest jakiś sposób na połączenie dwóch rejestratorów razem? sytuacja jest taka, że morganjest to zapis na moje standardowe wyjście, kiedy winstonzapisuje do /var/log/log-file.log.

Chciałbym, aby plik loggera łączył się z informacjami o ekspresowej transformacji i innymi informacjami, które chcę ( logger.info()) ..


Jaki jest sens robienia tego, mam na myśli, dlaczego na początku potrzebowałeś morgana, dlaczego nie napisać po prostu winstona middlewrare na ekspres?
Dimitri Kopriwa

Odpowiedzi:


142

Ten artykuł świetnie radzi sobie z tym, co chcesz zrobić.

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

Do konkretnego kodu prawdopodobnie potrzebujesz czegoś takiego:

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 }));

Spowoduje to skonfigurowanie Winstona do zapisywania dziennika w konsoli, a także pliku. Następnie możesz użyć ostatniego wyrażenia, aby przekazać dane wyjściowe z oprogramowania pośredniczącego Morgana do programu Winston.


Czy w tym procesie możemy użyć sygnatury czasowej?
bombayquant

25
Wydaje się, że nie ma potrzeby nadpisywania logger.stream .. W moim przypadku udało mi się to zrobićapp.use(morgan("combined", { stream: { write: message => logger.info(message) }}));
Devon Sams

19
Jeśli używasz metody @ DevonSams, otrzymasz pusty wiersz między zarejestrowanymi wierszami, ponieważ zarówno morgan, jak i winston dodają podział wiersza na końcu zarejestrowanej wiadomości. Możesz po prostu odciąć wyjście z wiadomości za pomocąlogger.info(message.trim())
Timo

2
Co jeśli chcę użyć logger.error zamiast logger.info, jeśli serwer odpowie 500?
Alendorff

3
Do winston: ^3.0.0użytku winston.createLoggerzamiastnew winston.Logger
streof

21

W maszynie:

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 }));

Dlaczego małe i nie połączone?
An-droid

Nie mogłem już sprawić, żeby to działało. Wygląda na to, że typy są nieprawidłowe. stackoverflow.com/questions/50048193/…
jpetitte

7

Zaktualizuj ostatnią linię, aby usunąć ostrzeżenie

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

3

dla Typescript innym sposobem na to, bez konieczności tworzenia klasy, jest

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 }));

To rozwiązanie pochodzi z tej strony Github https://github.com/winstonjs/winston/issues/1385 . Należy jednak pamiętać, że istnieje niewielka różnica między naszymi kodami. Zamiast:

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

Używam:

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

Pomogło mi to, ponieważ nie jestem zbyt duży w tworzeniu zajęć.


2

Morgan ma zły zwyczaj kończenia wiadomości rozszerzeniem \n więc aby wszystko było uporządkowane, możesz zechcieć to usunąć przed napisaniem do winston.

Można to zrobić na wiele różnych sposobów, na przykład po stronie formatu w winston lub aktualizując strumień, aby nie zapisywał pliku \n

class MyStream {
    write(text: string) {
        logger.info(text.replace(/\n$/, ''));
    }
}
let myStream = new MyStream()
app.use(morgan('tiny', { stream: myStream }));
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.