如何在node.js中logging每个方法调用,而无需在每个地方添加debugging行?

我想logging发出请求的用户的user_id,以及为JavaScript类调用的每个方法的方法名称。 例如:

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 

因为一切都是asynchronous用户35和78可能在同一时间做的东西。 所以我想确保每个日志行以user_id开头,这样我就可以grep了,而且一次只能看到一个用户的活动。

有没有一个超级聪明的方式来做到这一点,而不是每个方法都添加logging器语句?

我猜这是一个networking应用程序,在这种情况下,如果您使用连接,您可以使用logging器中间件logging用户和URLpath,这可能就足够了。 否则,你将不得不做一些元编程沿包装函数中的每个函数进行日志logging。

 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 } 

答案基本上是正确的,但是这里是如何避免无限recursion

使用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 

这是一个select,不完全确定它是多么可靠,这感觉有点不对劲:

 (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