Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

artedi

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

artedi - npm Package Compare versions

Comparing version 1.4.1 to 2.0.0

examples/artedi_v1_buckets.js

10

CHANGES.md

@@ -6,2 +6,12 @@ # Changelog

## 2.0.0 [backward incompatible if you use histograms]
* #17 Histogram buckets completely changed to be compatible with Prometheus. You
can now either pass in an array of bucket values. If you do not pass in bucket
values, you will get the default buckets:
```
[0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]
```
* Important: see [docs/migrating.md](docs/migrating.md) for details on migrating
from node-artedi v1.x to v2.x.
## 1.4.1

@@ -8,0 +18,0 @@ * #15 improve the performance of hashObj()

17

lib/collector.js

@@ -6,3 +6,3 @@ /*

*
* Copyright (c) 2017, Joyent, Inc.
* Copyright (c) 2018, Joyent, Inc.
*/

@@ -18,2 +18,3 @@

var lib_utils = require('./utils');
var lib_buckets = require('./buckets');
var lib_counter = require('./counter');

@@ -79,2 +80,11 @@ var lib_gauge = require('./gauge');

/*
* Indicates this version uses fixed buckets per node-artedi#17 instead of
* the previous versions that supported dynamic buckets. We add this to the
* collector so that things like node-fast can support both node-artedi v1
* and node-artedi v2 by checking whether this is true on an otherwise
* unknown `collector` object.
*/
this.FIXED_BUCKETS = true;
this.registry = {};

@@ -353,4 +363,7 @@ this.triggerRegistry = [];

},
exponentialBuckets: lib_buckets.exponentialBuckets,
FMT_PROM: FMT_PROM,
FMT_PROM_0_0_4: FMT_PROM_0_0_4
FMT_PROM_0_0_4: FMT_PROM_0_0_4,
linearBuckets: lib_buckets.linearBuckets,
logLinearBuckets: lib_buckets.logLinearBuckets
};

174

lib/histogram.js

@@ -20,3 +20,23 @@ /*

/*
* These default buckets match the official golang, javascript, rust and other
* client libraries.
*/
var DEFAULT_BUCKETS = [
0.005,
0.01,
0.025,
0.05,
0.1,
0.25,
0.5,
1,
2.5,
5,
10
];
/*
* A Histogram is a type of collector that represents a series of Counters. Each

@@ -29,5 +49,9 @@ * Counter corresponds to a certain range of values, called 'buckets.'

mod_assert.string(options.help, 'options.help');
mod_assert.optionalArrayOfNumber(options.buckets, 'options.buckets');
mod_assert.optionalObject(options.labels, 'options.labels');
mod_assert.optionalObject(options.parentLabels, 'options.parentLabels');
var i;
var prevBucket = -1;
this.staticLabels =

@@ -40,4 +64,13 @@ mod_jsprim.mergeObjects(options.parentLabels, options.labels, null);

this.buckets = options.buckets || DEFAULT_BUCKETS;
this.counters = {};
this.gauge = new lib_gauge.Gauge(options);
// Assert that buckets are monotonic
for (i = 0; i < this.buckets.length; i++) {
mod_assert.ok(this.buckets[i] > prevBucket,
'buckets should be monotonic [' + this.buckets[i] +
' > ' + prevBucket + ']');
prevBucket = this.buckets[i];
}
}

@@ -64,14 +97,6 @@

var i;
var counter;
var pairCopy;
var buckets;
var index, count, i, bucket;
var smaller;
var metric;
// For log-linear bucketing, we will produce five linear steps per log jump.
// At a point in the future, we may allow the user to provide this value,
// but five seems like a reasonable default.
var linearSteps = 5;
pairs = mod_jsprim.mergeObjects(pairs, this.staticLabels, null);

@@ -83,69 +108,12 @@ counter = this.labels(pairs);

/* Begin setting initial value for new buckets (if applicable). */
// Determine which bucket from the new order our value falls into.
buckets = getOrder(value, linearSteps);
if (!buckets) {
// The value passed in is too big (> 10 billion), so we just increment
// the +Inf counter, and add to the Gauge.
counter.increment({
le: '+Inf'
});
this.gauge.add(value, counter.staticLabels);
return;
}
// Find the largest bucket that the observed value falls into.
for (bucket in buckets) {
if (value <= buckets[bucket]) {
index = buckets[bucket];
break;
}
}
// Find the next-smallest bucket from the list of already-used buckets.
// The buckets are sorted when they are added to a metric vector.
for (bucket in counter.metricVec.buckets) {
if (counter.metricVec.buckets[bucket] < index) {
smaller = bucket;
}
}
// Check to see if the proper bucket for this value already exists in
// the bucket list.
if (counter.metricVec.buckets.indexOf(index) === -1) {
counter.metricVec.addBuckets(buckets);
if (smaller) {
// Copy value from the next-smallest bucket into the newly created
// buckets.
pairCopy['le'] = counter.metricVec.buckets[smaller];
count = counter.labels(pairCopy).value;
if (count > 0) {
for (bucket in buckets) {
pairCopy['le'] = buckets[bucket];
metric = counter.labels(pairCopy);
if (metric.value === 0) {
// We don't want to double the value of overlapping
// buckets.
counter.add(count, pairCopy);
}
}
}
}
}
/* Done setting initial value for new buckets. */
// Now we need to increment the Counters for the buckets >= the value
// passed in.
buckets = counter.metricVec.buckets;
index = buckets.indexOf(index);
for (i = 0; i < buckets.length; i++) {
pairCopy['le'] = buckets[i];
if (i < index) {
// We don't need to increment buckets that are smaller than what we
// received, but we do want to zero them out if they don't exist.
// Increment the counters for each bucket(le) where "value" is <= the bucket
for (i = 0; i < this.buckets.length; i++) {
pairCopy['le'] = this.buckets[i];
if (value <= this.buckets[i]) {
counter.increment(pairCopy);
} else {
// We don't need to increment buckets that are smaller than value,
// but we do want to zero them out if they don't exist.
counter.labels(pairCopy);
continue;
}
counter.increment(pairCopy);
}

@@ -296,62 +264,4 @@

/*
* Find (and return) a list of linear numbers that 'value' falls into.
* The 'steps' argument is provided, as we may allow the user to specify
* the number of linear 'steps' between logarithmic jumps. This idea is taken
* from DTrace's log/linear quantization ('llquantize()').
*
* The 'steps' argument is ignored for retrieving the order of values less than
* one.
*/
function getOrder(value, steps) {
var i, j, bucketVal, width, next;
var buckets;
// These values are relatively arbitrary. It's possible that we may want to
// allow the user to change these at some point.
var factor = 10;
var low = 0;
// This is an arbitrary high watermark. Setting this allows us to ensure
// that our loop will always exit.
// The maximum value that we can observe (without it falling into only the
// +Inf bucket) is 3,486,784,401
var high = 13;
bucketVal = 0.0001; // smallest possible precision.
for (i = low; i <= high; i++) {
buckets = [];
next = bucketVal * factor;
if (bucketVal < 1) {
// Ignore the 'step' count for very small values.
width = bucketVal;
} else {
// Otherwise enforce that we don't have more than 'step' buckets.
width = next > steps ? next / steps : 1;
}
for (j = 0; bucketVal <= next; bucketVal += width, j++) {
if (bucketVal < 10) {
// only keep a few decimal places when decimal precision matters
bucketVal = +(bucketVal.toFixed(4));
} else {
bucketVal = Math.ceil(bucketVal);
}
buckets[j] = bucketVal;
}
// Overlap buckets so we get something like:
// [0-10], [10-100], [100-1000].
bucketVal -= width;
if (value <= buckets[buckets.length - 1]) {
// The number is within this order.
return (buckets);
}
}
return (null);
}
module.exports = {
Histogram: Histogram
};
{
"name": "artedi",
"version": "1.4.1",
"version": "2.0.0",
"description": "a metric client library",

@@ -5,0 +5,0 @@ "main": "lib/collector.js",

@@ -42,8 +42,9 @@ # node-artedi: client library for metric collection

var histogram = collector.histogram({
name: 'http_request_latency_ms',
help: 'latency of muskie http requests'
name: 'http_request_latency_seconds',
help: 'latency of muskie http requests',
buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]
});
// Observe a latency of 998ms for a 'putobjectdir' request.
histogram.observe(998, {
histogram.observe(0.998, {
method: 'putobjectdir'

@@ -63,13 +64,19 @@ });

// # TYPE http_requests_completed counter
// http_requests_completed{zone="e5d3",method="getobject",code="200"} 1
// # HELP http_request_latency_ms latency of muskie http requests
// # TYPE http_request_latency_ms histogram
// http_request_latency_ms{zone="e5d3",method="getobject",code="200",le="729"} 0
// http_request_latency_ms{zone="e5d3",method="getobject",code="200",le="2187"} 1
// http_request_latency_ms{zone="e5d3",method="getobject",code="200",le="3645"} 1
// http_request_latency_ms{zone="e5d3",method="getobject",code="200",le="5103"} 1
// http_request_latency_ms{zone="e5d3",method="getobject",code="200",le="6561"} 1
// http_request_latency_ms{zone="e5d3",method="getobject",code="200",le="+Inf"} 1
// http_request_latency_ms_count{zone="e5d3",method="getobject",code="200"} 1
// http_request_latency_ms_sum{zone="e5d3",method="getobject",code="200"} 998
// http_requests_completed{method="getobject",code="200",zone="e5d3"} 1
// # HELP http_request_latency_seconds latency of muskie http requests
// # TYPE http_request_latency_seconds histogram
// http_request_latency_seconds{method="putobjectdir",le="0.005"} 0
// http_request_latency_seconds{method="putobjectdir",le="0.01"} 0
// http_request_latency_seconds{method="putobjectdir",le="0.025"} 0
// http_request_latency_seconds{method="putobjectdir",le="0.05"} 0
// http_request_latency_seconds{method="putobjectdir",le="0.01"} 0
// http_request_latency_seconds{method="putobjectdir",le="0.25"} 0
// http_request_latency_seconds{method="putobjectdir",le="0.5"} 0
// http_request_latency_seconds{method="putobjectdir",le="1"} 1
// http_request_latency_seconds{method="putobjectdir",le="2.5"} 1
// http_request_latency_seconds{method="putobjectdir",le="5"} 1
// http_request_latency_seconds{method="putobjectdir",le="10"} 1
// http_request_latency_seconds{le="+Inf",method="putobjectdir"} 1
// http_request_latency_seconds_count{method="putobjectdir"} 1
// http_request_latency_seconds_sum{method="putobjectdir"} 0.998
});

@@ -76,0 +83,0 @@ ```

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc