UNPKG

@metrics/client

Version:

A streaming metric producer. Allows producing counters, gauges, histograms and summaries in a way that is independent of your metrics system.

123 lines (103 loc) 2.4 kB
"use strict"; /* eslint prefer-rest-params: "off" */ const timeSpan = require("time-span"); const stream = require("readable-stream"); const crypto = require("crypto"); const Metric = require("@metrics/metric"); const Counter = require("./counter"); const Gauge = require("./gauge"); const Summary = require("./summary"); const Histogram = require("./histogram"); const push = Symbol("metrics:client:push"); const MetricsClient = class MetricsClient extends stream.Transform { constructor({ id } = {}) { super( Object.assign( { objectMode: true, }, ...arguments, ), ); Object.defineProperty(this, "id", { value: id || crypto.randomBytes(3 * 4).toString("base64"), enumerable: true, }); // Avoid hitting the max listeners limit when multiple // streams is piped into the same stream. this.on("pipe", () => { this.setMaxListeners(this.getMaxListeners() + 1); }); this.on("unpipe", () => { this.setMaxListeners(this.getMaxListeners() - 1); }); } get [Symbol.toStringTag]() { return "MetricsClient"; } [push](metric) { const met = metric; met.source = this.id; if (this._readableState.flowing) { this.push(met); return; } this.emit("drop", met); } counter(options) { const counter = new Counter(options); counter.on("metric", (metric) => { this[push](metric); }); return counter; } gauge(options) { const gauge = new Gauge(options); gauge.on("metric", (metric) => { this[push](metric); }); return gauge; } summary(options) { const summary = new Summary(options); summary.on("metric", (metric) => { this[push](metric); }); return summary; } histogram(options) { const histogram = new Histogram(options); histogram.on("metric", (metric) => { this[push](metric); }); return histogram; } timer(options = {}) { const end = timeSpan(); return (opts = {}) => { const meta = { ...options.meta, ...opts.meta }; const time = end.seconds(); const metric = new Metric({ type: 5, value: time, ...options, ...opts, meta, }); this[push](metric); }; } metric(options) { const metric = new Metric(options); this[push](metric); } _transform(metric, enc, next) { if (metric.source === this.id) { this.emit("drop", metric); next(null); return; } next(null, metric); } }; module.exports = MetricsClient;