Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I log every method call in node.js without adding debug lines everywhere?

I would like to log the user_id of the person making a request and the method name of every method called for a javascript class. For example:

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

Since everything is async user 35 and 78 might be doing stuff at the same time. So I want to make sure each log line starts with their user_id so I can grep for it and only see one user's activity at a time.

Is there a super clever way to do this without adding logger statements to every method?

like image 626
Andrew Arrow Avatar asked Apr 08 '13 21:04

Andrew Arrow


2 Answers

The answer is essentially correct, but here's how to avoid infinite 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
like image 103
mthorley Avatar answered Oct 24 '22 12:10

mthorley


This is one alternative, not entirely sure how reliable it is though, it feels a bit wrong:

(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;
})();

As you can see, it overwrites the call function - this creates a slight problem when you try to call console.log() so you need to swap the function back. But it seems to work!

EDIT

Since this is tagged 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
like image 21
phenomnomnominal Avatar answered Oct 24 '22 13:10

phenomnomnominal