NodeJS : How to debug "EventEmitter memory leak detected. 11 listeners added"

How can I debug my application witch throw this error:

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
    at Socket.EventEmitter.addListener (events.js:160:15)
    at Socket.Readable.on (_stream_readable.js:653:33)
    at Socket.EventEmitter.once (events.js:179:8)
    at TCP.onread (net.js:527:26)

I could not find the assumed leaking object for increasing listener limit by .setMaxListeners(0);

SOLUTION (from fardjad and jan salawa)

With jan salawa's searches I found a working library (longjohn) for increasing stack traces verbose. With fardjad's response I have found that we have to prototype EventEmitter.addListener AND EventEmitter.on.

With this solution I could get this new trace :

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
    at EventEmitter.addListener.EventEmitter.on (xxx/main.js:44:15)
    at Readable.on (_stream_readable.js:653:33)
    at ServerResponse.assignSocket (http.js:1072:10)
    at parser.onIncoming (http.js:1979:11)
    at parserOnHeadersComplete (http.js:119:23)
    at socket.ondata (http.js:1912:22)
    at TCP.onread (net.js:510:27)

It turns out that this is a bug in nodejs core, we are talking about this problem here :

https://github.com/joyent/node/issues/5108

Solution for bugged http servers thats throw an EventEmitter memory leak detected and fill up the available memory / available CPU times :

Revert to legacy version v0.8.23.

You can download and install/compile it from here :

http://blog.nodejs.org/2013/04/08/node-v0-8-23-legacy/

For me it's looks like your event loop is blocked. This can happen if you are doing cpu intensive tasks in node.js event loop. You can use child process to do intensive task.

You can check what is blocking node.js using following methods:

  1. Measure computation time of each call. Log if time is high so you know app is misbehaving.
  2. Set up a log schedule so you know when something blocking loop
    function timeTick() {
        var startTime = (new Date().getTime());
        function onTick() {
            var interval = (new Date().getTime()) - startTime;
            if(interval > 5)
                console.log('timeTick(): WARNING: interval = ' + interval);
        }
       process.nextTick(onTick);
    }
    setInterval(timeTick, 1000);
  3. Use profile.
  4. Use this for logging and profiling. It's library used in Nodejitsu.

This is exactly what happened to me. For me, I nested an event listener within another event listener accidentally.

Look at your code and make sure you DO NOT have an event listener block WITHIN another event listener block for example(unless you are doing it on purpose):

socket.on('data', function(data) {
//code goes here

socket.on('close' , function() {
//code goes here
     });

   });

In the wrong example above, the socket.on ('close') listener should be OUTSIDE of the socket.on('data') block.

In my case when I received 5 data streams, the socket.on('close') listener is waiting for a close event to happen. When I close once, another 4th closing event would execute. This is clearly not what I wanted. This is due to the nature of Node.js which is non-blocking. It 'remembers' events due to the callback function.

I tried to prototype the EventEmitter for adding log messages into addListener but i could not get it working

To hook addListener you can do something like this:

// on the first line of your main script
var events = require("events"),
    EventEmitter = events.EventEmitter;

var originalAddListener = EventEmitter.prototype.addListener;
EventEmitter.prototype.addListener = function (type, listener) {
    if (this.listenerCount(this, type) >= 10) {
        // TODO: PLACE YOUR CODE FOR DEBUGGING HERE
    }
    originalAddListener.apply(this, arguments);
}