Merge pull request #101 from derangeddk/add-metricsapp-option

Add metricsapp option
This commit is contained in:
Konstantin Pogorelov
2022-06-18 12:08:49 +02:00
committed by GitHub
5 changed files with 37 additions and 7 deletions

View File

@@ -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

View File

@@ -590,5 +590,23 @@ describe('index', () => {
});
});
});
it('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();
});
});
});
});
});

View File

@@ -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;

3
types/index.d.ts vendored
View File

@@ -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?: {

View File

@@ -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<T> = { -readonly [K in keyof T]: T[K] };
const wPromBundle: Writable<promBundle> = 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();