@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.
- package/.claude/settings.local.json +8 -0
- package/.gitattributes +4 -0
- package/.mocharc.js +14 -0
- package/CHANGELOG.md +2416 -0
- package/CLAUDE.md +84 -0
- package/CONTRIBUTING.md +124 -0
- package/GNU-AGPL-3.0.txt +665 -0
- package/LICENSE +1 -0
- package/README.md +248 -0
- package/bin/zm2 +3 -0
- package/bin/zm2-dev +3 -0
- package/bin/zm2-docker +3 -0
- package/bin/zm2-runtime +3 -0
- package/bin/zm2-windows +3 -0
- package/bin/zm2.ps1 +3 -0
- package/bun.lock +421 -0
- package/constants.js +114 -0
- package/index.js +13 -0
- package/lib/API/Configuration.js +212 -0
- package/lib/API/Containerizer.js +335 -0
- package/lib/API/Dashboard.js +459 -0
- package/lib/API/Deploy.js +117 -0
- package/lib/API/Extra.js +775 -0
- package/lib/API/ExtraMgmt/Docker.js +30 -0
- package/lib/API/Log.js +315 -0
- package/lib/API/LogManagement.js +371 -0
- package/lib/API/Modules/LOCAL.js +122 -0
- package/lib/API/Modules/Modularizer.js +148 -0
- package/lib/API/Modules/NPM.js +445 -0
- package/lib/API/Modules/TAR.js +362 -0
- package/lib/API/Modules/flagExt.js +46 -0
- package/lib/API/Modules/index.js +120 -0
- package/lib/API/Monit.js +247 -0
- package/lib/API/Serve.js +343 -0
- package/lib/API/Startup.js +629 -0
- package/lib/API/UX/helpers.js +213 -0
- package/lib/API/UX/index.js +9 -0
- package/lib/API/UX/pm2-describe.js +193 -0
- package/lib/API/UX/pm2-ls-minimal.js +31 -0
- package/lib/API/UX/pm2-ls.js +483 -0
- package/lib/API/Version.js +382 -0
- package/lib/API/interpreter.json +12 -0
- package/lib/API/pm2-plus/PM2IO.js +372 -0
- package/lib/API/pm2-plus/auth-strategies/CliAuth.js +288 -0
- package/lib/API/pm2-plus/auth-strategies/WebAuth.js +187 -0
- package/lib/API/pm2-plus/helpers.js +97 -0
- package/lib/API/pm2-plus/link.js +126 -0
- package/lib/API/pm2-plus/pres/motd +16 -0
- package/lib/API/pm2-plus/pres/motd.update +26 -0
- package/lib/API/pm2-plus/pres/welcome +28 -0
- package/lib/API/pm2-plus/process-selector.js +52 -0
- package/lib/API/schema.json +379 -0
- package/lib/API.js +1931 -0
- package/lib/Client.js +776 -0
- package/lib/Common.js +911 -0
- package/lib/Configuration.js +304 -0
- package/lib/Daemon.js +456 -0
- package/lib/Event.js +37 -0
- package/lib/God/ActionMethods.js +909 -0
- package/lib/God/ClusterMode.js +97 -0
- package/lib/God/ForkMode.js +297 -0
- package/lib/God/Methods.js +265 -0
- package/lib/God/Reload.js +240 -0
- package/lib/God.js +632 -0
- package/lib/HttpInterface.js +76 -0
- package/lib/ProcessContainer.js +305 -0
- package/lib/ProcessContainerBun.js +360 -0
- package/lib/ProcessContainerFork.js +42 -0
- package/lib/ProcessContainerForkBun.js +33 -0
- package/lib/ProcessUtils.js +55 -0
- package/lib/TreeKill.js +118 -0
- package/lib/Utility.js +430 -0
- package/lib/VersionCheck.js +46 -0
- package/lib/Watcher.js +117 -0
- package/lib/Worker.js +169 -0
- package/lib/binaries/CLI.js +1041 -0
- package/lib/binaries/DevCLI.js +183 -0
- package/lib/binaries/Runtime.js +101 -0
- package/lib/binaries/Runtime4Docker.js +192 -0
- package/lib/completion.js +229 -0
- package/lib/completion.sh +40 -0
- package/lib/motd +36 -0
- package/lib/templates/Dockerfiles/Dockerfile-java.tpl +7 -0
- package/lib/templates/Dockerfiles/Dockerfile-nodejs.tpl +8 -0
- package/lib/templates/Dockerfiles/Dockerfile-ruby.tpl +7 -0
- package/lib/templates/ecosystem-es.tpl +24 -0
- package/lib/templates/ecosystem-simple-es.tpl +8 -0
- package/lib/templates/ecosystem-simple.tpl +6 -0
- package/lib/templates/ecosystem.tpl +22 -0
- package/lib/templates/init-scripts/launchd.tpl +35 -0
- package/lib/templates/init-scripts/openrc.tpl +52 -0
- package/lib/templates/init-scripts/pm2-init-amazon.sh +86 -0
- package/lib/templates/init-scripts/rcd-openbsd.tpl +41 -0
- package/lib/templates/init-scripts/rcd.tpl +44 -0
- package/lib/templates/init-scripts/smf.tpl +43 -0
- package/lib/templates/init-scripts/systemd-online.tpl +22 -0
- package/lib/templates/init-scripts/systemd.tpl +22 -0
- package/lib/templates/init-scripts/upstart.tpl +103 -0
- package/lib/templates/logrotate.d/pm2 +10 -0
- package/lib/templates/sample-apps/http-server/README.md +14 -0
- package/lib/templates/sample-apps/http-server/api.js +9 -0
- package/lib/templates/sample-apps/http-server/ecosystem.config.js +14 -0
- package/lib/templates/sample-apps/http-server/package.json +11 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/README.md +45 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/custom-metrics.js +66 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/ecosystem.config.js +12 -0
- package/lib/templates/sample-apps/pm2-plus-metrics-actions/package.json +11 -0
- package/lib/templates/sample-apps/python-app/README.md +4 -0
- package/lib/templates/sample-apps/python-app/echo.py +7 -0
- package/lib/templates/sample-apps/python-app/ecosystem.config.js +12 -0
- package/lib/templates/sample-apps/python-app/package.json +11 -0
- package/lib/tools/Config.js +248 -0
- package/lib/tools/IsAbsolute.js +20 -0
- package/lib/tools/copydirSync.js +101 -0
- package/lib/tools/deleteFolderRecursive.js +19 -0
- package/lib/tools/find-package-json.js +74 -0
- package/lib/tools/fmt.js +72 -0
- package/lib/tools/isbinaryfile.js +94 -0
- package/lib/tools/json5.js +752 -0
- package/lib/tools/open.js +63 -0
- package/lib/tools/passwd.js +58 -0
- package/lib/tools/promise.min.js +1 -0
- package/lib/tools/sexec.js +55 -0
- package/lib/tools/treeify.js +113 -0
- package/lib/tools/which.js +120 -0
- package/lib/tools/xdg-open +861 -0
- package/package.json +219 -0
- package/paths.js +93 -0
- package/pm2 +11 -0
- package/preinstall.js +24 -0
- package/run.sh +9 -0
- package/types/index.d.ts +722 -0
- package/types/tsconfig.json +14 -0
|
@@ -0,0 +1,909 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013-2022 the PM2 project authors. All rights reserved.
|
|
3
|
+
* Use of this source code is governed by a license that
|
|
4
|
+
* can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @file ActionMethod like restart, stop, monitor... are here
|
|
10
|
+
* @author Alexandre Strzelewicz <as@unitech.io>
|
|
11
|
+
* @project PM2
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
var fs = require('fs');
|
|
15
|
+
var path = require('path');
|
|
16
|
+
var eachLimit = require('async/eachLimit');
|
|
17
|
+
var os = require('os');
|
|
18
|
+
var p = path;
|
|
19
|
+
var cst = require('../../constants.js');
|
|
20
|
+
var pkg = require('../../package.json');
|
|
21
|
+
var pidusage = require('pidusage');
|
|
22
|
+
var util = require('util');
|
|
23
|
+
var debug = require('debug')('zm2:ActionMethod');
|
|
24
|
+
var Utility = require('../Utility');
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Description
|
|
28
|
+
* @method exports
|
|
29
|
+
* @param {} God
|
|
30
|
+
* @return
|
|
31
|
+
*/
|
|
32
|
+
module.exports = function(God) {
|
|
33
|
+
/**
|
|
34
|
+
* Description
|
|
35
|
+
* @method getMonitorData
|
|
36
|
+
* @param {} env
|
|
37
|
+
* @param {} cb
|
|
38
|
+
* @return
|
|
39
|
+
*/
|
|
40
|
+
God.getMonitorData = function getMonitorData(env, cb) {
|
|
41
|
+
var processes = God.getFormatedProcesses();
|
|
42
|
+
var pids = processes.filter(filterBadProcess)
|
|
43
|
+
.map(function(pro, i) {
|
|
44
|
+
var pid = getProcessId(pro)
|
|
45
|
+
return pid;
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
// No pids, return empty statistics
|
|
49
|
+
if (pids.length === 0) {
|
|
50
|
+
return cb(null, processes.map(function(pro) {
|
|
51
|
+
pro['monit'] = {
|
|
52
|
+
memory : 0,
|
|
53
|
+
cpu : 0
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return pro
|
|
57
|
+
}))
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
pidusage(pids, function retPidUsage(err, statistics) {
|
|
61
|
+
// Just log, we'll set empty statistics
|
|
62
|
+
if (err) {
|
|
63
|
+
console.error('Error caught while calling pidusage');
|
|
64
|
+
console.error(err);
|
|
65
|
+
|
|
66
|
+
return cb(null, processes.map(function(pro) {
|
|
67
|
+
pro['monit'] = {
|
|
68
|
+
memory : 0,
|
|
69
|
+
cpu : 0
|
|
70
|
+
};
|
|
71
|
+
return pro
|
|
72
|
+
}))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!statistics) {
|
|
76
|
+
console.error('Statistics is not defined!')
|
|
77
|
+
|
|
78
|
+
return cb(null, processes.map(function(pro) {
|
|
79
|
+
pro['monit'] = {
|
|
80
|
+
memory : 0,
|
|
81
|
+
cpu : 0
|
|
82
|
+
};
|
|
83
|
+
return pro
|
|
84
|
+
}))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
processes = processes.map(function(pro) {
|
|
88
|
+
if (filterBadProcess(pro) === false) {
|
|
89
|
+
pro['monit'] = {
|
|
90
|
+
memory : 0,
|
|
91
|
+
cpu : 0
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return pro;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
var pid = getProcessId(pro);
|
|
98
|
+
var stat = statistics[pid];
|
|
99
|
+
|
|
100
|
+
if (!stat) {
|
|
101
|
+
pro['monit'] = {
|
|
102
|
+
memory : 0,
|
|
103
|
+
cpu : 0
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
return pro;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
pro['monit'] = {
|
|
110
|
+
memory: stat.memory,
|
|
111
|
+
cpu: Math.round(stat.cpu * 10) / 10
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
return pro;
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
cb(null, processes);
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Description
|
|
123
|
+
* @method dumpProcessList
|
|
124
|
+
* @param {} cb
|
|
125
|
+
* @return
|
|
126
|
+
*/
|
|
127
|
+
God.dumpProcessList = function(cb) {
|
|
128
|
+
var process_list = [];
|
|
129
|
+
var apps = Utility.clone(God.getFormatedProcesses());
|
|
130
|
+
var that = this;
|
|
131
|
+
|
|
132
|
+
// Don't override the actual dump file if process list is empty
|
|
133
|
+
// unless user explicitely did `pm2 dump`.
|
|
134
|
+
// This often happens when PM2 crashed, we don't want to override
|
|
135
|
+
// the dump file with an empty list of process.
|
|
136
|
+
if (!apps[0]) {
|
|
137
|
+
debug('[PM2] Did not override dump file because list of processes is empty');
|
|
138
|
+
return cb(null, {success:true, process_list: process_list});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function fin(err) {
|
|
142
|
+
|
|
143
|
+
// try to fix issues with empty dump file
|
|
144
|
+
// like #3485
|
|
145
|
+
if (process_list.length === 0) {
|
|
146
|
+
|
|
147
|
+
// fix : if no dump file, no process, only module and after pm2 update
|
|
148
|
+
if (!fs.existsSync(cst.DUMP_FILE_PATH) && typeof that.clearDump === 'function') {
|
|
149
|
+
that.clearDump(function(){});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// if no process in list don't modify dump file
|
|
153
|
+
// process list should not be empty
|
|
154
|
+
return cb(null, {success:true, process_list: process_list});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Back up dump file
|
|
158
|
+
try {
|
|
159
|
+
if (fs.existsSync(cst.DUMP_FILE_PATH)) {
|
|
160
|
+
fs.writeFileSync(cst.DUMP_BACKUP_FILE_PATH, fs.readFileSync(cst.DUMP_FILE_PATH));
|
|
161
|
+
}
|
|
162
|
+
} catch (e) {
|
|
163
|
+
console.error(e.stack || e);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Overwrite dump file, delete if broken
|
|
167
|
+
try {
|
|
168
|
+
fs.writeFileSync(cst.DUMP_FILE_PATH, JSON.stringify(process_list));
|
|
169
|
+
} catch (e) {
|
|
170
|
+
console.error(e.stack || e);
|
|
171
|
+
try {
|
|
172
|
+
// try to backup file
|
|
173
|
+
if (fs.existsSync(cst.DUMP_BACKUP_FILE_PATH)) {
|
|
174
|
+
fs.writeFileSync(cst.DUMP_FILE_PATH, fs.readFileSync(cst.DUMP_BACKUP_FILE_PATH));
|
|
175
|
+
}
|
|
176
|
+
} catch (e) {
|
|
177
|
+
// don't keep broken file
|
|
178
|
+
fs.unlinkSync(cst.DUMP_FILE_PATH);
|
|
179
|
+
console.error(e.stack || e);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return cb(null, {success:true, process_list: process_list});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function saveProc(apps) {
|
|
187
|
+
if (!apps[0])
|
|
188
|
+
return fin(null);
|
|
189
|
+
delete apps[0].pm2_env.instances;
|
|
190
|
+
delete apps[0].pm2_env.pm_id;
|
|
191
|
+
// Do not dump modules
|
|
192
|
+
if (!apps[0].pm2_env.pmx_module)
|
|
193
|
+
process_list.push(apps[0].pm2_env);
|
|
194
|
+
apps.shift();
|
|
195
|
+
return saveProc(apps);
|
|
196
|
+
}
|
|
197
|
+
saveProc(apps);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Description
|
|
202
|
+
* @method ping
|
|
203
|
+
* @param {} env
|
|
204
|
+
* @param {} cb
|
|
205
|
+
* @return CallExpression
|
|
206
|
+
*/
|
|
207
|
+
God.ping = function(env, cb) {
|
|
208
|
+
return cb(null, {msg : 'pong'});
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Description
|
|
213
|
+
* @method notifyKillPM2
|
|
214
|
+
*/
|
|
215
|
+
God.notifyKillPM2 = function() {
|
|
216
|
+
God.pm2_being_killed = true;
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Duplicate a process
|
|
221
|
+
* @method duplicateProcessId
|
|
222
|
+
* @param {} id
|
|
223
|
+
* @param {} cb
|
|
224
|
+
* @return CallExpression
|
|
225
|
+
*/
|
|
226
|
+
God.duplicateProcessId = function(id, cb) {
|
|
227
|
+
if (!(id in God.clusters_db))
|
|
228
|
+
return cb(God.logAndGenerateError(id + ' id unknown'), {});
|
|
229
|
+
|
|
230
|
+
if (!God.clusters_db[id] || !God.clusters_db[id].pm2_env)
|
|
231
|
+
return cb(God.logAndGenerateError('Error when getting proc || proc.pm2_env'), {});
|
|
232
|
+
|
|
233
|
+
var proc = Utility.clone(God.clusters_db[id].pm2_env);
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
delete proc.created_at;
|
|
237
|
+
delete proc.pm_id;
|
|
238
|
+
delete proc.unique_id;
|
|
239
|
+
|
|
240
|
+
// generate a new unique id for new process
|
|
241
|
+
proc.unique_id = Utility.generateUUID()
|
|
242
|
+
|
|
243
|
+
God.injectVariables(proc, function inject (_err, proc) {
|
|
244
|
+
return God.executeApp(Utility.clone(proc), function (err, clu) {
|
|
245
|
+
if (err) return cb(err);
|
|
246
|
+
God.notify('start', clu, true);
|
|
247
|
+
return cb(err, Utility.clone(clu));
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Start a stopped process by ID
|
|
254
|
+
* @method startProcessId
|
|
255
|
+
* @param {} id
|
|
256
|
+
* @param {} cb
|
|
257
|
+
* @return CallExpression
|
|
258
|
+
*/
|
|
259
|
+
God.startProcessId = function(id, cb) {
|
|
260
|
+
if (!(id in God.clusters_db))
|
|
261
|
+
return cb(God.logAndGenerateError(id + ' id unknown'), {});
|
|
262
|
+
|
|
263
|
+
var proc = God.clusters_db[id];
|
|
264
|
+
if (proc.pm2_env.status == cst.ONLINE_STATUS)
|
|
265
|
+
return cb(God.logAndGenerateError('process already online'), {});
|
|
266
|
+
if (proc.pm2_env.status == cst.LAUNCHING_STATUS)
|
|
267
|
+
return cb(God.logAndGenerateError('process already started'), {});
|
|
268
|
+
if (proc.process && proc.process.pid)
|
|
269
|
+
return cb(God.logAndGenerateError('Process with pid ' + proc.process.pid + ' already exists'), {});
|
|
270
|
+
|
|
271
|
+
return God.executeApp(God.clusters_db[id].pm2_env, function(err, proc) {
|
|
272
|
+
return cb(err, Utility.clone(proc));
|
|
273
|
+
});
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Stop a process and set it on state 'stopped'
|
|
279
|
+
* @method stopProcessId
|
|
280
|
+
* @param {} id
|
|
281
|
+
* @param {} cb
|
|
282
|
+
* @return Literal
|
|
283
|
+
*/
|
|
284
|
+
God.stopProcessId = function(id, cb) {
|
|
285
|
+
if (typeof id == 'object' && 'id' in id)
|
|
286
|
+
id = id.id;
|
|
287
|
+
|
|
288
|
+
if (!(id in God.clusters_db))
|
|
289
|
+
return cb(God.logAndGenerateError(id + ' : id unknown'), {});
|
|
290
|
+
|
|
291
|
+
var proc = God.clusters_db[id];
|
|
292
|
+
|
|
293
|
+
//clear time-out restart task
|
|
294
|
+
clearTimeout(proc.pm2_env.restart_task);
|
|
295
|
+
|
|
296
|
+
if (proc.pm2_env.status == cst.STOPPED_STATUS) {
|
|
297
|
+
proc.process.pid = 0;
|
|
298
|
+
return cb(null, God.getFormatedProcess(id));
|
|
299
|
+
}
|
|
300
|
+
// state == 'none' means that the process is not online yet
|
|
301
|
+
if (proc.state && proc.state === 'none')
|
|
302
|
+
return setTimeout(function() { God.stopProcessId(id, cb); }, 250);
|
|
303
|
+
|
|
304
|
+
console.log('Stopping app:%s id:%s', proc.pm2_env.name, proc.pm2_env.pm_id);
|
|
305
|
+
proc.pm2_env.status = cst.STOPPING_STATUS;
|
|
306
|
+
|
|
307
|
+
if (!proc.process.pid) {
|
|
308
|
+
console.error('app=%s id=%d does not have a pid', proc.pm2_env.name, proc.pm2_env.pm_id);
|
|
309
|
+
proc.pm2_env.status = cst.STOPPED_STATUS;
|
|
310
|
+
return cb(null, { error : true, message : 'could not kill process w/o pid'});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
God.killProcess(proc.process.pid, proc.pm2_env, function(err) {
|
|
314
|
+
proc.pm2_env.status = cst.STOPPED_STATUS;
|
|
315
|
+
|
|
316
|
+
God.notify('exit', proc);
|
|
317
|
+
|
|
318
|
+
if (err && err.type && err.type === 'timeout') {
|
|
319
|
+
console.error('app=%s id=%d pid=%s could not be stopped',
|
|
320
|
+
proc.pm2_env.name,
|
|
321
|
+
proc.pm2_env.pm_id,
|
|
322
|
+
proc.process.pid);
|
|
323
|
+
proc.pm2_env.status = cst.ERRORED_STATUS;
|
|
324
|
+
return cb(null, God.getFormatedProcess(id));
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (proc.pm2_env.pm_id.toString().indexOf('_old_') !== 0) {
|
|
328
|
+
try {
|
|
329
|
+
fs.unlinkSync(proc.pm2_env.pm_pid_path);
|
|
330
|
+
} catch (e) {}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (proc.pm2_env.axm_actions) proc.pm2_env.axm_actions = [];
|
|
334
|
+
if (proc.pm2_env.axm_monitor) proc.pm2_env.axm_monitor = {};
|
|
335
|
+
|
|
336
|
+
proc.process.pid = 0;
|
|
337
|
+
return cb(null, God.getFormatedProcess(id));
|
|
338
|
+
});
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
God.resetMetaProcessId = function(id, cb) {
|
|
342
|
+
if (!(id in God.clusters_db))
|
|
343
|
+
return cb(God.logAndGenerateError(id + ' id unknown'), {});
|
|
344
|
+
|
|
345
|
+
if (!God.clusters_db[id] || !God.clusters_db[id].pm2_env)
|
|
346
|
+
return cb(God.logAndGenerateError('Error when getting proc || proc.pm2_env'), {});
|
|
347
|
+
|
|
348
|
+
God.clusters_db[id].pm2_env.created_at = Utility.getDate();
|
|
349
|
+
God.clusters_db[id].pm2_env.unstable_restarts = 0;
|
|
350
|
+
God.clusters_db[id].pm2_env.restart_time = 0;
|
|
351
|
+
|
|
352
|
+
return cb(null, God.getFormatedProcesses());
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Delete a process by id
|
|
357
|
+
* It will stop it and remove it from the database
|
|
358
|
+
* @method deleteProcessId
|
|
359
|
+
* @param {} id
|
|
360
|
+
* @param {} cb
|
|
361
|
+
* @return Literal
|
|
362
|
+
*/
|
|
363
|
+
God.deleteProcessId = function(id, cb) {
|
|
364
|
+
God.deleteCron(id);
|
|
365
|
+
|
|
366
|
+
God.stopProcessId(id, function(err, proc) {
|
|
367
|
+
if (err) return cb(God.logAndGenerateError(err), {});
|
|
368
|
+
// ! transform to slow object
|
|
369
|
+
delete God.clusters_db[id];
|
|
370
|
+
|
|
371
|
+
if (Object.keys(God.clusters_db).length == 0)
|
|
372
|
+
God.next_id = 0;
|
|
373
|
+
return cb(null, proc);
|
|
374
|
+
});
|
|
375
|
+
return false;
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Restart a process ID
|
|
380
|
+
* If the process is online it will not put it on state stopped
|
|
381
|
+
* but directly kill it and let God restart it
|
|
382
|
+
* @method restartProcessId
|
|
383
|
+
* @param {} id
|
|
384
|
+
* @param {} cb
|
|
385
|
+
* @return Literal
|
|
386
|
+
*/
|
|
387
|
+
God.restartProcessId = function(opts, cb) {
|
|
388
|
+
var id = opts.id;
|
|
389
|
+
var env = opts.env || {};
|
|
390
|
+
|
|
391
|
+
if (typeof(id) === 'undefined')
|
|
392
|
+
return cb(God.logAndGenerateError('opts.id not passed to restartProcessId', opts));
|
|
393
|
+
if (!(id in God.clusters_db))
|
|
394
|
+
return cb(God.logAndGenerateError('God db process id unknown'), {});
|
|
395
|
+
|
|
396
|
+
var proc = God.clusters_db[id];
|
|
397
|
+
|
|
398
|
+
God.resetState(proc.pm2_env);
|
|
399
|
+
God.deleteCron(id);
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Merge new application configuration on restart
|
|
403
|
+
* Same system in reloadProcessId and softReloadProcessId
|
|
404
|
+
*/
|
|
405
|
+
Utility.extend(proc.pm2_env.env, env);
|
|
406
|
+
Utility.extendExtraConfig(proc, opts);
|
|
407
|
+
|
|
408
|
+
if (God.pm2_being_killed) {
|
|
409
|
+
return cb(God.logAndGenerateError('[RestartProcessId] PM2 is being killed, stopping restart procedure...'));
|
|
410
|
+
}
|
|
411
|
+
if (proc.pm2_env.status === cst.ONLINE_STATUS || proc.pm2_env.status === cst.LAUNCHING_STATUS) {
|
|
412
|
+
God.stopProcessId(id, function(err) {
|
|
413
|
+
if (God.pm2_being_killed)
|
|
414
|
+
return cb(God.logAndGenerateError('[RestartProcessId] PM2 is being killed, stopping restart procedure...'));
|
|
415
|
+
proc.pm2_env.restart_time += 1;
|
|
416
|
+
return God.startProcessId(id, cb);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
debug('[restart] process not online, starting it');
|
|
423
|
+
return God.startProcessId(id, cb);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Restart all process by name
|
|
430
|
+
* @method restartProcessName
|
|
431
|
+
* @param {} name
|
|
432
|
+
* @param {} cb
|
|
433
|
+
* @return Literal
|
|
434
|
+
*/
|
|
435
|
+
God.restartProcessName = function(name, cb) {
|
|
436
|
+
var processes = God.findByName(name);
|
|
437
|
+
|
|
438
|
+
if (processes && processes.length === 0)
|
|
439
|
+
return cb(God.logAndGenerateError('Unknown process'), {});
|
|
440
|
+
|
|
441
|
+
eachLimit(processes, cst.CONCURRENT_ACTIONS, function(proc, next) {
|
|
442
|
+
if (God.pm2_being_killed)
|
|
443
|
+
return next('[Watch] PM2 is being killed, stopping restart procedure...');
|
|
444
|
+
if (proc.pm2_env.status === cst.ONLINE_STATUS)
|
|
445
|
+
return God.restartProcessId({id:proc.pm2_env.pm_id}, next);
|
|
446
|
+
else if (proc.pm2_env.status !== cst.STOPPING_STATUS
|
|
447
|
+
&& proc.pm2_env.status !== cst.LAUNCHING_STATUS)
|
|
448
|
+
return God.startProcessId(proc.pm2_env.pm_id, next);
|
|
449
|
+
else
|
|
450
|
+
return next(util.format('[Watch] Process name %s is being stopped so I won\'t restart it', name));
|
|
451
|
+
}, function(err) {
|
|
452
|
+
if (err) return cb(God.logAndGenerateError(err));
|
|
453
|
+
return cb(null, God.getFormatedProcesses());
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
return false;
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Send system signal to process id
|
|
461
|
+
* @method sendSignalToProcessId
|
|
462
|
+
* @param {} opts
|
|
463
|
+
* @param {} cb
|
|
464
|
+
* @return CallExpression
|
|
465
|
+
*/
|
|
466
|
+
God.sendSignalToProcessId = function(opts, cb) {
|
|
467
|
+
var id = opts.process_id;
|
|
468
|
+
var signal = opts.signal;
|
|
469
|
+
|
|
470
|
+
if (!(id in God.clusters_db))
|
|
471
|
+
return cb(God.logAndGenerateError(id + ' id unknown'), {});
|
|
472
|
+
|
|
473
|
+
var proc = God.clusters_db[id];
|
|
474
|
+
|
|
475
|
+
//God.notify('send signal ' + signal, proc, true);
|
|
476
|
+
|
|
477
|
+
try {
|
|
478
|
+
process.kill(God.clusters_db[id].process.pid, signal);
|
|
479
|
+
} catch(e) {
|
|
480
|
+
return cb(God.logAndGenerateError('Error when sending signal (signal unknown)'), {});
|
|
481
|
+
}
|
|
482
|
+
return cb(null, God.getFormatedProcesses());
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Send system signal to all processes by name
|
|
487
|
+
* @method sendSignalToProcessName
|
|
488
|
+
* @param {} opts
|
|
489
|
+
* @param {} cb
|
|
490
|
+
* @return
|
|
491
|
+
*/
|
|
492
|
+
God.sendSignalToProcessName = function(opts, cb) {
|
|
493
|
+
var processes = God.findByName(opts.process_name);
|
|
494
|
+
var signal = opts.signal;
|
|
495
|
+
|
|
496
|
+
if (processes && processes.length === 0)
|
|
497
|
+
return cb(God.logAndGenerateError('Unknown process name'), {});
|
|
498
|
+
|
|
499
|
+
eachLimit(processes, cst.CONCURRENT_ACTIONS, function(proc, next) {
|
|
500
|
+
if (proc.pm2_env.status == cst.ONLINE_STATUS || proc.pm2_env.status == cst.LAUNCHING_STATUS) {
|
|
501
|
+
try {
|
|
502
|
+
process.kill(proc.process.pid, signal);
|
|
503
|
+
} catch(e) {
|
|
504
|
+
return next(e);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
return setTimeout(next, 200);
|
|
508
|
+
}, function(err) {
|
|
509
|
+
if (err) return cb(God.logAndGenerateError(err), {});
|
|
510
|
+
return cb(null, God.getFormatedProcesses());
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Stop watching daemon
|
|
517
|
+
* @method stopWatch
|
|
518
|
+
* @param {} method
|
|
519
|
+
* @param {} value
|
|
520
|
+
* @param {} fn
|
|
521
|
+
* @return
|
|
522
|
+
*/
|
|
523
|
+
God.stopWatch = function(method, value, fn) {
|
|
524
|
+
var env = null;
|
|
525
|
+
|
|
526
|
+
if (method == 'stopAll' || method == 'deleteAll') {
|
|
527
|
+
var processes = God.getFormatedProcesses();
|
|
528
|
+
|
|
529
|
+
processes.forEach(function(proc) {
|
|
530
|
+
God.clusters_db[proc.pm_id].pm2_env.watch = false;
|
|
531
|
+
God.watch.disable(proc.pm2_env);
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
} else {
|
|
535
|
+
|
|
536
|
+
if (method.indexOf('ProcessId') !== -1) {
|
|
537
|
+
env = God.clusters_db[value];
|
|
538
|
+
} else if (method.indexOf('ProcessName') !== -1) {
|
|
539
|
+
env = God.clusters_db[God.findByName(value)];
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
if (env) {
|
|
543
|
+
God.watch.disable(env.pm2_env);
|
|
544
|
+
env.pm2_env.watch = false;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return fn(null, {success:true});
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Toggle watching daemon
|
|
553
|
+
* @method toggleWatch
|
|
554
|
+
* @param {String} method
|
|
555
|
+
* @param {Object} application environment, should include id
|
|
556
|
+
* @param {Function} callback
|
|
557
|
+
*/
|
|
558
|
+
God.toggleWatch = function(method, value, fn) {
|
|
559
|
+
var env = null;
|
|
560
|
+
|
|
561
|
+
if (method == 'restartProcessId') {
|
|
562
|
+
env = God.clusters_db[value.id];
|
|
563
|
+
} else if(method == 'restartProcessName') {
|
|
564
|
+
env = God.clusters_db[God.findByName(value)];
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if (env) {
|
|
568
|
+
env.pm2_env.watch = !env.pm2_env.watch;
|
|
569
|
+
if (env.pm2_env.watch)
|
|
570
|
+
God.watch.enable(env.pm2_env);
|
|
571
|
+
else
|
|
572
|
+
God.watch.disable(env.pm2_env);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
return fn(null, {success:true});
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Start Watch
|
|
580
|
+
* @method startWatch
|
|
581
|
+
* @param {String} method
|
|
582
|
+
* @param {Object} application environment, should include id
|
|
583
|
+
* @param {Function} callback
|
|
584
|
+
*/
|
|
585
|
+
God.startWatch = function(method, value, fn) {
|
|
586
|
+
var env = null;
|
|
587
|
+
|
|
588
|
+
if (method == 'restartProcessId') {
|
|
589
|
+
env = God.clusters_db[value.id];
|
|
590
|
+
} else if(method == 'restartProcessName') {
|
|
591
|
+
env = God.clusters_db[God.findByName(value)];
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
if (env) {
|
|
595
|
+
if (env.pm2_env.watch)
|
|
596
|
+
return fn(null, {success:true, notrestarted:true});
|
|
597
|
+
|
|
598
|
+
God.watch.enable(env.pm2_env);
|
|
599
|
+
//env.pm2_env.env.watch = true;
|
|
600
|
+
env.pm2_env.watch = true;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
return fn(null, {success:true});
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Description
|
|
608
|
+
* @method reloadLogs
|
|
609
|
+
* @param {} opts
|
|
610
|
+
* @param {} cb
|
|
611
|
+
* @return CallExpression
|
|
612
|
+
*/
|
|
613
|
+
God.reloadLogs = function(opts, cb) {
|
|
614
|
+
console.log('Reloading logs...');
|
|
615
|
+
var processIds = Object.keys(God.clusters_db);
|
|
616
|
+
|
|
617
|
+
processIds.forEach(function (id) {
|
|
618
|
+
var cluster = God.clusters_db[id];
|
|
619
|
+
|
|
620
|
+
console.log('Reloading logs for process id %d', id);
|
|
621
|
+
|
|
622
|
+
if (cluster && cluster.pm2_env) {
|
|
623
|
+
// Cluster mode
|
|
624
|
+
if (cluster.send && cluster.pm2_env.exec_mode == 'cluster_mode') {
|
|
625
|
+
try {
|
|
626
|
+
cluster.send({
|
|
627
|
+
type:'log:reload'
|
|
628
|
+
});
|
|
629
|
+
} catch(e) {
|
|
630
|
+
console.error(e.message || e);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
// Fork mode
|
|
634
|
+
else if (cluster._reloadLogs) {
|
|
635
|
+
cluster._reloadLogs(function(err) {
|
|
636
|
+
if (err) God.logAndGenerateError(err);
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
return cb(null, {});
|
|
643
|
+
};
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Send Line To Stdin
|
|
647
|
+
* @method sendLineToStdin
|
|
648
|
+
* @param Object packet
|
|
649
|
+
* @param String pm_id Process ID
|
|
650
|
+
* @param String line Line to send to process stdin
|
|
651
|
+
*/
|
|
652
|
+
God.sendLineToStdin = function(packet, cb) {
|
|
653
|
+
if (typeof(packet.pm_id) == 'undefined' || !packet.line)
|
|
654
|
+
return cb(God.logAndGenerateError('pm_id or line field missing'), {});
|
|
655
|
+
|
|
656
|
+
var pm_id = packet.pm_id;
|
|
657
|
+
var line = packet.line;
|
|
658
|
+
|
|
659
|
+
var proc = God.clusters_db[pm_id];
|
|
660
|
+
|
|
661
|
+
if (!proc)
|
|
662
|
+
return cb(God.logAndGenerateError('Process with ID <' + pm_id + '> unknown.'), {});
|
|
663
|
+
|
|
664
|
+
if (proc.pm2_env.exec_mode == 'cluster_mode')
|
|
665
|
+
return cb(God.logAndGenerateError('Cannot send line to processes in cluster mode'), {});
|
|
666
|
+
|
|
667
|
+
if (proc.pm2_env.status != cst.ONLINE_STATUS && proc.pm2_env.status != cst.LAUNCHING_STATUS)
|
|
668
|
+
return cb(God.logAndGenerateError('Process with ID <' + pm_id + '> offline.'), {});
|
|
669
|
+
|
|
670
|
+
try {
|
|
671
|
+
proc.stdin.write(line, function() {
|
|
672
|
+
return cb(null, {
|
|
673
|
+
pm_id : pm_id,
|
|
674
|
+
line : line
|
|
675
|
+
});
|
|
676
|
+
});
|
|
677
|
+
} catch(e) {
|
|
678
|
+
return cb(God.logAndGenerateError(e), {});
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* @param {object} packet
|
|
684
|
+
* @param {function} cb
|
|
685
|
+
*/
|
|
686
|
+
God.sendDataToProcessId = function(packet, cb) {
|
|
687
|
+
if (typeof(packet.id) == 'undefined' ||
|
|
688
|
+
typeof(packet.data) == 'undefined' ||
|
|
689
|
+
!packet.topic)
|
|
690
|
+
return cb(God.logAndGenerateError('ID, DATA or TOPIC field is missing'), {});
|
|
691
|
+
|
|
692
|
+
var pm_id = packet.id;
|
|
693
|
+
var data = packet.data;
|
|
694
|
+
|
|
695
|
+
var proc = God.clusters_db[pm_id];
|
|
696
|
+
|
|
697
|
+
if (!proc)
|
|
698
|
+
return cb(God.logAndGenerateError('Process with ID <' + pm_id + '> unknown.'), {});
|
|
699
|
+
|
|
700
|
+
if (proc.pm2_env.status != cst.ONLINE_STATUS && proc.pm2_env.status != cst.LAUNCHING_STATUS)
|
|
701
|
+
return cb(God.logAndGenerateError('Process with ID <' + pm_id + '> offline.'), {});
|
|
702
|
+
|
|
703
|
+
try {
|
|
704
|
+
proc.send(packet);
|
|
705
|
+
}
|
|
706
|
+
catch(e) {
|
|
707
|
+
return cb(God.logAndGenerateError(e), {});
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
return cb(null, {
|
|
711
|
+
success: true,
|
|
712
|
+
data : packet
|
|
713
|
+
});
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Send Message to Process by id or name
|
|
718
|
+
* @method msgProcess
|
|
719
|
+
* @param {} cmd
|
|
720
|
+
* @param {} cb
|
|
721
|
+
* @return Literal
|
|
722
|
+
*/
|
|
723
|
+
God.msgProcess = function(cmd, cb) {
|
|
724
|
+
if ('id' in cmd) {
|
|
725
|
+
var id = cmd.id;
|
|
726
|
+
if (!(id in God.clusters_db))
|
|
727
|
+
return cb(God.logAndGenerateError(id + ' id unknown'), {});
|
|
728
|
+
var proc = God.clusters_db[id];
|
|
729
|
+
|
|
730
|
+
var action_exist = false;
|
|
731
|
+
|
|
732
|
+
proc.pm2_env.axm_actions.forEach(function(action) {
|
|
733
|
+
if (action.action_name == cmd.msg) {
|
|
734
|
+
action_exist = true;
|
|
735
|
+
// Reset output buffer
|
|
736
|
+
action.output = [];
|
|
737
|
+
}
|
|
738
|
+
});
|
|
739
|
+
if (action_exist == false) {
|
|
740
|
+
return cb(God.logAndGenerateError('Action doesn\'t exist ' + cmd.msg + ' for ' + proc.pm2_env.name), {});
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
if (proc.pm2_env.status == cst.ONLINE_STATUS || proc.pm2_env.status == cst.LAUNCHING_STATUS) {
|
|
744
|
+
/*
|
|
745
|
+
* Send message
|
|
746
|
+
*/
|
|
747
|
+
if (cmd.opts == null && !cmd.uuid)
|
|
748
|
+
proc.send(cmd.msg);
|
|
749
|
+
else
|
|
750
|
+
proc.send(cmd);
|
|
751
|
+
|
|
752
|
+
return cb(null, { process_count : 1, success : true });
|
|
753
|
+
}
|
|
754
|
+
else
|
|
755
|
+
return cb(God.logAndGenerateError(id + ' : id offline'), {});
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
else if ('name' in cmd) {
|
|
759
|
+
/*
|
|
760
|
+
* As names are not unique in case of cluster, this
|
|
761
|
+
* will send msg to all process matching 'name'
|
|
762
|
+
*/
|
|
763
|
+
var name = cmd.name;
|
|
764
|
+
var arr = Object.keys(God.clusters_db);
|
|
765
|
+
var sent = 0;
|
|
766
|
+
|
|
767
|
+
(function ex(arr) {
|
|
768
|
+
if (arr[0] == null || !arr) {
|
|
769
|
+
return cb(null, {
|
|
770
|
+
process_count : sent,
|
|
771
|
+
success : true
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
var id = arr[0];
|
|
776
|
+
|
|
777
|
+
if (!God.clusters_db[id] || !God.clusters_db[id].pm2_env) {
|
|
778
|
+
arr.shift();
|
|
779
|
+
return ex(arr);
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
var proc_env = God.clusters_db[id].pm2_env;
|
|
783
|
+
|
|
784
|
+
const isActionAvailable = proc_env.axm_actions.find(action => action.action_name === cmd.msg) !== undefined
|
|
785
|
+
|
|
786
|
+
// if action doesn't exist for this app
|
|
787
|
+
// try with the next one
|
|
788
|
+
if (isActionAvailable === false) {
|
|
789
|
+
arr.shift();
|
|
790
|
+
return ex(arr);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
if ((p.basename(proc_env.pm_exec_path) == name ||
|
|
795
|
+
proc_env.name == name ||
|
|
796
|
+
proc_env.namespace == name ||
|
|
797
|
+
name == 'all') &&
|
|
798
|
+
(proc_env.status == cst.ONLINE_STATUS ||
|
|
799
|
+
proc_env.status == cst.LAUNCHING_STATUS)) {
|
|
800
|
+
|
|
801
|
+
proc_env.axm_actions.forEach(function(action) {
|
|
802
|
+
if (action.action_name == cmd.msg) {
|
|
803
|
+
action_exist = true;
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
if (action_exist == false || proc_env.axm_actions.length == 0) {
|
|
808
|
+
arr.shift();
|
|
809
|
+
return ex(arr);
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
if (cmd.opts == null)
|
|
813
|
+
God.clusters_db[id].send(cmd.msg);
|
|
814
|
+
else
|
|
815
|
+
God.clusters_db[id].send(cmd);
|
|
816
|
+
|
|
817
|
+
sent++;
|
|
818
|
+
arr.shift();
|
|
819
|
+
return ex(arr);
|
|
820
|
+
}
|
|
821
|
+
else {
|
|
822
|
+
arr.shift();
|
|
823
|
+
return ex(arr);
|
|
824
|
+
}
|
|
825
|
+
return false;
|
|
826
|
+
})(arr);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
else return cb(God.logAndGenerateError('method requires name or id field'), {});
|
|
830
|
+
return false;
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Description
|
|
835
|
+
* @method getVersion
|
|
836
|
+
* @param {} env
|
|
837
|
+
* @param {} cb
|
|
838
|
+
* @return CallExpression
|
|
839
|
+
*/
|
|
840
|
+
God.getVersion = function(env, cb) {
|
|
841
|
+
process.nextTick(function() {
|
|
842
|
+
return cb(null, pkg.version);
|
|
843
|
+
});
|
|
844
|
+
};
|
|
845
|
+
|
|
846
|
+
God.monitor = function Monitor(pm_id, cb) {
|
|
847
|
+
if (!God.clusters_db[pm_id] || !God.clusters_db[pm_id].pm2_env)
|
|
848
|
+
return cb(new Error('Unknown pm_id'));
|
|
849
|
+
|
|
850
|
+
God.clusters_db[pm_id].pm2_env._km_monitored = true;
|
|
851
|
+
return cb(null, { success : true, pm_id : pm_id });
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
God.unmonitor = function Monitor(pm_id, cb) {
|
|
855
|
+
if (!God.clusters_db[pm_id] || !God.clusters_db[pm_id].pm2_env)
|
|
856
|
+
return cb(new Error('Unknown pm_id'));
|
|
857
|
+
|
|
858
|
+
God.clusters_db[pm_id].pm2_env._km_monitored = false;
|
|
859
|
+
return cb(null, { success : true, pm_id : pm_id });
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
God.getReport = function(arg, cb) {
|
|
863
|
+
var report = {
|
|
864
|
+
pm2_version : pkg.version,
|
|
865
|
+
node_version : 'N/A',
|
|
866
|
+
node_path : process.env['_'] || 'not found',
|
|
867
|
+
argv0 : process.argv0,
|
|
868
|
+
argv : process.argv,
|
|
869
|
+
user : process.env.USER,
|
|
870
|
+
uid : (cst.IS_WINDOWS === false && process.geteuid) ? process.geteuid() : 'N/A',
|
|
871
|
+
gid : (cst.IS_WINDOWS === false && process.getegid) ? process.getegid() : 'N/A',
|
|
872
|
+
env : process.env,
|
|
873
|
+
managed_apps : Object.keys(God.clusters_db).length,
|
|
874
|
+
started_at : God.started_at
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
if (process.versions && process.versions.node) {
|
|
878
|
+
report.node_version = process.versions.node;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
process.nextTick(function() {
|
|
882
|
+
return cb(null, report);
|
|
883
|
+
});
|
|
884
|
+
};
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
function filterBadProcess(pro) {
|
|
888
|
+
if (pro.pm2_env.status !== cst.ONLINE_STATUS) {
|
|
889
|
+
return false;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
if (pro.pm2_env.axm_options && pro.pm2_env.axm_options.pid) {
|
|
893
|
+
if (isNaN(pro.pm2_env.axm_options.pid)) {
|
|
894
|
+
return false;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
return true;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
function getProcessId(pro) {
|
|
902
|
+
var pid = pro.pid
|
|
903
|
+
|
|
904
|
+
if (pro.pm2_env.axm_options && pro.pm2_env.axm_options.pid) {
|
|
905
|
+
pid = pro.pm2_env.axm_options.pid;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
return pid
|
|
909
|
+
}
|