Node.js - Journalisation / Utilisation de Morgan et Winston

99

nous utilisons morganpour enregistrer notre transformation express:

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

En outre, nous utilisons winstonpour enregistrer nos autres journaux:

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

Existe-t-il un moyen de combiner les deux enregistreurs ensemble? la situation est maintenant d' morganécrire sur ma sortie standard, lors de l' winstonécriture dans /var/log/log-file.log.

Je souhaite que le fichier logger se combine à partir des informations de transformation express et des autres informations que je veux ( logger.info()) ..

Ou Smith
la source
Quel est l'intérêt de faire ça, je veux dire, pourquoi avez-vous besoin de Morgan au début, pourquoi ne pas simplement écrire un middlewrare winston pour express?
Dimitri Kopriwa le

Réponses:

141

Cet article fait un excellent travail pour ce que vous voulez faire.

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

Pour votre code spécifique, vous avez probablement besoin de quelque chose comme ceci:

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

Cela configurera Winston pour écrire un journal sur la console ainsi qu'un fichier. Ensuite, vous pouvez utiliser la dernière expression pour transmettre la sortie du middleware morgan à winston.

lindsaymacvean
la source
Pouvons-nous utiliser un horodatage dans ce processus?
bombayquant
23
Il ne semble pas nécessaire de remplacer logger.stream .. Dans mon cas, j'ai pu le faireapp.use(morgan("combined", { stream: { write: message => logger.info(message) }}));
Devon Sams
17
Si vous utilisez la méthode de @ DevonSams, vous obtiendrez une ligne vide entre les lignes journalisées car morgan et winston ajoutent un saut de ligne à la fin du message journalisé. Vous pouvez simplement couper le saut de ligne du message aveclogger.info(message.trim())
Timo
2
Que faire si je veux utiliser logger.error au lieu de logger.info, si le serveur répond avec 500?
Alendorff
3
A winston: ^3.0.0utiliser à la winston.createLoggerplace denew winston.Logger
streof
21

En texte manuscrit:

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 }));
Mahyar SEPEHR
la source
Pourquoi minuscule et non combiné?
An-droid
Je n'étais plus capable de faire fonctionner ça. Il semble que la saisie soit incorrecte. stackoverflow.com/questions/50048193/…
jpetitte
7

Mettez à jour la dernière ligne pour supprimer l'avertissement

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

pour Typescript, une autre façon de procéder, sans avoir besoin de créer une classe est

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

Cette solution a été dérivée de cette page Github https://github.com/winstonjs/winston/issues/1385 . Cependant, il est important de noter qu'il existe une légère différence entre nos codes. Au lieu de:

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

J'utilise:

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

Cela m'a aidé car je ne suis pas trop gros dans la création de classes.

Cris Shaki
la source
1

Morgan a la mauvaise habitude de terminer le message avec un \nafin de mettre les choses en ordre, vous voudrez peut-être le supprimer avant de l'écrire dans winston.

Cela peut être fait de différentes manières, comme du côté du format dans winston, ou en mettant à jour votre flux pour ne pas écrire le \n

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