{"id":13527124,"url":"https://github.com/keymetrics/pmx","last_synced_at":"2025-05-16T02:07:21.101Z","repository":{"id":26709347,"uuid":"30166555","full_name":"keymetrics/pmx","owner":"keymetrics","description":"(DEPRECATED) use @pm2/io instead (drop-in replacement) https://github.com/keymetrics/pm2-io-apm","archived":false,"fork":false,"pushed_at":"2019-05-19T04:26:43.000Z","size":529,"stargazers_count":264,"open_issues_count":24,"forks_count":32,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-05-01T19:39:26.589Z","etag":null,"topics":["average","calculation","keymetrics","metrics","nodejs","pm2"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/keymetrics.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-02-02T01:42:52.000Z","updated_at":"2025-01-02T01:03:50.000Z","dependencies_parsed_at":"2022-08-18T18:30:23.379Z","dependency_job_id":null,"html_url":"https://github.com/keymetrics/pmx","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keymetrics%2Fpmx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keymetrics%2Fpmx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keymetrics%2Fpmx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keymetrics%2Fpmx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keymetrics","download_url":"https://codeload.github.com/keymetrics/pmx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253788029,"owners_count":21964434,"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":["average","calculation","keymetrics","metrics","nodejs","pm2"],"created_at":"2024-08-01T06:01:41.613Z","updated_at":"2025-05-16T02:07:20.966Z","avatar_url":"https://github.com/keymetrics.png","language":"JavaScript","readme":"\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"http://pm2.keymetrics.io\"\u003e\n    \u003cimg width=411px src=\"https://raw.githubusercontent.com/keymetrics/pmx/master/pres/logo.png\"\u003e\n  \u003c/a\u003e\n  \u003cbr/\u003e\n  \u003cb\u003e\u003ca href=\"https://github.com/Unitech/pm2\"\u003ePM2\u003c/a\u003e programmatic integration\u003c/b\u003e\n  \u003cbr/\u003e\n  \u003cbr/\u003e\n  \u003ca href=\"https://travis-ci.org/keymetrics/pmx\"\u003e\n\u003cimg src=\"https://api.travis-ci.org/keymetrics/pmx.png?branch=master\"/\u003e\n  \u003c/a\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003c/div\u003e\n\n\nPMX allows you to create advanced interactions with [PM2](https://github.com/Unitech/pm2) and [Keymetrics.io](https://app.keymetrics.io/).\n\n# Table of Contents\n\n- [**Installation**](https://github.com/keymetrics/pmx/blob/master/README.md#installation)\n- [**Expose Custom Metrics**](https://github.com/keymetrics/pmx#expose-metrics-measure-anything)\n- [**Expose Triggerable Runtime Functions**](https://github.com/keymetrics/pmx#expose-functions-trigger-functions-remotely)\n- [**Report Exceptions and Alerts**](https://github.com/keymetrics/pmx#alert-system-for-custom-metrics)\n- [**Report Custom Events**](https://github.com/keymetrics/pmx#emit-events)\n- [**Monitor network traffic**](https://github.com/keymetrics/pmx#application-level-network-traffic-monitoring--display-used-ports)\n\n# Installation\n\nInstall pmx with npm:\n\n```bash\n$ npm install pmx --save\n```\n\n## Expose Metrics: Measure anything\n\nPMX allows you to expose code metrics from your code to the PM2 monit command or the Keymetrics Dashboard, in realtime and over time.\n\n4 measurements are available:\n\n- **Simple metrics**: Values that can be read instantly\n    - eg. Monitor variable value\n- **Counter**: Things that increment or decrement\n    - eg. Downloads being processed, user connected\n- **Meter**: Things that are measured as events / interval\n    - eg. Request per minute for a http server\n- **Histogram**: Keeps a reservoir of statistically relevant values biased towards the last 5 minutes to explore their distribution\n    - eg. Monitor the mean of execution of a query into database\n\n### Metric: Simple value reporting\n\nThis allow to expose values that can be read instantly.\n\n```javascript\nvar probe = pmx.probe();\n\n// Here the value function will be called each second to get the value\n// returned by Object.keys(users).length\nvar metric = probe.metric({\n  name    : 'Realtime user',\n  value   : function() {\n    return Object.keys(users).length;\n  }\n});\n\n// Here we are going to call valvar.set() to set the new value\nvar metric_2 = probe.metric({\n  name    : 'Realtime Value'\n});\n\nmetric_2.set(23);\n```\n\n#### Options\n\n- **name**: Probe name\n- **value**: (optional) function that allows to monitor a global variable\n\n### Counter: Sequential value change\n\nThings that increment or decrement.\n\n```javascript\nvar probe = pmx.probe();\n\n// The counter will start at 0\nvar counter = probe.counter({\n  name : 'Current req processed'\n});\n\nhttp.createServer(function(req, res) {\n  // Increment the counter, counter will eq 1\n  counter.inc();\n  req.on('end', function() {\n    // Decrement the counter, counter will eq 0\n    counter.dec();\n  });\n});\n```\n\n#### Options\n\n- **name**: Probe name\n\n### Meter: Average calculated values\n\nThings that are measured as events / interval.\n\n```javascript\nvar probe = pmx.probe();\n\nvar meter = probe.meter({\n  name      : 'req/sec',\n  samples   : 1  // This is per second. To get per min set this value to 60\n});\n\nhttp.createServer(function(req, res) {\n  meter.mark();\n  res.end({success:true});\n});\n```\n\n#### Options\n\n- **name**: Probe name\n- **samples**: (optional)(default: 1) Rate unit. Defaults to **1** sec.\n- **timeframe**: (optional)(default: 60) timeframe over which events will be analyzed. Defaults to **60** sec.\n\n### Histogram\n\nKeeps a resevoir of statistically relevant values biased towards the last 5 minutes to explore their distribution.\n\n```javascript\nvar probe = pmx.probe();\n\nvar histogram = probe.histogram({\n  name        : 'latency',\n  measurement : 'mean'\n});\n\nvar latency = 0;\n\nsetInterval(function() {\n  latency = Math.round(Math.random() * 100);\n  histogram.update(latency);\n}, 100);\n```\n\n#### Options\n\n- **name**: Probe name\n- **agg_type** : (optional)(default: none) Can be `sum`, `max`, `min`, `avg` (default) or `none`. It will impact the way the probe data are aggregated within the **Keymetrics** backend. Use `none` if this is irrelevant (eg: constant or string value).\n- **alert** : (optional)(default: null) For `Meter` and `Counter` probes.  Creates an alert object (see below).\n\n## Expose Functions: Trigger Functions remotely\n\nRemotely trigger functions from Keymetrics. These metrics takes place in the main Keymetrics Dashboard page under the Custom Action section.\n\n### Simple actions\n\nSimple action allows to trigger a function from Keymetrics. The function takes a function as a parameter (reply here) and need to be called once the job is finished.\n\nExample:\n\n```javascript\nvar pmx = require('pmx');\n\npmx.action('db:clean', function(reply) {\n  clean.db(function() {\n    /**\n     * reply() must be called at the end of the action\n     */\n     reply({success : true});\n  });\n});\n```\n\n### Scoped actions (beta)\n\nScoped Actions are advanced remote actions that can be also triggered from Keymetrics.\n\nTwo arguments are passed to the function, data (optional data sent from Keymetrics) and res that allows to emit log data and to end the scoped action.\n\nExample:\n\n```javascript\npmx.scopedAction('long running lsof', function(data, res) {\n  var child = spawn('lsof', []);\n\n  child.stdout.on('data', function(chunk) {\n    chunk.toString().split('\\n').forEach(function(line) {\n      res.send(line); // This send log to Keymetrics to be saved (for tracking)\n    });\n  });\n\n  child.stdout.on('end', function(chunk) {\n    res.end('end'); // This end the scoped action\n  });\n\n  child.on('error', function(e) {\n    res.error(e);  // This report an error to Keymetrics\n  });\n\n});\n```\n\n### Alert System for Custom Metrics\n\n**(Specific to Keymetrics)**\n\nThis alert system can monitor a Probe value and launch an exception when hitting a particular value.\n\nExample for a `cpu_usage` variable:\n\n```javascript\nvar metric = probe.metric({\n  name  : 'CPU usage',\n  value : function() {\n    return cpu_usage;\n  },\n  alert : {\n    mode  : 'threshold',\n    value : 95,\n    msg   : 'Detected over 95% CPU usage', // optional\n    func  : function() { //optional\n      console.error('Detected over 95% CPU usage');\n    },\n    cmp   : \"\u003c\" // optional\n  }\n});\n```\n\n#### Options\n\n- **mode** : `threshold`, `threshold-avg`.\n- **value** : Value that will be used for the exception check.\n- **msg** : String used for the exception.\n- **func** :  **optional**. Function declenched when exception reached.\n- **cmp** : **optional**. If current Probe value is not `\u003c`, `\u003e`, `=` to Threshold value the exception is launched. Can also be a function used for exception check taking 2 arguments and returning a bool.\n- **interval** : **optional**, `threshold-avg` mode. Sample length for monitored value (180 seconds default).\n- **timeout** : **optional**, `threshold-avg` mode. Time after which mean comparison starts (30 000 milliseconds default).\n\n## Report Alerts: Errors / Uncaught Exceptions\n\n**(Specific to Keymetrics)**\n\nBy default once PM2 is linked to Keymetrics, you will be alerted of any uncaught exception.\nThese errors are accessible in the **Issue** tab of Keymetrics.\n\n### Custom alert notification\n\nIf you need to alert about any critical errors you can do it programmatically:\n\n```javascript\nvar pmx = require('pmx');\n\npmx.notify({ success : false });\n\npmx.notify('This is an error');\n\npmx.notify(new Error('This is an error'));\n```\n\n### Add Verbosity to an Alert: Express Error handler\n\nWhen an uncaught exception is happening you can track from which routes it has been thrown.\nTo do that you have to attach the middleware `pmx.expressErrorHandler` at then end of your routes mounting:\n\n```javascript\nvar pmx = require('pmx');\n\n// All my routes\napp.get('/' ...);\napp.post(...);\n// All my routes\n\n// Here I attach the middleware to get more verbosity on exception thrown\napp.use(pmx.expressErrorHandler());\n```\n\n## Emit Events\n\nEmit events and get historical and statistics.\nThis is available in the **Events** page of Keymetrics.\n\n```javascript\nvar pmx = require('pmx');\n\npmx.emit('user:register', {\n  user : 'Alex registered',\n  email : 'thorustor@gmail.com'\n});\n```\n\n## Application level network traffic monitoring / Display used ports\n\nYou can monitor the network usage of a specific application by adding the option `network: true` when initializing PMX. If you enable the flag `ports: true` when you init pmx it will show which ports your app is listenting on.\n\nThese metrics will be shown in the Keymetrics Dashboard in the Custom Metrics section.\n\nExample:\n\n```javascript\npmx.init({\n  [...]\n  network : true, // Allow application level network monitoring\n  ports   : true  // Display ports used by the application\n});\n```\n\n## Advanced PMX configuration\n\n\n```javascript\nvar pmx = require('pmx').init({\n  network       : true, // (default: false) Network monitoring at the application level\n  ports         : true, // (default: false) Shows which ports your app is listening on\n  // can be 'express', 'hapi', 'http', 'restify'\n  excludedHooks: []\n});\n```\n\n## License\n\nMIT\n\n[![GA](https://ga-beacon.appspot.com/UA-51122580-2/pmx/readme?pixel\u0026useReferer)](https://github.com/igrigorik/ga-beacon)\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeymetrics%2Fpmx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeymetrics%2Fpmx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeymetrics%2Fpmx/lists"}