Add new option bypassOnFinish, for when response is required in bypass callback

This commit is contained in:
Henrik Karlsson
2022-12-09 17:19:10 +01:00
parent 93b0e8fafe
commit ea9f34aa3e
4 changed files with 44 additions and 0 deletions

View File

@@ -53,6 +53,7 @@ Which labels to include in `http_request_duration_seconds` metric:
* **metricsPath**: replace the `/metrics` route with a **regex** or exact **string**. Note: it is highly recommended to just stick to the default * **metricsPath**: replace the `/metrics` route with a **regex** or exact **string**. Note: it is highly recommended to just stick to the default
* **metricType**: histogram/summary selection. See more details below * **metricType**: histogram/summary selection. See more details below
* **bypass**: function taking express request as an argument and determines whether the given request should be excluded in the metrics, default: **() => false** * **bypass**: function taking express request as an argument and determines whether the given request should be excluded in the metrics, default: **() => false**
* **bypassOnFinish**: function taking express request and response as arguments and determines whether the given request should be excluded in the metrics, default: **() => false**. Prefer using **bypass** if you don't need the response object.
* **httpDurationMetricName**: Allows you change the name of HTTP duration metric, default: **`http_request_duration_seconds`**. * **httpDurationMetricName**: Allows you change the name of HTTP duration metric, default: **`http_request_duration_seconds`**.
### metricType option ### ### metricType option ###

View File

@@ -240,6 +240,44 @@ describe('index', () => {
}); });
}); });
it('bypass requests, checking res', done => {
const app = express();
const instance = bundle({
bypassOnFinish: (req, res) => res.statusCode === 404,
});
app.use(instance);
app.use('/200', (req, res) => res.send(''));
app.use('/404', (req, res) => res.status(404).send(''));
app.use('/500', (req, res) => res.status(500).send(''));
const agent = supertest(app);
agent.get('/200')
.expect(200)
.then(() => {
return agent
.get('/404')
.expect(404);
})
.then(() => {
return agent
.get('/500')
.expect(500);
})
.then(() => {
const metricHashMap = instance.metrics.http_request_duration_seconds.hashMap;
// only /200 and /500 should be counted
expect(metricHashMap['status_code:200'].count).toBe(1);
expect(metricHashMap['status_code:404']).not.toBeDefined();
expect(metricHashMap['status_code:500'].count).toBe(1);
return agent
.get('/metrics')
.expect(200);
})
.then(done);
});
it('complains about deprecated options', () => { it('complains about deprecated options', () => {
expect(() => bundle({prefix: 'hello'})).toThrow(); expect(() => bundle({prefix: 'hello'})).toThrow();
}); });

View File

@@ -182,6 +182,10 @@ function main(opts) {
const timer = metrics[httpMetricName].startTimer(labels); const timer = metrics[httpMetricName].startTimer(labels);
onFinished(res, () => { onFinished(res, () => {
if (opts.bypassOnFinish && opts.bypassOnFinish(req, res)) {
return;
}
if (opts.includeStatusCode) { if (opts.includeStatusCode) {
labels.status_code = opts.formatStatusCode(res, opts); labels.status_code = opts.formatStatusCode(res, opts);
} }

1
types/index.d.ts vendored
View File

@@ -28,6 +28,7 @@ declare namespace express_prom_bundle {
includeUp?: boolean; includeUp?: boolean;
bypass?: (req: Request) => boolean; bypass?: (req: Request) => boolean;
bypassOnFinish?: (req: Request, res: Response) => boolean;
excludeRoutes?: Array<string | RegExp>; excludeRoutes?: Array<string | RegExp>;