简体   繁体   English

如何在包装Firebug(或类似的)控制台api时访问行号

[英]How to access line numbers when wrapping Firebug (or similar) Console api

I have wrapped the console API to provide granular logging levels as well as few other sugar features. 我已经包装了控制台API,以提供精细的日志记录级别以及其他一些糖功能。

This works fine, the only problem is that firebug (or whatever other console) will always report the line number the log came from as the line the console API itself is invoked. 这很好,唯一的问题是firebug(或其他任何控制台)将始终报告日志来自控制台API本身的行号。

How would you suggest I make the console log the line number at which I call my wrapper function? 你怎么建议我让控制台记录我调用包装函数的行号?

I would prefer a cross browser solution but failing that a firebug plugin could be a good start. 我更喜欢跨浏览器解决方案,但没有一个firebug插件可能是一个良好的开端。

fyi I call my loging function like so: 我这样称呼我的登录功能:

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

Interesting problem... I may have a hack for you. 有趣的问题......我可能会有一个黑客攻击你。 I can't test this right now, but I think it might work. 我现在无法测试,但我认为它可能有效。

We know that a regular function call won't work, so I started thinking about #defines in C and macros in various other languages. 我们知道常规函数调用不起作用,所以我开始考虑C中的#defines和其他各种语言的宏。 Unfortunately, javascript doesn't have this, but perhaps an eval hack will work . 不幸的是,javascript没有这个,但也许eval hack会起作用 I'm expecting that eval will run the code as if it came from the same line - if not, bleh, ignore the rest of this answer. 我期待eval将运行代码,就好像它来自同一行 - 如果不是,那么,请忽略其余的答案。

My method works like this: 我的方法是这样的:

  1. Change your db.log function to point to eval (yes, ew) 将db.log函数更改为指向eval (是,否)
  2. Instead of passing in your LogLevels as an argument, create functions for each of them that returns a string with console.log in it and a custom message. 不要将LogLevels作为参数传递,而是为每个返回带有console.log的字符串和自定义消息的函数创建函数。

It should look something like this: 它应该看起来像这样:

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

You should be able to call it like this now: 您现在应该能够像这样调用它:

db.log(db.LogLevel.warn("Blah blah blah"));
//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');

So this recently came up again so I decided to revisit it. 所以这最近又出现了,所以我决定再次访问它。

Now I'm older and wiser it's clear to me a much better solution then what I was trying to do is to call the console functions as they are but selectively replace them with dummy functions when the level is turned down. 现在我更老了,更聪明一点,对我来说更清楚一个更好的解决方案然后我想要做的就是调用控制台功能,但是当关闭水平时选择性地用虚拟功能替换它们。 This gives me fine grained logging and accurate line number reporting. 这为我提供了精细的记录和准确的行号报告。 A few features have been lost from my previous solution but I think this is an acceptable compromise. 我之前的解决方案已经丢失​​了一些功能,但我认为这是一个可接受的折衷方案。

Here's a partial snip of my new logging lib which shows the main solution 这是我的新日志库的部分剪辑,它显示了主要的解决方案

...
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);
            }
        }

    }
...

You can see the full thing here: https://github.com/antiBaconMachine/abm-log 你可以在这里看到完整的东西: https//github.com/antiBaconMachine/abm-log

Here are two ways to wrap logging without losing context. 以下是两种在不丢失上下文的情况下包装日志记录 The first is a little bit ugly from the caller's side. 第一个是来自呼叫方的有点难看。 The second is only usable if you don't need the details of what was logged. 第二个仅在您不需要记录内容的详细信息时才可用。

See the JSFiddle for a demo: http://jsfiddle.net/epQ95/1/ 请参阅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);

Typically using the debug() or error() instead of log() functions will cause line numbers to be displayed. 通常使用debug()或error()而不是log()函数将导致显示行号。 I believe the Google Chrome console works similarly. 我相信Google Chrome控制台的工作方式与此类似。 ( firebug reference ) 萤火虫参考

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM