{"_id":"menoetius","_rev":"4652586","name":"menoetius","description":"node middleware to automatically instrument node applications for consumption by prometheus","dist-tags":{"latest":"0.0.3"},"maintainers":[{"name":"achingbrain","email":"alex@achingbrain.net"}],"time":{"modified":"2026-04-10T20:47:34.000Z","created":"2019-07-19T17:00:42.314Z","0.0.3":"2021-11-29T20:01:59.605Z","0.0.2":"2019-07-19T17:31:59.359Z","0.0.1":"2019-07-19T17:00:42.314Z"},"users":{},"author":{"name":"Roy Lines"},"repository":{"type":"git","url":"git+https://github.com/achingbrain/menoetius.git"},"versions":{"0.0.3":{"name":"menoetius","version":"0.0.3","description":"node middleware to automatically instrument node applications for consumption by prometheus","main":"index.js","scripts":{"test":"istanbul cover _mocha -dir ./coverage","coveralls":"cat ./coverage/lcov.info | coveralls"},"git-pre-hooks":{"pre-push":"npm test"},"repository":{"type":"git","url":"git+https://github.com/achingbrain/menoetius.git"},"keywords":["prometheus","metrics","express","restify"],"author":{"name":"Roy Lines"},"license":"MIT","bugs":{"url":"https://github.com/achingbrain/menoetius/issues"},"homepage":"https://github.com/achingbrain/menoetius#readme","engines":{"node":">=4.0.0"},"devDependencies":{"chai":"^4.0.2","coveralls":"^3.0.2","express":"^4.15.3","git-pre-hooks":"^1.2.0","hapi":"^18.1.0","istanbul":"^1.1.0-alpha.1","mocha":"^9.1.3","request":"^2.81.0","restify":"^8.3.3","sinon":"^12.0.1"},"dependencies":{"prom-client":"^14.0.1"},"gitHead":"b387fec5ad861483816fb5d0e65931c250252e00","_id":"menoetius@0.0.3","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"shasum":"b61c1c7e8ac6c3e70cc441a048f72f0263311bf2","size":7513,"noattachment":false,"key":"/menoetius/-/menoetius-0.0.3.tgz","tarball":"http://registry.cnpm.dingdandao.com/menoetius/download/menoetius-0.0.3.tgz"},"_npmUser":{"name":"achingbrain","email":"alex@achingbrain.net"},"directories":{},"maintainers":[{"name":"achingbrain","email":"alex@achingbrain.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/menoetius_0.0.3_1638216119424_0.23978236160911592"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2021-12-24T02:08:17.430Z","publish_time":1638216119605,"_cnpm_publish_time":1638216119605},"0.0.2":{"name":"menoetius","version":"0.0.2","description":"node middleware to automatically instrument node applications for consumption by prometheus","main":"index.js","scripts":{"test":"istanbul cover _mocha -dir ./coverage","coveralls":"cat ./coverage/lcov.info | coveralls"},"git-pre-hooks":{"pre-push":"npm test"},"repository":{"type":"git","url":"git+https://github.com/achingbrain/menoetius.git"},"keywords":["prometheus","metrics","express","restify"],"author":{"name":"Roy Lines"},"license":"MIT","bugs":{"url":"https://github.com/achingbrain/menoetius/issues"},"homepage":"https://github.com/achingbrain/menoetius#readme","engines":{"node":">=4.0.0"},"devDependencies":{"chai":"^4.0.2","coveralls":"^3.0.2","express":"^4.15.3","git-pre-hooks":"^1.2.0","hapi":"^18.1.0","istanbul":"^1.1.0-alpha.1","mocha":"^6.1.4","request":"^2.81.0","restify":"^8.3.3","sinon":"^7.3.2"},"dependencies":{"prom-client":"^11.5.3"},"gitHead":"86e57d96a2dbe8ec74936fa8271dd72e172c1bb6","_id":"menoetius@0.0.2","_npmVersion":"6.4.1","_nodeVersion":"10.15.3","_npmUser":{"name":"achingbrain","email":"alex@achingbrain.net"},"dist":{"shasum":"42173222b701e38591e57027c542fccd1c481fb0","size":7599,"noattachment":false,"key":"/menoetius/-/menoetius-0.0.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/menoetius/download/menoetius-0.0.2.tgz"},"maintainers":[{"name":"achingbrain","email":"alex@achingbrain.net"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/menoetius_0.0.2_1563557519199_0.04596544736538544"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2021-12-24T02:08:16.557Z","publish_time":1563557519359,"_cnpm_publish_time":1563557519359},"0.0.1":{"name":"menoetius","version":"0.0.1","description":"node middleware to automatically instrument node applications for consumption by prometheus","main":"index.js","scripts":{"test":"istanbul cover _mocha -dir $CIRCLE_ARTIFACTS","coveralls":"cat $CIRCLE_ARTIFACTS/lcov.info | coveralls"},"git-pre-hooks":{"pre-push":"npm test"},"repository":{"type":"git","url":"git+https://github.com/achingbrain/menoetius.git"},"keywords":["prometheus","metrics","express","restify"],"author":{"name":"Roy Lines"},"license":"MIT","bugs":{"url":"https://github.com/achingbrain/menoetius/issues"},"homepage":"https://github.com/achingbrain/menoetius#readme","engines":{"node":">=4.0.0"},"devDependencies":{"chai":"^4.0.2","coveralls":"^3.0.2","express":"^4.15.3","git-pre-hooks":"^1.2.0","hapi":"^18.1.0","istanbul":"^1.1.0-alpha.1","mocha":"^6.1.4","request":"^2.81.0","restify":"^8.3.3","sinon":"^7.3.2"},"dependencies":{"prom-client":"^11.5.3"},"gitHead":"4b84139b6f6dc51f26b98482fd76422eecdec520","_id":"menoetius@0.0.1","_npmVersion":"6.4.1","_nodeVersion":"10.15.3","_npmUser":{"name":"achingbrain","email":"alex@achingbrain.net"},"dist":{"shasum":"f754f79c72a8a725f62a1f35a60ae3f4778c504e","size":7694,"noattachment":false,"key":"/menoetius/-/menoetius-0.0.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/menoetius/download/menoetius-0.0.1.tgz"},"maintainers":[{"name":"achingbrain","email":"alex@achingbrain.net"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/menoetius_0.0.1_1563555642181_0.9353013407870634"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2021-12-24T02:08:16.244Z","publish_time":1563555642314,"_cnpm_publish_time":1563555642314}},"readme":"# Menoetius\n[![CircleCI](https://circleci.com/gh/achingbrain/menoetius/tree/master.svg?style=svg)](https://circleci.com/gh/achingbrain/menoetius/tree/master)\n[![Coverage Status](https://coveralls.io/repos/github/achingbrain/menoetius/badge.svg)](https://coveralls.io/github/achingbrain/menoetius)\n[![Dependencies Status](https://david-dm.org/achingbrain/menoetius/status.svg)](https://david-dm.org/achingbrain/menoetius)\n\n[![NPM](https://nodei.co/npm/menoetius.png)](https://nodei.co/npm/menoetius/)\n\nMiddleware to automatically instrument node applications for consumption by a [Prometheus](https://prometheus.io/) server.\n\nPrometheus is an open source monitoring solution that obtains metrics from servers by querying against the /metrics endpoint upon them.\n\nOnce instrumented, Menoetius automatically serves [response duration](#duration) metrics, plus nodejs [system metrics](#system) on the /metrics endpoint ready to be consumed by Prometheus.\n\nMenoetius will instrument websites and webservices that use [http](#http), [express](#express), [hapi](#hapi) and [restify](#restify).\n\n# Instrumentation\nMenoetius automatically measures a number of metrics once instrumented.\nThe following metrics are instrumented via the /metrics endpoint:\n\n## <a name=\"duration\"></a> Duration Metrics\nThere are two metrics measuring request duration:\n\n- **http\\_request\\_duration\\_milliseconds (summary)**: a [summary](https://prometheus.io/docs/concepts/metric_types/#summary) metric measuring the duration in milliseconds of all requests. It can be used to [calculate average request durations](https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations).\n- **http\\_request\\_buckets\\_milliseconds (histogram)**: a [histogram](https://prometheus.io/docs/concepts/metric_types/#histogram) metric used to count duration in buckets of sizes 500ms and 2000ms. This can be used to [calculate apdex](https://prometheus.io/docs/practices/histograms/#apdex-score) using a response time threshold of 500ms.\n\nIn each case, the following [labels](https://prometheus.io/docs/practices/naming/#labels) are used:\n\n- **status**: the http status code of the response, e.g. 200, 500\n- **method**: the http method of the request, e.g. put, post.\n- **path**: the path of the request. Note that /users/freddie is labelled /users/ so as not to flood prometheus with labels\n- **cardinality**: the cardinality of the request, e.g. /users/freddie has cardinality 'one', /users/ has cardinality 'many'\n\n## <a name=\"system\"></a> System Metrics\nThese are metrics provided by [prom-client](https://github.com/siimon/prom-client#default-metrics) that instrument the nodejs heap/rss usage and cpu usage etc.\n\n# Installation\n```\n> npm install --save menoetius\n```\n\nMenoetius has only one method, instrument, and it has the following signature:\n## instrument(server, options)\n\nThe first argument represents the server of the middleware.\n\nThe second argument is optional, and allows some configuration of menoetius\n\n- `url` - the url on which to serve metrics. Defaults to `/metrics`.\n\nSee the following examples of use with [http](#http), [express](#express), [hapi](#hapi) and [restify](#restify).\n\n# <a name=\"http\"></a> http\n```\nconst http = require('http');\nconst menoetius = require('../../index');\n\nconst server = http.createServer((req, res) => {\n  if(req.url !== '/metrics') {\n    res.statusCode = 200;\n    res.end();\n  }\n});\n\nmenoetius.instrument(server);\n\nserver.listen(8003, '127.0.0.1', () => {\n  console.log('http listening on 8003');\n});\n\n```\n# <a name=\"express\"></a> Express\n```\nconst express = require('express');\nconst menoetius = require('menoetius');\n\nconst app = express();\nmenoetius.instrument(app);\n\napp.get('/', (req, res) => {\n  res.send();\n});\n\napp.listen(3000, () => {\n  console.log('express server listening on port 3000');\n});\n\n```\n# <a name=\"hapi\"></a> Hapi\n```\nconst Hapi = require('hapi');\nconst menoetius = require('menoetius');\n\nconst server = Hapi.Server({\n    port: 8002\n})\n\nasync function init() {\n  try {\n    await epithemeus.instrument(server);\n\n    server.route({\n      method: 'GET',\n      path: '/',\n      handler: async (request, h) => {\n        return h.response()\n      }\n    })\n\n    await server.start()\n\n    console.log(`Hapi ${server.version} server listening on port 8002`)\n\n  } catch(err) {\n    console.log('Error', err);\n    process.exit(1);\n  }\n\n}\n\ninit();\n```\n# <a name=\"restify\"></a> Restify\n```\nconst restify = require('restify');\nconst menoetius = require('menoetius');\n\nconst server = restify.createServer();\n\nmenoetius.instrument(this.server);\n\nserver.get('/', (req, res, done) => {\n  res.send();\n  done();\n});\n\nserver.listen(3000, () => {\n  console.log('restify server listening on port 3000');\n});\n\n```\n\n# Try It Out\nThe docker-compose.yml file in the examples directory will create a prometheus server and an example each of an [http](#http), [express](#express), [hapi](#hapi) and [restify](#restify) server.\n\nAssuming you have installed [docker](https://docs.docker.com) and [docker-compose](https://docs.docker.com/compose/install/), you can try it out by doing the following:\n\n```\n> cd examples\n> docker-compose up\n```\n\nYou can then view the prometheus server on [http://127.0.0.1:9090](http://127.0.0.1:9090)\n\n# Etymology\n\n![Menoetius](https://www.greekmythology.com/images/mythology/menoetius_152.jpg)\n\n> Menoetius was a Titan god, son of Titans Iapetus and Clymene, and brother of Atlas, Prometheus and Epimetheus. His name derives from the Ancient Greek words \"menos\" (might) and \"oitos\" (doom), meaning \"doomed might\".\n>\n> [https://www.greekmythology.com/Titans/Menoetius/menoetius.html](https://www.greekmythology.com/Titans/Menoetius/menoetius.html)\n\nDoom also stalks this module as hopefully one day [https://github.com/roylines/node-epimetheus/pull/63](https://github.com/roylines/node-epimetheus/pull/63) will be merged, obviating the need for this module to exist.\n","_attachments":{},"homepage":"https://github.com/achingbrain/menoetius#readme","bugs":{"url":"https://github.com/achingbrain/menoetius/issues"},"license":"MIT"}