prom-client
prom-client copied to clipboard
[Feature] ExponentialBuckets with start and end
Usually when constructing exponential buckets I have a rough estimate in mind of what my boundaries are. I'd for instance think in terms of, start + end + count, rather than start + factor + count. And I find myself writing helper functions like:
function exponentialStartEndBuckets (start, end, count) {
const factor = (end / start) ** (1 / (count - 1));
return promClient.exponentialBuckets(start, factor, count);
}
I propose adding a helper function like this one (but probably better named).
Edit:
a more elaborate version that does some rounding
function roundToPrecision (num, precision = 0) {
// https://stackoverflow.com/a/18358056
return Number(`${Math.round(`${num}e+${precision}`)}e-${precision}`);
}
function exponentialStartEndBuckets (start, end, count) {
const factor = (end / start) ** (1 / (count - 1));
const buckets = promClient.exponentialBuckets(start, factor, count);
const precision = Math.max(0, -Math.floor(Math.log10(buckets[1] - buckets[0])));
return buckets.map(bucket => roundToPrecision(bucket, precision));
}
or even
function roundToPrecision (num, precision = 0) {
// https://stackoverflow.com/a/18358056
return Number(`${Math.round(`${num}e+${precision}`)}e-${precision}`);
}
function exponentialStartEndBuckets (start, end, count) {
const factor = (end / start) ** (1 / (count - 1));
const buckets = promClient.exponentialBuckets(start, factor, count);
let currentBucket = null;
return buckets.map(bucket => {
if (currentBucket === null) {
currentBucket = bucket;
} else {
const precision = Math.max(0, -Math.floor(Math.log10(bucket - currentBucket)));
currentBucket = roundToPrecision(bucket, precision);
}
return currentBucket;
});
}
@siimon I can cook up a PR for this. Do you have a preference/suggestion for naming the function?
Another option could be to have exponentialBuckets accept an object as the first parameter so it can be called as
exponentialBuckets(1, 2, 10);
exponentialBuckets({
start: 1,
factor: 2,
count: 10
});
exponentialBuckets({
start: 1,
end: 30,
count: 10
});
I think your suggestion is good, to have an object as first parameter. But if you implement it that way, please keep the backwards compatibility so we don't need to make a breaking change!
Thanks for your suggestion btw!