@zappinginc/zm2 6.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/.gitattributes +4 -0
  3. package/.mocharc.js +14 -0
  4. package/CHANGELOG.md +2416 -0
  5. package/CLAUDE.md +84 -0
  6. package/CONTRIBUTING.md +124 -0
  7. package/GNU-AGPL-3.0.txt +665 -0
  8. package/LICENSE +1 -0
  9. package/README.md +248 -0
  10. package/bin/zm2 +3 -0
  11. package/bin/zm2-dev +3 -0
  12. package/bin/zm2-docker +3 -0
  13. package/bin/zm2-runtime +3 -0
  14. package/bin/zm2-windows +3 -0
  15. package/bin/zm2.ps1 +3 -0
  16. package/bun.lock +421 -0
  17. package/constants.js +114 -0
  18. package/index.js +13 -0
  19. package/lib/API/Configuration.js +212 -0
  20. package/lib/API/Containerizer.js +335 -0
  21. package/lib/API/Dashboard.js +459 -0
  22. package/lib/API/Deploy.js +117 -0
  23. package/lib/API/Extra.js +775 -0
  24. package/lib/API/ExtraMgmt/Docker.js +30 -0
  25. package/lib/API/Log.js +315 -0
  26. package/lib/API/LogManagement.js +371 -0
  27. package/lib/API/Modules/LOCAL.js +122 -0
  28. package/lib/API/Modules/Modularizer.js +148 -0
  29. package/lib/API/Modules/NPM.js +445 -0
  30. package/lib/API/Modules/TAR.js +362 -0
  31. package/lib/API/Modules/flagExt.js +46 -0
  32. package/lib/API/Modules/index.js +120 -0
  33. package/lib/API/Monit.js +247 -0
  34. package/lib/API/Serve.js +343 -0
  35. package/lib/API/Startup.js +629 -0
  36. package/lib/API/UX/helpers.js +213 -0
  37. package/lib/API/UX/index.js +9 -0
  38. package/lib/API/UX/pm2-describe.js +193 -0
  39. package/lib/API/UX/pm2-ls-minimal.js +31 -0
  40. package/lib/API/UX/pm2-ls.js +483 -0
  41. package/lib/API/Version.js +382 -0
  42. package/lib/API/interpreter.json +12 -0
  43. package/lib/API/pm2-plus/PM2IO.js +372 -0
  44. package/lib/API/pm2-plus/auth-strategies/CliAuth.js +288 -0
  45. package/lib/API/pm2-plus/auth-strategies/WebAuth.js +187 -0
  46. package/lib/API/pm2-plus/helpers.js +97 -0
  47. package/lib/API/pm2-plus/link.js +126 -0
  48. package/lib/API/pm2-plus/pres/motd +16 -0
  49. package/lib/API/pm2-plus/pres/motd.update +26 -0
  50. package/lib/API/pm2-plus/pres/welcome +28 -0
  51. package/lib/API/pm2-plus/process-selector.js +52 -0
  52. package/lib/API/schema.json +379 -0
  53. package/lib/API.js +1931 -0
  54. package/lib/Client.js +776 -0
  55. package/lib/Common.js +911 -0
  56. package/lib/Configuration.js +304 -0
  57. package/lib/Daemon.js +456 -0
  58. package/lib/Event.js +37 -0
  59. package/lib/God/ActionMethods.js +909 -0
  60. package/lib/God/ClusterMode.js +97 -0
  61. package/lib/God/ForkMode.js +297 -0
  62. package/lib/God/Methods.js +265 -0
  63. package/lib/God/Reload.js +240 -0
  64. package/lib/God.js +632 -0
  65. package/lib/HttpInterface.js +76 -0
  66. package/lib/ProcessContainer.js +305 -0
  67. package/lib/ProcessContainerBun.js +360 -0
  68. package/lib/ProcessContainerFork.js +42 -0
  69. package/lib/ProcessContainerForkBun.js +33 -0
  70. package/lib/ProcessUtils.js +55 -0
  71. package/lib/TreeKill.js +118 -0
  72. package/lib/Utility.js +430 -0
  73. package/lib/VersionCheck.js +46 -0
  74. package/lib/Watcher.js +117 -0
  75. package/lib/Worker.js +169 -0
  76. package/lib/binaries/CLI.js +1041 -0
  77. package/lib/binaries/DevCLI.js +183 -0
  78. package/lib/binaries/Runtime.js +101 -0
  79. package/lib/binaries/Runtime4Docker.js +192 -0
  80. package/lib/completion.js +229 -0
  81. package/lib/completion.sh +40 -0
  82. package/lib/motd +36 -0
  83. package/lib/templates/Dockerfiles/Dockerfile-java.tpl +7 -0
  84. package/lib/templates/Dockerfiles/Dockerfile-nodejs.tpl +8 -0
  85. package/lib/templates/Dockerfiles/Dockerfile-ruby.tpl +7 -0
  86. package/lib/templates/ecosystem-es.tpl +24 -0
  87. package/lib/templates/ecosystem-simple-es.tpl +8 -0
  88. package/lib/templates/ecosystem-simple.tpl +6 -0
  89. package/lib/templates/ecosystem.tpl +22 -0
  90. package/lib/templates/init-scripts/launchd.tpl +35 -0
  91. package/lib/templates/init-scripts/openrc.tpl +52 -0
  92. package/lib/templates/init-scripts/pm2-init-amazon.sh +86 -0
  93. package/lib/templates/init-scripts/rcd-openbsd.tpl +41 -0
  94. package/lib/templates/init-scripts/rcd.tpl +44 -0
  95. package/lib/templates/init-scripts/smf.tpl +43 -0
  96. package/lib/templates/init-scripts/systemd-online.tpl +22 -0
  97. package/lib/templates/init-scripts/systemd.tpl +22 -0
  98. package/lib/templates/init-scripts/upstart.tpl +103 -0
  99. package/lib/templates/logrotate.d/pm2 +10 -0
  100. package/lib/templates/sample-apps/http-server/README.md +14 -0
  101. package/lib/templates/sample-apps/http-server/api.js +9 -0
  102. package/lib/templates/sample-apps/http-server/ecosystem.config.js +14 -0
  103. package/lib/templates/sample-apps/http-server/package.json +11 -0
  104. package/lib/templates/sample-apps/pm2-plus-metrics-actions/README.md +45 -0
  105. package/lib/templates/sample-apps/pm2-plus-metrics-actions/custom-metrics.js +66 -0
  106. package/lib/templates/sample-apps/pm2-plus-metrics-actions/ecosystem.config.js +12 -0
  107. package/lib/templates/sample-apps/pm2-plus-metrics-actions/package.json +11 -0
  108. package/lib/templates/sample-apps/python-app/README.md +4 -0
  109. package/lib/templates/sample-apps/python-app/echo.py +7 -0
  110. package/lib/templates/sample-apps/python-app/ecosystem.config.js +12 -0
  111. package/lib/templates/sample-apps/python-app/package.json +11 -0
  112. package/lib/tools/Config.js +248 -0
  113. package/lib/tools/IsAbsolute.js +20 -0
  114. package/lib/tools/copydirSync.js +101 -0
  115. package/lib/tools/deleteFolderRecursive.js +19 -0
  116. package/lib/tools/find-package-json.js +74 -0
  117. package/lib/tools/fmt.js +72 -0
  118. package/lib/tools/isbinaryfile.js +94 -0
  119. package/lib/tools/json5.js +752 -0
  120. package/lib/tools/open.js +63 -0
  121. package/lib/tools/passwd.js +58 -0
  122. package/lib/tools/promise.min.js +1 -0
  123. package/lib/tools/sexec.js +55 -0
  124. package/lib/tools/treeify.js +113 -0
  125. package/lib/tools/which.js +120 -0
  126. package/lib/tools/xdg-open +861 -0
  127. package/package.json +219 -0
  128. package/paths.js +93 -0
  129. package/pm2 +11 -0
  130. package/preinstall.js +24 -0
  131. package/run.sh +9 -0
  132. package/types/index.d.ts +722 -0
  133. package/types/tsconfig.json +14 -0
@@ -0,0 +1,187 @@
1
+
2
+ 'use strict'
3
+
4
+ const cst = require('../../../../constants.js');
5
+
6
+ const AuthStrategy = require('@pm2/js-api/src/auth_strategies/strategy')
7
+ const http = require('http')
8
+ const fs = require('fs')
9
+ const url = require('url')
10
+ const exec = require('child_process').exec
11
+ const tryEach = require('async/tryEach');
12
+
13
+ module.exports = class WebStrategy extends AuthStrategy {
14
+ // the client will try to call this but we handle this part ourselves
15
+ retrieveTokens (km, cb) {
16
+ this.authenticated = false
17
+ this.callback = cb
18
+ this.km = km
19
+ }
20
+
21
+ // so the cli know if we need to tell user to login/register
22
+ isAuthenticated () {
23
+ return new Promise((resolve, reject) => {
24
+ if (this.authenticated) return resolve(true)
25
+
26
+ let tokensPath = cst.PM2_IO_ACCESS_TOKEN
27
+ fs.readFile(tokensPath, (err, tokens) => {
28
+ if (err && err.code === 'ENOENT') return resolve(false)
29
+ if (err) return reject(err)
30
+
31
+ // verify that the token is valid
32
+ try {
33
+ tokens = JSON.parse(tokens || '{}')
34
+ } catch (err) {
35
+ fs.unlinkSync(tokensPath)
36
+ return resolve(false)
37
+ }
38
+
39
+ // if the refresh tokens is here, the user could be automatically authenticated
40
+ return resolve(typeof tokens.refresh_token === 'string')
41
+ })
42
+ })
43
+ }
44
+
45
+ // called when we are sure the user asked to be logged in
46
+ _retrieveTokens (optionalCallback) {
47
+ const km = this.km
48
+ const cb = this.callback
49
+
50
+ let verifyToken = (refresh) => {
51
+ return km.auth.retrieveToken({
52
+ client_id: this.client_id,
53
+ refresh_token: refresh
54
+ })
55
+ }
56
+ tryEach([
57
+ // try to find the token via the environment
58
+ (next) => {
59
+ if (!process.env.PM2_IO_TOKEN) {
60
+ return next(new Error('No token in env'))
61
+ }
62
+ verifyToken(process.env.PM2_IO_TOKEN)
63
+ .then((res) => {
64
+ return next(null, res.data)
65
+ }).catch(next)
66
+ },
67
+ // try to find it in the file system
68
+ (next) => {
69
+ fs.readFile(cst.PM2_IO_ACCESS_TOKEN, (err, tokens) => {
70
+ if (err) return next(err)
71
+ // verify that the token is valid
72
+ tokens = JSON.parse(tokens || '{}')
73
+ if (new Date(tokens.expire_at) > new Date(new Date().toISOString())) {
74
+ return next(null, tokens)
75
+ }
76
+
77
+ verifyToken(tokens.refresh_token)
78
+ .then((res) => {
79
+ return next(null, res.data)
80
+ }).catch(next)
81
+ })
82
+ },
83
+ // otherwise make the whole flow
84
+ (next) => {
85
+ return this.loginViaWeb((data) => {
86
+ // verify that the token is valid
87
+ verifyToken(data.access_token)
88
+ .then((res) => {
89
+ return next(null, res.data)
90
+ }).catch(err => next(err))
91
+ })
92
+ }
93
+ ], (err, result) => {
94
+ // if present run the optional callback
95
+ if (typeof optionalCallback === 'function') {
96
+ optionalCallback(err, result)
97
+ }
98
+
99
+ if (result.refresh_token) {
100
+ this.authenticated = true
101
+ let file = cst.PM2_IO_ACCESS_TOKEN
102
+ fs.writeFile(file, JSON.stringify(result), () => {
103
+ return cb(err, result)
104
+ })
105
+ } else {
106
+ return cb(err, result)
107
+ }
108
+ })
109
+ }
110
+
111
+ loginViaWeb (cb) {
112
+ const redirectURL = `${this.oauth_endpoint}${this.oauth_query}`
113
+
114
+ console.log(`${cst.PM2_IO_MSG} Please follow the popup or go to this URL :`, '\n', ' ', redirectURL)
115
+
116
+ let shutdown = false
117
+ let server = http.createServer((req, res) => {
118
+ // only handle one request
119
+ if (shutdown === true) return res.end()
120
+ shutdown = true
121
+
122
+ let query = url.parse(req.url, true).query
123
+
124
+ res.write(`
125
+ <head>
126
+ <script>
127
+ </script>
128
+ </head>
129
+ <body>
130
+ <h2 style="text-align: center">
131
+ You can go back to your terminal now :)
132
+ </h2>
133
+ </body>`)
134
+ res.end()
135
+ server.close()
136
+ return cb(query)
137
+ })
138
+ server.listen(43532, () => {
139
+ this.open(redirectURL)
140
+ })
141
+ }
142
+
143
+ deleteTokens (km) {
144
+ return new Promise((resolve, reject) => {
145
+ // revoke the refreshToken
146
+ km.auth.revoke()
147
+ .then(res => {
148
+ // remove the token from the filesystem
149
+ let file = cst.PM2_IO_ACCESS_TOKEN
150
+ fs.unlinkSync(file)
151
+ return resolve(res)
152
+ }).catch(reject)
153
+ })
154
+ }
155
+
156
+ open (target, appName, callback) {
157
+ let opener
158
+ const escape = function (s) {
159
+ return s.replace(/"/g, '\\"')
160
+ }
161
+
162
+ if (typeof (appName) === 'function') {
163
+ callback = appName
164
+ appName = null
165
+ }
166
+
167
+ switch (process.platform) {
168
+ case 'darwin': {
169
+ opener = appName ? `open -a "${escape(appName)}"` : `open`
170
+ break
171
+ }
172
+ case 'win32': {
173
+ opener = appName ? `start "" ${escape(appName)}"` : `start ""`
174
+ break
175
+ }
176
+ default: {
177
+ opener = appName ? escape(appName) : `xdg-open`
178
+ break
179
+ }
180
+ }
181
+
182
+ if (process.env.SUDO_USER) {
183
+ opener = 'sudo -u ' + process.env.SUDO_USER + ' ' + opener
184
+ }
185
+ return exec(`${opener} "${escape(target)}"`, callback)
186
+ }
187
+ }
@@ -0,0 +1,97 @@
1
+
2
+ var cst = require('../../../constants.js');
3
+ var Common = require('../../Common.js');
4
+
5
+ const chalk = require('ansis');
6
+ const forEach = require('async/forEach');
7
+ const open = require('../../tools/open.js');
8
+ const Modules = require('../Modules');
9
+
10
+ function processesAreAlreadyMonitored(CLI, cb) {
11
+ CLI.Client.executeRemote('getMonitorData', {}, function(err, list) {
12
+ if (err) return cb(false);
13
+ var l = list.filter(l => l.pm2_env.km_link == true)
14
+ var l2 = list.filter(l => l.name == 'pm2-server-monit')
15
+
16
+ return cb(l.length > 0 && l2.length > 0 ? true : false)
17
+ })
18
+ }
19
+
20
+ module.exports = function(CLI) {
21
+ CLI.prototype.openDashboard = function() {
22
+ if (!this.gl_interact_infos) {
23
+ Common.printError(chalk.bold.white('Agent if offline, type `$ pm2 plus` to log in'));
24
+ return this.exitCli(cst.ERROR_EXIT);
25
+ }
26
+
27
+ var uri = `https://app.pm2.io/#/r/${this.gl_interact_infos.public_key}`
28
+ console.log(cst.PM2_IO_MSG + ` Opening ${uri}`)
29
+ open(uri);
30
+ setTimeout(_ => {
31
+ this.exitCli();
32
+ }, 200);
33
+ };
34
+
35
+ CLI.prototype.clearSetup = function (opts, cb) {
36
+ const modules = ['event-loop-inspector']
37
+ this.gl_is_km_linked = false
38
+
39
+ forEach(modules, (_module, next) => {
40
+ Modules.uninstall(this, _module, () => {
41
+ next()
42
+ });
43
+ }, (err) => {
44
+ this.reload('all', () => {
45
+ return cb()
46
+ })
47
+ })
48
+ }
49
+
50
+ /**
51
+ * Install required package and enable flags for current running processes
52
+ */
53
+ CLI.prototype.minimumSetup = function (opts, cb) {
54
+ var self = this;
55
+ this.gl_is_km_linked = true
56
+
57
+ function install(cb) {
58
+ var modules = []
59
+
60
+ if (opts.type === 'enterprise' || opts.type === 'plus') {
61
+ modules = ['pm2-logrotate', 'pm2-server-monit']
62
+ if (opts.type === 'enterprise') {
63
+ modules.push('deep-metrics')
64
+ }
65
+ }
66
+
67
+ forEach(modules, (_module, next) => {
68
+ Modules.install(self, _module, {}, () => {
69
+ next()
70
+ });
71
+ }, (err) => {
72
+ self.reload('all', () => {
73
+ return cb()
74
+ })
75
+ })
76
+ }
77
+
78
+ processesAreAlreadyMonitored(self, (already_monitored) => {
79
+ if (already_monitored) {
80
+ console.log(cst.PM2_IO_MSG + ` PM2 ${opts.type || ''} bundle already installed`);
81
+ return cb()
82
+ }
83
+
84
+ if (opts.installAll)
85
+ return install(cb)
86
+
87
+ // promptly.confirm(chalk.bold('Install all pm2 plus dependencies ? (y/n)'), (err, answer) => {
88
+ // if (!err && answer === true)
89
+ return install(cb)
90
+ // self.reload('all', () => {
91
+ // return cb()
92
+ // })
93
+ // });
94
+ })
95
+ }
96
+
97
+ }
@@ -0,0 +1,126 @@
1
+
2
+ var cst = require('../../../constants.js');
3
+ var Common = require('../../Common.js');
4
+ var chalk = require('ansis');
5
+ var fs = require('fs');
6
+ var KMDaemon = require('@pm2/agent/src/InteractorClient');
7
+ var pkg = require('../../../package.json')
8
+
9
+ module.exports = function(CLI) {
10
+
11
+ CLI.prototype.linkManagement = function(cmd, public_key, machine, opts, cb) {
12
+ var that = this;
13
+
14
+ // pm2 link stop || kill
15
+ if (cmd == 'stop' || cmd == 'kill') {
16
+ that.gl_is_km_linked = false
17
+ console.log(cst.PM2_IO_MSG + ' Stopping agent...');
18
+
19
+ return that.killAgent(function(err) {
20
+ if (err) {
21
+ Common.printError(err);
22
+ return process.exit(cst.ERROR_EXIT);
23
+ }
24
+ console.log(cst.PM2_IO_MSG + ' Stopped');
25
+
26
+ that.reload('all', () => {
27
+ return process.exit(cst.SUCCESS_EXIT);
28
+ })
29
+ });
30
+ }
31
+
32
+ // pm2 link info
33
+ if (cmd == 'info') {
34
+ console.log(cst.PM2_IO_MSG + ' Getting agent information...');
35
+ that.agentInfos(function(err, infos) {
36
+ if (err) {
37
+ console.error(cst.PM2_IO_MSG_ERR + ' ' + err.message);
38
+ return that.exitCli(cst.ERROR_EXIT);
39
+ }
40
+ console.log(infos);
41
+ return that.exitCli(cst.SUCCESS_EXIT);
42
+ });
43
+ return false;
44
+ }
45
+
46
+ // pm2 link delete
47
+ if (cmd == 'delete') {
48
+ that.gl_is_km_linked = false
49
+ console.log(cst.PM2_IO_MSG + ' Permanently disable agent...');
50
+ that.killAgent(function(err) {
51
+ try {
52
+ fs.unlinkSync(cst.INTERACTION_CONF);
53
+ } catch(e) {
54
+ console.log(cst.PM2_IO_MSG + ' No interaction config file found');
55
+ return process.exit(cst.SUCCESS_EXIT);
56
+ }
57
+ console.log(cst.PM2_IO_MSG + ' Agent interaction ended');
58
+ if (!cb)
59
+ return process.exit(cst.SUCCESS_EXIT);
60
+ return cb()
61
+ });
62
+ return false;
63
+ }
64
+
65
+ if (cmd && !public_key) {
66
+ console.error(cst.PM2_IO_MSG + ' Command [%s] unknown or missing public key', cmd);
67
+ return process.exit(cst.ERROR_EXIT);
68
+ }
69
+
70
+ // pm2 link xxx yyy
71
+ var infos;
72
+
73
+ if (!cmd) {
74
+ infos = null;
75
+ }
76
+ else
77
+ infos = {
78
+ public_key : public_key,
79
+ secret_key : cmd,
80
+ machine_name : machine,
81
+ info_node : opts.infoNode || null,
82
+ pm2_version: pkg.version
83
+ }
84
+
85
+ that.link(infos, cb)
86
+ };
87
+
88
+ CLI.prototype.link = function(infos, cb) {
89
+ var that = this;
90
+
91
+ process.env.WS_JSON_PATCH = true
92
+
93
+ KMDaemon.launchAndInteract(cst, infos, function(err, dt) {
94
+ if (err) {
95
+ Common.printError(cst.PM2_IO_MSG + ' Run `$ pm2 plus` to connect')
96
+ return that.exitCli(cst.ERROR_EXIT);
97
+ }
98
+ console.log(chalk.bold.green('[+] PM2+ activated!'))
99
+ if (!cb) {
100
+ return that.exitCli(cst.SUCCESS_EXIT);
101
+ }
102
+ return cb(null, dt)
103
+ });
104
+ };
105
+
106
+ CLI.prototype.agentInfos = function(cb) {
107
+ KMDaemon.getInteractInfo(this._conf, function(err, data) {
108
+ if (err)
109
+ return cb(Common.retErr(err));
110
+ return cb(null, data);
111
+ });
112
+ };
113
+
114
+ CLI.prototype.killAgent = function(cb) {
115
+ var that = this;
116
+ KMDaemon.killInteractorDaemon(that._conf, function(err) {
117
+ if (err)
118
+ return cb ? cb(Common.retErr(err)) : that.exitCli(cst.SUCCESS_EXIT);
119
+ return cb ? cb(null) : that.exitCli(cst.SUCCESS_EXIT);
120
+ });
121
+ };
122
+
123
+ CLI.prototype.unlink = function(cb) {
124
+ this.linkManagement('delete', cb);
125
+ };
126
+ };
@@ -0,0 +1,16 @@
1
+
2
+ ██████╗ ███╗ ███╗██████╗ ██╗ ██╗ ██████╗
3
+ ██╔══██╗████╗ ████║╚════██╗ ██║ ██╔╝██╔═══██╗
4
+ ██████╔╝██╔████╔██║ █████╔╝ ██║ ██╔╝ ██║ ██║
5
+ ██╔═══╝ ██║╚██╔╝██║██╔═══╝ ██║ ██╔╝ ██║ ██║
6
+ ██║ ██║ ╚═╝ ██║███████╗ ██║██╔╝ ╚██████╔╝
7
+ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝╚═╝ ╚═════╝
8
+
9
+ https://pm2.io/
10
+
11
+ Harden your Node.js Production Environment
12
+
13
+ - Real-time Monitoring Web Interface
14
+ - Pro Active Alerting System
15
+ - Production Profiling for Memory and CPU
16
+ - PM2 Runtime High Availability Fallback
@@ -0,0 +1,26 @@
1
+
2
+ -------------
3
+
4
+
5
+ ██████╗ ███╗ ███╗██████╗ ██╗ ██╗ ██████╗
6
+ ██╔══██╗████╗ ████║╚════██╗ ██║ ██╔╝██╔═══██╗
7
+ ██████╔╝██╔████╔██║ █████╔╝ ██║ ██╔╝ ██║ ██║
8
+ ██╔═══╝ ██║╚██╔╝██║██╔═══╝ ██║ ██╔╝ ██║ ██║
9
+ ██║ ██║ ╚═╝ ██║███████╗ ██║██╔╝ ╚██████╔╝
10
+ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝╚═╝ ╚═════╝
11
+
12
+ https://pm2.io/
13
+
14
+ Harden your Node.js Production Environment
15
+
16
+ - Real-time Monitoring Web Interface
17
+ - Pro Active Alerting System
18
+ - Production Profiling for Memory and CPU
19
+ - ZM2 Runtime High Availability Fallback
20
+
21
+
22
+ Start using it by typing:
23
+
24
+ $ zm2 plus
25
+
26
+ -------------
@@ -0,0 +1,28 @@
1
+
2
+ -------------
3
+
4
+ PM2 Plus Edition
5
+
6
+
7
+ PM2 Plus is a monitoring dashboard
8
+ specialized for Node.js Apps.
9
+
10
+ Create an account:
11
+ $ pm2 plus register
12
+
13
+ Connect your local PM2 to the PM2 Plus servers:
14
+ $ pm2 plus connect
15
+
16
+ See our UI with your own realtime dashboard:
17
+ $ pm2 plus web
18
+
19
+ More details available there:
20
+ http://pm2.io/plus
21
+
22
+ -------------
23
+
24
+ Having complex or specific needs?
25
+ You can also checkout our enterprise offer at:
26
+ http://pm2.io/enterprise
27
+
28
+ -------------
@@ -0,0 +1,52 @@
1
+ const fs = require('fs');
2
+ const forEachLimit = require('async/forEachLimit');
3
+
4
+ var cst = require('../../../constants.js');
5
+ var Common = require('../../Common.js');
6
+
7
+ module.exports = function(CLI) {
8
+ /**
9
+ * Monitor Selectively Processes (auto filter in interaction)
10
+ * @param String state 'monitor' or 'unmonitor'
11
+ * @param String target <pm_id|name|all>
12
+ * @param Function cb callback
13
+ */
14
+ CLI.prototype.monitorState = function(state, target, cb) {
15
+ var that = this;
16
+
17
+ if (!target) {
18
+ Common.printError(cst.PREFIX_MSG_ERR + 'Please specify an <app_name|pm_id>');
19
+ return cb ? cb(new Error('argument missing')) : that.exitCli(cst.ERROR_EXIT);
20
+ }
21
+
22
+ function monitor (pm_id, cb) {
23
+ // State can be monitor or unmonitor
24
+ that.Client.executeRemote(state, pm_id, cb);
25
+ }
26
+ if (target === 'all') {
27
+ that.Client.getAllProcessId(function (err, procs) {
28
+ if (err) {
29
+ Common.printError(err);
30
+ return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
31
+ }
32
+ forEachLimit(procs, 1, monitor, function (err, res) {
33
+ return typeof cb === 'function' ? cb(err, res) : that.speedList();
34
+ });
35
+ });
36
+ } else if (!Number.isInteger(parseInt(target))) {
37
+ this.Client.getProcessIdByName(target, true, function (err, procs) {
38
+ if (err) {
39
+ Common.printError(err);
40
+ return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
41
+ }
42
+ forEachLimit(procs, 1, monitor, function (err, res) {
43
+ return typeof cb === 'function' ? cb(err, res) : that.speedList();
44
+ });
45
+ });
46
+ } else {
47
+ monitor(parseInt(target), function (err, res) {
48
+ return typeof cb === 'function' ? cb(err, res) : that.speedList();
49
+ });
50
+ }
51
+ };
52
+ }