From c4be86b6514219b60caa5cf271efac0ea103567d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Dyhrberg=20Thegler?= Date: Fri, 17 Jun 2022 13:41:36 +0200 Subject: [PATCH 1/6] Add metricsApp option Lets you supply an additional express app on which to mount the metrics endpoint --- src/index.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 6f85193..cc6969e 100644 --- a/src/index.js +++ b/src/index.js @@ -68,7 +68,8 @@ function main(opts) { formatStatusCode: main.normalizeStatusCode, metricType: 'histogram', promClient: {}, - promRegistry: promClient.register + promRegistry: promClient.register, + metricsApp: null, }, opts ); @@ -204,6 +205,13 @@ function main(opts) { next(); }; + if (opts.metricsApp) { + opts.metricsApp.get(opts.metricsPath || '/metrics', async (req, res, next) => { + res.set('Content-Type', opts.promRegistry.contentType); + return res.end(await opts.promRegistry.metrics()); + }); + } + middleware.metrics = metrics; middleware.promClient = promClient; middleware.metricsMiddleware = metricsMiddleware; From bcac9f523a455d78b3a635ffa2fd133f62e3db25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Dyhrberg=20Thegler?= Date: Fri, 17 Jun 2022 13:42:54 +0200 Subject: [PATCH 2/6] Add option to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6259aee..88f6404 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ Additional options for **summary**: to keep `express-prom-bundle` runnable using confit (e.g. with kraken.js) without writing any JS code, see [advanced example](https://github.com/jochen-schweizer/express-prom-bundle/blob/master/advanced-example.js) * **promRegistry**: Optional `promClient.Registry` instance to attach metrics to. Defaults to global `promClient.register`. +* **metricsApp**: Allows you to attach the metrics endpoint to a different express app. You probably want to use it in combination with `autoregister: false`. ### More details on includePath option From 5a1efd7fe66d074d1ad27b78648fac53db053574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Dyhrberg=20Thegler?= Date: Fri, 17 Jun 2022 20:42:35 +0200 Subject: [PATCH 3/6] Add typings --- types/index.d.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/types/index.d.ts b/types/index.d.ts index 16ef31b..6bdc5a7 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,6 +1,6 @@ // TypeScript Version: 2.8 -import { Request, RequestHandler, Response } from 'express'; +import { Request, RequestHandler, Response, Express } from 'express'; import { DefaultMetricsCollectorConfiguration, Registry } from 'prom-client'; export {}; @@ -49,6 +49,7 @@ declare namespace express_prom_bundle { formatStatusCode?: NormalizeStatusCodeFn; transformLabels?: TransformLabelsFn; urlPathReplacement?: string; + metricsApp?: Express; // https://github.com/disjunction/url-value-parser#options urlValueParser?: { From a1284ec3e5b507568fd6a9420e5ba8e9a3dc68a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Dyhrberg=20Thegler?= Date: Fri, 17 Jun 2022 21:01:03 +0200 Subject: [PATCH 4/6] Add test for typings --- types/test.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/types/test.ts b/types/test.ts index 42061b5..176cd54 100644 --- a/types/test.ts +++ b/types/test.ts @@ -1,10 +1,11 @@ -import { Request, RequestHandler, Response } from 'express'; +import * as express from 'express'; + import * as promClient from 'prom-client'; import * as promBundle from 'express-prom-bundle'; // $ExpectType Middleware -const middleware: RequestHandler = promBundle({ includeMethod: true }); +const middleware: express.RequestHandler = promBundle({ includeMethod: true }); // $ExpectType: string middleware.name; @@ -57,7 +58,8 @@ promBundle({ normalizePath: [ ['^/foo', '/example'] // replace /foo with /example ], - formatStatusCode: (res: Response) => res.statusCode + 100 + formatStatusCode: (res: express.Response) => res.statusCode + 100, + metricsApp: express() }); promClient.register.clear(); @@ -79,14 +81,14 @@ promBundle({ type Writable = { -readonly [K in keyof T]: T[K] }; const wPromBundle: Writable = promBundle; -wPromBundle.normalizePath = (req: Request, opts: promBundle.Opts) => { +wPromBundle.normalizePath = (req: express.Request, opts: promBundle.Opts) => { const path = promBundle.normalizePath(req, opts); // count all docs as one path, but /docs/login as a separate one return path.match(/^\/docs/) && !path.match(/^\/login/) ? '/docs/*' : path; }; -wPromBundle.normalizeStatusCode = (res: Response) => res.statusCode.toString(); +wPromBundle.normalizeStatusCode = (res: express.Response) => res.statusCode.toString(); // $ExpectType RequestHandler promBundle.clusterMetrics(); From 1ee094eb041ab886e90884b75f69f47c8d63f07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Dyhrberg=20Thegler?= Date: Fri, 17 Jun 2022 21:01:14 +0200 Subject: [PATCH 5/6] Add jasmine test --- spec/index.spec.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/spec/index.spec.js b/spec/index.spec.js index 55e3152..69cb399 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -590,5 +590,23 @@ describe('index', () => { }); }); }); + + fit('additional metricsApp can be used', done => { + const app = express(); + const metricsApp = express(); + const bundled = bundle({metricsApp}); + + app.use(bundled); + + const agent = supertest(app); + const metricsAgent = supertest(metricsApp); + agent.get('/').end(() => { + metricsAgent.get('/metrics').end((err, res) => { + expect(res.status).toBe(200); + expect(res.text).toMatch(/status_code="404"/); + done(); + }); + }); + }); }); }); From 2293d1cd408c4b8932f614a25cb7a0cef7bb81d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Dyhrberg=20Thegler?= Date: Fri, 17 Jun 2022 21:19:53 +0200 Subject: [PATCH 6/6] Remove exclusive test running Silly me --- spec/index.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/index.spec.js b/spec/index.spec.js index 69cb399..b4cf671 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -591,7 +591,7 @@ describe('index', () => { }); }); - fit('additional metricsApp can be used', done => { + it('additional metricsApp can be used', done => { const app = express(); const metricsApp = express(); const bundled = bundle({metricsApp});