{"id":14676807,"url":"https://github.com/phil-r/stats","last_synced_at":"2025-08-01T00:31:55.945Z","repository":{"id":34896104,"uuid":"186882187","full_name":"phil-r/stats","owner":"phil-r","description":"📊 Request statistics middleware that stores response times, status code counts, etc","archived":false,"fork":false,"pushed_at":"2023-03-04T03:44:33.000Z","size":759,"stargazers_count":22,"open_issues_count":21,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-22T21:56:44.019Z","etag":null,"topics":["benchmarking","counter","express","express-middleware","fastify","koa","middleware","node","nodejs","polka","rayo","requests","statistics","stats"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phil-r.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-05-15T18:28:59.000Z","updated_at":"2024-03-28T18:01:13.000Z","dependencies_parsed_at":"2023-12-19T04:22:47.287Z","dependency_job_id":"da9c2828-ae0c-41cb-babb-0b0244dec351","html_url":"https://github.com/phil-r/stats","commit_stats":{"total_commits":227,"total_committers":5,"mean_commits":45.4,"dds":0.4581497797356828,"last_synced_commit":"3624afdab1df897c19d25cfd81db95816644c7e0"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phil-r%2Fstats","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phil-r%2Fstats/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phil-r%2Fstats/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phil-r%2Fstats/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phil-r","download_url":"https://codeload.github.com/phil-r/stats/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228321331,"owners_count":17901604,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["benchmarking","counter","express","express-middleware","fastify","koa","middleware","node","nodejs","polka","rayo","requests","statistics","stats"],"created_at":"2024-09-12T09:00:56.561Z","updated_at":"2024-12-05T15:10:07.701Z","avatar_url":"https://github.com/phil-r.png","language":"JavaScript","readme":"# stats\n\n\u003e Request statistics middleware\n\n[![NPM version](http://img.shields.io/npm/v/@phil-r/stats.svg?style=flat-square)](https://www.npmjs.com/package/@phil-r/stats)\n[![build status](https://github.com/phil-r/stats/workflows/Testing/badge.svg)](https://github.com/phil-r/stats/actions)\n[![code coverage](https://img.shields.io/codecov/c/github/phil-r/stats.svg?style=flat-square)](https://codecov.io/gh/phil-r/stats)\n[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)\n\n## Installation\n\n```bash\nnpm i @phil-r/stats\n```\n\n## API\n\n```js\nconst initStats = require('@phil-r/stats');\nconst { statsMiddleware, getStats } = initStats({\n  endpointStats: true,\n  complexEndpoints: ['/user/:id'],\n  customStats: true,\n  addHeader: true,\n});\n```\n\n### initStats([options])\n\nReturns `statsMiddleware` middleware function and `getStats` function,\nthat returns current stats\n\n#### Options\n\n`initStats` accepts optional `options` object that may contain any of the following keys:\n\n##### endpointStats\n\nDefaults to `false`\n\nBoolean that indicates whether to track per endpoint stats.\n\n##### complexEndpoints\n\nDefaults to `[]`\n\nUsed in conjunction with `endpointStats`\n\nUse it in case your application has routes with params or wildcard routes\n\n**Recommended** for applications that have endpoints like `/user/123`\n\n##### customStats\n\nDefaults to `false`\n\nAdds `startMeasurement` and `finishMeasurement` functions to the request objects\nand allows measuring any parts of the app.\n\n**Usage:**\n\n```js\nfunction handler(req, res) {\n  const measurement = req.startMeasurement('measurementName');\n  // Some code...\n  req.finishMeasurement(measurement);\n}\n```\n\n##### addHeader\n\nDefaults to `false`\n\nAdds `X-Response-Time` header to all responses, can be used to replace\n[`expressjs/response-time`](https://github.com/expressjs/response-time)\n\n## Example\n\nExamples for popular node web frameworks can be found [here](./examples)\n\nHere is the example of usage in express app:\n\n```js\nconst app = require('express')();\nconst initStats = require('@phil-r/stats');\n\nconst { statsMiddleware, getStats } = initStats({\n  endpointStats: true,\n  complexEndpoints: ['/user/:id'],\n  customStats: true,\n  addHeader: true,\n});\n\napp.use(statsMiddleware);\napp.get('/', (req, res) =\u003e res.end('Hello'));\napp.get('/user/:id', (req, res) =\u003e res.end(`Hello ${req.params.id}`));\napp.get('/long', async (req, res) =\u003e {\n  const measurement = req.startMeasurement('long');\n  await new Promise((resolve) =\u003e {\n    setTimeout(() =\u003e resolve(), 2000);\n  });\n  req.finishMeasurement(measurement);\n  res.end(`Long job finished`);\n});\napp.get('/stats', (req, res) =\u003e res.send(getStats()));\n\napp.listen(8080);\nconsole.log('Server listens at http://localhost:8080');\n```\n\nVisiting http://localhost:8080/stats will give following result:\n\n```json\n{\n  \"uptime\": 63881,\n  \"uptimeHumanReadable\": \"1m 4s\",\n  \"statusCodes\": {\n    \"200\": 5,\n    \"404\": 4\n  },\n  \"uuid\": \"330d9cc6-7d40-4964-888c-4d2817905ee1\",\n  \"pid\": 90603,\n  \"totalTime\": 4020.3912830000004,\n  \"averageTime\": 446.7101425555556,\n  \"count\": 9,\n  \"endpointStats\": {\n    \"GET /long\": {\n      \"totalTime\": 4009.410922,\n      \"averageTime\": 2004.705461,\n      \"count\": 2,\n      \"statusCodes\": {\n        \"200\": 2\n      }\n    },\n    \"GET /favicon.ico\": {\n      \"totalTime\": 4.286955,\n      \"averageTime\": 1.07173875,\n      \"count\": 4,\n      \"statusCodes\": {\n        \"404\": 4\n      }\n    },\n    \"GET /stats\": {\n      \"totalTime\": 6.227342999999999,\n      \"averageTime\": 6.227342999999999,\n      \"count\": 1,\n      \"statusCodes\": {\n        \"200\": 1\n      }\n    },\n    \"GET /user/:id\": {\n      \"totalTime\": 0.466063,\n      \"averageTime\": 0.2330315,\n      \"count\": 2,\n      \"statusCodes\": {\n        \"200\": 2\n      }\n    }\n  },\n  \"customStats\": {\n    \"long\": {\n      \"totalTime\": 4005.556455,\n      \"averageTime\": 2002.7782275,\n      \"started\": 2,\n      \"count\": 2\n    }\n  }\n}\n```\n\nAll time related results are in milliseconds\n\n# [License](LICENSE)\n\nThis is a fork of [zenmate/stats](https://github.com/zenmate/stats)\n\n# Inspired by\n\n[`expressjs/response-time`](https://github.com/expressjs/response-time) and [`thoas/stats`](https://github.com/thoas/stats)\n","funding_links":[],"categories":["Middleware"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphil-r%2Fstats","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphil-r%2Fstats","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphil-r%2Fstats/lists"}