5 ms·
The problem with wrapping console.log is that you lose the ability to know what line number initiated the log entry. The line number Chrome gives for the log li
by goodside 14y ago
The problem with wrapping console.log is that you lose the ability to know what line number initiated the log entry. The line number Chrome gives for the log line will always be where you call console.log inside the wrapper, not the line where you call the wrapper. Since there's no way to grab the line number of a caller in JS (Chrome's dev console uses browser hooks unavailable in JS), you can't even emulate the line number reporting yourself as a suffix to the log entry.
- windsurfer 14y agoYou actually can get the line number of a caller in JS: https://github.com/eriwen/javascript-stacktrace https://github.com/eriwen/javascript-stacktrace
- niggler 14y agoYou can just parse (new Error).stack: var __LINE__ = (new Error).stack.split("\n")[1].match(/:([0-9]+):/)[1];
- cristiantincu 14y ago`(new Error()).stack` is non-standard. But that’s a nice hack, nevertheless.
- niggler 14y agoThe underlying construct (console.log processing "%c" and styles) is nonstandard to begin with.
- cristiantincu 14y agoYes. It will not break, though. Unless you’re running it on an old IE that doesn’t host the `window.console` object.
- tracker1 14y agoI do something similar for logging my node apps... in .Net I use reflection for essentially the same.
- afschwartz 14y agoThanks for these suggestions. You can track progress on this here: https://github.com/adamschwartz/log/issues/1 https://github.com/adamschwartz/log/issues/1
- k3n 14y agoNote: that uses arguments.callee, which is disallowed in ES5 strict-mode.
- k3n 14y agoAfter looking at the code in more depth, I feel I should point out that it looks like `arguments.callee` is only the last-ditch fallback for generating a trace. I see baked-in support for Chrome, IE, FF, Safari, and Opera, and so unless your preferred browser is something else (or you want to target every possible browser) then you could change just a few lines to make it strict mode compliant.
- kevingadd 14y agoThis will severely degrade performance in almost every scenario. I don't recommend doing it by default, though it is a nice feature to have. Sometimes you want to be able to call console.log a few times per frame in a game without your framerate dropping into the single digits.
- cristiantincu 14y agoCalling `console.log()` in “production mode” is a bad idea, anyway. Ideally, you’ll want those calls stripped at some point, in your build script.
- gjuggler 14y agoUsing straight console.log statements seems to be non-negotiable for effective debugging, at least until a good workaround for the above is found. For using Chrome's logging styles, we define a few short helper functions — l1(), l2(), l3(), etc. — that return predefined CSS strings, then doing our logging like console.log("%cThis is a heading", l1()) console.log("%cLess important stuff", l2()) This means you're only adding 6 or so characters to get nice styled console messages that also maintain the nice line numbers and links to the source. Plus, it's similar enough to h1, h2, etc. that it's easy to remember. We found that varying the font color (black vs. gray) and margin-left (2em, 4em) were most helpful in differentiating more and less important log messages.
- CGamesPlay 14y agoI recommend simply using console.debug, console.log, console.warn, and console.error, which differentiate for you.
- cristiantincu 14y agoWhat about `console.info()`? Or is it a bit too adventurous?
- jaredmcateer 14y agoinfo and log are indistinguishable, at least in Chrome.
- cristiantincu 14y agoYes. So much about differentiation.
- jQueryIsAwesome 14y agoMaybe add console.assert to that list: console.assert(str.length === 10, "String is not 10 characters long!"); and console.group/groupEnd console.group("sums"); console.log(1 + 1); console.log(2 - 3); console.groupEnd();
- dribnet 14y ago> there's no way to grab the line number of a caller in JS But this is easily fixed by converting the function call to a macro, right? Oh wait - this isn't a ClojureScript library... so nevermind.
- jQueryIsAwesome 14y agoI found a way... well, sort of: var log = function(){ args = [].slice.call(arguments); args.unshift(console); return console.log.bind.apply(console.log, args) } But you have to add extra parenthesis at the end, hopefully is not too much overhead for most devs. log("message")()
- bgrins 14y agoHere is a way to fix this: https://gist.github.com/bgrins/5108712 https://gist.github.com/bgrins/5108712. When you call `log` it will preserve the line number. Here is a demo: http://jsfiddle.net/bgrins/MZWtG/ http://jsfiddle.net/bgrins/MZWtG/.