172 votes

Un wrapper approprié pour console.log avec un numéro de ligne correct ?

Je suis en train de développer une application, et je place une commande globale isDebug un interrupteur. Je voudrais envelopper console.log pour une utilisation plus pratique.

//isDebug controls the entire site.
var isDebug = true;

//debug.js
function debug(msg, level){
    var Global = this;
    if(!(Global.isDebug && Global.console && Global.console.log)){
        return;
    }
    level = level||'info';
    Global.console.log(level + ': '+ msg);
}

//main.js
debug('Here is a msg.');

J'obtiens alors ce résultat dans la console de Firefox.

info: Here is a msg.                       debug.js (line 8)

Et si je veux enregistrer avec le numéro de ligne où debug() est appelé, comme info: Here is a msg. main.js (line 2) ?

4voto

Alvin Wong Points 5803

Si vous voulez simplement contrôler si le débogage est utilisé et avoir le numéro de ligne correct, vous pouvez faire ceci à la place :

if(isDebug && window.console && console.log && console.warn && console.error){
    window.debug = {
        'log': window.console.log,
        'warn': window.console.warn,
        'error': window.console.error
    };
}else{
    window.debug = {
        'log': function(){},
        'warn': function(){},
        'error': function(){}
    };
}

Lorsque vous avez besoin d'accéder au débogage, vous pouvez le faire :

debug.log("log");
debug.warn("warn");
debug.error("error");

Si isDebug == true Les numéros de ligne et les noms de fichiers affichés dans la console seront corrects, car debug.log etc est en fait un alias de console.log etc.

Si isDebug == false aucun message de débogage n'est affiché, car debug.log etc ne fait simplement rien (une fonction vide).

Comme vous le savez déjà, une fonction wrapper perturbera les numéros de ligne et les noms de fichier, c'est pourquoi il est préférable d'éviter d'utiliser des fonctions wrapper.

4voto

Brett Zamir Points 5355

Voici un moyen de conserver votre console tout en ajoutant un nom de fichier et un numéro de ligne ou d'autres informations de suivi de pile sur la sortie :

(function () {
  'use strict';
  var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
  var isChrome = !!window.chrome && !!window.chrome.webstore;
  var isIE = /*@cc_on!@*/false || !!document.documentMode;
  var isEdge = !isIE && !!window.StyleMedia;
  var isPhantom = (/PhantomJS/).test(navigator.userAgent);
  Object.defineProperties(console, ['log', 'info', 'warn', 'error'].reduce(function (props, method) {
    var _consoleMethod = console[method].bind(console);
    props[method] = {
      value: function MyError () {
        var stackPos = isOpera || isChrome ? 2 : 1;
        var err = new Error();
        if (isIE || isEdge || isPhantom) { // Untested in Edge
          try { // Stack not yet defined until thrown per https://docs.microsoft.com/en-us/scripting/javascript/reference/stack-property-error-javascript
            throw err;
          } catch (e) {
            err = e;
          }
          stackPos = isPhantom ? 1 : 2;
        }

        var a = arguments;
        if (err.stack) {
          var st = err.stack.split('\n')[stackPos]; // We could utilize the whole stack after the 0th index
          var argEnd = a.length - 1;
          [].slice.call(a).reverse().some(function(arg, i) {
            var pos = argEnd - i;
            if (typeof a[pos] !== 'string') {
              return false;
            }
            if (typeof a[0] === 'string' && a[0].indexOf('%') > -1) { pos = 0 } // If formatting
            a[pos] += ' \u00a0 (' + st.slice(0, st.lastIndexOf(':')) // Strip out character count
              .slice(st.lastIndexOf('/') + 1) + ')'; // Leave only path and line (which also avoids ":" changing Safari console formatting)
            return true;
          });
        }
        return _consoleMethod.apply(null, a);
      }
    };
    return props;
  }, {}));
}());

Alors utilisez-le comme ceci :

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <script src="console-log.js"></script>
</head>
<body>
  <script>
  function a () {
    console.log('xyz'); // xyz   (console-log.html:10)
  }
  console.info('abc'); // abc   (console-log.html:12)
  console.log('%cdef', "color:red;"); // (IN RED:) // def   (console-log.html:13)
  a();
  console.warn('uuu'); // uuu   (console-log.html:15)
  console.error('yyy'); // yyy   (console-log.html:16)
  </script>
</body>
</html>

Cela fonctionne dans Firefox, Opera, Safari, Chrome et IE 10 (pas encore testé sur IE11 ou Edge).

3voto

deathangel908 Points 2269

L'idée avec bind Function.prototype.bind est brillant. Vous pouvez également utiliser la bibliothèque npm line-logger . Il montre les fichiers sources d'origine :

Créez le logger quelqu'un une fois dans votre projet :

var LoggerFactory = require('lines-logger').LoggerFactory;
var loggerFactory = new LoggerFactory();
var logger = loggerFactory.getLoggerColor('global', '#753e01');

Imprimer les journaux :

logger.log('Hello world!')();

enter image description here

1voto

Rufus Points 1087
//isDebug controls the entire site.
var isDebug = true;

//debug.js
function debug(msg, level){
    var Global = this;
    if(!(Global.isDebug && Global.console && Global.console.log)){
        return;
    }
    level = level||'info';
    return 'console.log(\'' + level + ': '+ JSON.stringify(msg) + '\')';
}

//main.js
eval(debug('Here is a msg.'));

Cela me donnera info: "Here is a msg." main.js(line:2) .

Mais le supplément eval est nécessaire, dommage.

1voto

Vladimir M Points 11

Je me suis moi-même penché sur cette question ces derniers temps. J'avais besoin de quelque chose de très simple pour contrôler la journalisation, mais aussi pour conserver les numéros de ligne. Ma solution n'est pas aussi élégante dans le code, mais elle fournit ce dont j'ai besoin. Si l'on est assez prudent avec les fermetures et la rétention.

J'ai ajouté un petit wrapper au début de l'application :

window.log = {
    log_level: 5,
    d: function (level, cb) {
        if (level < this.log_level) {
            cb();
        }
    }
};

Pour que plus tard je puisse simplement faire :

log.d(3, function(){console.log("file loaded: utils.js");});

Je l'ai testé sur firefox et crome, et les deux navigateurs semblent afficher le journal de la console comme prévu. Si vous n'êtes pas satisfait, vous pouvez toujours étendre la méthode 'd' et lui passer d'autres paramètres, afin qu'elle puisse effectuer une journalisation supplémentaire.

Je n'ai pas encore trouvé d'inconvénients sérieux à mon approche, à l'exception de la vilaine ligne de code pour la journalisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X