diff --git a/lib/helper.js b/lib/helper.js index 06db60e..2926a4f 100644 --- a/lib/helper.js +++ b/lib/helper.js @@ -3,14 +3,56 @@ var termTypes = protodef.Term.TermType; var datumTypes = protodef.Datum.DatumType; var net = require('net'); +var logLevels = { + error: 0, + warn: 1, + info: 2, + verbose: 3, + debug: 4, +}; -function createLogger(poolMaster, silent) { - return function(message) { - if (silent !== true) { - console.error(message); +function createLogger(poolMaster, logger, logLevel) { + var maxLevel = logLevels[logLevel]; + if (maxLevel === undefined) { + throw new Error('Unsupported log level: ' + logLevel); + } + + var log = Function.prototype; + if (logger === undefined) { + log = function(message, level) { + if (level === 'error') { + console.error(message); + } else if (level === 'warn') { + console.warn(message); + } else { + console.log(message); + } + }; + } else if (logger) { + if (typeof logger === 'function') { + log = logger; + } else if (typeof logger === 'object') { + log = function(message, logLevel) { + logger[logLevel](message); + }; + } else { + throw new TypeError('`options.log` must be an object or function'); } - poolMaster.emit('log', message); } + + return { + log: function(level, message) { + if (logLevels[level] <= maxLevel) { + log(message, level); + poolMaster.emit('log', message, level); + } + }, + error: function(error) { + log(error.stack, 'error'); + poolMaster.emit('log', error.stack, 'error'); + poolMaster.emit('error', error); + } + }; } module.exports.createLogger = createLogger; diff --git a/lib/pool.js b/lib/pool.js index 85e1412..101ce4b 100644 --- a/lib/pool.js +++ b/lib/pool.js @@ -61,7 +61,7 @@ function Pool(r, options) { } }, 0); this.id = Math.floor(Math.random()*100000); - this._log('Creating a pool connected to '+this.getAddress()); + this._log('info', 'Creating a pool connected to: ' + this.getAddress()); } util.inherits(Pool, events.EventEmitter); @@ -152,7 +152,8 @@ Pool.prototype.putConnection = function(connection) { else if (self._extraConnections > 0) { self._extraConnections--; connection.close().error(function(error) { - self._log('Fail to properly close a connection. Error:'+JSON.stringify(error)); + self._log('debug', 'Failed to close a connection properly: ' + error.message); + self._log.error(error); }); clearTimeout(connection.timeout); } @@ -162,7 +163,8 @@ Pool.prototype.putConnection = function(connection) { // Note that because we have available connections here, the pool master has no pending // queries. connection.close().error(function(error) { - self._log('Fail to properly close a connection. Error:'+JSON.stringify(error)); + self._log('debug', 'Failed to close a connection properly: ' + error.message); + self._log.error(error); }); clearTimeout(connection.timeout); } @@ -219,7 +221,7 @@ Pool.prototype.createConnection = function() { } // Need another flag else if ((self._slowlyGrowing === true) && (self._slowGrowth === true) && (self._consecutiveFails > 0)) { - self._log('Exiting slow growth mode'); + self._log('info', 'Exiting slow growth mode'); self._consecutiveFails = 0; self._slowGrowth = false; self._slowlyGrowing = false; @@ -231,7 +233,8 @@ Pool.prototype.createConnection = function() { connection.on('error', function(error) { // We are going to close connection, but we don't want another process to use it before // So we remove it from the pool now (if it's inside) - self._log('Error emitted by a connection: '+JSON.stringify(error)); + self._log('debug', 'Error emitted by a connection: ' + error.message); + self._log.error(error); for(var i=0; i