basic-metrics
v0.2.0
Published
Metric aggregator hopefully without opinions
Downloads
3
Readme
Basic Metrics
This library is supposed to be the foundation for reporting metrics. It shouldn't matter what stack you decided to go with whether it be StatsD, Prometheus or New Relic. We all implement metrics the same way in our internal libraries. This library was created so we could have metrics gathered without opinions. Meaning your metric naming can be gathered for whatever stack you decided to go with. No naming convention is enforced.
Notes during unstable release
Right now this library is unstable as we figure out what the format this should be in. As of today I think Counters and Gauges solve the current problems that I need to solve for my use cases. Summaries and histograms will need additional work. Contracts may change depending on the needs of the community or as problems are discovered.
Looking forward
The main idea for this is to have two options of getting metrics.
The first use case would be up to the user to implement their own interval for reporting. This library will expose the necessary endpoints for you to gather the metrics that have been accounted for.
The second use case is a little more advanced. I would like this lib to be able to account for burst metrics. As an example, if the user sets a limit of 200 metrics per summary, and if we have more than 200 metrics coming in for a given interval, metrics will be lost. This would mean the library could emit when it is time to announce metrics to a given platform. And also increase that frequency in the case of burst requests/metrics so that way we don't lose metrics. This of course would be configurable and left up to the user to decide what best fits their scenario.
Getting started
npm i -S basic-metrics
yarn add basic-metrics
// some-metric-file.js
const { createMetricClient } = require('basic-metrics');
const client = createMetricClient({
name: 'my-metric-client',
attributes: {
host: process.env.HOST
}
});
setInterval(() => {
const payload = client.report();
/*
{
metrics: [
{
name: 'axios.post.success',
value: 300,
type: 'count',
startTime: 123467,
endTime: 123457,
attributes: {
host: 'my-machine',
DOH: 'https://will.ruin.net/sarcasm'
}
},
{
name: 'axios.post.failed',
value: 0,
type: 'count',
startTime: 1234567,
endTime: 123456,
attributes: {
host: 'my-machine',
DOH: 'https://will.ruin.net/sarcasm'
}
}
],
length: 2
}
*/
axios.post('newrelic.com', payload);
}, 1000);
module.exports = client;
// some-axios-wrapper.js
const client = require('./some-metric-file');
const attributes = { DOH: 'https://will.ruin.net/sarcasm' };
const requestSuccess = client.createCounter({ name: 'axios.post.success', attributes });
const requestFail = client.createCounter({ name: 'axios.post.failed', attributes });
exports.makeHypotheticalDestructiveRequest = async () => {
try {
const result = await axios.post(attributes.DOH, 'Whereis Google.com');
requestSuccess.increment();
return result;
} catch (e) {
requestFail.increment();
console.error(e);
throw e;
}
};
Api
createMetricClient
const { createMetricClient } = require('basic-metrics');
// Config is optional
const client = createMetricClient({
name: ''// Global name for client
attributes: {} // (optional) global Object for describing all metrics
})
client.report(); // executes all reports on all known metrics
client.createCounter
const { createMetricClient } = require('basic-metrics');
const client = createMetricClient();
const counter = client.createCounter({
name: 'my.counter.success', //Name of counter
attributes: {} // (optional) object for describing this metric. Merges with global attributes
reportSettings: { // (optional) object for configuring how reporting works
resetValueOnReport: false // default(false) sets the value to 0 when report is called.
}
});
counter.increment((num = 1)); // increases count by 1 can be specified more
counter.report(); // get report object for counter. Will reset startTime
Counter Report Object
{
name: 'my.counter',
value: 3,
type: 'count',
startTime: 123456,
endTime: 53211,
}
client.createGauge
const { createMetricClient } = require('basic-metrics');
const client = createMetricClient();
const gauge = client.createGuage({
name: 'my.gauge.variable', // Name of gauge
attributes: {} // (Optional) object for describing this metric. Merges with global attributes
});
gauge.increment((num = 1)); // Increase the gauge by x default: 1
gauge.decrement((num = 1)); // Decrease the gauge by x default: 1 (negative numbers will increment the gauge.)
gauge.set(); // Set the gauge to a predefined number
gauge.report(); // get the report for the gauge. Will reset the startTime
Gauge Report Object
{
name: 'my.gauge',
value: 3,
type: 'gauge',
startTime: 123456,
endTime: 53211,
}
client.createSummary
const { createMetricClient } = require('basic-metrics');
const client = createMetricClient();
const sum = client.createSummary({
name: 'my.summary', // Name of gauge
attributes: {} // (Optional) object for describing this metric. Merges with global attributes
});
sum.observe(); // Observes a number (Will throw if num is not a number)
sum.report(); // get the report for the gauge. Will reset the startTime
Summary Report Object
{
name: 'my.summary',
type: 'summary',
startTime: 123556,
endTime: 12357,
breakdown: {
count: 0,
min: 0,
max: 0,
sum: 0,
p99: 0,
p95: 0
},
attributes: {}
}