Compare commits

...

40 Commits
6.0.0 ... 6.3.2

Author SHA1 Message Date
Konstantin Pogorelov
2478e617bb bump 6.3.2 2021-02-18 15:31:34 +01:00
Konstantin Pogorelov
92db62dc90 run dtslint on travis with --onlyTestTsNext as a workaround for failing prom-client typing with older TS versions 2021-02-18 15:05:08 +01:00
Konstantin Pogorelov
3ffdeef8ae add linting (eslint) to travis 2021-02-18 13:04:39 +01:00
Konstantin Pogorelov
7c35f1beb6 add indentation rule for eslint 2021-02-18 13:03:25 +01:00
Konstantin Pogorelov
c44d157cfe codestyle: fix indentation 2021-02-18 13:01:26 +01:00
Konstantin Pogorelov
731fd3ec01 replace node_js v13 with v14 in travis config 2021-02-18 12:52:00 +01:00
Konstantin Pogorelov
3f587fb760 reduce minimal peer prom-client version to 12, allow any higher major version (let's be optimistic), see #76 2021-02-18 12:12:06 +01:00
Konstantin Pogorelov
3c2779d0d1 bump 6.3.1 2020-12-24 12:23:39 +01:00
Konstantin Pogorelov
a3c15b1645 support Promise response from .metrics() and .clusterMetrics(), see #71 2020-12-24 12:23:20 +01:00
Konstantin Pogorelov
f4677ce6c6 update dev. prom-client to v13, see #71 2020-12-24 12:17:02 +01:00
Konstantin Pogorelov
958453eb91 bump 6.3.0 2020-11-29 15:48:17 +01:00
Konstantin Pogorelov
0205d4cfc8 fix bypass test, minor change to docs, move bypass logic after serving the /metrics route, see MR #70 2020-11-29 15:47:28 +01:00
yacine
bffb4cf16e changed wording + added doc + unit test 2020-11-29 15:13:01 +01:00
yacine
52fdbf030f ability to exclude incoming request from metrics 2020-11-28 21:42:52 +01:00
Konstantin Pogorelov
c55d5f4862 fix duplicate httpDurationMetricName in types 2020-10-06 13:05:26 +02:00
Konstantin Pogorelov
75b1e2cafa bump 6.2.0 2020-10-06 12:54:37 +02:00
Konstantin Pogorelov
e2a8869b7f Merge pull request #43 from GabrielCastro/patch-1
update types to correct transformLabels
2020-10-06 12:51:26 +02:00
Konstantin Pogorelov
c64772dfc9 Merge pull request #55 from dpc/dpc-patch-1
Add a missing option to `Opts`
2020-10-06 12:49:33 +02:00
Konstantin Pogorelov
c1b1022fb5 Merge pull request #56 from Collaborne/pr/middleware-result
Declare that the metricsMiddleware is accessible on the bundle as well
2020-10-06 12:48:39 +02:00
Konstantin Pogorelov
16dfa7f926 bump version to 6.1.0 2020-07-22 18:24:43 +02:00
Konstantin Pogorelov
7e58bd3d06 Merge pull request #47 from jochen-schweizer/dependabot/npm_and_yarn/eslint-utils-1.4.3
Bump eslint-utils from 1.3.1 to 1.4.3
2020-07-22 18:19:46 +02:00
Konstantin Pogorelov
adf15f03f4 Merge pull request #52 from jochen-schweizer/dependabot/npm_and_yarn/acorn-6.4.1
Bump acorn from 6.0.4 to 6.4.1
2020-07-22 18:19:28 +02:00
Konstantin Pogorelov
6629c09dfa Merge pull request #60 from anxolin/add-missing-metric-name-opt
Add missing metric name parameter
2020-07-22 18:16:32 +02:00
Konstantin Pogorelov
fe2d1d25ec Merge pull request #64 from jochen-schweizer/dependabot/npm_and_yarn/handlebars-4.7.6
Bump handlebars from 4.0.12 to 4.7.6
2020-07-22 18:16:03 +02:00
Konstantin Pogorelov
a5d63925ce Merge pull request #62 from jonaskello/patch-1
Fix spelling
2020-07-22 18:15:30 +02:00
dependabot[bot]
43ba2091d3 Bump handlebars from 4.0.12 to 4.7.6
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.0.12 to 4.7.6.
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.12...v4.7.6)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-22 16:13:09 +00:00
dependabot[bot]
1909018c17 Bump acorn from 6.0.4 to 6.4.1
Bumps [acorn](https://github.com/acornjs/acorn) from 6.0.4 to 6.4.1.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.0.4...6.4.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-22 16:13:05 +00:00
dependabot[bot]
52f3a955df Bump eslint-utils from 1.3.1 to 1.4.3
Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.3.1 to 1.4.3.
- [Release notes](https://github.com/mysticatea/eslint-utils/releases)
- [Commits](https://github.com/mysticatea/eslint-utils/compare/v1.3.1...v1.4.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-22 16:12:59 +00:00
Konstantin Pogorelov
e2800e7d30 Merge pull request #53 from jochen-schweizer/dependabot/npm_and_yarn/js-yaml-3.13.1
Bump js-yaml from 3.12.0 to 3.13.1
2020-07-22 18:12:31 +02:00
Konstantin Pogorelov
fff0384605 Merge pull request #63 from jochen-schweizer/dependabot/npm_and_yarn/lodash-4.17.19
Bump lodash from 4.17.11 to 4.17.19
2020-07-22 18:12:11 +02:00
Konstantin Pogorelov
514745b23a Merge pull request #46 from aaronleesmith/feature/customizable-prom-registry
Allows for customizing promRegistry when creating prom bundle.
2020-07-22 18:10:08 +02:00
dependabot[bot]
77730b9df5 Bump lodash from 4.17.11 to 4.17.19
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-16 00:02:18 +00:00
Jonas Kello
6d9da12d97 Fix spelling 2020-06-06 18:59:44 +02:00
Anxo Rodriguez
f1f36f0fb7 Add missing metric name parameter 2020-04-27 19:36:43 +02:00
Andreas Kohn
d2f0088f3c Declare that the metricsMiddleware is accessible on the bundle as well
Related-to: #49
2020-04-09 21:09:38 +02:00
Dawid Ciężarkiewicz
4f89424c79 Add a missing option to Opts 2020-04-09 09:28:22 -07:00
dependabot[bot]
33765b3654 Bump js-yaml from 3.12.0 to 3.13.1
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.12.0 to 3.13.1.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.12.0...3.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-03-21 18:08:10 +00:00
Aaron Smith
0a1fda31de Fixes lint issue. 2019-09-19 11:39:11 -06:00
Aaron Smith
7654a4ec79 Allows for customizing promRegistry when creating prom bundle. 2019-09-19 11:10:43 -06:00
Gabriel Castro
faeeb7b57b update types to correct transformLabels returning
`transformLabels` should return void as the library expects
the labels object to be modified in place and does not use the return value
2019-07-22 16:38:14 -04:00
9 changed files with 176 additions and 94 deletions

View File

@@ -17,6 +17,7 @@
"extends": "eslint:recommended",
"rules": {
"indent": [1, 2],
"array-bracket-spacing": [2, "never"],
"block-scoped-var": 2,
"brace-style": [2, "1tbs"],

View File

@@ -2,12 +2,12 @@ language: node_js
node_js:
- "10"
- "12"
- "13"
- "14"
notifications:
email: false
before_install:
- npm install prom-client
script:
- npm run lint
- npm test
- npm run dtslint
- npm run dtslint-next

View File

@@ -46,12 +46,13 @@ Which labels to include in `http_request_duration_seconds` metric:
* **includeStatusCode**: HTTP status code (200, 400, 404 etc.), default: **true**
* **includeMethod**: HTTP method (GET, PUT, ...), default: **false**
* **includePath**: URL path (see importent details below), default: **false**
* **includePath**: URL path (see important details below), default: **false**
* **customLabels**: an object containing extra labels, e.g. ```{project_name: 'hello_world'}```.
Most useful together with **transformLabels** callback, otherwise it's better to use native Prometheus relabeling.
* **includeUp**: include an auxiliary "up"-metric which always returns 1, default: **true**
* **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**
### metricType option ###
@@ -85,6 +86,7 @@ Additional options for **summary**:
* **promClient**: options for promClient startup, e.g. **collectDefaultMetrics**. This option was added
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`.
### More details on includePath option

113
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "express-prom-bundle",
"version": "5.1.5",
"version": "6.3.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -115,9 +115,9 @@
}
},
"acorn": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz",
"integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==",
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
"dev": true
},
"acorn-jsx": {
@@ -210,7 +210,7 @@
},
"async": {
"version": "1.5.2",
"resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
},
@@ -892,10 +892,21 @@
}
},
"eslint-utils": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz",
"integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==",
"dev": true
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
"integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.1.0"
},
"dependencies": {
"eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
"dev": true
}
}
},
"eslint-visitor-keys": {
"version": "1.0.0",
@@ -1254,25 +1265,23 @@
"dev": true
},
"handlebars": {
"version": "4.0.12",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz",
"integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==",
"version": "4.7.6",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz",
"integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==",
"dev": true,
"requires": {
"async": "^2.5.0",
"optimist": "^0.6.1",
"minimist": "^1.2.5",
"neo-async": "^2.6.0",
"source-map": "^0.6.1",
"uglify-js": "^3.1.4"
"uglify-js": "^3.1.4",
"wordwrap": "^1.0.0"
},
"dependencies": {
"async": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
"integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
"dev": true,
"requires": {
"lodash": "^4.17.10"
}
"minimist": {
"version": "1.2.5",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
"source-map": {
"version": "0.6.1",
@@ -1354,7 +1363,7 @@
},
"http-errors": {
"version": "1.6.3",
"resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"dev": true,
"requires": {
@@ -1621,9 +1630,9 @@
"dev": true
},
"js-yaml": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
"integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
@@ -1817,9 +1826,9 @@
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true
},
"log-driver": {
@@ -1957,6 +1966,12 @@
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
"dev": true
},
"neo-async": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@@ -2031,30 +2046,6 @@
"integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=",
"dev": true
},
"optimist": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
"dev": true,
"requires": {
"minimist": "~0.0.1",
"wordwrap": "~0.0.2"
},
"dependencies": {
"minimist": {
"version": "0.0.10",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
"dev": true
},
"wordwrap": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
"integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
"dev": true
}
}
},
"optionator": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
@@ -2207,9 +2198,9 @@
"dev": true
},
"prom-client": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/prom-client/-/prom-client-12.0.0.tgz",
"integrity": "sha512-JbzzHnw0VDwCvoqf8y1WDtq4wSBAbthMB1pcVI/0lzdqHGJI3KBJDXle70XK+c7Iv93Gihqo0a5LlOn+g8+DrQ==",
"version": "13.0.0",
"resolved": "https://registry.npmjs.org/prom-client/-/prom-client-13.0.0.tgz",
"integrity": "sha512-M7ZNjIO6x+2R/vjSD13yjJPjpoZA8eEwH2Bp2Re0/PvzozD7azikv+SaBtZes4Q1ca/xHjZ4RSCuTag3YZLg1A==",
"dev": true,
"requires": {
"tdigest": "^0.1.1"
@@ -2355,7 +2346,7 @@
},
"resolve": {
"version": "1.1.7",
"resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
"dev": true
},
@@ -2516,7 +2507,7 @@
},
"source-map": {
"version": "0.2.0",
"resolved": "http://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
"integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
"dev": true,
"optional": true,
@@ -2669,7 +2660,7 @@
},
"superagent": {
"version": "2.3.0",
"resolved": "http://registry.npmjs.org/superagent/-/superagent-2.3.0.tgz",
"resolved": "https://registry.npmjs.org/superagent/-/superagent-2.3.0.tgz",
"integrity": "sha1-cDUpoHFOV+EjlZ3e+84ZOy5Q0RU=",
"dev": true,
"requires": {
@@ -2687,7 +2678,7 @@
},
"supertest": {
"version": "2.0.1",
"resolved": "http://registry.npmjs.org/supertest/-/supertest-2.0.1.tgz",
"resolved": "https://registry.npmjs.org/supertest/-/supertest-2.0.1.tgz",
"integrity": "sha1-oFgIHXiPFRXUcA11Aogea3WeRM0=",
"dev": true,
"requires": {

View File

@@ -1,6 +1,6 @@
{
"name": "express-prom-bundle",
"version": "6.0.0",
"version": "6.3.2",
"description": "express middleware with popular prometheus metrics in one bundle",
"main": "src/index.js",
"keywords": [
@@ -17,8 +17,10 @@
"types": "types",
"scripts": {
"test": "node_modules/jasme/run.js",
"lint": "eslint src",
"coverage": "make coverage",
"dtslint": "dtslint types"
"dtslint": "dtslint types",
"dtslint-next": "dtslint --onlyTestTsNext types"
},
"author": "Konstantin Pogorelov <or@pluseq.com>",
"license": "MIT",
@@ -36,13 +38,13 @@
"jasme": "^6.0.0",
"koa": "^2.6.2",
"koa-connect": "^2.0.1",
"prom-client": "^12.0.0",
"prom-client": "^13.0.0",
"supertest": "^3.3.0",
"supertest-koa-agent": "^0.3.0",
"typescript": "^3.4.5"
},
"peerDependencies": {
"prom-client": "^12.0.0"
"prom-client": ">=12.0.0"
},
"repository": {
"type": "git",

View File

@@ -200,6 +200,46 @@ describe('index', () => {
});
});
it('bypass requests', done => {
const app = express();
const instance = bundle({
bypass: (req)=> {
// metrics added here to attempt skipping /metrics
// this should fail though, because serving /metrics preceeds bypassing
return !!req.url.match(/test|bad.word|metrics/)
}
});
app.use(instance);
app.use('/test', (req, res) => res.send('it worked'));
app.use('/some/bad-word', (req, res) => res.send('it worked too'));
app.use('/good-word', (req, res) => res.send('this will be counted'));
const agent = supertest(app);
agent
.get('/test')
.end(() => {
agent
.get('/some/bad-word')
.end(() => {
agent
.get('/good-word')
.end(() => {
const metricHashMap = instance.metrics.http_request_duration_seconds.hashMap;
expect(metricHashMap['status_code:200']).toBeDefined();
// only /good-word should be counted
expect(metricHashMap['status_code:200'].count).toBe(1);
agent
.get('/metrics')
.end((err, res) => {
expect(res.status).toBe(200);
done();
});
});
});
});
});
it('complains about deprecated options', () => {
expect(() => bundle({prefix: 'hello'})).toThrow();
});

View File

@@ -17,20 +17,37 @@ function matchVsRegExps(element, regexps) {
}
function clusterMetrics() {
const aggregatorRegistry = new promClient.AggregatorRegistry();
const aggregatorRegistry = new promClient.AggregatorRegistry();
const metricsMiddleware = function(req, res) {
aggregatorRegistry.clusterMetrics((err, clusterMetrics) => {
if (err) {
console.error(err);
return res.sendStatus(500);
}
res.set('Content-Type', aggregatorRegistry.contentType);
res.send(clusterMetrics);
});
};
const metricsMiddleware = function(req, res) {
function sendClusterMetrics(clusterMetrics) {
res.set('Content-Type', aggregatorRegistry.contentType);
res.send(clusterMetrics);
}
return metricsMiddleware;
function sendClusterMetricsError(err) {
console.error(err);
return res.sendStatus(500);
}
// since prom-client@13 clusterMetrics() method doesn't take cb param,
// but we provide it anyway, as at this stage it's unknown which version of prom-client is used
const response = aggregatorRegistry.clusterMetrics((err, clusterMetrics) => {
if (err) {
return sendClusterMetricsError(err);
}
sendClusterMetrics(clusterMetrics);
});
// if we find out that it was a promise and our cb was useless...
if (response && response.then) {
response
.then(result => sendClusterMetrics(result))
.catch(err => sendClusterMetricsError(err));
}
};
return metricsMiddleware;
}
function main(opts) {
@@ -50,7 +67,8 @@ function main(opts) {
normalizePath: main.normalizePath,
formatStatusCode: main.normalizeStatusCode,
metricType: 'histogram',
promClient: {}
promClient: {},
promRegistry: promClient.register
}, opts
);
@@ -92,14 +110,16 @@ function main(opts) {
labelNames: labels,
percentiles: opts.percentiles || [0.5, 0.75, 0.95, 0.98, 0.99, 0.999],
maxAgeSeconds: opts.maxAgeSeconds,
ageBuckets: opts.ageBuckets
ageBuckets: opts.ageBuckets,
registers: [opts.promRegistry]
});
} else if (opts.metricType === 'histogram' || !opts.metricType) {
return new promClient.Histogram({
name: httpMetricName,
help: 'duration histogram of http responses labeled with: ' + labels.join(', '),
labelNames: labels,
buckets: opts.buckets || [0.003, 0.03, 0.1, 0.3, 1.5, 10]
buckets: opts.buckets || [0.003, 0.03, 0.1, 0.3, 1.5, 10],
registers: [opts.promRegistry]
});
} else {
throw new Error('metricType option must be histogram or summary');
@@ -113,14 +133,25 @@ function main(opts) {
if (opts.includeUp !== false) {
metrics.up = new promClient.Gauge({
name: 'up',
help: '1 = up, 0 = not up'
help: '1 = up, 0 = not up',
registers: [opts.promRegistry]
});
metrics.up.set(1);
}
const metricsMiddleware = function(req, res) {
const metricsMiddleware = function(req, res, next) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(promClient.register.metrics());
const metricsResponse = opts.promRegistry.metrics();
// starting from prom-client@13 .metrics() returns a Promise
if (metricsResponse.then) {
metricsResponse
.then(output => res.end(output))
.catch(err => next(err));
} else {
// compatibility fallback for previous versions of prom-client@<=12
res.end(metricsResponse);
}
};
const metricsMatch = opts.metricsPath instanceof RegExp ? opts.metricsPath
@@ -130,7 +161,13 @@ function main(opts) {
const path = req.originalUrl || req.url; // originalUrl gets lost in koa-connect?
if (opts.autoregister && path.match(metricsMatch)) {
return metricsMiddleware(req, res);
return metricsMiddleware(req, res);
}
// bypass() is checked only after /metrics was processed
// if you wish to disable /metrics use autoregister:false instead
if (opts.bypass && opts.bypass(req)) {
return next();
}
if (opts.excludeRoutes && matchVsRegExps(path, opts.excludeRoutes)) {

14
types/index.d.ts vendored
View File

@@ -1,7 +1,7 @@
// TypeScript Version: 2.8
import { Request, RequestHandler, Response } from 'express';
import { DefaultMetricsCollectorConfiguration } from 'prom-client';
import { DefaultMetricsCollectorConfiguration, Registry } from 'prom-client';
export {};
@@ -15,7 +15,7 @@ declare namespace express_prom_bundle {
type NormalizePathEntry = [string | RegExp, string];
type NormalizePathFn = (req: Request, opts: Opts) => string;
type NormalizeStatusCodeFn = (res: Response) => number | string;
type TransformLabelsFn = (labels: Labels, req: Request, res: Response) => Labels;
type TransformLabelsFn = (labels: Labels, req: Request, res: Response) => void;
interface Opts {
autoregister?: boolean;
@@ -28,9 +28,13 @@ declare namespace express_prom_bundle {
includePath?: boolean;
includeUp?: boolean;
bypass?: (req: Request) => boolean;
metricType?: 'summary' | 'histogram';
metricsPath?: string;
httpDurationMetricName?: string;
promClient?: { collectDefaultMetrics?: DefaultMetricsCollectorConfiguration };
promRegistry?: Registry;
normalizePath?: NormalizePathEntry[] | NormalizePathFn;
formatStatusCode?: NormalizeStatusCodeFn;
transformLabels?: TransformLabelsFn;
@@ -44,6 +48,10 @@ declare namespace express_prom_bundle {
};
}
interface Middleware extends RequestHandler {
metricsMiddleware: RequestHandler;
}
const normalizePath: NormalizePathFn;
const normalizeStatusCode: NormalizeStatusCodeFn;
@@ -55,4 +63,4 @@ interface express_prom_bundle {
normalizeStatusCode: express_prom_bundle.NormalizeStatusCodeFn;
}
declare function express_prom_bundle(opts: express_prom_bundle.Opts): RequestHandler;
declare function express_prom_bundle(opts: express_prom_bundle.Opts): express_prom_bundle.Middleware;

View File

@@ -3,7 +3,7 @@ import * as promClient from 'prom-client';
import * as promBundle from 'express-prom-bundle';
// $ExpectType RequestHandler
// $ExpectType Middleware
const middleware: RequestHandler = promBundle({ includeMethod: true });
// $ExpectType: string
@@ -11,7 +11,7 @@ middleware.name;
promClient.register.clear();
// $ExpectType RequestHandler
// $ExpectType Middleware
promBundle({
normalizePath: [
// collect paths like "/customer/johnbobson" as just one "/custom/#name"
@@ -30,7 +30,7 @@ promBundle({
promClient.register.clear();
// $ExpectType RequestHandler
// $ExpectType Middleware
promBundle({
buckets: [0.1, 0.4, 0.7],
includeMethod: true,
@@ -46,6 +46,7 @@ promBundle({
collectDefaultMetrics: {
}
},
promRegistry: new promClient.Registry(),
urlValueParser: {
minHexLength: 5,
extraMasks: [