Crossposting from related question (A proper wrapper for console.log with correct line number?) but with updated solution to address multiple methods.
I liked @fredrik's answer, so I rolled it up with another answer which splits the Webkit stacktrace, and merged it with @PaulIrish's safe console.log wrapper. "Standardizes" the filename:line
to a "special object" so it stands out and looks mostly the same in FF and Chrome.
Testing in fiddle: http://jsfiddle.net/drzaus/pWe6W/9/
_log = (function (methods, undefined) {
var Log = Error; // does this do anything? proper inheritance...?
Log.prototype.write = function (args, method) {
///
/// Paulirish-like console.log wrapper. Includes stack trace via @fredrik SO suggestion (see remarks for sources).
///
/// list of details to log, as provided by `arguments`
/// the console method to use: debug, log, warn, info, error
/// Includes line numbers by calling Error object -- see
/// * http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
/// * https://stackoverflow.com/questions/13815640/a-proper-wrapper-for-console-log-with-correct-line-number
/// * https://stackoverflow.com/a/3806596/1037948
///
// 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[method]) {
if (console[method].apply) { console[method].apply(console, args); } else { console[method](args); } // nicer display in some browsers
}
};
var extractLineNumberFromStack = function (stack) {
///
/// Get the line/filename detail from a Webkit stack trace. See https://stackoverflow.com/a/3806596/1037948
///
/// the stack string
// correct line number according to how Log().write implemented
var line = stack.split('\n')[3];
// fix for various display text
line = (line.indexOf(' (') >= 0
? line.split(' (')[1].substring(0, line.length - 1)
: line.split('at ')[1]
);
return line;
};
// method builder
var logMethod = function(method) {
return function (params) {
///
/// Paulirish-like console.log wrapper
///
/// list your logging parameters
// 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), method); // turn into proper array & declare method to use
};//-- fn logMethod
};
var result = logMethod('log'); // base for backwards compatibility, simplicity
// add some extra juice
for(var i in methods) result[methods[i]] = logMethod(methods[i]);
return result; // expose
})(['error', 'debug', 'info', 'warn']);//--- _log