9

我已经包装了控制台 API 以提供精细的日志记录级别以及其他一些糖功能。

这很好用,唯一的问题是萤火虫(或任何其他控制台)将始终报告日志来自的行号作为调用控制台 API 本身的行。

您如何建议我让控制台记录我调用包装函数的行号?

我更喜欢跨浏览器解决方案,但如果没有一个 firebug 插件可能是一个好的开始。

仅供参考,我这样称呼我的日志记录功能:

db.log(db.LogLevel.WARN, "Blah Blah Blah");
4

5 回答 5

3

有趣的问题......我可能有一个黑客给你。我现在无法对此进行测试,但我认为它可能会起作用。

我们知道常规的函数调用是行不通的,所以我开始考虑 C 中的#defines 和其他各种语言中的宏。不幸的是,javascript 没有这个,但也许evalhack 会起作用。我期望eval它将像来自同一行一样运行代码 - 如果不是,请忽略这个答案的其余部分。

我的方法是这样的:

  1. 将您的 db.log 函数更改为指向eval(是的,ew)
  2. 与其将 LogLevels 作为参数传递,不如为它们中的每一个创建函数,返回其中包含的字符串console.log和自定义消息。

它应该看起来像这样:

db = {LogLevel: {}};
db.log = eval;
db.LogLevel.warn = function(message) {
   return "console.log('THIS IS A WARNING: " + message + "');";
};

您现在应该可以这样称呼它:

db.log(db.LogLevel.warn("Blah blah blah"));
于 2010-12-13T03:08:01.593 回答
1
//trust me, this way rocks!  Auto prepend a logHead, yet keep correct line number displayed debug view.
//Output sample:
//  5/10 1:13:52.553  hi                                    a.js:100
//  5/10 1:13:52.553  err                                   b.js:200

    var Log = {
        debug : true,

        /*
         * log.d(logData1, logData2, ...)
         *  --> console.log( getLogHead(), logData1, logData2, ...)
         * 
         * @comment Using bind and property accesser
         * @see http://ejohn.org/blog/javascript-getters-and-setters/
         */
        get d() { 
            if ( !this.debug) return _emptyFunc;
            return console.log.bind( console, this._getLogHeader() );
        },

        /*
         * output error info
         */
        get e() { 
            return console.error.bind( console, this._getLogHeader() );
        },

        /**
         * get current time in 01/31 23:59:59.999 format
         */
        _getLogHeader : function () {

            var millisec = Date.now();
            this._dtNow.setTime( millisec );
            //toLocaleString is 2013/01/31 23:59:59
            return this._dtNow.toLocaleString().slice( 5 ) + '.' + ('000' + millisec).slice( -3 ) + ' ';
        },
        _dtNow: new Date(),
        _emptyFunc: function() {}
    };


    //enjoy it !
        Log.d('hi');
        Log.e('err');
于 2013-05-09T16:08:55.677 回答
0

通常使用 debug() 或 error() 而不是 log() 函数将导致显示行号。我相信 Google Chrome 控制台的工作方式类似。(萤火虫参考

于 2010-11-05T21:26:53.333 回答
0

所以这最近又出现了,所以我决定重新审视它。

现在我年纪大了,更聪明了,我很清楚一个更好的解决方案,然后我试图做的是按原样调用控制台功能,但在关卡关闭时有选择地用虚拟功能替换它们。这为我提供了细粒度的日志记录和准确的行号报告。我以前的解决方案丢失了一些功能,但我认为这是一个可以接受的折衷方案。

这是我的新日志库的部分片段,它显示了主要解决方案

...
levels : ["debug","info","warn","error"],

    init : function(minLevel) {
        var params = abm.getUrlParams();
        minLevel = params["debug"] || minLevel;

        //TODO: firebug lite
        window.console = window.console || {};

        var clear = false;
        for (var i=0; i<self.levels.length; i++) {
            var level = self.levels[i];
            originalFunctions[i] = originalFunctions[i] 
            || console[level] || fallback;

            if (level && (clear || level===minLevel)) {
                console[level] = originalFunctions[i];
                clear=true;
            } else {
                console[level] = suppressed(level);
            }
        }

    }
...

你可以在这里看到完整的东西:https ://github.com/antiBaconMachine/abm-log

于 2012-08-30T14:30:31.053 回答
0

这里有两种方法可以在不丢失上下文的情况下包装日志记录。从调用者的角度来看,第一个有点难看。第二个仅在您不需要记录的详细信息时才可用。

有关演示,请参阅 JSFiddle:http: //jsfiddle.net/epQ95/1/

// logger method 1: allows for fully functional log-wrapping without losing context,
//                  but, it is very ugly from the caller's perspective.
var debug = function () {
    // do my extra special stuff
    window.console.log("logging to server 1: ", arguments);

    // do regular console logging, if possible
    if (window.console && window.console.log) {
        return window.console.log.apply.bind(window.console.log, window.console, arguments);
    } else {
        return function () {};
    }
};

// caller
debug("logger method", 1)();

// logger method 2: pretty calling, but you don't know what was logged,
//                  just that something definitely was.
var Logger = {};
Logger.__defineGetter__("debug", function () {
    // do my extra special stuff
    window.console.log("logging to server 2: don't know what was logged");

    // do regular console logging, if possible
    if (window.console && window.console.log) {
        return console.log.bind(window.console);
    } else {
        return function () {};
    }
});

// caller
Logger.debug("logger method", 2);
于 2013-08-13T22:31:04.177 回答