yaorg / node-measured

A Node metrics library for measuring and reporting application-level metrics, inspired by Coda Hale, Yammer Inc's Dropwizard Metrics Libraries
https://yaorg.github.io/node-measured/
MIT License
516 stars 52 forks source link

Get max value of a counter - Feature request (or potentially stupid user) #81

Closed JohnMcLear closed 4 years ago

JohnMcLear commented 4 years ago

Analogy to keep things simple..

I use counters && counter.inc/dec to have stats how many active connections we have.

I need to know what the maximum connections have been since application start. I wonder if this is something that node-measured provides and I'm just missing it. Obivously I can write logic on inc event => if value is > value in variable => overwrite variable value with newValue but I want to keep things clean and inside measured if I can...

Sorry again if I'm missing something obvious here..

fieldju commented 4 years ago

When you say maximum connections have been since application start. i'm not 100% sure what you mean.

Let's assume you mean max concurrent active connections and you you are keeping track of concurrent active connections with a counter.

You could maybe do something like this with a CachedGuage

const { CachedGauge, Counter } = require('measured-core');

const activeConnections = new Counter();
const currentMax = 0;
const updateIntervalInSeconds = 1; // How often we should compare activeConnections the currentMax and update the gauge value
const maxActiveConnections = new CachedGauge(() => {
    return new Promise(resolve => {
        const curActiveConnections = activeConnections.toJSON();
        currentMax = curActiveConnections > currentMax ? curActiveConnections : currentMax;
        resolve(currentMax);
    });
}, updateIntervalInSeconds);  

http.createServer(function(req, res) {
    activeConnections.inc();
    req.on('end', function() {
        activeConnections.dec();
    });
});

☝️ This will sample the current active count every second. This is a sampling if you need to be exact you can use a settable gauge in the request loop. warning, I am not sure if that will have a performance impact.

👇 Here is the exact value

const { SettableGuage, Counter } = require('measured-core');

const activeConnections = new Counter();
const maxActiveConnections = new SettableGauge();
http.createServer(function(req, res) {
    activeConnections.inc();
    const cur = activeConnections.toJSON();
    const currentMax = maxActiveConnections.toJSON()
    if (cur > currentMax) {
        maxActiveConnections.setValue(cur);
    }
    req.on('end', function() {
        activeConnections.dec();
    });
});

See: https://yaorg.github.io/node-measured/packages/measured-node-metrics/ for how you could adapt any of these 2 approaches and still get the other requests metrics in a custom middleware.

JohnMcLear commented 4 years ago

I ended up just doing it the super simple / hacky way

var maxPS = 0;
...

if(Math.round(jstats.changeFromServer.currentRate) > maxPS){
  maxPS = Math.round(jstats.changeFromServer.currentRate);
}
console.log("Max(per second)", maxPS || Math.round(jstats.changeFromServer.currentRate));

https://github.com/JohnMcLear/etherpad-load-test/commit/abd8213ad6ed773040821de098e8c315f4cd80f1