realm-object-server
Version:
124 lines • 4.02 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const dgram = require("dgram");
const Logger_1 = require("../shared/Logger");
const Statsd_1 = require("./Statsd");
class StatsdMetric {
constructor(sink, params, metricType) {
this.metricType = metricType;
this.name = params.name;
this.sink = sink;
}
emit(labels, value) {
this.sink.emit({
name: this.name,
labels,
stats: [{ value, type: this.metricType }],
});
}
}
class StatsdCounter extends StatsdMetric {
constructor(sink, params) {
super(sink, params, Statsd_1.MetricType.Counter);
}
inc(labels, value = 1) {
this.emit(labels, `+${value}`);
}
reset(labels, value = 0) {
this.emit(labels, `${value}`);
}
}
class StatsdGauge extends StatsdMetric {
constructor(sink, params) {
super(sink, params, Statsd_1.MetricType.Gauge);
}
inc(labels, value = 1) {
this.emit(labels, `+${value}`);
}
reset(labels, value = 0) {
this.emit(labels, `${value}`);
}
dec(labels, value = 1) {
this.emit(labels, `-${value}`);
}
set(labels, value) {
this.emit(labels, `${value}`);
}
}
class StatsdHistogram extends StatsdMetric {
constructor(sink, params) {
super(sink, params, Statsd_1.MetricType.Histogram);
}
observe(labels, value) {
this.emit(labels, `${value}`);
}
startTimer(labels) {
return () => { };
}
}
class StatsdStatsSink {
constructor(config = {}) {
this.metrics = {};
this.logger = config.logger || new Logger_1.MuteLogger();
this.hostname = config.hostname || "localhost";
this.port = config.port || 8125;
const socketType = config.socketType || "udp4";
this.client = dgram.createSocket(socketType);
}
counter(params) {
if (params.name in this.metrics) {
throw new Error(`The sink already has a counter named ${name}`);
}
else {
const counter = new StatsdCounter(this, params);
this.metrics[params.name] = counter;
return counter;
}
}
gauge(params) {
if (params.name in this.metrics) {
throw new Error(`The sink already has a counter named ${name}`);
}
else {
const gauge = new StatsdGauge(this, params);
this.metrics[params.name] = gauge;
return gauge;
}
}
histogram(params) {
if (params.name in this.metrics) {
throw new Error(`The sink already has a counter named ${name}`);
}
else {
const histogram = new StatsdHistogram(this, params);
this.metrics[params.name] = histogram;
return histogram;
}
}
emit(metric) {
const labelParts = this.generateLabelParts(metric.labels);
const namespace = [metric.name, ...labelParts].join(",");
const statsString = metric.stats.map(stats => `${stats.value}|${stats.type}`).join(":");
const message = `${namespace}:${statsString}`;
this.logger.trace(`Emitting statsd message "${message}"`);
this.client.send(message, this.port, this.hostname, (error) => {
if (error) {
this.logger.warn("Failed to emit statsd message", { error });
}
});
}
generateLabelParts(labels) {
return Object.keys(labels).filter(key => {
const value = labels[key];
const valid = value.indexOf(",") === -1 && value.indexOf("=") === -1;
if (!valid) {
this.logger.warn(`Skipping label "${key}", its value cannot contain comma (,) or equal-sign (=), it was "${value}"`);
}
return valid;
}).map(key => {
return `${key}=${labels[key]}`;
});
}
}
exports.StatsdStatsSink = StatsdStatsSink;
//# sourceMappingURL=StatsdStatsSink.js.map