{"_id":"@isaacs/express-prometheus-middleware","_rev":"1-181b6e2d7ece21f4610e076575c90fd2","name":"@isaacs/express-prometheus-middleware","dist-tags":{"latest":"1.2.1"},"versions":{"1.2.0":{"name":"@isaacs/express-prometheus-middleware","version":"1.2.0","description":"RED/USE metrics for express applications (forked to remove vulnerable optional deps)","keywords":["express","prometheus","metrics","monit"],"main":"src/index.js","repository":{"type":"git","url":"git+https://github.com/joao-fontenele/express-prometheus-middleware.git"},"author":{"name":"João Paulo Fontenele Brito","email":"jpfb@icomp.ufam.edu.br"},"license":"MIT","private":false,"scripts":{"lint":"eslint . && echo '✔  Your .js files look good.'","release":"standard-version"},"devDependencies":{"@commitlint/cli":"^8.3.5","@commitlint/config-conventional":"^8.3.4","@ls-age/commitlint-circle":"^1.0.0","eslint":"^6.6.0","eslint-config-airbnb-base":"^14.0.0","eslint-plugin-import":"^2.13.0","express":"4.x","husky":"^4.2.5","prom-client":">= 10.x <= 13.x","standard-version":"^9.2.0"},"dependencies":{"response-time":"^2.3.2","url-value-parser":"^2.0.0"},"peerDependencies":{"express":"4.x","prom-client":">= 10.x <= 13.x"},"gitHead":"e0e93ee0fa91700b7bd6769f80176d392053c9a3","bugs":{"url":"https://github.com/joao-fontenele/express-prometheus-middleware/issues"},"homepage":"https://github.com/joao-fontenele/express-prometheus-middleware#readme","_id":"@isaacs/express-prometheus-middleware@1.2.0","_nodeVersion":"19.4.0","_npmVersion":"9.3.0","dist":{"integrity":"sha512-RkLdkivlYUNQabLiyTXzVMDn8kYfR22WGH3T0OQvcz1XXAzazhAQKKPuXf41JY/icMZ+naTbMk42QVSXdw5msg==","shasum":"396dd0e39d4f62142712c7964d76283dabb55a04","tarball":"https://registry.npmjs.org/@isaacs/express-prometheus-middleware/-/express-prometheus-middleware-1.2.0.tgz","fileCount":6,"unpackedSize":17394,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCJYrE8zAc+uoMgwrFp7AjAadBIpy6/sx4P2u0XHsI52QIhALWF6b/ldXjVJYp6li2W+X2voUPccvYYssOf66v1wXKk"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj0YwlACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqOeg//aK3NnuNgNgWUhB1UtW23Yab3/Mv2WLYqires70hRz7eiy9+T\r\ni7mAiS9nyOH/6bo66Jnk3ALQtWSQip7bDBD6znLYtvQOCJxn8CQIul+EC+SV\r\n5pZhrwTFFUaYzxI4ZDXDUJg4a+Dg/532R8vehvhKPUyeX6gZcIAIB20y+ohQ\r\nf4/y9H6skpehgAUNVYq7NavwQXyzhqNfqlc5XPQRwB+oyGIOyFNMEWEruT9g\r\nTLRaZESQL5NtTWWIX0Xc/HLVWzg4t5m49IbDfO/GSB2pzW5KGe48/7gbdNHU\r\nHoha3XIuUWntPFejoq2+e3CNof/DRyPoRR9rnYl46hwO/yGzdfZWvdnX1v8Q\r\nIkGTwOt7DttFthcmSeOuyxKm6BUk6UpYFAaTvjm531TWcbjdQmw2wZWjH/hF\r\nhKFiEq9B7mMQW23DBxAgOTpSDX8lGD+5QGPhfmaaDI2pwraBM2bC52oRynOL\r\nlY4crPRLzDJL49NKRg1ck0fCWeqbEsYN+ykhrddr2hO/zvGGcBqj5kJzHvtr\r\nGA1NVWYDHsTuNTqiWCUHhh1WNggGpLycMC95GesYSHEKW9nfiZSg08vnVXwK\r\nCXDgPUo7L1vWCetAZm59EFTb2E2YCjCDaeNN6/0nwFF29IMMLMgrLv42yZhe\r\n0nPu7q15v6UrkJhjiyHg81wx4TMtX5s0aPU=\r\n=8O8f\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"isaacs","email":"i@izs.me"},"directories":{},"maintainers":[{"name":"isaacs","email":"i@izs.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/express-prometheus-middleware_1.2.0_1674677285085_0.07185729106763783"},"_hasShrinkwrap":false},"1.2.1":{"name":"@isaacs/express-prometheus-middleware","version":"1.2.1","description":"RED/USE metrics for express applications (forked to remove vulnerable optional deps)","keywords":["express","prometheus","metrics","monit"],"main":"src/index.js","types":"src/index.d.ts","repository":{"type":"git","url":"git+https://github.com/joao-fontenele/express-prometheus-middleware.git"},"author":{"name":"João Paulo Fontenele Brito","email":"jpfb@icomp.ufam.edu.br"},"license":"MIT","private":false,"scripts":{"lint":"eslint . && echo '✔  Your .js files look good.'","release":"standard-version"},"devDependencies":{"@commitlint/cli":"^8.3.5","@commitlint/config-conventional":"^8.3.4","@ls-age/commitlint-circle":"^1.0.0","eslint":"^6.6.0","eslint-config-airbnb-base":"^14.0.0","eslint-plugin-import":"^2.13.0","express":"4.x","husky":"^4.2.5","prom-client":">= 10.x <= 13.x","standard-version":"^9.2.0"},"dependencies":{"response-time":"^2.3.2","url-value-parser":"^2.0.0"},"peerDependencies":{"express":"4.x","prom-client":">= 10.x <= 13.x"},"gitHead":"401c78e1732f3eb9ba9072bb987aed4ba7924736","bugs":{"url":"https://github.com/joao-fontenele/express-prometheus-middleware/issues"},"homepage":"https://github.com/joao-fontenele/express-prometheus-middleware#readme","_id":"@isaacs/express-prometheus-middleware@1.2.1","_nodeVersion":"19.4.0","_npmVersion":"9.3.0","dist":{"integrity":"sha512-l+5S2vC6DvOhrFBwsTr4U4lhLESivDhg56DaDscdu5mtL+xfk/hdNoYOIhBO9Z8Q9dpUtnGyU5dchG44nrQBQA==","shasum":"0936f24046eee899b750c901bf33a2ff5c748803","tarball":"https://registry.npmjs.org/@isaacs/express-prometheus-middleware/-/express-prometheus-middleware-1.2.1.tgz","fileCount":7,"unpackedSize":20421,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDlOEE/gpUkzEE461CDwxoUw7odVYbS9/dA6c5T0SFGCQIhAPdlz908eHlfoyWMn6IJ1Musdy1sw8q0X0Tl0yQzssy6"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj0Y2QACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr0NA/+JSVhglwoTy3fuA1DqXj5vAU4Ds93gsT0F3FBHdU97Wrxwc0f\r\nHFh94sY6dPMGeOwLTr57xWNvCDPp6U11Ztcro8bD2Ct+FCppWAVEKoT+O8ck\r\nfHZvxJp04crU9Q+jBRw1HWoJBqN9TP6Zmb/4KSvI4k6js4GF3rO4+3f5hKM9\r\nG9xxNsC4diPpH/BfK/wJdWdFhnnxhOdg6sumcFmQ2tpxJezXppmT4jI2cab/\r\nFrpk/PE12ANMeoN1XtoLFXMwjI35bU0IPW8vnMJdpbYTGzuAI2Tw1r4pZH8S\r\nRJqqhDvCqfVkkmWAwN3C/735qFTPYlL7b+ss1dAUMQS9MvDYpHFyrb/r8ZFm\r\n0S2G7P2B3XddM3bAX5KyPnxdubBmbfmnIadDe9v2XUrZ/Mqtg3oObpTD4VKS\r\ncWUtqQTpbMCEFSUkDoDrzG2uLz+tuwQhMA6cm3UIaJ4r1I81pvuTuZUyLjFn\r\ntaLuJwtneH/udUWP1MkaIufHIFay8TVNq9cayFvQIQ5LHYhYZMngNqtTSZ9b\r\na9T7rQG8qPskKbDLqmqri+EPB3drop2k+l9a+RDJRcVr+IeZ7aUp7mw/pW+i\r\nmWxS4VXWlTnOiopc7isoRP9u0rk/bO9am8dCOGk1eXDLzIkJ/HVOnScmG0Qw\r\nrxCM4iHWta8XEgASNz1M7/baisV4zkveS3I=\r\n=TQKA\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"isaacs","email":"i@izs.me"},"directories":{},"maintainers":[{"name":"isaacs","email":"i@izs.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/express-prometheus-middleware_1.2.1_1674677648578_0.6178209061277891"},"_hasShrinkwrap":false}},"time":{"created":"2023-01-25T20:08:05.027Z","1.2.0":"2023-01-25T20:08:05.294Z","modified":"2023-01-25T20:14:08.862Z","1.2.1":"2023-01-25T20:14:08.783Z"},"maintainers":[{"name":"isaacs","email":"i@izs.me"}],"description":"RED/USE metrics for express applications (forked to remove vulnerable optional deps)","homepage":"https://github.com/joao-fontenele/express-prometheus-middleware#readme","keywords":["express","prometheus","metrics","monit"],"repository":{"type":"git","url":"git+https://github.com/joao-fontenele/express-prometheus-middleware.git"},"author":{"name":"João Paulo Fontenele Brito","email":"jpfb@icomp.ufam.edu.br"},"bugs":{"url":"https://github.com/joao-fontenele/express-prometheus-middleware/issues"},"license":"MIT","readme":"# Express Prometheus Middleware\n\n[![npm](https://img.shields.io/npm/v/express-prometheus-middleware.svg)](https://www.npmjs.com/package/express-prometheus-middleware)\n[![Dependency Status](https://david-dm.org/joao-fontenele/express-prometheus-middleware.svg)](https://david-dm.org/joao-fontenele/express-prometheus-middleware)\n[![devDependency Status](https://david-dm.org/joao-fontenele/express-prometheus-middleware/dev-status.svg)](https://david-dm.org/joao-fontenele/express-prometheus-middleware#info=devDependencies)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/express-prometheus-middleware/community)\n\nThis is a middleware for express servers, that expose metrics for prometheus.\n\nThe metrics exposed allows to calculate common RED (Request, Error rate, Duration of requests), and USE (Utilisation, Error rate, and Saturation), metrics\n\n## Install\n\n``` bash\nyarn add express-prometheus-middleware\n# or\nnpm i --save express-prometheus-middleware\n```\n\n## Usage\n\n### Options\n\n| Name | Description | Default |\n| :-: | :- | :- |\n| metricsPath | Url route that will expose the metrics for scraping. | `/metrics` |\n| metricsApp  | Express app that will expose metrics endpoint, if an app is provided, use it, instead of instantiating a new one | `null` |\n| collectDefaultMetrics | Whether or not to collect `prom-client` default metrics. These metrics are usefull for collecting saturation metrics, for example. | `true` |\n| collectGCMetrics | Whether or not to collect garbage collection metrics via module `prometheus-gc-stats`. Dependency `prometheus-gc-stats` is marked as optional, hence if this option is set to `true` but npm/yarn could not install the dependency, no garbage collection metric will be collected. | `false` |\n| requestDurationBuckets | Buckets for the request duration metrics (in seconds) histogram | Uses `prom-client` utility: `Prometheus.exponentialBuckets(0.05, 1.75, 8)` |\n| requestLengthBuckets | Buckets for the request length metrics (in bytes) histogram | no buckets (The request length metrics are not collected): `[]` |\n| responseLengthBuckets | Buckets for the response length metrics (in bytes) histogram | no buckets (The response length metrics are not collected) `[]` |\n| extraMasks | Optional, list of regexes to be used as argument to [url-value-parser](https://www.npmjs.com/package/url-value-parser), this will cause extra route params,  to be replaced with a `#val` placeholder.  | no extra masks: `[]` |\n| authenticate | Optional authentication callback, the function should receive as argument, the `req` object and return truthy for sucessfull authentication, or falsy, otherwise. This option supports Promise results. | `null` |\n| prefix | Optional prefix for the metrics name | no prefix added |\n| customLabels | Optional Array containing extra labels, used together with  `transformLabels` | no extra labels: `[]` |\n| transformLabels | Optional `function(labels, req, res)` adds to the labels object dynamic values for each label in `customLabels` | `null` |\n| normalizeStatus | Optional parameter to disable normalization of the status code. Example of normalized and non-normalized status code respectively: 4xx and 422.| true\n### Example\n\n```js\nconst express = require('express');\nconst promMid = require('express-prometheus-middleware');\nconst app = express();\n\nconst PORT = 9091;\napp.use(promMid({\n  metricsPath: '/metrics',\n  collectDefaultMetrics: true,\n  requestDurationBuckets: [0.1, 0.5, 1, 1.5],\n  requestLengthBuckets: [512, 1024, 5120, 10240, 51200, 102400],\n  responseLengthBuckets: [512, 1024, 5120, 10240, 51200, 102400],\n  /**\n   * Uncomenting the `authenticate` callback will make the `metricsPath` route\n   * require authentication. This authentication callback can make a simple\n   * basic auth test, or even query a remote server to validate access.\n   * To access /metrics you could do:\n   * curl -X GET user:password@localhost:9091/metrics\n   */\n  // authenticate: req => req.headers.authorization === 'Basic dXNlcjpwYXNzd29yZA==',\n  /**\n   * Uncommenting the `extraMasks` config will use the list of regexes to\n   * reformat URL path names and replace the values found with a placeholder value\n  */\n  // extraMasks: [/..:..:..:..:..:../],\n  /**\n   * The prefix option will cause all metrics to have the given prefix.\n   * E.g.: `app_prefix_http_requests_total`\n   */\n  // prefix: 'app_prefix_',\n  /**\n   * Can add custom labels with customLabels and transformLabels options\n   */\n  // customLabels: ['contentType'],\n  // transformLabels(labels, req) {\n  //   // eslint-disable-next-line no-param-reassign\n  //   labels.contentType = req.headers['content-type'];\n  // },\n}));\n\n// curl -X GET localhost:9091/hello?name=Chuck%20Norris\napp.get('/hello', (req, res) => {\n  console.log('GET /hello');\n  const { name = 'Anon' } = req.query;\n  res.json({ message: `Hello, ${name}!` });\n});\n\napp.listen(PORT, () => {\n  console.log(`Example api is listening on http://localhost:${PORT}`);\n});\n```\n\n### Metrics exposed\n\n- Default metrics from [prom-client](https://github.com/siimon/prom-client)\n- `http_requests_total`: Counter for total requests received, has labels `route`, `method`, `status`\n- `http_request_duration_seconds`: - Duration of HTTP requests in seconds, has labels `route`, `method`, `status`\n\nThe labels `route` and `status` are normalized:\n\n- `route`: will normalize id like route params\n- `status`: will normalize to status code family groups, like `2XX` or `4XX`.\n\n### Example prometheus queries\n\nIn the examples below, Suppose you tagged your application as \"myapp\", in the prometheus scrapping config.\n\n#### Running instances\n\n```js\nsum(up{app=\"myapp\"})\n```\n\n#### Overall error rate\n\nRate of http status code 5XX responses\n\n```js\nsum(rate(http_requests_total{status=\"5XX\", app=\"myapp\"}[5m]))\n```\n\n#### 95% of requests served within seconds\n\n```js\nhistogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket{app=\"myapp\"}[5m])) by (le))\n```\n\n#### 95% of request length\n\n```js\nhistogram_quantile(0.95, sum(rate(http_request_length_bytes_bucket{app=\"myapp\"}[5m])) by (le))\n```\n\n#### 95% of response length\n\n```js\nhistogram_quantile(0.95, sum(rate(http_response_length_bytes_bucket{app=\"myapp\"}[5m])) by (le))\n```\n\n#### Average response time in seconds\n\n```js\nsum(rate(http_request_duration_seconds_sum{app=\"myapp\"}[5m])) by (instance) / sum(rate(http_request_duration_seconds_count{app=\"myapp\"}[5m])) by (instance)\n```\n\n#### Overall Request rate\n\n```js\nsum(rate(http_requests_total{app=\"myapp\"}[5m])) by (instance)\n```\n\n#### Request rate by route\n\nIn this example we are removing some health/status-check routes, replace them with your needs.\n\n```js\nsum(rate(http_requests_total{app=\"myapp\", route!~\"/|/healthz\"}[5m])) by (instance, route)\n```\n\n#### CPU usage\n\n```js\nrate(process_cpu_system_seconds_total{app=\"myapp\"}[5m])\nrate(process_cpu_user_seconds_total{app=\"myapp\"}[5m])\n```\n\n#### Memory usage\n\n```js\nnodejs_heap_size_total_bytes{app=\"myapp\"}\nnodejs_heap_size_used_bytes{app=\"myapp\"}\n```\n","readmeFilename":"README.md"}