Node.js - logging / Gunakan morgan dan winston


99

kami gunakan morganuntuk mencatat transformasi ekspres kami:

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

Juga, kami menggunakan winstonuntuk mencatat logging kami yang lain:

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

Apakah ada cara untuk menggabungkan kedua logger tersebut? situasinya sekarang adalah morganmenulis ke output standar saya, ketika winstonmenulis ke /var/log/log-file.log.

Saya berharap file logger akan digabungkan dari informasi transformasi ekspres, dan dari informasi lain yang saya inginkan ( logger.info()) ..


Apa gunanya melakukan ini, maksud saya, mengapa Anda membutuhkan morgan di awal, mengapa tidak menulis saja winston middlewrare untuk ekspres?
Dimitri Kopriwa

Jawaban:


141

Artikel ini melakukan pekerjaan yang sangat baik untuk apa yang ingin Anda lakukan.

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

Untuk kode spesifik Anda, Anda mungkin memerlukan sesuatu seperti ini:

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

Ini akan mengatur Winston untuk menulis log ke konsol serta file. Kemudian Anda dapat menggunakan ekspresi terakhir untuk meneruskan output dari morgan middleware ke winston.


Bisakah kita menggunakan stempel waktu dalam proses ini?
bombayquant

24
Sepertinya tidak perlu menimpa logger.stream .. Dalam kasus saya, saya bisa melakukannyaapp.use(morgan("combined", { stream: { write: message => logger.info(message) }}));
Devon Sams

17
Jika Anda menggunakan metode @ DevonSams, Anda akan mendapatkan baris kosong di antara baris yang dicatat karena morgan dan winston menambahkan pemutusan baris di akhir pesan yang dicatat. Anda cukup memangkas penggalan baris dari pesan denganlogger.info(message.trim())
Timo

2
Bagaimana jika saya ingin menggunakan logger.error daripada logger.info, jika server merespon dengan 500?
Alendorff

3
Untuk winston: ^3.0.0digunakan winston.createLoggersebagai penggantinew winston.Logger
streof

21

Dalam Ketikan:

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

Mengapa mungil dan tidak digabungkan?
An-droid

Saya tidak bisa membuat ini bekerja lagi. Sepertinya pengetikannya salah. stackoverflow.com/questions/50048193/…
jpetitte

7

Perbarui baris terakhir untuk menghapus peringatan

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

3

untuk Ketikan cara lain untuk melakukannya, tanpa perlu membuat kelas adalah

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

Solusi ini diperoleh dari halaman Github ini https://github.com/winstonjs/winston/issues/1385 . Namun, penting untuk diperhatikan bahwa ada sedikit perbedaan antara kode kami. Dari pada:

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

Saya menggunakan:

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

Ini membantu saya karena saya tidak terlalu suka membuat kelas.


2

Morgan memiliki kebiasaan buruk untuk mengakhiri pesan dengan kata-kata \nuntuk membuat semuanya teratur, Anda mungkin ingin menghapusnya sebelum menulisnya ke winston.

Ini dapat dilakukan dengan berbagai cara seperti pada sisi format di winston, atau dengan memperbarui aliran Anda agar tidak menulis \n

class MyStream {
    write(text: string) {
        logger.info(text.replace(/\n$/, ''));
    }
}
let myStream = new MyStream()
app.use(morgan('tiny', { stream: myStream }));
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.