web-dev-qa-db-fra.com

Comment êtes-vous censé créer le flux de journalisation Winston pour Morgan dans TypeScript

Quelle est la bonne façon de créer un journal Winston dans TypeScript qui enregistre la journalisation du middleware express Morgan? J'ai trouvé un certain nombre d'échantillons de JavaScript, mais j'ai eu du mal à les convertir en TypeScript, car je reçois une erreur Type '{ write: (message: string, encoding: any) => {}; logger: any; }' is not assignable to type '(options?: any) => ReadableStream'. Object literal may only specify known properties, and 'write' does not exist in type '(options?: any) => ReadableStream'..

Voici mon code:

import { Logger, transports } from 'winston';

// http://tostring.it/2014/06/23/advanced-logging-with-nodejs/
// https://www.loggly.com/ultimate-guide/node-logging-basics/

const logger = new Logger({
    transports: [
        new (transports.Console)({
            level: process.env.NODE_ENV === 'production' ? 'error' : 'debug',
            handleExceptions: true,
            json: false,
            colorize: true
        }),
        new (transports.File)({
            filename: 'debug.log', level: 'info',
            handleExceptions: true,
            json: true,
            colorize: false
        })
    ],
    exitOnError: false,
});



if (process.env.NODE_ENV !== 'production') {
    logger.debug('Logging initialized at debug level');
}



// [ts]
// Type '{ write: (message: string, encoding: any) => {}; logger: any; }' is not assignable to type '(options?: any) => ReadableStream'.
//   Object literal may only specify known properties, and 'write' does not exist in type '(options?: any) => ReadableStream'.
logger.stream = {
    write: function (message: string, encoding: any) {
        logger.info(message);
    };
}


export default logger;

J'ai pu contourner ce problème en ajustant mon code afin qu'il utilise const winston = require('winston');, mais j'aimerais savoir comment vous êtes censé le faire en maintenant des types?

5
JoAMoS

Finalement, j'ai fini avec cela comme une solution. J'ai créé une classe avec une méthode appelée write

export class LoggerStream {
    write(message: string) {
        logger.info(message.substring(0, message.lastIndexOf('\n')));
    }
}

puis, lors de l'ajout à Express, j'ai créé une instance de la classe:

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

Cela fonctionne bien pour ma situation

1
JoAMoS

Merci à @estus qui m'a passé où j'ai été suspendu. Voici la solution que j'ai finalement utilisée:

import { Logger, transports } from 'winston';
import stream from 'stream';
import split from 'split';

// http://tostring.it/2014/06/23/advanced-logging-with-nodejs/
// https://www.loggly.com/ultimate-guide/node-logging-basics/

const logger = new Logger({
    transports: [
        new (transports.Console)({
            level: process.env.NODE_ENV === 'production' ? 'error' : 'debug',
            handleExceptions: true,
            json: false,
            colorize: true
        }),
        new (transports.File)({
            filename: 'debug.log', level: 'info',
            handleExceptions: true,
            json: true,
            colorize: false
        })
    ],
    exitOnError: false,
});

if (process.env.NODE_ENV !== 'production') {
    logger.debug('Logging initialized at debug level');
}

logger.stream = split().on('data', function (message: string) {
    logger.info(message);
});

export default logger;

Finalement, cette question m’a amené à la solution finale - https://github.com/expressjs/morgan/issues/70

3
JoAMoS

stream est supposé être une fonction d'usine qui renvoie un flux, pas un flux lui-même.

Un flux est censé être un véritable flux lisible et non un objet qui l'imite.

Puisqu'il est supposé être accessible en écriture, il devrait s'agir d'un duplex:

logger.stream = (options?: any) => new stream.Duplex({
    write: function (message: string, encoding: any) {
        logger.info(message);
    }
});

C’est une solution suggérée par les types Winston TS. Je ne peux pas confirmer si cela fonctionne correctement.

3
estus