61 votes

Extension de console.log sans affecter la ligne de log

Je voudrais étendre la fonction 'console.log' pour ajouter des informations supplémentaires à sa sortie - mais je ne veux pas affecter le script nom/numéro de ligne des informations générées par le navigateur dans la fenêtre console. Voyez comment, si je crée ma propre implémentation, j'obtiens des informations de traçage inutiles, au cas où je voudrais localiser cette région de code... (elles sont toutes liées à l'implémentation du journal, et non au script qui a provoqué le message du journal).

enter image description here

Fondamentalement, mon application est une infrastructure très enfichable, où toute sortie de journal peut se produire dans un nombre quelconque de cadres. En tant que tel, je veux que chaque message de journal comprenne un identifiant unique spécial au début du message de journal.

J'ai essayé de remplacer la méthode console.log par la mienne, mais chrome se plaint en disant Uncaught TypeError: Illegal invocation

Voici comment je le remplace

var orig = console.log;
console.log = function( message )
{
    orig( (window == top ? '[root]' : '[' + window.name + ']') + ': ' + message );
}

Des idées ?

[EDIT] Note : Après avoir résolu le problème de 'l'invocation illégale', il semble que le nom de fichier/numéro de ligne soit toujours 'pollué' par l'override...

[EDIT] Il semblerait que la réponse générale soit - NON - en dépit de quelques confusions, la fonctionnalité souhaitée n'est PAS réalisable dans les versions actuelles des navigateurs.

0 votes

A partir d'aujourd'hui, votre dernier Modifier n'est finalement pas valide. Voir ma réponse stackoverflow.com/a/41328175/253098

0 votes

Voici une excellente réponse : stackoverflow.com/a/32928812/274502

0 votes

Presque un duplicata de javascript - Un wrapper approprié pour console.log avec un numéro de ligne correct ? - Stack Overflow Toutefois, cette question est un cas particulier pour lequel l'équipe d'experts de l'UE a été créée. bind La solution fonctionne.

37voto

kylehuff Points 1166

Oui, il est possible d'ajouter des informations sans perturber les numéros de ligne d'origine de l'invocation du journal. Certaines des autres réponses données ici s'en rapprochent, mais l'astuce consiste à faire en sorte que votre méthode d'enregistrement personnalisée renvoie le logger modifié. Vous trouverez ci-dessous un exemple simple qui n'a été que modérément testé et qui utilise la variante contextuelle.

log = function() {
    var context = "My Descriptive Logger Prefix:";
    return Function.prototype.bind.call(console.log, console, context);
}();

Ceci peut être utilisé avec :

log("A log message..."); 

Voici un jsfiddle : http://jsfiddle.net/qprro98v/

On pourrait facilement être créatif et passer la variable de contexte, et supprimer les parenthèses d'auto-exécution de la définition de la fonction. Par exemple, log("DEBUG :")("Un message de débogage"), log("INFO :")("Voici quelques informations"), etc.

La seule partie vraiment importante de la fonction (en ce qui concerne les numéros de ligne) est qu'elle renvoie le logger.

0 votes

Vous pouvez également ajouter plus d'un paramètre comme Function.prototype.bind.call(console.log, console, "%ccontext: ", "font-weight:bold;"); si par exemple vous voulez une sortie comme : " le contexte : texte du journal" (au moins dans chrome et firefox)

0 votes

@MarcoSacchi Comment puis-je faire si je veux enregistrer tous les messages en vert par exemple et pas seulement le préfixe ?

13voto

Si votre cas d'utilisation peut s'accommoder de quelques restrictions, il est possible d'avoir recours à des solutions de rechange. est un moyen de faire en sorte que cela fonctionne. Les restrictions sont les suivantes :

  • Le contenu supplémentaire du journal doit être calculé au moment de la liaison ; il ne peut pas être sensible au temps ni dépendre d'une quelconque manière du message de journal entrant.

  • Le contenu supplémentaire du journal ne peut être placé qu'au début du message du journal.

Avec ces restrictions, les mesures suivantes peuvent vous convenir :

var context = "ALIASED LOG:"
var logalias;

if (console.log.bind === 'undefined') { // IE < 10
    logalias = Function.prototype.bind.call(console.log, console, context);
}
else {
    logalias = console.log.bind(console, context);
}

logalias('Hello, world!');

http://jsfiddle.net/Wk2mf/

0 votes

Cela fonctionne-t-il vraiment correctement ? Votre clause IE < 10 semble être erronée. Ne devrait-elle pas être if(console.log.bind === undefined) ?

0 votes

Je pense que vous avez raison, bien que je n'aie pas une copie d'IE 9 à portée de main pour faire des tests. J'ai corrigé le code et le jsfiddle.

8voto

Bradley Points 61

C'est en fait possible dans chrome au moins. Voici le plus pertinent. Cela peut varier en fonction de la configuration, et la façon dont j'ai obtenu les divisions a été d'enregistrer toute la pile, et de trouver les informations dont j'avais besoin.

        var stack = new Error().stack;
        var file = stack.split("\n")[2].split("/")[4].split("?")[0]
        var line = stack.split("\n")[2].split(":")[5];

Voici le tout, en préservant l'enregistrement des objets natifs.

var orig = console.log
console.log = function(input) {
    var isChrome = navigator.userAgent.indexOf("Chrome") !== -1;
    if(isChrome){
        var stack = new Error().stack;
        var file = stack.split("\n")[2].split("/")[4].split("?")[0]
        var line = stack.split("\n")[2].split(":")[5];
        var append = file + ":" + line;
    }
    orig.apply(console, [input, append])
}

2 votes

Le concept derrière ce hack est vraiment bon, mais stack.split("\n")[2].split(":")[5] ? À quoi ressemblent vos erreurs ? Le 5e indice est hors norme pour moi ; j'ai du mal à deviner ce qui est différent dans le navigateur que vous utilisez pour que vous ayez plusieurs points supplémentaires sur une ligne par rapport à ce que je vois.

0 votes

J'ai obtenu ça en enregistrant le tout et en le divisant jusqu'à ce que j'obtienne ce dont j'avais besoin. Je ne suis pas sûr de savoir pourquoi ces différences existent.

0 votes

Les différences sont dues au fait que la pile est différente pour chaque codebase. Vous avez une LINE1 qui a une commande d'enregistrement et vous voulez connaître sa position. Le nombre d'appels de fonction entre LINE1 et votre nouvel appel Error() est important. Plus il y a d'appels, plus vous devez descendre dans la pile.

3voto

David Points 36241

Vous devez appeler le console.log avec le bon contexte ( console ) :

orig.call(console, message);

Pour compléter votre fonction permettant des arguments multiples :

var orig = console.log;
console.log = function() {
    var msgs = [],
        prefix = (window== top ? '[root]' : '[' + window.name + ']');
    while(arguments.length) {
        msgs.push(prefix + ': ' + [].shift.call(arguments));
    }
    orig.apply(console, msgs);
};

Démonstration : http://jsfiddle.net/je2wR/

N'oubliez pas que vous perdez le navigateur intégré d'objets/de tableaux dans la console lorsque vous combinez des objets avec des chaînes de caractères à l'aide de la commande + signe.

3 votes

Merci David - malheureusement, malgré votre code bien écrit, il semble que le problème original demeure. Dans votre jsfiddle, Chrome indique que c'est la "ligne 30" qui a généré la sortie du journal ( orig.apply(console, msgs); ), alors que j'ai besoin qu'il dise en fait la ligne 30 - comme si console.log n'était pas surchargé... C'est l'essentiel de ce que je veux dire, le remplacement de console.log semble casser la trace de la pile de la console.

0 votes

OK, j'ai mal compris, j'ai regardé votre code et j'ai supposé que vous aviez un problème de codage avec la fonction de journal personnalisé.

0 votes

Oui, j'ai probablement été un peu ambigu, je pense que j'avais la vision étroite que l'annulation allait résoudre le problème. Je me suis frappé la tête contre celui-ci pendant un petit moment, et je me suis dit qu'il devait y avoir une "API magique" que l'on appelle pour sortir une pile de la pile avant d'appeler "console.log" pour s'assurer que le fichier/ligne "parent" est utilisé... je n'ai pas trouvé de documentation cependant. Peut-être est-ce interne et non disponible pour les développeurs JS... vœux pieux Avis aux développeurs de Google Chrome qui pourraient nous écouter ?

2voto

Ben West Points 334

Je viens de répondre à cette question dans un message qui m'a aidé à répondre à la question initiale sur les alias :

(http://stackoverflow.com/a/12942764/401735)

my_log_alias = console.log.bind(console)

Apparemment, la capacité à le faire a été conçue. Testé. Fonctionne.

Par la suite, mon_log_alias est identique à console.log et peut être appelé de la même manière. En l'appelant depuis l'intérieur d'une fonction, le numéro de ligne de cet appel de fonction sera signalé, y compris la ligne à l'intérieur d'un alias ou d'une fonction de conseil, le cas échéant.

Plus précisément, le numéro de ligne fourni par Chrome vous indiquera le fichier dans lequel se trouve la ligne, de sorte que ce que vous faites n'est peut-être pas nécessaire ; envisagez de signaler ce problème en tant que bogue ou demande d'amélioration de Chrome pour qu'il fournisse cette information dans console.log.

0 votes

Malheureusement, appeler my_log_alias('test') produit toujours le numéro de ligne de la fonction alias, et non l'appelant original comme souhaité, rendant tous les numéros de ligne inutiles.

1 votes

Vraiment ? en utilisant la méthode ci-dessus ? Est-il possible qu'un autre plugin ait déjà conseillé la méthode et que vous appeliez l'alias ? Est-ce que le numéro de ligne sur lequel vous avez implémenté cette méthode est signalé ? et appelez-vous my_log_alias depuis VOTRE alias, ou l'appelez-vous directement ?

0 votes

Je ne pense pas que vous puissiez créer un bidule montrant que cela fonctionne ? Le seul extrait ci-dessus n'est pas suffisant pour être sûr que nous parlons du même scénario...

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