zmarouf / client

Streaming, system agnostic metrics

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

@metrics/client

A streaming metric producer. Allows producing counters, gauges, time series in a way that is independent of your metrics system so that you can produce metrics and let consumers decide how to consume them. Additionally, you can pipe together different metrics streams before finally consuming them all in a single location.

Quick start

The client is intended to be used in the following way:

Step 1.

Instantiate a new client

const client = new Metrics();

Step 2.

Use the client for instrumentation

client.metric({
    name: 'unique_metic_name',
    description: 'Description of metric being collected',
    value: 10,
});

Step 3.

Pipe collected metrics to a collector

client.pipe(consumer);

The client supports 2 types of metric creation use cases. 1. timers (via client.timer) and 2. Non timers (via client.metric)

  • Histograms are supported by using the timer functionality.
  • Gauges are supported via setting the value property.
  • Counters are implicit. ie. Each metric added can be counted by a consumer.
  • Timestamps are always generated by default for all metrics.
  • By default the client will only buffer up 100 metrics items before it starts dropping the oldest metric from the stream for each new metric it adds. This should prevent any memory leaks associated with not consuming the stream.

Examples

A metric to be used in a counter

client.metric({
    name: 'my_counter',
    description: 'Counter description',
});

Setting a value to be used in a gauge

client.metric({
    name: 'my_gauge',
    description: 'Gauge description',
    value: 123,
});

A timer to be used in a histogram

const end = client.timer({
    name: 'my_histogram',
    description: 'Histogram description'
});
await something();
end();

A timer to be used in a histogram and a gauge

const end = client.timer({
    name: 'my_histogram_gauge',
    description: 'Histogram gauge example'
});
await something();
end({ value: 123 });

Composing metric streams

One of the goals of @metrics/client is to allow any number of modules to produce their own metrics, not know about where they might be consumed.

This can be achieved by including and instantiating a @metrics/client client in each module, using it to create metrics and then exposing the client for consumption elsewhere.

Example

// module-1

const Metrics = require('@metrics/client');
const client = new Metrics();

client.metric({...})

module.exports.metrics = client;
// module-2

const Metrics = require('@metrics/client');
const client = new Metrics();

client.metric({...})

module.exports.metrics = client;
// consuming module
const module1 = require('module-1');
const module2 = require('module-2');
const consumer = require('some-consumer');

module1.pipe(module2).pipe(consumer);

Metrics consumption

In order to consume metrics produced by @metrics/client you just need to listen for data and use your favourite metrics client to convert our data format into something usable by your system of choice.

Example: Prometheus using prom-client

const { Counter } = require('prom-client');
const { Writable } = require('stream');

class Consumer extends Writable {
    constructor() {
        super({ objectMode: true });

        this.counter = new Counter({
            name: 'my_metric_counter',
            help: 'Counts http request type things',
            labelNames: ['url', 'method'],
        });
    }

    _write(metric, enc, cb) {
        this.counter.labels(metric.meta.url, metric.meta.method).inc(1);
        cb();
    }
}

API

new Metrics(options)

Creates a new instance of the metrics client.

options

name description type default
maxBuffer Max number of metrics to retain if not consumed. Keeps most recent. number 100

Example

const client = new Metrics(options);

return: Duplex Stream

instance methods

.metric(options)

Collects a metric. As a minimum, a name and description for the metric must be provided.

options

name description type default required
name Metric name. valid characters: a-z,A-Z,0-9,_ string null true
description Metric description string null true
value Arbitrary value for the metric (used for gauges) string|number null false
meta Available to be used to hold any misc data. object null false

n.b. In practice, meta can be used as a way to label metrics. Use each key of the meta object as the label name and the value as the label value

return: void

client.metric({
    name: '',
    description: '',
});

.timer(options)

Starts a metric timer and returns and end function to be called when the measurement should be considered finished.

options

name description type default required
name Metric name. valid characters: a-z,A-Z,0-9,_ string null true
description Metric description string null true
value Arbitrary value for the metric (used for gauges) string|number null false
meta Available to be used to hold any misc data object null false

n.b. In practice, meta can be used as a way to label metrics. Use each key of the meta object as the label name and the value as the label value

return: function Returns an end function (see below) to be used to indicate that the timer measurement is finished.

Example

const end = client.timer(options);
.end(options)

Stops a previously started timer, merges timers options with end options and and sets the measured time value.

options

name description type default required
name Metric name. valid characters: a-z,A-Z,0-9,_ string null true
description Metric description string null true
value Arbitrary value for the metric (used for gauges) string|number null false
meta Available to be used to hold any misc data object null false

n.b. In practice, meta can be used as a way to label metrics. Use each key of the meta object as the label name and the value as the label value

return: void

Example

const end = client.timer(options);
// ... thing to be measured
end(options);

About

Streaming, system agnostic metrics


Languages

Language:JavaScript 100.0%