jochen-schweizer / express-prom-bundle

express middleware with standard prometheus metrics in one bundle
MIT License
310 stars 68 forks source link

Allow custom tags #11

Closed ericuldall closed 7 years ago

ericuldall commented 7 years ago

It would be a great feature to allow custom tags when applying this middleware. Perhaps the end user has some environment variables they would like to be scraped by prometheus to improve dashboard display granularity.

Example:

const promBundle = require("express-prom-bundle");
const app = require("express")();
var customTags = {
  "zone": process.env.ZONE,
  "env": "production",
  "version": "1.0.0"
};
const metricsMiddleware = promBundle({includeMethod: true, includeCustomTags: customTags});

app.use(metricsMiddleware);
app.use(/* your middleware */);
app.listen(3000);

Then in our output it would be:

http_request_duration_seconds_count{status_code="200",method="GET",path="/",zone="us-central1-b",env="production",version="1.0.0"} 1

Is this something that would be accepted as a PR?

disjunction commented 7 years ago

Hi @ericuldall Thanks for the contribution! I decided for a little simpler solution though, introducing two different metrics: customLabels and transformLabels. The docs were extended accordingly.

I removed validation, since I expect the developers to understand what they're doing ;) The validation is needed where the software's decisions are not straight forward.

Your example would look like this now:

const metricsMiddleware = promBundle({includeMethod: true, customLabels: customTags});

... and transformLabels can be used for a dynamicly changing labels. See https://github.com/jochen-schweizer/express-prom-bundle/blob/master/advanced-example.js

Hope it's not too much of a change compared to your intention.

ericuldall commented 7 years ago

Is the update available on npm?

ericuldall commented 7 years ago

I see the update to the docs there. Thanks for adding this! It will be very useful.

kolesan commented 3 years ago

Is it possible to use transformLabels to add a custom tag depending on the response body?

In my case I need a custom label to track GraphQL error metrics. And the list of errors is returned in the response body together with the data.

disjunction commented 3 years ago

why not? The signature is: transformLabels: function(labels, req, res). So if you accumulate the data you need in either of req or res, then you can also can transform the labels accordingly.

I'd say res.locals is a fine place for the metrics.

kolesan commented 3 years ago

My question was a bit premature, sorry.

It was born from the lack of understanding of how express works, and the intricacies of reading a response body in a middleware.

I did end up putting errors from response body on to res.locals and then transforming a custom label using using their values. Thank you.

If anyone stumbles upon this issue in the same situation I was in, I used this to read the body:

function(res) {
    var end = res.end;
    res.end = function(chunk) {
        res.locals.errors = undefined;
        if (chunk) {
            try {
                res.locals.errors = JSON.parse(chunk.toString('utf-8')).errors;
            } catch {
            }
        }
        end.apply(this, arguments);
    }
}

Inspired by this answer https://stackoverflow.com/a/33881887/6493014