6
votes

Comment faire fonctionner la bibliothèque de journalisation `winston` comme` console.log`?

La bibliothèque winston est idéale pour les transports et la flexibilité. Je voudrais l'utiliser pour permettre la configuration des niveaux et la redirection vers des fichiers, mais je voudrais reproduire le comportement de console.log pour le formatage et les problèmes.

Voici ce que j'ai jusqu'à présent:

log.info("Hello", "Bob");
log.info("Hello", 123, {someObj: 1});

Mais cela ne fonctionne pas:

const log = winston.createLogger({
  level: 'debug',
  format: format.combine(
    format.timestamp({format: 'YYYY-MM-DD HH:mm:ss.SSS'}),
    format.splat(),
    format.colorize(),
    format.printf(({level, message, label, timestamp}) => `${timestamp} ${label || '-'} ${level}: ${message}`),
  ),
  transports: [
    new winston.transports.Stream({
      stream: process.stderr,
      level: 'debug',
    })
  ],
});

log.info("Hello, %s", "Bob");   // Works: outputs "Hello, Bob"

Je voudrais tous les objets superflus après ceux repris par splat () code > pour être ajouté, séparé par des espaces et converti en chaîne de préférence en utilisant util.inspect().


3 commentaires

Vous avez besoin d'un autre transport pour console const console = new winston.transports.Console (); Consultez la documentation. Le seul problème auquel j'ai été confronté était que stack trace était formaté en chaîne, donc pas joliment sur le terminal


Ma question porte sur le formatage des arguments supplémentaires, pas sur les transports.


@ DS.Je suis dans le même bateau. avez-vous déjà trouvé une solution? cette bibliothèque était bonne. modifier, je viens de le comprendre. donc je vais laisser ma solution pour tout le monde ici.


3 Réponses :


3
votes

J'ai eu un problème similaire, et après de nombreux essais et erreurs, je pense avoir une solution qui pourrait vous intéresser. Comme je l'ai mentionné dans ma dernière mise à jour, nous avons fini par construire notre propre enregistreur. Eh bien, au cours du week-end, j'ai publié cet enregistreur sur npm, et vous êtes invités à le vérifier.

Il devrait avoir une sortie plus ou moins identique à console.log . Si vous remarquez des incohérences, veuillez me le faire savoir.

Aussi a également plusieurs transports, et vous pouvez même en transmettre des personnalisés, et vous pouvez même «envelopper» les fonctions de la console pour les intégrer rapidement dans votre projet.

exemple de code:

const {createLogger,wrapConsole,unwrapConsole} = require('@r3wt/log');
const log = createLogger({log_level:'info',transports:['console','file']});
wrapConsole(log);//wraps the console globally with the log instance, making integration into large existing project less painful

// NOTE: only the following 4 functions are wrapped. 
console.log('hi!');
console.warn('warning');
console.error('error');
console.info('info');

unwrapConsole();//unwrap console globally


5 commentaires

Quand j'essaye votre code exact avec les deux lignes de mon exemple, le résultat que j'obtiens est: info: Hello {"0": "B", "1": "o", "2": "b" } et info: Bonjour {"someObj": 1} qui est assez médiocre (pas vraiment d'imprimer la chaîne, en omettant entièrement le nombre). C'est winston 3.2.1.


@DS. comment appelez-vous, pouvez-vous me donner un exemple? J'ai également mis à jour le message avec la solution finale que j'utilise dans mon projet


Je pense que vous avez peut-être mal compris ma question, qui portait sur des appels comme log.info ('application s'exécutant sur le port', 3000) (notez l'absence de "% d"), qui fonctionne avec console.log et avec les anciens winston, mais pas avec les nouveaux formateurs winston.


@DS. ma faute. Honnêtement, nous avons fini par nous éloigner de winston et juste écrire notre propre enregistreur. Désolé, je n'ai pas pu vous aider.


@DS. J'en ai fait une autre tentative et j'ai publié mon travail sur NPM. s'il vous plaît laissez-moi savoir si la sortie et les fonctionnalités répondent à vos besoins.



13
votes

Répondre à ma propre question. Le problème vient du format.splat - pur util.format offre un comportement plus simple et plus attendu. Le remplacement de format.splat par ce utilFormatter résout le problème:

const log = winston.createLogger({
  level: 'debug',
  format: format.combine(
    format.timestamp({format: 'YYYY-MM-DD HH:mm:ss.SSS'}),
    utilFormatter(),     // <-- this is what changed
    format.colorize(),
    format.printf(({level, message, label, timestamp}) => `${timestamp} ${label || '-'} ${level}: ${message}`),
  ),
  transports: [
    new winston.transports.Stream({
      stream: process.stderr,
      level: 'debug',
    })
  ],
});

log.info("Hello, %s", "Bob");          // Works: outputs "Hello, Bob"
log.info("Hello", "Bob");              // Works: outputs "Hello Bob"
log.info("Hello", 123, {someObj: 1});  // Works: outputs "Hello 123 { someObj: 1} "

L'exemple de ma question ressemble alors à ceci:

const util = require('util');

function transform(info, opts) {
  const args = info[Symbol.for('splat')];
  if (args) { info.message = util.format(info.message, ...args); }
  return info;
}

function utilFormatter() { return {transform}; }


1 commentaires

Manquer ce cas log.info ({someObj: 1});



-1
votes

J'ai fait cette solution de contournement, mais je n'utilise finalement pas winston:

const wrapper = (original: any) => {
    return (...args: any[]): any => original(args.map((a) => `${a}`).join(' '))
}

logger.error = wrapper(logger.error)
logger.warn = wrapper(logger.warn)
logger.info = wrapper(logger.info)

Au fait, logger est une instance de winston.Logger


0 commentaires