Permalink
Browse files

project init

  • Loading branch information...
chenshijie committed Feb 15, 2012
1 parent a4eedae commit 2e58375d7fe44cea2a3c875ed43955904b5179b7
View
@@ -1,3 +1,5 @@
#Virtual Gateway
#Virtual Gateway
##
No changes.
View
No changes.
View
@@ -0,0 +1,17 @@
var streamLogger = require('./streamlogger');
exports.logger = function(logfile) {
var _logger = new streamLogger.StreamLogger(logfile || '/dev/stdout');
_logger.level = _logger.levels.debug;
process.on('SIGUSR2', function() {
_logger.reopen(function() {
console.log('log file reopened!');
});
});
return { info : function(msg) {
_logger.info('[' + process.pid + ']' + msg);
}, debug : function(msg) {
_logger.debug('[' + process.pid + ']' + msg);
} };
};
View
@@ -0,0 +1,149 @@
var sys = require('util'), fs = require('fs'), events = require('events'), clone = function(obj) {
if (obj == null || typeof (obj) != 'object')
return obj;
var temp = obj.constructor(); // changed
for ( var key in obj)
temp[key] = clone(obj[key]);
return temp;
};
var StreamLogger = exports.StreamLogger = function() {
this.filePaths = [];
for ( var i = arguments.length; i != 0; i--)
this.filePaths.push(arguments[i - 1]);
this.fstreams = [];
this.emitter = new events.EventEmitter();
this.levels = { debug : 0, info : 1, warn : 2, fatal : 3 };
this.level = this.levels.info;
this.open();
};
StreamLogger.prototype.__defineGetter__("levels", function() {
return clone(this.levelList);
});
StreamLogger.prototype.__defineSetter__("levels", function(newLevels) {
this.levelList = this.levelList || {};
// Make sure the level name doesn't conflict with an existing function name
for ( var newLevel in newLevels) {
if (this[newLevel] && (this.levelList[newLevel] == undefined)) {
this.emitter.emit("error", "Invalid log level '" + newLevel + "', conflicting name");
delete (newLevels[newLevel]);
}
}
this.levelList = newLevels;
// Build a reverse mapping of level values to keys, for fast lookup later
this.revLevels = {};
for ( var lName in this.levelList) {
var lVal = this.levels[lName];
this.revLevels[lVal] = lName;
}
// Remove old levels
for ( var oldLevel in this.levelList)
delete (this[oldLevel]);
// Setup a method for each log level
for ( var logLevel in this.levelList) {
this[logLevel] = (function(logLevel) {
return function(message, callback) {
this.logAtLevel(message, this.levelList[logLevel], callback);
};
})(logLevel);
}
});
// Create write streams for all the files, emit 'open', if/when
// all streams open. Will fire callback after as well
StreamLogger.prototype.open = function(callback) {
var emitter = this.emitter;
for ( var i = this.filePaths.length; i != 0; i--) {
var filePath = this.filePaths[i - 1];
var unopenedFilePathCount = this.filePaths.length;
var stream = fs.createWriteStream(filePath, { flags : 'a', mode : 0644, encoding : 'utf8' }).addListener('open', function(fd) {
unopenedFilePathCount--;
if (unopenedFilePathCount == 0) {
emitter.emit("open");
if (callback)
callback();
}
}).addListener('error', function(err) {
emitter.emit('error', err, filePath);
});
this.fstreams.push(stream);
}
};
// Close all write streams, fire the callback after all streams are closed
// Also emits 'close' after all streams are closed
StreamLogger.prototype.close = function(callback) {
for ( var i = this.fstreams.length; i != 0; i--) {
this.fstreams[i - 1].end();
}
// We're done closing, so emit the callbacks, then remove the fstreams
this.fstreams = [];
this.emitter.emit("close");
if (callback)
callback();
};
StreamLogger.prototype.reopen = function(callback) {
var slSelf = this;
this.close(function() {
slSelf.open(function() {
if (callback)
callback();
});
});
};
StreamLogger.prototype.logAtLevel = function(message, level, callback) {
var levelName = this.revLevels[level];
this.emitter.emit('message', message, levelName);
this.emitter.emit('message-' + levelName, message);
if (level < this.level)
return false / this.emitter.emit('loggedMessage', message, levelName);
this.emitter.emit('loggedMessage-' + levelName, message);
// Check if there's a custom formatting callback
if (this.format) {
var outMessage = this.format(message, levelName);
} else {
var outMessage = (new Date).toLocaleISOString() + ' - ' + levelName + ': ' + message;
}
for ( var i = this.fstreams.length; i != 0; i--) {
var fstream = this.fstreams[i - 1];
// Ideally we could trap the errors #write creates, I'm not sure
// if thats possible though
if (fstream.writable) {
fstream.write(outMessage + "\n");
if (callback)
callback();
} else
this.emitter.emit('error', "Stream not writable", fstream.path);
}
};
Date.prototype.toLocaleISOString = function() {
var date = this;
var pad = function(i) {
if (i < 10) {
return '0' + i;
}
return i;
};
var pad3 = function(i) {
if (i < 100) {
return '0' + i;
} else if (i < 10) {
return '00' + i;
}
return i;
};
return [ date.getFullYear(), pad(date.getMonth() + 1), pad(date.getDate()) ].join('-') + ' ' + [ pad(date.getHours()), pad(date.getMinutes()), pad(date.getSeconds()) ].join(':') + '.' + pad3(date.getMilliseconds());
};
View
@@ -0,0 +1,42 @@
var url = require('url');
var _ = require('underscore');
_.mixin(require('underscore.string'));
var crypto = require('crypto');
exports.md5 = function(str, encoding) {
return crypto.createHash('md5').update(str).digest(encoding || 'hex');
};
exports.getTimestamp = function() {
return Math.floor(Date.now() / 1000);
};
exports.getDateString = function() {
var date = new Date();
var pad = function(i) {
if (i < 10) {
return '0' + i;
}
return i;
};
return [ date.getFullYear(), pad(date.getMonth() + 1), pad(date.getDate()) ].join('');
};
exports.getLocaleISOString = function() {
var date = new Date();
var pad = function(i) {
if (i < 10) {
return '0' + i;
}
return i;
};
var pad3 = function(i) {
if (i < 100) {
return '0' + i;
} else if (i < 10) {
return '00' + i;
}
return i;
};
return [ date.getFullYear(), pad(date.getMonth() + 1), pad(date.getDate()) ].join('-') + ' ' + [ pad(date.getHours()), pad(date.getMinutes()), pad(date.getSeconds()) ].join(':') + '.' + pad3(date.getMilliseconds());
};
View
No changes.
View
No changes.
View
No changes.

0 comments on commit 2e58375

Please sign in to comment.