dl
Version:
DreamLab Libs
217 lines (167 loc) • 5.82 kB
JavaScript
var core = require('core');
var Types = core.common.Types;
var MaasReporter = require('./MaasReporter.js').MaasReporter;
var Logger = function (name) {
// this one should be used outside of this module to create conditional console.logs and thus avoid
// evaluating unnecessary functions while in production
this.debug = false;
this._name = name;
this._config = {};
this._parent = this;
this._children = [];
this._createdReporters = {};
this._activeReporters = {};
this._metricPrefix = null;
this._debugMetrics = false;
this._reportStats = false;
this._statsTimer = null;
};
Logger.prototype._updateStatsTimer = function () {
if (!this._statsTimer && this._reportStats && this.isRoot()) {
var that = this;
this._statsTimer = setInterval(function () {
for (var reporter in that._activeReporters) {
var stats = that._activeReporters[reporter].getStats();
for (var metric in stats) {
that.gauge('logger.' + metric, stats[metric]);
}
that._activeReporters[reporter].flushStats();
}
}, 5000);
} else if ((this._statsTimer && !this._reportStats) || !this.isRoot()) {
clearInterval(this._statsTimer);
this._statsTimer = null;
}
};
Logger.prototype.removeChild = function (logger) {
if (this._children.indexOf(logger) > -1) {
this._children.splice(this._children.indexOf(logger), 1);
}
return this;
};
Logger.prototype.addChild = function (logger) {
if (this._children.indexOf(logger) === -1) {
this._children.push(logger);
}
return this;
};
Logger.prototype.getParent = function () {
return this._parent;
};
Logger.prototype.setParent = function (parent) {
this._parent.removeChild(this);
this._parent = parent;
this._parent.addChild(this);
this.configure();
return this;
};
Logger.prototype.isRoot = function () {
return this._parent === this;
};
Logger.prototype.getReporter = function (reporter) {
if (this.isRoot()) {
return this._createdReporters[reporter];
} else {
return this._parent.getReporter(reporter);
}
};
Logger.prototype.getConfig = function () {
return this._config;
};
Logger.prototype.configure = function (newConfig) {
if (!newConfig || !Types.isObject(newConfig)) {
newConfig = this._config || {};
}
var parentConfig = this._parent.getConfig();
this._config = JSON.parse(JSON.stringify(newConfig));
this.debug = !!newConfig.debug || parentConfig.debug;
this._metricPrefix = newConfig.metricPrefix || parentConfig.metricPrefix;
this._debugMetrics = newConfig.debugMetrics || parentConfig.debugMetrics;
this._reportStats = newConfig.reportStats || parentConfig.reportStats;
this._updateStatsTimer();
var reporters = newConfig.reporters || parentConfig.reporters || {};
this._activeReporters = {};
for (var name in reporters) {
if (!reporters.hasOwnProperty(name)) {
continue;
}
var reporter = this.getReporter(name);
if (!reporter) {
// default logger
if (!this.isRoot()) {
console.warn('Logger: Use root logger to configure new reporters');
continue;
}
if (!Logger.REPORTER.hasOwnProperty(name)) {
console.warn('Logger: Unknown log reporter', name);
continue;
}
this._createdReporters[name] = reporter = new Logger.REPORTER[name]();
this._createdReporters[name].setConfig(reporters[name]);
} else if (this.isRoot()) {
this._createdReporters[name].setConfig(reporters[name]);
}
this._activeReporters[name] = reporter;
}
// update configuration of sub loggers
for (var i = 0, l = this._children.length; i < l; i++) {
if (this._children[i] === this) {
continue;
}
this._children[i].configure();
}
return this;
};
Logger.prototype._getMetric = function (metric, skipPrefix) {
if (Types.isArray(metric)) {
metric = metric.join('.');
}
if (this._metricPrefix && !skipPrefix) {
metric = this._metricPrefix + '.' + metric;
}
return metric;
};
Logger.prototype.gauge = function (metric, value, buckets) {
metric = this._getMetric(metric);
for (var reporter in this._activeReporters) {
this._activeReporters[reporter].gauge(metric, value, buckets);
}
if (this._debugMetrics) {
console.log('Logger[%s]: %s ~= %s', this._name, metric, value);
}
};
Logger.prototype.counter = function (metric) {
metric = this._getMetric(metric);
for (var reporter in this._activeReporters) {
this._activeReporters[reporter].counter(metric);
}
if (this._debugMetrics) {
console.log('Logger[%s]: %s ++', this._name, metric);
}
};
Logger.prototype.timer = function (metric, timeout, buckets) {
timeout = timeout || Logger.DEFAULT_TIMER_TIMEOUT;
metric = this._getMetric(metric, true); // skip prefix here since it will be added later
var timer;
var startAt = Date.now();
var that = this;
if (timeout) {
timer = setTimeout(function () {
that.counter(metric + '.timeouts');
that.gauge(metric, Date.now() - startAt, buckets);
}, timeout);
}
return {
done: function () {
var time = Date.now() - startAt;
clearTimeout(timer);
that.gauge(metric, time, buckets);
return time;
}
}
};
Logger.DEFAULT_TIMER_TIMEOUT = 60 * 1000;
Logger.REPORTER = {
MAAS: MaasReporter
};
exports.Logger = Logger;