mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-26 15:15:49 +00:00
Log: New logging system.
Right now, all I've done is move the logging function from utils to its own file. I've also refactored it and created some classes. Next step would be to somehow get rid of the trace setting. The Remote class should have nothing to do with logging settings. Perhaps we can keep the setting for backwards compatibility only, but the main way to turn logging on/off or filter logging messages should be through the Log class.
This commit is contained in:
116
src/js/ripple/log.js
Normal file
116
src/js/ripple/log.js
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Logging functionality for ripple-lib and any applications built on it.
|
||||
*/
|
||||
var Log = function (namespace) {
|
||||
if (!namespace) {
|
||||
this._namespace = [];
|
||||
} else if (Array.isArray(namespace)) {
|
||||
this._namespace = namespace;
|
||||
} else {
|
||||
this._namespace = [""+namespace];
|
||||
}
|
||||
|
||||
this._prefix = this._namespace.concat(['']).join(': ');
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a sub-logger.
|
||||
*
|
||||
* You can have a hierarchy of loggers.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var log = require('ripple').log.sub('server');
|
||||
*
|
||||
* log.info('connection successful');
|
||||
* // prints: "server: connection successful"
|
||||
*/
|
||||
Log.prototype.sub = function (namespace) {
|
||||
var subNamespace = this._namespace.slice();
|
||||
if (namespace && "string" === typeof namespace) subNamespace.push(namespace);
|
||||
var subLogger = new Log(subNamespace);
|
||||
subLogger._setParent(this);
|
||||
return subLogger;
|
||||
};
|
||||
|
||||
Log.prototype._setParent = function (parentLogger) {
|
||||
this._parent = parentLogger;
|
||||
};
|
||||
|
||||
Log.makeLevel = function (level) {
|
||||
return function () {
|
||||
arguments[0] = this._prefix + arguments[0];
|
||||
|
||||
Log.engine.logObject.apply(Log, Array.prototype.slice.call(arguments));
|
||||
};
|
||||
};
|
||||
|
||||
Log.prototype.debug = Log.makeLevel(1);
|
||||
Log.prototype.info = Log.makeLevel(2);
|
||||
Log.prototype.warn = Log.makeLevel(3);
|
||||
Log.prototype.error = Log.makeLevel(4);
|
||||
|
||||
/**
|
||||
* Basic logging connector.
|
||||
*
|
||||
* This engine has no formatting and works with the most basic of "console.log"
|
||||
* implementations. This is the logging engine used in Node.js.
|
||||
*/
|
||||
var BasicLogEngine = {
|
||||
logObject: function logObject(msg) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
args = args.map(function(arg) {
|
||||
return JSON.stringify(arg, null, 2);
|
||||
});
|
||||
|
||||
args.unshift(msg);
|
||||
|
||||
console.log.apply(console, args);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Null logging connector.
|
||||
*
|
||||
* This engine simply swallows all messages. Used when console.log is not
|
||||
* available.
|
||||
*/
|
||||
var NullLogEngine = {
|
||||
logObject: function () {}
|
||||
};
|
||||
|
||||
Log.engine = NullLogEngine;
|
||||
|
||||
if (console && console.log) Log.engine = BasicLogEngine;
|
||||
|
||||
/**
|
||||
* Provide a root logger as our main export.
|
||||
*
|
||||
* This means you can use the logger easily on the fly:
|
||||
* ripple.log.debug('My object is', myObj);
|
||||
*/
|
||||
module.exports = new Log();
|
||||
|
||||
/**
|
||||
* This is the logger for ripple-lib internally.
|
||||
*/
|
||||
module.exports.internal = module.exports.sub();
|
||||
|
||||
/**
|
||||
* Expose the class as well.
|
||||
*/
|
||||
module.exports.Log = Log;
|
||||
|
||||
/**
|
||||
* An easy way to create a new logger for a namespace.
|
||||
*
|
||||
* Browser:
|
||||
* var log = ripple.log.called('client.id');
|
||||
* log.debug('My object is', myObj);
|
||||
*
|
||||
* Node.js:
|
||||
* var log = require('ripple').log.called('gateway.main');
|
||||
* log.debug('My object is', myObj);
|
||||
*/
|
||||
module.exports.called = Log.makeLogger;
|
||||
30
src/js/ripple/log.web.js
Normal file
30
src/js/ripple/log.web.js
Normal file
@@ -0,0 +1,30 @@
|
||||
var exports = module.exports = require('./log.js');
|
||||
|
||||
/**
|
||||
* Log engine for browser consoles.
|
||||
*
|
||||
* Browsers tend to have better consoles that support nicely formatted
|
||||
* JavaScript objects. This connector passes objects through to the logging
|
||||
* function without any stringification.
|
||||
*/
|
||||
var InteractiveLogEngine = {
|
||||
logObject: function (msg, obj) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
args = args.map(function(arg) {
|
||||
if (/MSIE/.test(navigator.userAgent)) {
|
||||
return JSON.stringify(arg, null, 2);
|
||||
} else {
|
||||
return arg;
|
||||
}
|
||||
});
|
||||
|
||||
args.unshift(msg);
|
||||
|
||||
console.log.apply(console, args);
|
||||
}
|
||||
};
|
||||
|
||||
if (window.console && window.console.log) {
|
||||
exports.Log.engine = InteractiveLogEngine;
|
||||
}
|
||||
@@ -30,6 +30,7 @@ var RippleError = require('./rippleerror').RippleError;
|
||||
var utils = require('./utils');
|
||||
var sjcl = require('./utils').sjcl;
|
||||
var config = require('./config');
|
||||
var log = require('./log').internal.sub('remote');
|
||||
|
||||
/**
|
||||
Interface to manage the connection to a Ripple server.
|
||||
@@ -358,7 +359,7 @@ Remote.prototype.setSecret = function(account, secret) {
|
||||
|
||||
Remote.prototype._trace = function() {
|
||||
if (this.trace) {
|
||||
utils.logObject.apply(utils, arguments);
|
||||
log.info.apply(log, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ var EventEmitter = require('events').EventEmitter;
|
||||
var Transaction = require('./transaction').Transaction;
|
||||
var Amount = require('./amount').Amount;
|
||||
var utils = require('./utils');
|
||||
var log = require('./log').internal.sub('server');
|
||||
|
||||
/**
|
||||
* @constructor Server
|
||||
@@ -104,7 +105,7 @@ Server.onlineStates = [
|
||||
|
||||
Server.prototype._setState = function(state) {
|
||||
if (state !== this._state) {
|
||||
this._remote._trace('server: set_state:', state);
|
||||
this._remote.trace && log.info('set_state:', state);
|
||||
this._state = state;
|
||||
this.emit('state', state);
|
||||
|
||||
@@ -189,7 +190,7 @@ Server.prototype.connect = function() {
|
||||
// we will automatically reconnect.
|
||||
if (this._connected) return;
|
||||
|
||||
this._remote._trace('server: connect:', this._opts.url);
|
||||
this._remote.trace && log.info('connect:', this._opts.url);
|
||||
|
||||
// Ensure any existing socket is given the command to close first.
|
||||
if (this._ws) this._ws.close();
|
||||
@@ -223,7 +224,7 @@ Server.prototype.connect = function() {
|
||||
// If we are no longer the active socket, simply ignore any event
|
||||
if (ws === self._ws) {
|
||||
self.emit('socket_error');
|
||||
self._remote._trace('server: onerror:', self._opts.url, e.data || e);
|
||||
self._remote.trace && log.info('onerror:', self._opts.url, e.data || e);
|
||||
|
||||
// Most connection errors for WebSockets are conveyed as 'close' events with
|
||||
// code 1006. This is done for security purposes and therefore unlikely to
|
||||
@@ -247,7 +248,7 @@ Server.prototype.connect = function() {
|
||||
ws.onclose = function onClose() {
|
||||
// If we are no longer the active socket, simply ignore any event
|
||||
if (ws === self._ws) {
|
||||
self._remote._trace('server: onclose:', self._opts.url, ws.readyState);
|
||||
self._remote.trace && log.info('onclose:', self._opts.url, ws.readyState);
|
||||
self._handleClose();
|
||||
}
|
||||
};
|
||||
@@ -274,7 +275,7 @@ Server.prototype._retryConnect = function() {
|
||||
|
||||
function connectionRetry() {
|
||||
if (self._shouldConnect) {
|
||||
self._remote._trace('server: retry', self._opts.url);
|
||||
self._remote.trace && log.info('retry', self._opts.url);
|
||||
self.connect();
|
||||
}
|
||||
};
|
||||
@@ -351,9 +352,9 @@ Server.prototype._handleMessage = function(message) {
|
||||
delete self._requests[message.id];
|
||||
|
||||
if (!request) {
|
||||
this._remote._trace('server: UNEXPECTED:', self._opts.url, message);
|
||||
this._remote.trace && log.info('UNEXPECTED:', self._opts.url, message);
|
||||
} else if (message.status === 'success') {
|
||||
this._remote._trace('server: response:', self._opts.url, message);
|
||||
this._remote.trace && log.info('response:', self._opts.url, message);
|
||||
|
||||
request.emit('success', message.result);
|
||||
|
||||
@@ -361,7 +362,7 @@ Server.prototype._handleMessage = function(message) {
|
||||
emitter.emit('response_' + request.message.command, message.result, request, message);
|
||||
});
|
||||
} else if (message.error) {
|
||||
this._remote._trace('server: error:', self._opts.url, message);
|
||||
this._remote.trace && log.info('error:', self._opts.url, message);
|
||||
|
||||
request.emit('error', {
|
||||
error : 'remoteError',
|
||||
@@ -372,7 +373,7 @@ Server.prototype._handleMessage = function(message) {
|
||||
break;
|
||||
|
||||
case 'path_find':
|
||||
this._remote._trace('server: path_find:', self._opts.url, message);
|
||||
this._remote.trace && log.info('path_find:', self._opts.url, message);
|
||||
break;
|
||||
|
||||
}
|
||||
@@ -431,7 +432,7 @@ Server.prototype._handleResponseSubscribe = function(message) {
|
||||
|
||||
Server.prototype.sendMessage = function(message) {
|
||||
if (this._ws) {
|
||||
this._remote._trace('server: request:', this._opts.url, message);
|
||||
this._remote.trace && log.info('request:', this._opts.url, message);
|
||||
this._ws.send(JSON.stringify(message));
|
||||
}
|
||||
};
|
||||
@@ -451,7 +452,7 @@ Server.prototype.request = function(request) {
|
||||
|
||||
// Only bother if we are still connected.
|
||||
if (!this._ws) {
|
||||
this._remote._trace('server: request: DROPPING:', self._opts.url, request.message);
|
||||
this._remote.trace && log.info('request: DROPPING:', self._opts.url, request.message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,18 +92,6 @@ function chunkString(str, n, leftAlign) {
|
||||
return ret;
|
||||
};
|
||||
|
||||
function logObject(msg) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
args = args.map(function(arg) {
|
||||
return JSON.stringify(arg, null, 2);
|
||||
});
|
||||
|
||||
args.unshift(msg);
|
||||
|
||||
console.log.apply(console, args);
|
||||
};
|
||||
|
||||
function assert(assertion, msg) {
|
||||
if (!assertion) {
|
||||
throw new Error("Assertion failed" + (msg ? ": "+msg : "."));
|
||||
@@ -157,7 +145,6 @@ exports.hexToArray = hexToArray;
|
||||
exports.stringToArray = stringToArray;
|
||||
exports.stringToHex = stringToHex;
|
||||
exports.chunkString = chunkString;
|
||||
exports.logObject = logObject;
|
||||
exports.assert = assert;
|
||||
exports.arrayUnique = arrayUnique;
|
||||
exports.toTimestamp = toTimestamp;
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
var exports = module.exports = require('./utils.js');
|
||||
|
||||
// We override this function for browsers, because they print objects nicer
|
||||
// natively than JSON.stringify can.
|
||||
exports.logObject = function (msg, obj) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
args = args.map(function(arg) {
|
||||
if (/MSIE/.test(navigator.userAgent)) {
|
||||
return JSON.stringify(arg, null, 2);
|
||||
} else {
|
||||
return arg;
|
||||
}
|
||||
});
|
||||
|
||||
args.unshift(msg);
|
||||
|
||||
console.log.apply(console, args);
|
||||
};
|
||||
Reference in New Issue
Block a user