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) ?

9voto

fredrik Points 5010

De : Comment obtenir le numéro de ligne de la fonction appelante JavaScript ? Comment obtenir l'URL de la source de l'appelant JavaScript ? le site Error a une propriété de numéro de ligne (en FF). Donc quelque chose comme ceci devrait fonctionner :

var err = new Error();
Global.console.log(level + ': '+ msg + 'file: ' + err.fileName + ' line:' + err.lineNumber);

Dans le navigateur Webkit, vous avez err.stack qui est une chaîne représentant la pile d'appels actuelle. Elle affichera le numéro de la ligne en cours et d'autres informations.

UPDATE

Pour obtenir le numéro de ligne correct, vous devez invoquer l'erreur sur cette ligne. Quelque chose comme :

var Log = Error;
Log.prototype.write = function () {
    var args = Array.prototype.slice.call(arguments, 0),
        suffix = this.lineNumber ? 'line: '  + this.lineNumber : 'stack: ' + this.stack;

    console.log.apply(console, args.concat([suffix]));
};

var a = Log().write('monkey' + 1, 'test: ' + 2);

var b = Log().write('hello' + 3, 'test: ' + 4);

9voto

Brian Grinstead Points 2248

Un moyen de conserver le numéro de ligne est ici : https://gist.github.com/bgrins/5108712 . Cela se résume plus ou moins à ceci :

if (Function.prototype.bind) {
    window.log = Function.prototype.bind.call(console.log, console);
}
else {
    window.log = function() { 
        Function.prototype.apply.call(console.log, console, arguments);
    };
}

Vous pourriez l'envelopper avec isDebug et mettre window.log a function() { } si vous ne déboguez pas.

8voto

kzahel Points 856

Chrome Devtools vous permet d'y parvenir avec Blackboxing . Vous pouvez créer un wrapper console.log qui peut avoir des effets secondaires, appeler d'autres fonctions, etc., tout en conservant le numéro de la ligne qui a appelé la fonction wrapper.

Il suffit de mettre un petit wrapper console.log dans un fichier séparé, par ex.

(function() {
    var consolelog = console.log
    console.log = function() {
        // you may do something with side effects here.
        // log to a remote server, whatever you want. here
        // for example we append the log message to the DOM
        var p = document.createElement('p')
        var args = Array.prototype.slice.apply(arguments)
        p.innerText = JSON.stringify(args)
        document.body.appendChild(p)

        // call the original console.log function
        consolelog.apply(console,arguments)
    }
})()

Nommez-le quelque chose comme log-blackbox.js

Ensuite, allez dans les paramètres de Chrome Devtools et trouvez la section "Blackboxing", ajoutez un motif pour le nom de fichier que vous voulez mettre en boîte noire, dans ce cas log-blackbox.js

7voto

sub_stantial Points 1284

Vous pouvez passer le numéro de ligne à votre méthode de débogage, comme ceci :

//main.js
debug('Here is a msg.', (new Error).lineNumber);

Ici, (new Error).lineNumber vous donnerait le numéro de la ligne actuelle dans votre javascript code.

5voto

solendil Points 5098

Solutions de suivi des piles afficher le numéro de ligne mais ne permettent pas de cliquer pour aller à la source, ce qui est un problème majeur. La seule solution pour conserver ce comportement est de lier à la fonction d'origine.

La liaison empêche d'inclure une logique intermédiaire, car cette logique perturberait les numéros de ligne. Cependant, en redéfinissant les fonctions liées et en jouant avec la console substitution de chaîne il est encore possible d'obtenir un comportement supplémentaire.

Ce point présente un cadre de journalisation minimaliste qui offre des modules, des niveaux de journalisation, un formatage et des numéros de ligne cliquables appropriés en 34 lignes. Utilisez-le comme base ou inspiration pour vos propres besoins.

var log = Logger.get("module").level(Logger.WARN);
log.error("An error has occured", errorObject);
log("Always show this.");

EDIT : le résumé est inclus ci-dessous

/*
 * Copyright 2016, Matthieu Dumas
 * This work is licensed under the Creative Commons Attribution 4.0 International License.
 * To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/
 */

/* Usage : 
 * var log = Logger.get("myModule") // .level(Logger.ALL) implicit
 * log.info("always a string as first argument", then, other, stuff)
 * log.level(Logger.WARN) // or ALL, DEBUG, INFO, WARN, ERROR, OFF
 * log.debug("does not show")
 * log("but this does because direct call on logger is not filtered by level")
 */
var Logger = (function() {
    var levels = {
        ALL:100,
        DEBUG:100,
        INFO:200,
        WARN:300,
        ERROR:400,
        OFF:500
    };
    var loggerCache = {};
    var cons = window.console;
    var noop = function() {};
    var level = function(level) {
        this.error = level<=levels.ERROR ? cons.error.bind(cons, "["+this.id+"] - ERROR - %s") : noop;
        this.warn = level<=levels.WARN ? cons.warn.bind(cons, "["+this.id+"] - WARN - %s") : noop;
        this.info = level<=levels.INFO ? cons.info.bind(cons, "["+this.id+"] - INFO - %s") : noop;
        this.debug = level<=levels.DEBUG ? cons.log.bind(cons, "["+this.id+"] - DEBUG - %s") : noop;
        this.log = cons.log.bind(cons, "["+this.id+"] %s");
        return this;
    };
    levels.get = function(id) {
        var res = loggerCache[id];
        if (!res) {
            var ctx = {id:id,level:level}; // create a context
            ctx.level(Logger.ALL); // apply level
            res = ctx.log; // extract the log function, copy context to it and returns it
            for (var prop in ctx)
                res[prop] = ctx[prop];
            loggerCache[id] = res;
        }
        return res;
    };
    return levels; // return levels augmented with "get"
})();

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