remote-logger-browser
Version:
Remote-Logger javascript support library to be run in browsers
228 lines (212 loc) • 7.61 kB
JavaScript
(function (global, undefined) {
var log = function () {};
if (typeof console !== 'undefined' && typeof console.log === 'function') {
log = console.log;
}
var Socket = (function () {
var s = {};
s.ws = null;
s.caches = [];
s.proto = {
MessageCatalog: {
CATALOG_INFORMATION: 1,
CATALOG_WARNING: 2,
CATALOG_ERROR: 3,
CATALOG_FATAL: 4,
CATALOG_DEBUG: 5,
CATALOG_ASSERT: 6,
CATALOG_VERBOSE: 7
}
};
s.ready = 0; // 协议是否可以载入,0 为初始状态,等待载入结果 , 1 已载入 , -1 载入失败
s.connect = function (wss, reconnectable) {
if (s.ws != null) {
s.ws.onclose = null;
s.ws.onopen = null;
s.ws.onerror = null;
s.ws.close();
s.ws = null;
}
reconnectable = typeof reconnectable === 'undefined' ? false : (!!reconnectable);
s.ws = new WebSocket(wss);
s.ws.onopen = function () {
for(var i = 0; i < s.caches.length; i ++) {
var encoded = s.encode(s.caches[i]);
if (encoded.length > 0) {
s.ws.send(encoded);
}
}
s.caches.splice(0, s.caches.length);
};
s.ws.onerror = function (error) {
//
};
s.ws.onclose = function () {
if (reconnectable) {
window.setTimeout(function () {
s.connect(wss);
}, 3000);
}
};
};
/*
* @message [object] message object which should have {timestamp:, message:, type:, path:}
*/
s.encode = function (message) {
try {
var append = s.proto.AppendMessage.encode(message).finish();
if (!(append instanceof Uint8Array) || append === null) {
throw 'Failed to encode AppendMessage, expects a UInt8Array but actual got a ' + (typeof append);
}
var writer = s.proto.MessageHeader.encode({tag: s.proto.HeaderTags.V1, type: s.proto.MessageIdentity.APPEND_MESSAEG, package: append.length});
var package = writer.write(append).finish();
return window.protobuf.util.base64.encode(package, 0, package.length);
} catch (exception) {
log(exception);
}
return '';
};
/*
* @message [object] message object which should have {timestamp:, message:, type:, path:}
*/
s.send = function (message) {
log(message.message);
if (s.ready === -1) return; // 如果协议载入不成功,不缓存也无法发送
if (s.ws === null || s.ws.readyState !== 1) {
s.caches.push(message);
return;
}
var encoded = s.encode(message);
if (encoded.length > 0) {
s.ws.send(encoded);
}
};
return s;
} ());
function Logger() {
this.path = [];
if (arguments.length > 0) {
for(var index = 0; index < arguments.length; index ++) {
var param = arguments[index];
if (typeof param === 'undefined') continue;
if (param === null) continue;
if (index === 0 && param instanceof Array) {
for(var i = 0; i < param.length; i++) {
this.path.push(param[i]);
}
continue;
}
if (typeof param === 'object') {
this.path.push(JSON.stringify(param));
continue;
}
this.path.push(param.toString());
}
}
}
Logger.connect = function (wss) {
log('WebSocket is not supported by this browser, @' + wss);
};
Logger.prototype.log = function (type, message) {
Socket.send({timestamp: (new Date().getTime()) / 1000, message: message, type: type, path: this.path});
};
Logger.prototype.info = function (message) {
this.log(Socket.proto.MessageCatalog.CATALOG_INFORMATION, message);
};
Logger.prototype.warn = function (message) {
this.log(Socket.proto.MessageCatalog.CATALOG_WARNING, message);
};
Logger.prototype.error = function (message) {
this.log(Socket.proto.MessageCatalog.CATALOG_ERROR, message);
};
Logger.prototype.fatal = function (message) {
this.log(Socket.proto.MessageCatalog.CATALOG_FATAL, message);
};
Logger.prototype.debug = function (message) {
this.log(Socket.proto.MessageCatalog.CATALOG_DEBUG, message);
};
Logger.prototype.assert = function (message) {
this.log(Socket.proto.MessageCatalog.CATALOG_ASSERT, message);
};
Logger.prototype.verbose = function (message) {
this.log(Socket.proto.MessageCatalog.CATALOG_VERBOSE, message);
};
Logger.connect = function () {
log('No require eivronment to use logger.js');
return;
}
if (typeof window === 'undefined' || window === null) {
log('RemoteLogger only can run inside browsers');
return;
}
if (typeof WebSocket === 'undefined' || WebSocket === null) {
log('RemoteLogger depends on HTML5 WebSocket which should be supported by browsers');
return;
}
if (typeof window.protobuf === 'undefined' || window.protobuf === null) {
log('RemoteLogger depends on protobuf.js which should be loaded before');
return;
}
Logger.connect = function (wss, proto, reconnectable) {
proto = typeof proto !== 'string' ? '/log.proto' : proto;
if (Socket.ready === 1) { // proto aready connected
Socket.connect(wss, reconnectable);
return;
}
if (Socket.ready === -1) { // unable to load proto
return;
}
window.protobuf.load(proto, function (err, root) {
if (err) {
log('RemoteLogger unable to load "/log.proto". ' + err);
return;
}
var MessageIdentity, MessageHeader, MessageCatalog, AppendMessage, HeaderTags;
try {
MessageIdentity = root.lookupEnum('logging.remote.protocols.MessageIdentity');
if (typeof MessageIdentity === 'undefined' || MessageIdentity === null) {
throw "MessageIdentity not found in log.proto, may caused by incorrect file or version";
}
MessageHeader = root.lookup('logging.remote.protocols.MessageHeader');
if (typeof MessageHeader === 'undefined' || MessageHeader === null) {
throw "MessageHeader not found in log.proto, may caused by incorrect file or version";
}
MessageCatalog = root.lookupEnum('logging.remote.protocols.MessageCatalog');
if (typeof MessageCatalog === 'undefined' || MessageCatalog === null) {
throw "MessageCatalog not found in log.proto, may caused by incorrect file or version";
}
AppendMessage = root.lookup('logging.remote.protocols.AppendMessage');
if (typeof AppendMessage === 'undefined' || AppendMessage === null) {
throw "AppendMessage not found in log.proto, may caused by incorrect file or version";
}
HeaderTags = root.lookupEnum('logging.remote.protocols.HeaderTags');
if (typeof HeaderTags === 'undefined' || HeaderTags === null) {
throw "HeaderTags not found in log.proto, may caused by incorrect file or version";
}
Socket.proto.MessageIdentity = MessageIdentity;
Socket.proto.MessageHeader = MessageHeader;
Socket.proto.MessageCatalog = MessageCatalog;
Socket.proto.AppendMessage = AppendMessage;
Socket.proto.HeaderTags = HeaderTags;
Socket.ready = 1;
Socket.connect(wss, reconnectable);
} catch(exception) {
log(exception);
Socket.ready = -1; // 协议载入失败
return;
}
});
};
// Expose globally
global.Logger = Logger;
// Be nice to AMD
if (typeof define === "function" && define.amd) {
define([], function() {
return { Logger: Logger };
});
}
// Be nice to CommonJS
if (typeof module === "object" && module && module.exports) module.exports.Logger = Logger;
// Be friendly to exports
if (typeof exports === 'object' && exports) exports.Logger = Logger;
} (typeof window==="object"&&window||typeof self==="object"&&self||this));