async-logging
Advanced tools
Comparing version 0.1.7 to 0.1.8
@@ -43,4 +43,9 @@ 'use strict'; | ||
}, _this.drainInterval); | ||
} | ||
}; | ||
HttpTransport.prototype.reconnect = function(url, protocol){ | ||
//no need to reconnect for http | ||
}; | ||
HttpTransport.prototype.log = function(message){ | ||
@@ -47,0 +52,0 @@ |
@@ -8,3 +8,4 @@ 'use strict'; | ||
'WebSocketTransport' : require('./ws-transport.js').WebSocketTransport, | ||
'HttpTransport' : require('./http-transport.js').HttpTransport | ||
'HttpTransport' : require('./http-transport.js').HttpTransport, | ||
'WebSocketOtherwiseHttpTransport' : require('./ws-http-transport.js').WebSocketOtherwiseHttpTransport, | ||
}; |
@@ -42,21 +42,21 @@ 'use strict'; | ||
var mapped = { | ||
type : log.type || 'URL', | ||
name: log.name, | ||
request: log.uuid, | ||
parent: log.parent || '0', | ||
clazz: log.clazz || 'atomicEvent', | ||
event : log.event, | ||
duration: log.duration, | ||
pid: log.pid, | ||
tid: log.tid || assignThread(log.pid, log.uuid), | ||
machine: log.machine, | ||
ipAddress: log.ipAddress || log.ip, | ||
pool: log.pool, | ||
level: log.level, | ||
msg: log.msg, | ||
rlogid: log.rlogid, | ||
timestamp: log.timestamp || Date.now() | ||
'type' : log.type || 'URL', | ||
'name': log.name, | ||
'request': log.uuid, | ||
'parent': log.parent || '0', | ||
'clazz': log.clazz || 'atomicEvent', | ||
'event' : log.event, | ||
'duration': log.duration, | ||
'pid': log.pid, | ||
'tid': log.tid || assignThread(log.pid, log.uuid), | ||
'machine': log.machine, | ||
'ipAddress': log.ipAddress || log.ip, | ||
'pool': log.pool, | ||
'level': log.level, | ||
'msg': log.msg, | ||
'rlogid': log.rlogid, | ||
'timestamp': log.timestamp || Date.now() | ||
}; | ||
//in case there's anything else not mapped. | ||
_.extend(mapped, _.omit(log, 'type', 'uuid', 'parent', 'begin', 'end', 'event', 'duration', 'name', 'pid', 'tid', 'machine', 'ipAddress', 'pool', 'level', 'msg', 'rlogid', 'timestamp')); | ||
_.defaults(mapped, log); | ||
@@ -70,9 +70,9 @@ return mapped; | ||
} | ||
else if(_.isEqual('atomicEvent', node.clazz)){ | ||
else if('atomicEvent' === node.clazz){ | ||
return node; | ||
} | ||
else if(_.isEqual('heartbeat', node.clazz)){ | ||
else if('heartbeat' === node.clazz){ | ||
return node; | ||
} | ||
else if(_.isEqual('end', node.clazz)){ | ||
else if('end' === node.clazz){ | ||
return node; | ||
@@ -108,3 +108,3 @@ } | ||
} | ||
else if(_.isEqual('atomicEvent', node.clazz) || _.isEqual('heartbeat', node.clazz)){ | ||
else if('atomicEvent' === node.clazz || 'heartbeat' === node.clazz){ | ||
return 'end'; | ||
@@ -114,15 +114,14 @@ } | ||
var complete = _.reduce(family[node.event] || [], function(memoize, c){ | ||
if(!memoize || !validateTree(family, c)){ | ||
return null; | ||
} | ||
if(!memoize || !validateTree(family, c)){ | ||
return null; | ||
} | ||
if(_.isEqual(c.clazz, 'begin')){ | ||
memoize[c.event] = 'begin'; | ||
} | ||
else{ | ||
memoize[c.event] = 'end'; | ||
} | ||
return memoize; | ||
}, | ||
{}); | ||
if(c.clazz === 'begin'){ | ||
memoize[c.event] = 'begin'; | ||
} | ||
else{ | ||
memoize[c.event] = 'end'; | ||
} | ||
return memoize; | ||
}, {}); | ||
@@ -135,3 +134,3 @@ if(!complete){ | ||
return _.isEmpty(children) || _.every(children, function(elem){ | ||
return _.isEqual(elem, 'end'); | ||
return elem === 'end'; | ||
}); | ||
@@ -155,4 +154,4 @@ }; | ||
clazz = mapped.clazz, | ||
begin = _.isEqual('begin', clazz), | ||
end = _.isEqual('end', clazz), | ||
begin = 'begin' === clazz, | ||
end = 'end' === clazz, | ||
event = mapped.event, | ||
@@ -167,3 +166,3 @@ request= mapped.request; | ||
if(parent === '0' && !begin && !end){ | ||
if(_.isEqual('atomicEvent', clazz)){ | ||
if('atomicEvent' === clazz){ | ||
_this.atomicEvents.push(mapped); | ||
@@ -173,3 +172,3 @@ | ||
} | ||
else if(_.isEqual('heartbeat', clazz)){ | ||
else if('heartbeat' === clazz){ | ||
_this.heartbeats.push(mapped); | ||
@@ -258,4 +257,9 @@ | ||
emitter.emit('cleaned', {till: till}); | ||
emitter.emit('cleaned', { | ||
'till': till, | ||
'atomicEvents' : _this.atomicEvents.length, | ||
'heartbeats' : _this.heartbeats.length, | ||
'transactions': _.keys(_this.transactions).length | ||
}); | ||
}); | ||
}; |
'use strict'; | ||
var WebSocketTransport = require("./index.js").WebSocketTransport, | ||
assert = require("assert"); | ||
var WebSocketTransport = require('./index.js').WebSocketTransport, | ||
assert = require('assert'); | ||
@@ -6,0 +6,0 @@ var LogClient = exports.LogClient = function(options){ |
@@ -21,3 +21,3 @@ 'use strict'; | ||
var server = options.app || http.createServer(function(request, response) { | ||
var server = http.createServer(options.app || function(request, response) { | ||
//try not closing the http connection. | ||
@@ -37,16 +37,18 @@ console.log('[log-cluster] received: ' + request.url); | ||
actualOptions = { | ||
port: 3000, | ||
monPort: 3001, | ||
cluster: true, | ||
noWorkers: os.cpus().length + 1, | ||
connThreshold: 1024,//concurrent connections shouldn't exceed 1k, otherwise performance degradation would be obvious. | ||
ecv: { | ||
'port': 3000, | ||
'monPort': 3001, | ||
'cluster': true, | ||
'noWorkers': os.cpus().length + 1, | ||
'connThreshold': 1024,//concurrent connections shouldn't exceed 1k, otherwise performance degradation would be obvious. | ||
'ecv': { | ||
control: true | ||
}, | ||
heartbeatInterval : 60000, | ||
LogListener : LogListener, | ||
LogBuffer : LogBuffer, | ||
LogPublisher: WinstonPublisher, | ||
cleanDuration : 1000 * 60,//one min | ||
'heartbeatInterval' : 60000, | ||
'LogListener' : LogListener, | ||
'LogBuffer' : LogBuffer, | ||
'LogPublisher': WinstonPublisher, | ||
'cleanDuration' : 1000 * 60,//one min | ||
'machineName' : os.hostname() | ||
}; | ||
//let user options overwrite defaults | ||
_.extend(actualOptions, options); | ||
@@ -61,9 +63,9 @@ | ||
var logCluster = new Cluster({ | ||
port: actualOptions.port, | ||
monPort: actualOptions.monPort, | ||
cluster: actualOptions.cluster, | ||
noWorkers: actualOptions.noWorkers, | ||
connThreshold: actualOptions.connThreshold, | ||
ecv: actualOptions.ecv, | ||
heartbeatInterval: actualOptions.heartbeatInterval | ||
'port': actualOptions.port, | ||
'monPort': actualOptions.monPort, | ||
'cluster': actualOptions.cluster, | ||
'noWorkers': actualOptions.noWorkers, | ||
'connThreshold': actualOptions.connThreshold, | ||
'ecv': actualOptions.ecv, | ||
'heartbeatInterval': actualOptions.heartbeatInterval | ||
}); | ||
@@ -77,3 +79,3 @@ | ||
//either a constructor or an instance | ||
_.isFunction(actualOptions.LogListener) ? actualOptions.LogListener(wss, emitter) : actualOptions.LogListener; | ||
_.isFunction(actualOptions.LogListener) ? actualOptions.LogListener(wss, emitter, actualOptions.app, actualOptions.machineName) : actualOptions.LogListener; | ||
_.isFunction(actualOptions.LogBuffer) ? actualOptions.LogBuffer(emitter) : actualOptions.LogBuffer; | ||
@@ -98,3 +100,1 @@ _.isFunction(actualOptions.LogPublisher) ? actualOptions.LogPublisher(emitter) : actualOptions.LogPublisher; | ||
}; | ||
exports.LogClient = require('./log-client.js').LogClient; |
@@ -21,3 +21,3 @@ 'use strict'; | ||
var LogListener = exports.LogListener = function(wss, emitter){ | ||
var LogListener = exports.LogListener = function(wss, emitter, app, machineName){ | ||
@@ -54,3 +54,2 @@ var _this = this; | ||
console.log(util.format('[log-websocket] message received:\n%j', logs)); | ||
_.each(logs, function(log){ | ||
@@ -86,2 +85,32 @@ emitter.emit('log', log); | ||
}); | ||
if(app){ | ||
var express = require('express'); | ||
app.use(express.bodyParser()); | ||
app.post('/log', function(req, res){ | ||
_.each(req.body.logs || [], function(log){ | ||
//console.log(util.format('[listener] received messages:\n %j', log)); | ||
//seems like a bug from body parser where duration is parsed as string instead of number; | ||
log.duration = log.duration && _.isString(log.duration) ? parseInt(log.duration, 10) : log.duration; | ||
log.timestamp = log.timestamp && _.isString(log.timestamp) ? parseInt(log.timestamp, 10) : log.timestamp; | ||
emitter.emit('log', log); | ||
}); | ||
res.send(200, ''); | ||
}); | ||
app.get('/ws', function(req, res){ | ||
console.log('[listener] accepted websocket request'); | ||
res.send(util.format('ws://%s:8080/', machineName, 200)); | ||
}); | ||
} | ||
}; |
'use strict'; | ||
var winston = require("winston"); | ||
var winston = require('winston'); | ||
@@ -10,20 +10,20 @@ var WinstonPublisher = exports.WinstonPublisher = function(emitter){ | ||
transports: [ | ||
new winston.transports.File({ filename: './logs/all.log' }) | ||
new winston.transports.File({ filename: './log/all.log' }) | ||
], | ||
exceptionHandlers: [ | ||
new winston.transports.File({ filename: './logs/exceptions.log' }) | ||
new winston.transports.File({ filename: './log/exceptions.log' }) | ||
] | ||
}); | ||
emitter.on("atomicEvent", function(atomicEvent){ | ||
emitter.on('atomicEvent', function(atomicEvent){ | ||
logger.log(atomicEvent.level, atomicEvent.msg, atomicEvent); | ||
}); | ||
emitter.on("heartbeat", function(heartbeat){ | ||
emitter.on('heartbeat', function(heartbeat){ | ||
logger.log(atomicEvent.level, heartbeat.msg, heartbeat); | ||
}); | ||
emitter.on("transaction", function(tx){ | ||
emitter.on('transaction', function(tx){ | ||
logger.log(atomicEvent.level, tx.msg, tx); | ||
}); | ||
}; |
@@ -14,3 +14,4 @@ 'use strict'; | ||
'connection': null, | ||
'queue': [], | ||
'adhocs': [], | ||
'groups': {}, | ||
'url': options.url, | ||
@@ -33,3 +34,3 @@ 'protocol': options.protocol || 'log-protocol', | ||
_this.connection = null; | ||
setTimeout(_.bind(_this.connect, _this, url, protocol), _this.reconnectInterval);//wait for 1 sec and continue reconnect | ||
setTimeout(_.bind(_this.reconnect, _this, url, protocol), _this.reconnectInterval);//wait for 1 sec and continue reconnect | ||
}); | ||
@@ -46,2 +47,4 @@ | ||
clearTimeout(serverReady); | ||
console.log('[log-transport] ws connected'); | ||
connection.scheduler = connection.scheduler || setInterval(_.bind(_this.drain, _this, connection), _this.drainInterval);//sending message only after server side 'ready' | ||
@@ -60,3 +63,3 @@ }); | ||
_this.connection = null; | ||
_this.connect(url, protocol);//reconnect | ||
_this.reconnect(url, protocol);//reconnect | ||
}); | ||
@@ -66,6 +69,19 @@ }); | ||
client.connect(url, protocol); | ||
} | ||
}; | ||
WebSocketTransport.prototype.reconnect = function(url, protocol){ | ||
this.connect(url, protocol); | ||
}; | ||
WebSocketTransport.prototype.log = function(message){ | ||
this.queue.push(message); | ||
var uuid = message.uuid; | ||
if(!uuid){ | ||
this.adhocs.push(message); | ||
} | ||
else{ | ||
var group = this.groups[uuid] || []; | ||
group.push(message); | ||
this.groups[uuid] = group; | ||
} | ||
}; | ||
@@ -75,29 +91,32 @@ | ||
if(!_.isEmpty(this.queue)){ | ||
console.log('[log-transport] ws drain'); | ||
try{ | ||
//this is an enhancement which tries to mitigate the problem of possible cutoff of transactions | ||
//the transactional messages will only be sent after they've been baked for 1 minute, and in the same batch | ||
var threshold = Date.now() - 60000, groups = {}, adhocs = [], devide = {'graduates':[], 'youths':[]}; | ||
_.each(this.queue, function(elem){ | ||
if(elem.uuid){ | ||
groups[elem.uuid] = groups[elem.uuid] || []; | ||
groups[elem.uuid].push(elem); | ||
var _this = this, | ||
threshold = Date.now() - _this.readyThreshold, | ||
graduates = []; | ||
if(_this.adhocs.length){ | ||
connection.sendBytes(msgpack.pack(_this.adhocs)); | ||
_this.adhocs = []; | ||
} | ||
//split the groups to graduates and youths, graduates are the messages (transactional) older than 1 minute | ||
var groups = _this.groups; | ||
_.each(groups, function(group, uuid){ | ||
if(group[0].timestamp < threshold){ | ||
graduates = graduates.concat(group); | ||
delete groups[uuid]; | ||
} | ||
else{ | ||
adhocs.push(elem); | ||
} | ||
}); | ||
connection.sendBytes(msgpack.pack(adhocs)); | ||
//split the groups to graduates and youths, graduates are the messages (transactional) older than 1 minute | ||
_.reduce(_.values(groups), function(memoize, group){ | ||
var team = group[0].timestamp < threshold ? 'graduates' : 'youths'; | ||
memoize[team] = memoize[team].concat(gorup); | ||
return memoize; | ||
}, devide); | ||
connection.sendBytes(msgpack.pack(devide.graduates)); | ||
this.queue = devide.youths; | ||
if(graduates.length){ | ||
connection.sendBytes(msgpack.pack(graduates)); | ||
} | ||
} | ||
catch(e){ | ||
console.log(e); | ||
} | ||
}; |
{ | ||
"author": "cubejs", | ||
"name": "async-logging", | ||
"version": "0.1.7", | ||
"version": "0.1.8", | ||
"description": "0.1.6 is the same as 0.2.2 just to get around ebay-logging-client vs. async-logging-client change", | ||
@@ -6,0 +6,0 @@ "repository": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
31328
19
674