opossum-prometheus
Advanced tools
Comparing version 0.0.2 to 0.0.3
@@ -5,2 +5,10 @@ # Changelog | ||
### [0.0.3](https://github.com/lholmquist/opossum-prometheus/compare/v0.0.2...v0.0.3) (2019-09-18) | ||
### Features | ||
* allow one circuit to be pass in without an array. ([#5](https://github.com/lholmquist/opossum-prometheus/issues/5)) ([02ca8f5](https://github.com/lholmquist/opossum-prometheus/commit/02ca8f5)), closes [#4](https://github.com/lholmquist/opossum-prometheus/issues/4) | ||
* allow to add circuits dynamicaly ([#7](https://github.com/lholmquist/opossum-prometheus/issues/7)) ([afbaef2](https://github.com/lholmquist/opossum-prometheus/commit/afbaef2)) | ||
### 0.0.2 (2019-08-13) |
19
index.js
@@ -12,3 +12,3 @@ 'use strict'; | ||
// https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels | ||
function normalizePrefix(prefixName) { | ||
function normalizePrefix (prefixName) { | ||
return `circuit_${prefixName.replace(/[ |-]/g, '_')}_`; | ||
@@ -19,2 +19,7 @@ } | ||
constructor (circuits, registry) { | ||
if (circuits instanceof client.Registry) { | ||
registry = circuits; | ||
circuits = undefined; | ||
} | ||
this._registry = registry || client.register; | ||
@@ -29,6 +34,16 @@ this._client = client; | ||
if (circuits) { | ||
this.add(circuits); | ||
} | ||
} | ||
add (circuits) { | ||
if (!circuits) { | ||
return; | ||
} | ||
circuits = Array.isArray(circuits) ? circuits : [circuits]; | ||
let prefix; | ||
circuits.forEach(circuit => { | ||
prefix = normalizePrefix(circuit.name); | ||
for (let eventName of circuit.eventNames()) { | ||
for (const eventName of circuit.eventNames()) { | ||
const counter = new this._client.Counter({ | ||
@@ -35,0 +50,0 @@ name: `${prefix}${eventName}`, |
{ | ||
"name": "opossum-prometheus", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Prometheus metrics for opossum circuit breaker", | ||
@@ -9,3 +9,3 @@ "main": "index.js", | ||
"test": "nyc tape test/*.js | tap-spec", | ||
"coverage": "nyc report && if [ $CODACY_OPOSSUM_PROMETHEUS'' != '' ] ; then nyc report --reporter=text-lcov | codacy-coverage; fi", | ||
"coverage": "nyc report && if [ $CODACY_PROJECT_TOKEN'' != '' ] ; then nyc report --reporter=text-lcov | codacy-coverage; fi", | ||
"ci": "npm run test && npm run coverage", | ||
@@ -32,5 +32,5 @@ "prerelease": "npm run ci", | ||
"nyc": "^14.1.1", | ||
"opossum": "^3.0.0", | ||
"opossum": "^4.0.0", | ||
"standard-version": "^7.0.0", | ||
"standardx": "^3.0.1", | ||
"standardx": "^5.0.0", | ||
"tap-spec": "^5.0.0", | ||
@@ -37,0 +37,0 @@ "tape": "^4.11.0" |
@@ -5,5 +5,6 @@ # Prometheus Metrics for Opossum Circuit Breaker | ||
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/6dcbcd9e5a6649faafb5b00ceeecb4db)](https://www.codacy.com/app/nodeshift/opossum-prometheus?utm_source=github.com&utm_medium=referral&utm_content=nodeshift/opossum-prometheus&utm_campaign=Badge_Grade) | ||
[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/6dcbcd9e5a6649faafb5b00ceeecb4db)](https://www.codacy.com/app/nodeshift/opossum-prometheus?utm_source=github.com&utm_medium=referral&utm_content=nodeshift/opossum-prometheus&utm_campaign=Badge_Coverage) | ||
[![dependencies Status](https://david-dm.org/nodeshift/opossum-prometheus/status.svg)](https://david-dm.org/nodeshift/opossum-prometheus) | ||
[![Known Vulnerabilities](https://snyk.io/test/npm/opossum-prometheus/badge.svg)](https://snyk.io/test/npm/opossum-prometheus) [![Greenkeeper badge](https://badges.greenkeeper.io/nodeshift/opossum-prometheus.svg)](https://greenkeeper.io/) | ||
This module provides [Prometheus](https://prometheus.io/) metrics for | ||
@@ -17,8 +18,8 @@ [opossum](https://github.com/nodeshift/opossum) circuit breakers. To use | ||
```js | ||
const circuitBreaker = require('opossum'); | ||
const CircuitBreaker = require('opossum'); | ||
const PrometheusMetrics = require('opossum-prometheus'); | ||
// create a couple of circuit breakers | ||
const c1 = circuitBreaker(someFunction); | ||
const c2 = circuitBreaker(someOtherfunction); | ||
const c1 = new CircuitBreaker(someFunction); | ||
const c2 = new CircuitBreaker(someOtherfunction); | ||
@@ -28,2 +29,7 @@ // Provide them to the constructor | ||
//... | ||
// Provide other circuit breaker later | ||
const c3 = new CircuitBreaker(someOtherfunction3); | ||
prometheus.add([C3]); | ||
// Write metrics to the console | ||
@@ -34,2 +40,23 @@ console.log(prometheus.metrics); | ||
This module would typically be used in an application that can provide | ||
an endpoint for the Prometheus server to monitor. | ||
an endpoint for the Prometheus server to monitor. | ||
The `prometheusRegistry` constructor parameter allows you to provide an existing | ||
[prom-client](https://github.com/siimon/prom-client) registry. | ||
The metrics about the circuit will be added to the provided registry instead | ||
of the global registry. | ||
The [default metrics](https://github.com/siimon/prom-client#default-metrics) | ||
will not be added to the provided registry. | ||
```js | ||
const CircuitBreaker = require('opossum'); | ||
const PrometheusMetrics = require('opossum-prometheus'); | ||
const { Registry } = require('prom-client'); | ||
// Create a registry | ||
const registry = new Registry(); | ||
// create a circuit | ||
const circuit = new CircuitBreaker(functionThatMightFail); | ||
const metrics = new PrometheusMetrics(circuit, registry) | ||
``` | ||
'use strict'; | ||
const test = require('tape'); | ||
const circuitBreaker = require('opossum'); | ||
const CircuitBreaker = require('opossum'); | ||
const PrometheusMetrics = require('../'); | ||
@@ -23,6 +23,26 @@ const client = require('prom-client'); | ||
test('The factory function accept no parameter', t => { | ||
t.plan(1); | ||
const prometheus = new PrometheusMetrics(); | ||
t.ok(prometheus); | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('The factory function takes an object instead of just an Array', t => { | ||
t.plan(2); | ||
const c1 = new CircuitBreaker(passFail, { name: 'fred' }); | ||
const prometheus = new PrometheusMetrics(c1); | ||
t.equal(c1.name, 'fred'); | ||
t.ok(/circuit_fred_/.test(prometheus.metrics)); | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('The factory function provides access to metrics for all circuits', t => { | ||
t.plan(4); | ||
const c1 = circuitBreaker(passFail, { name: 'fred' }); | ||
const c2 = circuitBreaker(passFail, { name: 'bob' }); | ||
const c1 = new CircuitBreaker(passFail, { name: 'fred' }); | ||
const c2 = new CircuitBreaker(passFail, { name: 'bob' }); | ||
const prometheus = new PrometheusMetrics([c1, c2]); | ||
@@ -40,6 +60,6 @@ t.equal(c1.name, 'fred'); | ||
const registry = new Registry(); | ||
const c1 = circuitBreaker(passFail, { | ||
const c1 = new CircuitBreaker(passFail, { | ||
name: 'fred' | ||
}); | ||
const c2 = circuitBreaker(passFail, { | ||
const c2 = new CircuitBreaker(passFail, { | ||
name: 'bob' | ||
@@ -58,102 +78,171 @@ }); | ||
test('Circuit fire/success/failure are counted', t => { | ||
const circuit = circuitBreaker(passFail); | ||
const fire = /circuit_passFail_fire 2/; | ||
const success = /circuit_passFail_success 1/; | ||
const failure = /circuit_passFail_failure 1/; | ||
const prometheus = new PrometheusMetrics([circuit]); | ||
t.plan(3); | ||
circuit.fire(1) | ||
.then(_ => circuit.fire(-1)) | ||
.catch(_ => { | ||
const metrics = prometheus.metrics; | ||
t.ok(fire.test(metrics), fire); | ||
t.ok(success.test(metrics), success); | ||
t.ok(failure.test(metrics), failure); | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
}); | ||
test('The add function takes an object instead of just an Array', t => { | ||
t.plan(2); | ||
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)); | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('Metrics are enabled for all circuit events', t => { | ||
const circuit = circuitBreaker(passFail); | ||
const prometheus = new PrometheusMetrics([circuit]); | ||
const metrics = prometheus.metrics; | ||
t.plan(circuit.eventNames().length); | ||
for (let name of circuit.eventNames()) { | ||
const match = new RegExp(`circuit_passFail_${name}`); | ||
t.ok(match.test(metrics), name); | ||
} | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('The add function provides access to metrics for all circuits', t => { | ||
t.plan(6); | ||
const c1 = new CircuitBreaker(passFail, { name: 'fred' }); | ||
const c2 = new CircuitBreaker(passFail, { name: 'bob' }); | ||
const c3 = new CircuitBreaker(passFail, { name: 'foo' }); | ||
const prometheus = new PrometheusMetrics([c1]); | ||
prometheus.add([c2, c3]); | ||
t.equal(c1.name, 'fred'); | ||
t.equal(c2.name, 'bob'); | ||
t.equal(c3.name, 'foo'); | ||
t.ok(/circuit_fred_/.test(prometheus.metrics)); | ||
t.ok(/circuit_bob_/.test(prometheus.metrics)); | ||
t.ok(/circuit_foo_/.test(prometheus.metrics)); | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('Default prometheus metrics are enabled', t => { | ||
const circuit = circuitBreaker(passFail); | ||
const prometheus = new PrometheusMetrics([circuit]); | ||
const metrics = prometheus.metrics; | ||
const names = [ | ||
'process_cpu_seconds_total', | ||
'process_open_fds', | ||
'process_max_fds', | ||
'process_virtual_memory_bytes', | ||
'process_resident_memory_bytes', | ||
'process_heap_bytes', | ||
'process_start_time_seconds' | ||
]; | ||
t.plan(names.length); | ||
for (let name of names) { | ||
const match = new RegExp(`opossum_${name}`); | ||
t.ok(match.test(metrics), name); | ||
} | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('The add function accepts zero parameters', t => { | ||
t.plan(1); | ||
const prometheus = new PrometheusMetrics(); | ||
prometheus.add(); | ||
t.notOk(/circuit_/.test(prometheus.metrics)); | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('Should not add default metrics to custom registry', t => { | ||
const registry = new Registry(); | ||
const circuit = circuitBreaker(passFail); | ||
const prometheus = new PrometheusMetrics([circuit], registry); | ||
const metrics = prometheus.metrics; | ||
const names = [ | ||
'process_cpu_seconds_total', | ||
'process_open_fds', | ||
'process_max_fds', | ||
'process_virtual_memory_bytes', | ||
'process_resident_memory_bytes', | ||
'process_heap_bytes', | ||
'process_start_time_seconds' | ||
]; | ||
t.plan(names.length); | ||
for (let name of names) { | ||
const match = new RegExp(`opossum_${name}`); | ||
t.notOk(match.test(metrics), name); | ||
} | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('Circuit fire/success/failure are counted', t => { | ||
const circuit = new CircuitBreaker(passFail); | ||
const fire = /circuit_passFail_fire 2/; | ||
const success = /circuit_passFail_success 1/; | ||
const failure = /circuit_passFail_failure 1/; | ||
const prometheus = new PrometheusMetrics([circuit]); | ||
t.plan(3); | ||
circuit.fire(1) | ||
.then(_ => circuit.fire(-1)) | ||
.catch(_ => { | ||
const metrics = prometheus.metrics; | ||
t.ok(fire.test(metrics), fire); | ||
t.ok(success.test(metrics), success); | ||
t.ok(failure.test(metrics), failure); | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
}); | ||
test('Node.js specific metrics are enabled', t => { | ||
const circuit = circuitBreaker(passFail); | ||
const prometheus = new PrometheusMetrics([circuit]); | ||
const metrics = prometheus.metrics; | ||
const names = [ | ||
'nodejs_eventloop_lag', | ||
'nodejs_active_handles', | ||
'nodejs_active_requests', | ||
'nodejs_heap_size_total_bytes', | ||
'nodejs_heap_size_used_bytes', | ||
'nodejs_external_memory_bytes', | ||
'nodejs_heap_space_size_total_bytes', | ||
'nodejs_heap_space_size_used_bytes', | ||
'nodejs_heap_space_size_available_bytes', | ||
'nodejs_version_info' | ||
]; | ||
t.plan(names.length); | ||
for (let name of names) { | ||
const match = new RegExp(`opossum_${name}`); | ||
t.ok(match.test(metrics), name); | ||
} | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('Metrics are enabled for all circuit events', t => { | ||
const circuit = new CircuitBreaker(passFail); | ||
const prometheus = new PrometheusMetrics([circuit]); | ||
const metrics = prometheus.metrics; | ||
t.plan(circuit.eventNames().length); | ||
for (const name of circuit.eventNames()) { | ||
const match = new RegExp(`circuit_passFail_${name}`); | ||
t.ok(match.test(metrics), name); | ||
} | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('Default prometheus metrics are enabled', t => { | ||
const circuit = new CircuitBreaker(passFail); | ||
const prometheus = new PrometheusMetrics([circuit]); | ||
const metrics = prometheus.metrics; | ||
const names = [ | ||
'process_cpu_seconds_total', | ||
'process_open_fds', | ||
'process_max_fds', | ||
'process_virtual_memory_bytes', | ||
'process_resident_memory_bytes', | ||
'process_heap_bytes', | ||
'process_start_time_seconds' | ||
]; | ||
t.plan(names.length); | ||
for (const name of names) { | ||
const match = new RegExp(`opossum_${name}`); | ||
t.ok(match.test(metrics), name); | ||
} | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('Should not add default metrics to custom registry', t => { | ||
const registry = new Registry(); | ||
const circuit = new CircuitBreaker(passFail); | ||
const prometheus = new PrometheusMetrics([circuit], registry); | ||
const metrics = prometheus.metrics; | ||
const names = [ | ||
'process_cpu_seconds_total', | ||
'process_open_fds', | ||
'process_max_fds', | ||
'process_virtual_memory_bytes', | ||
'process_resident_memory_bytes', | ||
'process_heap_bytes', | ||
'process_start_time_seconds' | ||
]; | ||
t.plan(names.length); | ||
for (const name of names) { | ||
const match = new RegExp(`opossum_${name}`); | ||
t.notOk(match.test(metrics), name); | ||
} | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('Default prometheus metrics are enabled without circuit', t => { | ||
const registry = new Registry(); | ||
const prometheus = new PrometheusMetrics(registry); | ||
const metrics = prometheus.metrics; | ||
const names = [ | ||
'nodejs_eventloop_lag', | ||
'nodejs_active_handles', | ||
'nodejs_active_requests', | ||
'nodejs_heap_size_total_bytes', | ||
'nodejs_heap_size_used_bytes', | ||
'nodejs_external_memory_bytes', | ||
'nodejs_heap_space_size_total_bytes', | ||
'nodejs_heap_space_size_used_bytes', | ||
'nodejs_heap_space_size_available_bytes', | ||
'nodejs_version_info', | ||
'process_cpu_seconds_total', | ||
'process_open_fds', | ||
'process_max_fds', | ||
'process_virtual_memory_bytes', | ||
'process_resident_memory_bytes', | ||
'process_heap_bytes', | ||
'process_start_time_seconds' | ||
]; | ||
t.plan(names.length); | ||
for (const name of names) { | ||
const match = new RegExp(`opossum_${name}`); | ||
t.notOk(match.test(metrics), name); | ||
} | ||
prometheus.clear(); | ||
t.end(); | ||
}); | ||
test('Node.js specific metrics are enabled', t => { | ||
const circuit = new CircuitBreaker(passFail); | ||
const prometheus = new PrometheusMetrics([circuit]); | ||
const metrics = prometheus.metrics; | ||
const names = [ | ||
'nodejs_eventloop_lag', | ||
'nodejs_active_handles', | ||
'nodejs_active_requests', | ||
'nodejs_heap_size_total_bytes', | ||
'nodejs_heap_size_used_bytes', | ||
'nodejs_external_memory_bytes', | ||
'nodejs_heap_space_size_total_bytes', | ||
'nodejs_heap_space_size_used_bytes', | ||
'nodejs_heap_space_size_available_bytes', | ||
'nodejs_version_info' | ||
]; | ||
t.plan(names.length); | ||
for (const name of names) { | ||
const match = new RegExp(`opossum_${name}`); | ||
t.ok(match.test(metrics), name); | ||
} | ||
prometheus.clear(); | ||
t.end(); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19186
289
59
1