Node.js - การบันทึก / ใช้มอร์แกนและวินสตัน


103

เราใช้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()) ..


ฉันหมายถึงอะไรทำไมคุณถึงต้องการมอร์แกนในการขอทานทำไมไม่เพียงแค่เขียนเครื่องหมายกลางของวินสตันสำหรับการแสดง
Dimitri Kopriwa

คำตอบ:


144

บทความนี้ทำงานได้อย่างยอดเยี่ยมสำหรับสิ่งที่คุณต้องการทำ

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 เขียนบันทึกลงในคอนโซลเช่นเดียวกับไฟล์ จากนั้นคุณสามารถใช้นิพจน์สุดท้ายเพื่อส่งเอาต์พุตจากมิดเดิลแวร์ของมอร์แกนไปยังวินสตัน


เราสามารถใช้การประทับเวลาในกระบวนการนี้ได้หรือไม่
bombayquant

26
ดูเหมือนว่าจะไม่จำเป็นต้องแทนที่ logger.stream .. ในกรณีของฉันฉันทำได้app.use(morgan("combined", { stream: { write: message => logger.info(message) }}));
Devon Sams

20
หากคุณใช้วิธีของ @ DevonSams คุณจะได้รับบรรทัดว่างระหว่างบรรทัดที่บันทึกเนื่องจากทั้ง morgan และ winston กำลังเพิ่ม linebreak ในส่วนท้ายของข้อความที่บันทึก คุณสามารถตัดเส้นแบ่งออกจากข้อความด้วยlogger.info(message.trim())
Timo

3
จะเป็นอย่างไรถ้าฉันต้องการใช้ logger.error แทน logger.info หากเซิร์ฟเวอร์ตอบสนองด้วย 500
Alendorff

4
เพื่อwinston: ^3.0.0ใช้winston.createLoggerแทนnew winston.Logger
streof

21

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

ทำไมเล็กและไม่รวมกัน?
An-droid

ฉันไม่สามารถทำให้มันทำงานได้อีกต่อไป ดูเหมือนว่าการพิมพ์จะไม่ถูกต้อง stackoverflow.com/questions/50048193/…
jpetitte


3

สำหรับ 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 }));

การแก้ปัญหานี้ได้รับการ hived จากหน้านี้ Github https://github.com/winstonjs/winston/issues/1385 อย่างไรก็ตามโปรดทราบว่ามีความแตกต่างเล็กน้อยระหว่างรหัสของเรา แทน:

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

ฉันใช้:

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

สิ่งนี้ช่วยฉันได้เนื่องจากการสร้างชั้นเรียนไม่ใหญ่เกินไป


3

มอร์แกนมีนิสัยไม่ดีในการลงท้ายข้อความด้วยไฟล์ \nนี้เพื่อทำให้สิ่งต่างๆเป็นระเบียบคุณอาจต้องการลบสิ่งนั้นออกก่อนที่จะเขียนถึงวินสตัน

ซึ่งสามารถทำได้หลายวิธีเช่นในด้านรูปแบบใน winston หรือโดยการอัปเดตสตรีมของคุณไม่ให้เขียน \n

class MyStream {
    write(text: string) {
        logger.info(text.replace(/\n$/, ''));
    }
}
let myStream = new MyStream()
app.use(morgan('tiny', { stream: myStream }));
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.