From ea9f34aa3e361cb312ca4b7ff24b5f5d23cb6dd3 Mon Sep 17 00:00:00 2001 From: Henrik Karlsson Date: Fri, 9 Dec 2022 17:19:10 +0100 Subject: [PATCH] Add new option bypassOnFinish, for when response is required in bypass callback --- README.md | 1 + spec/index.spec.js | 38 ++++++++++++++++++++++++++++++++++++++ src/index.js | 4 ++++ types/index.d.ts | 1 + 4 files changed, 44 insertions(+) diff --git a/README.md b/README.md index 88f6404..86133a6 100644 --- a/README.md +++ b/README.md @@ -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 * **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** +* **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`**. ### metricType option ### diff --git a/spec/index.spec.js b/spec/index.spec.js index 3236696..181457a 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -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', () => { expect(() => bundle({prefix: 'hello'})).toThrow(); }); diff --git a/src/index.js b/src/index.js index 88e80bc..bad1eeb 100644 --- a/src/index.js +++ b/src/index.js @@ -182,6 +182,10 @@ function main(opts) { const timer = metrics[httpMetricName].startTimer(labels); onFinished(res, () => { + if (opts.bypassOnFinish && opts.bypassOnFinish(req, res)) { + return; + } + if (opts.includeStatusCode) { labels.status_code = opts.formatStatusCode(res, opts); } diff --git a/types/index.d.ts b/types/index.d.ts index 6bdc5a7..bec8583 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -28,6 +28,7 @@ declare namespace express_prom_bundle { includeUp?: boolean; bypass?: (req: Request) => boolean; + bypassOnFinish?: (req: Request, res: Response) => boolean; excludeRoutes?: Array;