realm-object-server
Version:
121 lines • 4.93 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const lodash_1 = require("lodash");
const realms_1 = require("../realms");
const Statsd_1 = require("./Statsd");
class StatsdToMetricsRealm {
constructor(config, receiver) {
this.mappings = {
"realm_state_size": {
className: "RealmStateSize",
properties: (metric) => ({
path: decodeURIComponent(metric.labels.path)
})
},
"realm_file_size": {
className: "RealmFileSize",
properties: (metric) => ({
path: decodeURIComponent(metric.labels.path)
})
},
};
this.metricsToSave = [];
this.onMetric = (metric) => {
this.handleMetric(metric).catch(err => {
this.logger.error(`Failed handling the metric: ${err.message}`, {
error: err,
metric,
});
});
};
this.doSaveMetrics = () => __awaiter(this, void 0, void 0, function* () {
yield this.ensureRealm();
if (!this.realm || this.metricsToSave.length === 0) {
return;
}
this.logger.debug(`Saving ${this.metricsToSave.length} metric(s)`);
this.realm.write(() => {
for (const { name, metric, emitted } of this.metricsToSave) {
if (name in this.mappings) {
const { className, properties: deriveProperties } = this.mappings[name];
if (metric.stats.length >= 1) {
const value = parseFloat(metric.stats[metric.stats.length - 1].value);
const properties = Object.assign({}, (deriveProperties ? deriveProperties(metric) : {}), { value,
emitted });
this.realm.create(className, properties, true);
}
else {
this.logger.debug("Skipping metric without stats", { metric });
}
}
else {
throw new Error(`Cannot save metric "${name}" without a mapping`);
}
}
});
this.metricsToSave = [];
});
this.logger = config.logger;
this.openRealm = config.openRealm;
this.saveMetrics = lodash_1.throttle(this.doSaveMetrics, config.saveWait || StatsdToMetricsRealm.DEFAULT_SAVE_WAIT);
if (receiver) {
this.listenTo(receiver);
}
}
listenTo(receiver) {
if (this.receiver) {
throw new Error("Already listening to another receiver");
}
else if (!receiver) {
throw new Error("Cannot listen to a missing receiver");
}
this.receiver = receiver;
this.receiver.addListener("metric", this.onMetric);
}
stop() {
if (!this.receiver) {
throw new Error("Not listening to a receiver");
}
this.receiver.removeListener("metric", this.onMetric);
delete this.receiver;
this.saveMetrics.cancel();
if (this.realm) {
this.realm.close();
delete this.realm;
}
}
handleMetric(metric) {
return __awaiter(this, void 0, void 0, function* () {
const name = Statsd_1.parseMetricName(metric);
if (name in this.mappings) {
this.metricsToSave.push({ name, metric, emitted: new Date() });
yield this.saveMetrics();
}
else {
}
});
}
ensureRealm() {
return __awaiter(this, void 0, void 0, function* () {
try {
if (!this.realm) {
this.realm = yield this.openRealm(realms_1.MetricsRealm);
}
}
catch (err) {
this.logger.error(`Failed to open metrics Realm: ${err.message}`, { error: err });
}
});
}
}
StatsdToMetricsRealm.DEFAULT_SAVE_WAIT = 10000;
exports.StatsdToMetricsRealm = StatsdToMetricsRealm;
//# sourceMappingURL=StatsdToMetricsRealm.js.map