2013-04-08 36 views
8

我想記錄發出請求的用戶的user_id以及爲JavaScript類調用的每個方法的方法名稱。例如:如何在node.js中記錄每個方法調用,而無需在所有地方添加調試行?

35 - log_in 
35 - list_of_other_users 
78 - log_in 
35 - send_message_to_user 
35 - connect_to_redis 
78 - list_of_other_users 

因爲一切都是異步用戶35和78可能在同一時間做的東西。所以我想確保每個日誌行以它們的user_id開頭,這樣我就可以grep,並且一次只能看到一個用戶的活動。

有沒有一種超級聰明的方式來做到這一點,而不需要向每個方法添加記錄器語句?

+0

的可能的複製[如何調試的Node.js應用程序?(http://stackoverflow.com/questions/1911015/how-do-i-debug-node-js-應用程序) – Sylar 2016-06-27 16:54:23

回答

2

我猜這是一個web應用程序,在這種情況下,如果您使用連接,您可以使用記錄器中間件記錄用戶和URL路徑,這可能就足夠了。否則,你將不得不按照包裝函數中的每個函數來執行一些元編程來執行日誌記錄。

function logCall(realFunc, instance) { 
    return function() { 
     log.debug('User: ' + instance.user_id + ' method ' + realFunc.name); 
     return realFunc.apply(instance, arguments); 
    }; 
} 

爲此,您的類方法必須被命名爲函數,而不是匿名。

function sendMessage() { 
    //code to send message 
    //can use `this` to access instance properties 
} 
function MyClass(userId) { 
    this.userId = userId; //or whatever 
    this.sendMessage = logCall(sendMessage, this); 
    //repeat above line for each instance method you want instrumented for logging 
} 
4

這是一個選擇,不能完全肯定這是雖然有多可靠,感覺有點不對勁:

(function() { 
    var oldCall = Function.prototype.call; 
    var newCall = function(self) { 
    Function.prototype.call = oldCall; 
    console.log('Function called:', this.name); 
    var args = Array.prototype.slice.call(arguments, 1); 
    Function.prototype.call = newCall; 
    this.apply(self, args); 
    } 
    Function.prototype.call = newCall; 
})(); 

正如你所看到的,它覆蓋call功能 - 這創造了一個小問題當您嘗試撥打console.log()時,您需要將功能交換回去。但它似乎工作!

編輯

由於這是標記的CoffeeScript:

do -> 
    oldCall = Function::call 
    newCall = (self) -> 
    Function::call = oldCall 
    console.log "Function called: #{this.name}" 
    args = Array.prototype.slice.call arguments, 1 
    Function::call = newCall 
    this.apply self, args 
    Function::call = newCall 
+0

這對我來說是一個無限遞歸,因爲slice被稱爲函數。在設置newCall之前,我必須移動切片調用並將結果作爲下面的變量傳遞。不知道現在是否可行 – 2014-02-03 14:19:54

+1

@AlexLehmann如何更改代碼以避免無限遞歸? – 2014-04-10 04:11:22

5

答案基本上是正確的,但在這裏是如何避免無限遞歸

的Javascript

(function() { 
    var oldCall = Function.prototype.call; 
    var newCall = function(self) { 
    Function.prototype.call = oldCall; 
    console.log('Function called:', this.name); 
    var args = Array.prototype.slice.call(arguments, 1); 
    var res = this.apply(self, args); 
    Function.prototype.call = newCall; 
    return res 
    } 
    Function.prototype.call = newCall; 
})(); 

CoffeeScript的

do -> 
    oldCall = Function::call 
    newCall = (self) -> 
    Function::call = oldCall 
    console.log "Function called: #{this.name}" 
    args = Array.prototype.slice.call arguments, 1 
    res = this.apply self, args 
    Function::call = newCall 
    res 
    Function::call = newCall 
+1

這很棒,但是您能否介紹一下這個工作原理,並提供一個使用示例?它非常先進,SE也適用於初學者/中級用戶。 :d – zehelvion 2017-04-12 07:57:40

相關問題