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

发布于 2024-09-11 14:41:47 字数 304 浏览 9 评论 0原文

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

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

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

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

仅供参考,我这样称呼我的日志函数:

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

I have wrapped the console API to provide granular logging levels as well as few other sugar features.

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.

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.

fyi I call my loging function like so:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

痞味浪人 2024-09-18 14:41:47

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

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

我的方法是这样工作的:

  1. 将 db.log 函数更改为指向 eval (是的,ew)
  2. 不要将 LogLevels 作为参数传递,而是为每个函数创建返回带有 < 的字符串的函数。其中的 code>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"));

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. Unfortunately, javascript doesn't have this, but perhaps an eval hack will work. 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.

My method works like this:

  1. Change your db.log function to point to eval (yes, ew)
  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.

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"));
风透绣罗衣 2024-09-18 14:41:47
//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');
//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');
傻比既视感 2024-09-18 14:41:47

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

Typically using the debug() or error() instead of log() functions will cause line numbers to be displayed. I believe the Google Chrome console works similarly. (firebug reference)

简美 2024-09-18 14:41:47

所以最近这个问题再次出现,所以我决定重新审视它。

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

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

...
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

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

不知在何时 2024-09-18 14:41:47

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

请参阅 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);

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/

// 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文