Obecnie tworzę aplikację i umieszczam isDebug
przełącznik globalny . Chciałbym owinąć się console.log
dla wygodniejszego użytkowania.
//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.');
Następnie otrzymuję ten wynik w konsoli Firefox.
info: Here is a msg. debug.js (line 8)
Co jeśli chcę zalogować się z numerem linii debug()
, na przykład info: Here is a msg. main.js (line 2)
?
javascript
Rufus
źródło
źródło
console.log
do informacji,console.warn
ostrzeżenia iconsole.error
błędu, zamiast dodawać cośconsole.log
za pomocą funkcji opakowującej.console
należy go użyć. Aby osiągnąć taki cel, jedyną drogą wydaje się opakowanie?Odpowiedzi:
To jest stare pytanie i wszystkie udzielone odpowiedzi są zbyt hakerskie, mają DUŻE problemy z przeglądarkami i nie zapewniają niczego super użytecznego. To rozwiązanie działa w każdej przeglądarce i raportuje wszystkie dane konsoli dokładnie tak, jak powinno. Nie są wymagane żadne hacki i jedna linia kodu Sprawdź kod .
var debug = console.log.bind(window.console)
Utwórz przełącznik w ten sposób:
isDebug = true // toggle this to turn on / off for global controll if (isDebug) var debug = console.log.bind(window.console) else var debug = function(){}
Następnie po prostu zadzwoń w następujący sposób:
debug('This is happening.')
Możesz nawet przejąć console.log za pomocą takiego przełącznika:
if (!isDebug) console.log = function(){}
Jeśli chcesz zrobić z tym coś pożytecznego ... Możesz dodać wszystkie metody konsoli i opakować je w funkcję wielokrotnego użytku, która daje nie tylko kontrolę globalną, ale także poziom klasy:
var Debugger = function(gState, klass) { this.debug = {} if (gState && klass.isDebug) { for (var m in console) if (typeof console[m] == 'function') this.debug[m] = console[m].bind(window.console, klass.toString()+": ") }else{ for (var m in console) if (typeof console[m] == 'function') this.debug[m] = function(){} } return this.debug } isDebug = true //global debug state debug = Debugger(isDebug, this) debug.log('Hello log!') debug.trace('Hello trace!')
Teraz możesz dodać go do swoich zajęć:
var MyClass = function() { this.isDebug = true //local state this.debug = Debugger(isDebug, this) this.debug.warn('It works in classses') }
źródło
console.log
dwukrotnie, wiążąc niestandardowąlog()
funkcję zawierającą dwa wywołaniaconsole.log
, jednak numery linii odzwierciedlałyby linię, któraconsole.log
faktycznie się znajduje, a nie miejsce, w którymdebug.log
jest wywoływana. Możesz jednak zrobić takie rzeczy, jak dodawanie dynamicznych prefiksów / sufiksów itp. Istnieją również sposoby na zrekompensowanie problemu z numerem linii, ale myślę, że to kolejne pytanie. Sprawdź ten projekt, aby zobaczyć przykład: github.com/arctelix/iDebugConsole/blob/master/README.mdthis.isDebug
nafalse
, nie będzie to miało znaczenia. Po prostu nie wiem, czy da się to obejść, może jest to zamierzone. W tym sensieisDebug
jest to dość mylącevar
i powinno byćconst
zamiast tego.Podobała mi się odpowiedź @ fredrik , więc zwinąłem ją z inną odpowiedzią, która dzieli ślad stosu Webkit i połączyłem ją z bezpiecznym opakowaniem console.log @ PaulIrish . „Standaryzuje” na
filename:line
„obiekt specjalny”, dzięki czemu wyróżnia się i wygląda prawie tak samo w FF i Chrome.Testowanie na skrzypcach: http://jsfiddle.net/drzaus/pWe6W/
_log = (function (undefined) { var Log = Error; // does this do anything? proper inheritance...? Log.prototype.write = function (args) { /// <summary> /// Paulirish-like console.log wrapper. Includes stack trace via @fredrik SO suggestion (see remarks for sources). /// </summary> /// <param name="args" type="Array">list of details to log, as provided by `arguments`</param> /// <remarks>Includes line numbers by calling Error object -- see /// * http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/ /// * /programming/13815640/a-proper-wrapper-for-console-log-with-correct-line-number /// * https://stackoverflow.com/a/3806596/1037948 /// </remarks> // via @fredrik SO trace suggestion; wrapping in special construct so it stands out var suffix = { "@": (this.lineNumber ? this.fileName + ':' + this.lineNumber + ":1" // add arbitrary column value for chrome linking : extractLineNumberFromStack(this.stack) ) }; args = args.concat([suffix]); // via @paulirish console wrapper if (console && console.log) { if (console.log.apply) { console.log.apply(console, args); } else { console.log(args); } // nicer display in some browsers } }; var extractLineNumberFromStack = function (stack) { /// <summary> /// Get the line/filename detail from a Webkit stack trace. See https://stackoverflow.com/a/3806596/1037948 /// </summary> /// <param name="stack" type="String">the stack string</param> if(!stack) return '?'; // fix undefined issue reported by @sigod // correct line number according to how Log().write implemented var line = stack.split('\n')[2]; // fix for various display text line = (line.indexOf(' (') >= 0 ? line.split(' (')[1].substring(0, line.length - 1) : line.split('at ')[1] ); return line; }; return function (params) { /// <summary> /// Paulirish-like console.log wrapper /// </summary> /// <param name="params" type="[...]">list your logging parameters</param> // only if explicitly true somewhere if (typeof DEBUGMODE === typeof undefined || !DEBUGMODE) return; // call handler extension which provides stack trace Log().write(Array.prototype.slice.call(arguments, 0)); // turn into proper array };//-- fn returned })();//--- _log
Działa to również w węźle i możesz to przetestować za pomocą:
// no debug mode _log('this should not appear'); // turn it on DEBUGMODE = true; _log('you should', 'see this', {a:1, b:2, c:3}); console.log('--- regular log ---'); _log('you should', 'also see this', {a:4, b:8, c:16}); // turn it off DEBUGMODE = false; _log('disabled, should not appear'); console.log('--- regular log2 ---');
źródło
console
metod, takich jakwarn
,error
itp - stackoverflow.com/a/14842659/1037948var line = stack.split('\n')[2];
-'undefined' is not an object
if(!stack) return '?'
do metody, która zawodzi, a nie gdzie jest wywoływana (więc jeśli ktoś używa samej metody, jest również „chroniony”)Możesz zachować numery wierszy i wyprowadzić poziom dziennika, używając sprytnie
Function.prototype.bind
:function setDebug(isDebug) { if (window.isDebug) { window.debug = window.console.log.bind(window.console, '%s: %s'); } else { window.debug = function() {}; } } setDebug(true); // ... debug('level', 'This is my message.'); // --> level: This is my message. (line X)
Idąc o krok dalej, możesz skorzystać z
console
rozróżnień błąd / ostrzeżenie / informacje i nadal mieć niestandardowe poziomy. Spróbuj!function setDebug(isDebug) { if (isDebug) { window.debug = { log: window.console.log.bind(window.console, '%s: %s'), error: window.console.error.bind(window.console, 'error: %s'), info: window.console.info.bind(window.console, 'info: %s'), warn: window.console.warn.bind(window.console, 'warn: %s') }; } else { var __no_op = function() {}; window.debug = { log: __no_op, error: __no_op, warn: __no_op, info: __no_op } } } setDebug(true); // ... debug.log('wat', 'Yay custom levels.'); // -> wat: Yay custom levels. (line X) debug.info('This is info.'); // -> info: This is info. (line Y) debug.error('Bad stuff happened.'); // -> error: Bad stuff happened. (line Z)
źródło
console.debug(...)
zfunction name
iarguments
- czy są jakieś przemyślenia, jak to zrobić?%s
ze%o
w Chrome będzie drukować parametry w sposób, że można się spodziewać (obiekty są rozszerzalne, numery i łańcuchy są kolorowe, etc).Od: Jak uzyskać numer linii funkcji wywołującej JavaScript? Jak uzyskać adres URL źródła wywołującego JavaScript?
Error
obiekt ma właściwość numer wiersza (w FF). Więc coś takiego powinno działać:var err = new Error(); Global.console.log(level + ': '+ msg + 'file: ' + err.fileName + ' line:' + err.lineNumber);
W przeglądarce Webkit masz
err.stack
ciąg znaków reprezentujący aktualny stos wywołań. Wyświetli aktualny numer linii i więcej informacji.AKTUALIZACJA
Aby uzyskać poprawny numer linii, musisz wywołać błąd w tej linii. Coś jak:
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);
źródło
new Error();
daje mi kontekst, w którym jest wykonywany, jeśli go wstawię,debug.js
otrzymaminfo: Here is a msg. file: http://localhost/js/debug.js line:7
.Log = Error
? Nadal modyfikujesz klasę Error, prawda?Sposób na zachowanie numeru linii jest tutaj: https://gist.github.com/bgrins/5108712 . Mniej więcej sprowadza się to do tego:
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); }; }
Możesz to opakować
isDebug
i ustawićwindow.log
na,function() { }
jeśli nie debugujesz.źródło
Możesz przekazać numer linii do metody debugowania, na przykład:
//main.js debug('Here is a msg.', (new Error).lineNumber);
Tutaj
(new Error).lineNumber
daje ci bieżący numer linii w twoimjavascript
kodzie.źródło
Chrome Devtools pozwala to osiągnąć dzięki Blackboxing . Możesz utworzyć opakowanie console.log, które może mieć efekty uboczne, wywoływać inne funkcje itp. I nadal zachować numer wiersza, który wywołał funkcję opakowania.
Wystarczy umieścić małe opakowanie console.log w osobnym pliku, np
(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) } })()
Nazwij go na przykład log-blackbox.js
Następnie przejdź do ustawień Chrome Devtools i znajdź sekcję „Blackboxing”, dodaj wzorzec nazwy pliku, który chcesz blackbox, w tym przypadku log-blackbox.js
źródło
Znalazłem proste rozwiązanie, aby połączyć zaakceptowaną odpowiedź (powiązanie z console.log / błąd / itp.) Z jakąś zewnętrzną logiką do filtrowania tego, co jest faktycznie rejestrowane.
// or window.log = {...} var log = { ASSERT: 1, ERROR: 2, WARN: 3, INFO: 4, DEBUG: 5, VERBOSE: 6, set level(level) { if (level >= this.ASSERT) this.a = console.assert.bind(window.console); else this.a = function() {}; if (level >= this.ERROR) this.e = console.error.bind(window.console); else this.e = function() {}; if (level >= this.WARN) this.w = console.warn.bind(window.console); else this.w = function() {}; if (level >= this.INFO) this.i = console.info.bind(window.console); else this.i = function() {}; if (level >= this.DEBUG) this.d = console.debug.bind(window.console); else this.d = function() {}; if (level >= this.VERBOSE) this.v = console.log.bind(window.console); else this.v = function() {}; this.loggingLevel = level; }, get level() { return this.loggingLevel; } }; log.level = log.DEBUG;
Stosowanie:
log.e('Error doing the thing!', e); // console.error log.w('Bonus feature failed to load.'); // console.warn log.i('Signed in.'); // console.info log.d('Is this working as expected?'); // console.debug log.v('Old debug messages, output dominating messages'); // console.log; ignored because `log.level` is set to `DEBUG` log.a(someVar == 2) // console.assert
console.assert
używa rejestrowania warunkowego.źródło
Jeśli chcesz po prostu kontrolować, czy używane jest debugowanie i mieć poprawny numer linii, możesz to zrobić:
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(){} }; }
Jeśli potrzebujesz dostępu do debugowania, możesz to zrobić:
debug.log("log"); debug.warn("warn"); debug.error("error");
Jeśli
isDebug == true
, numery wierszy i nazwy plików wyświetlane w konsoli będą poprawne, ponieważdebug.log
etc jest w rzeczywistości aliasemconsole.log
itp.Jeśli
isDebug == false
nie są wyświetlane żadne komunikaty debugowania, ponieważdebug.log
etc po prostu nic nie robi (pusta funkcja).Jak już wiesz, funkcja opakowująca zepsuje numery wierszy i nazwy plików, więc dobrym pomysłem jest zapobieganie używaniu funkcji opakowujących.
źródło
isDebug = true
idebug.js
, ale ta odpowiedź działa!window.debug = window.console
byłoby trochę czystsze.isDebug == false
. : {isDebug===true
. Lub wydarzenie do tego: jsfiddle.net/fredrik/x6Jw5Rozwiązania śledzenia stosu wyświetlają numer linii, ale nie pozwalają na kliknięcie, aby przejść do źródła, co jest głównym problemem. Jedynym rozwiązaniem pozwalającym zachować to zachowanie jest powiązanie z oryginalną funkcją.
Wiązanie uniemożliwia włączenie logiki pośredniej, ponieważ ta logika mogłaby zepsuć numery linii. Jednak dzięki przedefiniowaniu funkcji związanych i graniu z podstawianiem ciągów konsoli , nadal możliwe jest pewne dodatkowe zachowanie.
To streszczenie przedstawia minimalistyczną strukturę rejestrowania, która oferuje moduły, poziomy dziennika, formatowanie i odpowiednie klikalne numery linii w 34 liniach. Wykorzystaj go jako podstawę lub inspirację do własnych potrzeb.
var log = Logger.get("module").level(Logger.WARN); log.error("An error has occured", errorObject); log("Always show this.");
EDYCJA: treść zawarta poniżej
/* * 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" })();
źródło
Pomysł z bindem
Function.prototype.bind
jest genialny. Możesz również użyć rejestratora wierszy biblioteki npm . Pokazuje pliki źródłowe pochodzenia:Utwórz rejestrator każdego raz w swoim projekcie:
var LoggerFactory = require('lines-logger').LoggerFactory; var loggerFactory = new LoggerFactory(); var logger = loggerFactory.getLoggerColor('global', '#753e01');
Drukuj dzienniki:
logger.log('Hello world!')();
źródło
Oto sposób na zachowanie istniejących
console
instrukcji rejestrowania podczas dodawania nazwy pliku i numeru wiersza lub innych informacji o śledzeniu stosu do danych wyjściowych:(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; }, {})); }());
Następnie użyj tego w ten sposób:
<!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>
Działa to w przeglądarkach Firefox, Opera, Safari, Chrome i IE 10 (jeszcze nie testowane w IE11 ani Edge).
źródło
my test log message (myscript.js:42) VM167 mypage.html:15
:), która nie jest tak dobra do czytania, a także nie jest połączona. Wciąż dobra robota, a więc upvote.//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.'));
To mi da
info: "Here is a msg." main.js(line:2)
.Ale
eval
trzeba, szkoda.źródło
Kod z http://www.briangrinstead.com/blog/console-log-helper-function :
// Full version of `log` that: // * Prevents errors on console methods when no console present. // * Exposes a global 'log' function that preserves line numbering and formatting. (function () { var method; var noop = function () { }; var methods = [ 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn' ]; var length = methods.length; var console = (window.console = window.console || {}); while (length--) { method = methods[length]; // Only stub undefined methods. if (!console[method]) { console[method] = noop; } } 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); }; } })(); var a = {b:1}; var d = "test"; log(a, d);
źródło
log
jest wywoływana zSam ostatnio przyglądałem się temu problemowi. Potrzebowałem czegoś bardzo prostego do sterowania rejestrowaniem, ale także do zachowania numerów linii. Moje rozwiązanie nie wygląda tak elegancko w kodzie, ale zapewnia to, co jest mi potrzebne. Jeśli ktoś jest wystarczająco ostrożny przy zamykaniu i utrzymywaniu.
Dodałem małą otulinę na początek aplikacji:
window.log = { log_level: 5, d: function (level, cb) { if (level < this.log_level) { cb(); } } };
Więc później mogę po prostu zrobić:
log.d(3, function(){console.log("file loaded: utils.js");});
Przetestowałem to z Firefox i Crome, i obie przeglądarki wydają się wyświetlać dziennik konsoli zgodnie z przeznaczeniem. Jeśli wypełnisz w ten sposób, zawsze możesz rozszerzyć metodę 'd' i przekazać do niej inne parametry, aby mógł wykonać dodatkowe logowanie.
Nie znalazłem jeszcze żadnych poważnych wad mojego podejścia, z wyjątkiem brzydkiej linii w kodzie do logowania.
źródło
window.line = function () { var error = new Error(''), brower = { ie: !-[1,], // !!window.ActiveXObject || "ActiveXObject" in window opera: ~window.navigator.userAgent.indexOf("Opera"), firefox: ~window.navigator.userAgent.indexOf("Firefox"), chrome: ~window.navigator.userAgent.indexOf("Chrome"), safari: ~window.navigator.userAgent.indexOf("Safari"), // /^((?!chrome).)*safari/i.test(navigator.userAgent)? }, todo = function () { // TODO: console.error('a new island was found, please told the line()\'s author(roastwind)'); }, line = (function(error, origin){ // line, column, sourceURL if(error.stack){ var line, baseStr = '', stacks = error.stack.split('\n'); stackLength = stacks.length, isSupport = false; // mac版本chrome(55.0.2883.95 (64-bit)) if(stackLength == 11 || brower.chrome){ line = stacks[3]; isSupport = true; // mac版本safari(10.0.1 (12602.2.14.0.7)) }else if(brower.safari){ line = stacks[2]; isSupport = true; }else{ todo(); } if(isSupport){ line = ~line.indexOf(origin) ? line.replace(origin, '') : line; line = ~line.indexOf('/') ? line.substring(line.indexOf('/')+1, line.lastIndexOf(':')) : line; } return line; }else{ todo(); } return '😭'; })(error, window.location.origin); return line; } window.log = function () { var _line = window.line.apply(arguments.callee.caller), args = Array.prototype.slice.call(arguments, 0).concat(['\t\t\t@'+_line]); window.console.log.apply(window.console, args); } log('hello');
oto moje rozwiązanie na to pytanie. kiedy wywołasz metodę: log, wydrukuje ona numer linii, w której drukujesz dziennik
źródło
Mała zmiana polega na tym, że funkcja debug () zwraca funkcję, która jest następnie wykonywana tam, gdzie jej potrzebujesz - debug (message) (); i tak prawidłowo pokazuje poprawny numer linii i skrypt wywołujący w oknie konsoli, jednocześnie zezwalając na różne warianty, takie jak przekierowanie jako alert lub zapisywanie do pliku.
var debugmode='console'; var debugloglevel=3; function debug(msg, type, level) { if(level && level>=debugloglevel) { return(function() {}); } switch(debugmode) { case 'alert': return(alert.bind(window, type+": "+msg)); break; case 'console': return(console.log.bind(window.console, type+": "+msg)); break; default: return (function() {}); } }
Ponieważ zwraca funkcję, ta funkcja musi zostać wykonana w linii debugowania za pomocą () ;. Po drugie, wiadomość jest wysyłana do funkcji debugowania, a nie do funkcji zwracanej, która umożliwia wstępne przetwarzanie lub sprawdzenie, czego możesz potrzebować, na przykład sprawdzenie stanu na poziomie dziennika, zwiększenie czytelności wiadomości, pomijanie różnych typów lub tylko raportowanie elementów spełniające kryteria poziomu dziennika;
debug(message, "serious", 1)(); debug(message, "minor", 4)();
źródło
Tutaj możesz uprościć logikę. Zakłada się, że Twoja globalna flaga debugowania NIE jest dynamiczna i ustawiona podczas ładowania aplikacji lub przekazywana jako konfiguracja. Ma to służyć do oznaczania środowiska (np. Drukowanie tylko w trybie deweloperskim, a nie produkcyjnym)
Vanilla JS:
(function(window){ var Logger = {}, noop = function(){}; ['log', 'debug', 'info', 'warn', 'error'].forEach(function(level){ Logger[level] = window.isDebug ? window.console[level] : noop; }); window.Logger = Logger; })(this);
ES6:
((window) => { const Logger = {}; const noop = function(){}; ['log', 'debug', 'info', 'warn', 'error'].forEach((level) => { Logger[level] = window.isDebug ? window.console[level] : noop; }); window.Logger = Logger; })(this);
Moduł:
const Logger = {}; const noop = function(){}; ['log', 'debug', 'info', 'warn', 'error'].forEach((level) => { Logger[level] = window.isDebug ? window.console[level] : noop; }); export default Logger;
Kątowy 1.x:
angular .module('logger', []) .factory('Logger', ['$window', function Logger($window) { const noop = function(){}; const logger = {}; ['log', 'debug', 'info', 'warn', 'error'].forEach((level) => { logger[level] = $window.isDebug ? $window.console[level] : noop; }); return logger; } ]);
Wszystko, co musisz teraz zrobić, to zamienić wszystkie referencje konsoli na Logger
źródło
Ta implementacja jest oparta na wybranej odpowiedzi i pomaga zmniejszyć ilość szumów w konsoli błędów: https://stackoverflow.com/a/32928812/516126
var Logging = Logging || {}; const LOG_LEVEL_ERROR = 0, LOG_LEVEL_WARNING = 1, LOG_LEVEL_INFO = 2, LOG_LEVEL_DEBUG = 3; Logging.setLogLevel = function (level) { const NOOP = function () { } Logging.logLevel = level; Logging.debug = (Logging.logLevel >= LOG_LEVEL_DEBUG) ? console.log.bind(window.console) : NOOP; Logging.info = (Logging.logLevel >= LOG_LEVEL_INFO) ? console.log.bind(window.console) : NOOP; Logging.warning = (Logging.logLevel >= LOG_LEVEL_WARNING) ? console.log.bind(window.console) : NOOP; Logging.error = (Logging.logLevel >= LOG_LEVEL_ERROR) ? console.log.bind(window.console) : NOOP; } Logging.setLogLevel(LOG_LEVEL_INFO);
źródło
Niektóre odpowiedzi na ten problem okazały się dla mnie zbyt skomplikowane. Oto proste rozwiązanie, wyrenderowane w Coffeescript. Dostosowano go z wersji Briana Grinsteada tutaj
Zakłada globalny obiekt konsoli.
# exposes a global 'log' function that preserves line numbering and formatting. (() -> methods = [ 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'] noop = () -> # stub undefined methods. for m in methods when !console[m] console[m] = noop if Function.prototype.bind? window.log = Function.prototype.bind.call(console.log, console); else window.log = () -> Function.prototype.apply.call(console.log, console, arguments) )()
źródło
Sposób, w jaki to rozwiązałem, polegał na utworzeniu obiektu, a następnie utworzeniu nowej właściwości obiektu za pomocą Object.defineProperty () i zwróceniu właściwości konsoli, która była wtedy używana jako normalna funkcja, ale teraz z rozszerzonymi możliwościami.
var c = {}; var debugMode = true; var createConsoleFunction = function(property) { Object.defineProperty(c, property, { get: function() { if(debugMode) return console[property]; else return function() {}; } }); };
Następnie, aby zdefiniować właściwość, po prostu wykonaj ...
createConsoleFunction("warn"); createConsoleFunction("log"); createConsoleFunction("trace"); createConsoleFunction("clear"); createConsoleFunction("error"); createConsoleFunction("info");
Teraz możesz używać swojej funkcji tak samo, jak
c.error("Error!");
źródło
Na podstawie innych odpowiedzi (głównie @arctelix) stworzyłem to dla Node ES6, ale szybki test pokazał również dobre wyniki w przeglądarce. Po prostu przekazuję drugą funkcję jako odniesienie.
let debug = () => {}; if (process.argv.includes('-v')) { debug = console.log; // debug = console; // For full object access }
źródło
Oto moja funkcja rejestratora (oparta na niektórych odpowiedziach). Mam nadzieję, że ktoś może to wykorzystać:
const DEBUG = true; let log = function ( lvl, msg, fun ) {}; if ( DEBUG === true ) { log = function ( lvl, msg, fun ) { const d = new Date(); const timestamp = '[' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() + '.' + d.getMilliseconds() + ']'; let stackEntry = new Error().stack.split( '\n' )[2]; if ( stackEntry === 'undefined' || stackEntry === null ) { stackEntry = new Error().stack.split( '\n' )[1]; } if ( typeof fun === 'undefined' || fun === null ) { fun = stackEntry.substring( stackEntry.indexOf( 'at' ) + 3, stackEntry.lastIndexOf( ' ' ) ); if ( fun === 'undefined' || fun === null || fun.length <= 1 ) { fun = 'anonymous'; } } const idx = stackEntry.lastIndexOf( '/' ); let file; if ( idx !== -1 ) { file = stackEntry.substring( idx + 1, stackEntry.length - 1 ); } else { file = stackEntry.substring( stackEntry.lastIndexOf( '\\' ) + 1, stackEntry.length - 1 ); } if ( file === 'undefined' || file === null ) { file = '<>'; } const m = timestamp + ' ' + file + '::' + fun + '(): ' + msg; switch ( lvl ) { case 'log': console.log( m ); break; case 'debug': console.log( m ); break; case 'info': console.info( m ); break; case 'warn': console.warn( m ); break; case 'err': console.error( m ); break; default: console.log( m ); break; } }; }
Przykłady:
log( 'warn', 'log message', 'my_function' ); log( 'info', 'log message' );
źródło
Wiem, że to stare pytanie, ale już od jakiegoś czasu pracuję nad własnym rozwiązaniem. Wracam, żeby zobaczyć, czy są tam nowe informacje. Ponieważ nie wygląda na to, żeby ktoś się zbliżył, pomyślałem, że wrzucę moje rozwiązanie do wyżymaczki (ponieważ wydaje się, że nadal jest to najbardziej aktywny wątek w tej sprawie):
https://github.com/fatlard1993/log
Początkowo zastosowałem podobne podejście do niektórych innych odpowiedzi, dopóki nie dowiedziałem się o proxy. To dało mi pomysł i motywację, aby zrobić to, czym jest teraz.
źródło