From bf828aaa775f55715e8acb0e4f3a13503b24a029 Mon Sep 17 00:00:00 2001 From: Franck Roudet Date: Wed, 2 Oct 2019 16:31:55 +0200 Subject: [PATCH 1/3] fix #1 --- README.md | 5 +++++ index.js | 15 +++++++++++++++ test/prometheus-test.js | 23 +++++++++++++++++------ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9e6dd7c..7a412c6 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,11 @@ This module provides [Prometheus](https://prometheus.io/) metrics for it with your circuit breakers, just pass them in to the `PrometheusMetrics` constructor. +For each circuit breaker, the metrics are: + +* a `prometheus counter` for each event name +* a `prometheus summary` for the events `success`, `failed` execution time. + Example: ```js diff --git a/index.js b/index.js index 8820282..02f5ede 100644 --- a/index.js +++ b/index.js @@ -23,6 +23,7 @@ class PrometheusMetrics { this._registry = registry || client.register; this._client = client; this.counters = []; + this.summaries = []; if (!registry) { this.interval = this._client @@ -52,6 +53,20 @@ class PrometheusMetrics { counter.inc(); }); this.counters.push(counter); + + if (eventName === 'success' || eventName === 'failure') { + // not the timeout event because runtime == timeout + const summary = new this._client.Summary({ + name: `${prefix}${eventName}_perf`, + help: + `A summary of the ${circuit.name} circuit's ${eventName} event`, + registers: [this._registry] + }); + circuit.on(eventName, (result, runTime) => { + summary.observe(runTime); + }); + this.summaries.push(summary); + } } }); } diff --git a/test/prometheus-test.js b/test/prometheus-test.js index 44d32b4..b664f98 100644 --- a/test/prometheus-test.js +++ b/test/prometheus-test.js @@ -31,30 +31,33 @@ test('The factory function accept no parameter', t => { }); test('The factory function takes an object instead of just an Array', t => { - t.plan(2); + t.plan(3); const c1 = new CircuitBreaker(passFail, { name: 'fred' }); const prometheus = new PrometheusMetrics(c1); t.equal(c1.name, 'fred'); t.ok(/circuit_fred_/.test(prometheus.metrics)); + t.ok(/circuit_fred_.*perf/.test(prometheus.metrics)); prometheus.clear(); t.end(); }); test('The factory function provides access to metrics for all circuits', t => { - t.plan(4); + t.plan(6); const c1 = new CircuitBreaker(passFail, { name: 'fred' }); const c2 = new CircuitBreaker(passFail, { name: 'bob' }); const prometheus = new PrometheusMetrics([c1, c2]); t.equal(c1.name, 'fred'); t.equal(c2.name, 'bob'); t.ok(/circuit_fred_/.test(prometheus.metrics)); + t.ok(/circuit_fred_.*perf/.test(prometheus.metrics)); t.ok(/circuit_bob_/.test(prometheus.metrics)); + t.ok(/circuit_bob_.*perf/.test(prometheus.metrics)); prometheus.clear(); t.end(); }); test('The factory function uses a custom prom-client registry', t => { - t.plan(6); + t.plan(10); const registry = new Registry(); const c1 = new CircuitBreaker(passFail, { name: 'fred' @@ -66,26 +69,31 @@ test('The factory function uses a custom prom-client registry', t => { t.equal(c1.name, 'fred'); t.equal(c2.name, 'bob'); t.ok(/circuit_fred_/.test(registry.metrics())); + t.ok(/circuit_fred_.*perf/.test(registry.metrics())); t.ok(/circuit_bob_/.test(registry.metrics())); + t.ok(/circuit_bob_.*perf/.test(registry.metrics())); t.ok(/circuit_fred_/.test(prometheus.metrics)); + t.ok(/circuit_fred_.*perf/.test(prometheus.metrics)); t.ok(/circuit_bob_/.test(prometheus.metrics)); + t.ok(/circuit_bob_.*perf/.test(prometheus.metrics)); prometheus.clear(); t.end(); }); test('The add function takes an object instead of just an Array', t => { - t.plan(2); + t.plan(3); const c1 = new CircuitBreaker(passFail, { name: 'fred' }); const prometheus = new PrometheusMetrics(); prometheus.add(c1); t.equal(c1.name, 'fred'); t.ok(/circuit_fred_/.test(prometheus.metrics)); + t.ok(/circuit_fred_.*perf/.test(prometheus.metrics)); prometheus.clear(); t.end(); }); test('The add function provides access to metrics for all circuits', t => { - t.plan(6); + t.plan(9); const c1 = new CircuitBreaker(passFail, { name: 'fred' }); const c2 = new CircuitBreaker(passFail, { name: 'bob' }); const c3 = new CircuitBreaker(passFail, { name: 'foo' }); @@ -95,13 +103,16 @@ test('The add function provides access to metrics for all circuits', t => { t.equal(c2.name, 'bob'); t.equal(c3.name, 'foo'); t.ok(/circuit_fred_/.test(prometheus.metrics)); + t.ok(/circuit_fred_.*perf/.test(prometheus.metrics)); t.ok(/circuit_bob_/.test(prometheus.metrics)); + t.ok(/circuit_bob_.*perf/.test(prometheus.metrics)); t.ok(/circuit_foo_/.test(prometheus.metrics)); + t.ok(/circuit_foo_.*perf/.test(prometheus.metrics)); prometheus.clear(); t.end(); }); -test('The add function accepts zero parameters', t => { +test('The add function called without parameter do nothing', t => { t.plan(1); const prometheus = new PrometheusMetrics(); prometheus.add(); From de08441622daa778f89be4c0dba34da0bd6a024b Mon Sep 17 00:00:00 2001 From: Lance Ball Date: Wed, 2 Oct 2019 10:49:58 -0400 Subject: [PATCH 2/3] Fix indent for README.md list item --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7a412c6..4a67720 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ constructor. For each circuit breaker, the metrics are: -* a `prometheus counter` for each event name -* a `prometheus summary` for the events `success`, `failed` execution time. + * a `prometheus counter` for each event name + * a `prometheus summary` for the events `success`, `failed` execution time. Example: From bf907594ca5cf8b9f2f7e3e6a4c3c05db55cb02b Mon Sep 17 00:00:00 2001 From: Lance Ball Date: Wed, 2 Oct 2019 11:36:30 -0400 Subject: [PATCH 3/3] squash: fix indent (again) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4a67720..98bd22d 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ constructor. For each circuit breaker, the metrics are: - * a `prometheus counter` for each event name - * a `prometheus summary` for the events `success`, `failed` execution time. + * a `prometheus counter` for each event name + * a `prometheus summary` for the events `success`, `failed` execution time. Example: