2013-04-08 48 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

相关问题