keymetrics / pm2-io-apm

PM2.io APM for Node.JS
Apache License 2.0
147 stars 39 forks source link

Network metric results in MaxListenerExceededWarning errors #275

Open BeeFox-sys opened 4 years ago

BeeFox-sys commented 4 years ago

In trying to set up my metrics, I have encounted an error where enabling the network metric results in repeated postings of the MaxListenerExceededWarning error. Here is how I am initalizing the io:

io.init({
    metrics: {
        eventLoop: false,
        network: true,
        http: false,
        gc: false,
        v8: false
    }
});

Here is the error:

(node:3784) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 data listeners added to [TLSSocket]. Use emitter.setMaxListeners() to increase limit

And here is the traceback:

(node:6300) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 data listeners added to [TLSSocket]. Use emitter.setMaxListeners() to increase limit
    at _addListener (events.js:389:17)
    at TLSSocket.addListener (events.js:405:10)
    at TLSSocket.Readable.on (_stream_readable.js:853:35)
    at TLSSocket.read (C:\Users\Fiona\Desktop\Code\discordbots\blasebot\node_modules\@pm2\io\build\main\metrics\network.js:78:26)      
    at maybeReadMore_ (_stream_readable.js:624:12)
    at processTicksAndRejections (internal/process/task_queues.js:80:21)

A prompt solution would be great! Thanks! Node version: v14.5.0 pm2/io version: 4.3.5

glebcha commented 2 years ago

Exact snippet that raised error in my particular case this.on('data', (data) => {....}

setTimeout(() => {
    const property = netModule.Socket.prototype.read;
    const isWrapped = property && property.__wrapped === true;
    if (isWrapped) {
        return this.logger(`Already patched socket read, canceling`);
    }
    shimmer.wrap(netModule.Socket.prototype, 'read', function (original) {
        return function () {
            this.on('data', (data) => {
                if (typeof data.length === 'number') {
                    downloadMeter.mark(data.length);
                }
            });
            return original.apply(this, arguments);
        };
    });
}, 500);