9

コンソール API をラップして、詳細なログ レベルとその他のいくつかのシュガー機能を提供します。

これは正常に動作しますが、唯一の問題は、firebug (または他のコンソール) が、コンソール API 自体が呼び出された行として、ログの元の行番号を常に報告することです。

ラッパー関数を呼び出す行番号をコンソールに記録させるにはどうすればよいでしょうか?

私はクロスブラウザソリューションを好みますが、firebug プラグインが良いスタートになる可能性があることに失敗しました.

参考までに、ログ機能を次のように呼び出します。

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

5 に答える 5

3

興味深い問題...ハックがあるかもしれません。現時点ではテストできませんが、うまくいくと思います。

通常の関数呼び出しが機能しないことはわかっているので、C の #defines や他のさまざまな言語のマクロについて考え始めました。残念ながら、javascript にはこれがありませんがevalハックが機能する可能性があります。同じ行から来たかのようにコードが実行されることを期待していevalます-そうでない場合は、この回答の残りを無視してください。

私の方法は次のように機能します:

  1. db.log 関数をeval(yes, ew)を指すように変更します。
  2. console.logLogLevels を引数として渡す代わりに、文字列とカスタム メッセージを返す関数をそれぞれに作成します。

次のようになります。

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

通常、log() 関数の代わりに debug() または error() を使用すると、行番号が表示されます。Google Chrome コンソールも同様に機能すると思います。( firebug 参照)

于 2010-11-05T21:26:53.333 に答える
0

コンテキストを失わずにロギングをラップする 2 つの方法を次に示します。1 つ目は、呼び出し側から見ると少し見にくいです。2 番目は、ログに記録された内容の詳細が必要ない場合にのみ使用できます。

デモについては、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 に答える
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 に答える