@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,371 @@
|
|
|
1
|
+
var chalk = require('ansis');
|
|
2
|
+
var util = require('util');
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var exec = require('child_process').exec;
|
|
5
|
+
var path = require('path');
|
|
6
|
+
|
|
7
|
+
var Log = require('./Log');
|
|
8
|
+
var cst = require('../../constants.js');
|
|
9
|
+
var Common = require('../Common.js');
|
|
10
|
+
|
|
11
|
+
module.exports = function(CLI) {
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Description
|
|
15
|
+
* @method flush
|
|
16
|
+
* @return
|
|
17
|
+
*/
|
|
18
|
+
CLI.prototype.flush = function(api, cb) {
|
|
19
|
+
var that = this;
|
|
20
|
+
|
|
21
|
+
if (!api) {
|
|
22
|
+
Common.printOut(cst.PREFIX_MSG + 'Flushing ' + cst.PM2_LOG_FILE_PATH);
|
|
23
|
+
fs.closeSync(fs.openSync(cst.PM2_LOG_FILE_PATH, 'w'));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
that.Client.executeRemote('getMonitorData', {}, function(err, list) {
|
|
27
|
+
if (err) {
|
|
28
|
+
Common.printError(err);
|
|
29
|
+
return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
|
|
30
|
+
}
|
|
31
|
+
list.forEach(function(l) {
|
|
32
|
+
if (typeof api == 'undefined') {
|
|
33
|
+
Common.printOut(cst.PREFIX_MSG + 'Flushing:');
|
|
34
|
+
Common.printOut(cst.PREFIX_MSG + l.pm2_env.pm_out_log_path);
|
|
35
|
+
Common.printOut(cst.PREFIX_MSG + l.pm2_env.pm_err_log_path);
|
|
36
|
+
|
|
37
|
+
if (l.pm2_env.pm_log_path) {
|
|
38
|
+
Common.printOut(cst.PREFIX_MSG + l.pm2_env.pm_log_path);
|
|
39
|
+
fs.closeSync(fs.openSync(l.pm2_env.pm_log_path, 'w'));
|
|
40
|
+
}
|
|
41
|
+
fs.closeSync(fs.openSync(l.pm2_env.pm_out_log_path, 'w'));
|
|
42
|
+
fs.closeSync(fs.openSync(l.pm2_env.pm_err_log_path, 'w'));
|
|
43
|
+
}
|
|
44
|
+
else if (l.pm2_env.pm_id == api || l.pm2_env.name === api) {
|
|
45
|
+
Common.printOut(cst.PREFIX_MSG + 'Flushing:');
|
|
46
|
+
|
|
47
|
+
if (l.pm2_env.pm_log_path && fs.existsSync(l.pm2_env.pm_log_path)) {
|
|
48
|
+
Common.printOut(cst.PREFIX_MSG + l.pm2_env.pm_log_path);
|
|
49
|
+
fs.closeSync(fs.openSync(l.pm2_env.pm_log_path, 'w'));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (l.pm2_env.pm_out_log_path && fs.existsSync(l.pm2_env.pm_out_log_path)) {
|
|
53
|
+
Common.printOut(cst.PREFIX_MSG + l.pm2_env.pm_out_log_path);
|
|
54
|
+
fs.closeSync(fs.openSync(l.pm2_env.pm_out_log_path, 'w'));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (l.pm2_env.pm_err_log_path && fs.existsSync(l.pm2_env.pm_err_log_path)) {
|
|
58
|
+
Common.printOut(cst.PREFIX_MSG + l.pm2_env.pm_err_log_path);
|
|
59
|
+
fs.closeSync(fs.openSync(l.pm2_env.pm_err_log_path, 'w'));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
Common.printOut(cst.PREFIX_MSG + 'Logs flushed');
|
|
65
|
+
return cb ? cb(null, list) : that.exitCli(cst.SUCCESS_EXIT);
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
CLI.prototype.logrotate = function(opts, cb) {
|
|
70
|
+
var that = this;
|
|
71
|
+
|
|
72
|
+
if (process.getuid() != 0) {
|
|
73
|
+
return exec('whoami', function(err, stdout, stderr) {
|
|
74
|
+
Common.printError(cst.PREFIX_MSG + 'You have to run this command as root. Execute the following command:');
|
|
75
|
+
Common.printError(cst.PREFIX_MSG + chalk.gray(' sudo env PATH=$PATH:' + path.dirname(process.execPath) + ' pm2 logrotate -u ' + stdout.trim()));
|
|
76
|
+
|
|
77
|
+
cb ? cb(Common.retErr('You have to run this with elevated rights')) : that.exitCli(cst.ERROR_EXIT);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!fs.existsSync('/etc/logrotate.d')) {
|
|
82
|
+
Common.printError(cst.PREFIX_MSG + '/etc/logrotate.d does not exist we can not copy the default configuration.');
|
|
83
|
+
return cb ? cb(Common.retErr('/etc/logrotate.d does not exist')) : that.exitCli(cst.ERROR_EXIT);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
var templatePath = path.join(cst.TEMPLATE_FOLDER, cst.LOGROTATE_SCRIPT);
|
|
87
|
+
Common.printOut(cst.PREFIX_MSG + 'Getting logrorate template ' + templatePath);
|
|
88
|
+
var script = fs.readFileSync(templatePath, {encoding: 'utf8'});
|
|
89
|
+
|
|
90
|
+
var user = opts.user || 'root';
|
|
91
|
+
|
|
92
|
+
script = script.replace(/%HOME_PATH%/g, cst.PM2_ROOT_PATH)
|
|
93
|
+
.replace(/%USER%/g, user);
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
fs.writeFileSync('/etc/logrotate.d/pm2-'+user, script);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
console.error(e.stack || e);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
Common.printOut(cst.PREFIX_MSG + 'Logrotate configuration added to /etc/logrotate.d/pm2');
|
|
102
|
+
return cb ? cb(null, {success:true}) : that.exitCli(cst.SUCCESS_EXIT);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Description
|
|
107
|
+
* @method reloadLogs
|
|
108
|
+
* @return
|
|
109
|
+
*/
|
|
110
|
+
CLI.prototype.reloadLogs = function(cb) {
|
|
111
|
+
var that = this;
|
|
112
|
+
|
|
113
|
+
Common.printOut('Reloading all logs...');
|
|
114
|
+
that.Client.executeRemote('reloadLogs', {}, function(err, logs) {
|
|
115
|
+
if (err) {
|
|
116
|
+
Common.printError(err);
|
|
117
|
+
return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
|
|
118
|
+
}
|
|
119
|
+
Common.printOut('All logs reloaded');
|
|
120
|
+
return cb ? cb(null, logs) : that.exitCli(cst.SUCCESS_EXIT);
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Description
|
|
126
|
+
* @method streamLogs
|
|
127
|
+
* @param {String} id
|
|
128
|
+
* @param {Number} lines
|
|
129
|
+
* @param {Boolean} raw
|
|
130
|
+
* @return
|
|
131
|
+
*/
|
|
132
|
+
CLI.prototype.streamLogs = function(id, lines, raw, timestamp, exclusive, highlight) {
|
|
133
|
+
var that = this;
|
|
134
|
+
var files_list = [];
|
|
135
|
+
|
|
136
|
+
// If no argument is given, we stream logs for all running apps
|
|
137
|
+
id = id || 'all';
|
|
138
|
+
lines = lines !== undefined ? lines : 20;
|
|
139
|
+
lines = lines < 0 ? -(lines) : lines;
|
|
140
|
+
|
|
141
|
+
// Avoid duplicates and check if path is different from '/dev/null'
|
|
142
|
+
var pushIfUnique = function(entry) {
|
|
143
|
+
var exists = false;
|
|
144
|
+
|
|
145
|
+
if (entry.path.toLowerCase
|
|
146
|
+
&& entry.path.toLowerCase() !== '/dev/null') {
|
|
147
|
+
|
|
148
|
+
files_list.some(function(file) {
|
|
149
|
+
if (file.path === entry.path)
|
|
150
|
+
exists = true;
|
|
151
|
+
return exists;
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
if (exists)
|
|
155
|
+
return;
|
|
156
|
+
|
|
157
|
+
files_list.push(entry);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Get the list of all running apps
|
|
162
|
+
that.Client.executeRemote('getMonitorData', {}, function(err, list) {
|
|
163
|
+
var regexList = [];
|
|
164
|
+
var namespaceList = [];
|
|
165
|
+
|
|
166
|
+
if (err) {
|
|
167
|
+
Common.printError(err);
|
|
168
|
+
that.exitCli(cst.ERROR_EXIT);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (lines === 0)
|
|
172
|
+
return Log.stream(that.Client, id, raw, timestamp, exclusive, highlight);
|
|
173
|
+
|
|
174
|
+
Common.printOut(chalk.bold.gray(util.format.call(this, '[TAILING] Tailing last %d lines for [%s] process%s (change the value with --lines option)', lines, id, id === 'all' ? 'es' : '')));
|
|
175
|
+
|
|
176
|
+
// Populate the array `files_list` with the paths of all files we need to tail
|
|
177
|
+
list.forEach(function(proc) {
|
|
178
|
+
if (proc.pm2_env && (id === 'all' ||
|
|
179
|
+
proc.pm2_env.name == id ||
|
|
180
|
+
proc.pm2_env.pm_id == id)) {
|
|
181
|
+
if (proc.pm2_env.pm_out_log_path && exclusive !== 'err')
|
|
182
|
+
pushIfUnique({
|
|
183
|
+
path : proc.pm2_env.pm_out_log_path,
|
|
184
|
+
app_name :proc.pm2_env.pm_id + '|' + proc.pm2_env.name,
|
|
185
|
+
type : 'out'});
|
|
186
|
+
if (proc.pm2_env.pm_err_log_path && exclusive !== 'out')
|
|
187
|
+
pushIfUnique({
|
|
188
|
+
path : proc.pm2_env.pm_err_log_path,
|
|
189
|
+
app_name : proc.pm2_env.pm_id + '|' + proc.pm2_env.name,
|
|
190
|
+
type : 'err'
|
|
191
|
+
});
|
|
192
|
+
} else if(proc.pm2_env && proc.pm2_env.namespace == id) {
|
|
193
|
+
if(namespaceList.indexOf(proc.pm2_env.name) === -1) {
|
|
194
|
+
namespaceList.push(proc.pm2_env.name)
|
|
195
|
+
}
|
|
196
|
+
if (proc.pm2_env.pm_out_log_path && exclusive !== 'err')
|
|
197
|
+
pushIfUnique({
|
|
198
|
+
path : proc.pm2_env.pm_out_log_path,
|
|
199
|
+
app_name :proc.pm2_env.pm_id + '|' + proc.pm2_env.name,
|
|
200
|
+
type : 'out'});
|
|
201
|
+
if (proc.pm2_env.pm_err_log_path && exclusive !== 'out')
|
|
202
|
+
pushIfUnique({
|
|
203
|
+
path : proc.pm2_env.pm_err_log_path,
|
|
204
|
+
app_name : proc.pm2_env.pm_id + '|' + proc.pm2_env.name,
|
|
205
|
+
type : 'err'
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
// Populate the array `files_list` with the paths of all files we need to tail, when log in put is a regex
|
|
209
|
+
else if(proc.pm2_env && (isNaN(id) && id[0] === '/' && id[id.length - 1] === '/')) {
|
|
210
|
+
var regex = new RegExp(id.replace(/\//g, ''));
|
|
211
|
+
if(regex.test(proc.pm2_env.name)) {
|
|
212
|
+
if(regexList.indexOf(proc.pm2_env.name) === -1) {
|
|
213
|
+
regexList.push(proc.pm2_env.name);
|
|
214
|
+
}
|
|
215
|
+
if (proc.pm2_env.pm_out_log_path && exclusive !== 'err')
|
|
216
|
+
pushIfUnique({
|
|
217
|
+
path : proc.pm2_env.pm_out_log_path,
|
|
218
|
+
app_name : proc.pm2_env.pm_id + '|' + proc.pm2_env.name,
|
|
219
|
+
type : 'out'});
|
|
220
|
+
if (proc.pm2_env.pm_err_log_path && exclusive !== 'out')
|
|
221
|
+
pushIfUnique({
|
|
222
|
+
path : proc.pm2_env.pm_err_log_path,
|
|
223
|
+
app_name : proc.pm2_env.pm_id + '|' + proc.pm2_env.name,
|
|
224
|
+
type : 'err'
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
//for fixing issue https://github.com/Unitech/pm2/issues/3506
|
|
231
|
+
/* if (files_list && files_list.length == 0) {
|
|
232
|
+
Common.printError(cst.PREFIX_MSG_ERR + 'No file to stream for app [%s], exiting.', id);
|
|
233
|
+
return process.exit(cst.ERROR_EXIT);
|
|
234
|
+
}*/
|
|
235
|
+
|
|
236
|
+
if (!raw && (id === 'all' || id === 'PM2') && exclusive === false) {
|
|
237
|
+
Log.tail([{
|
|
238
|
+
path : cst.PM2_LOG_FILE_PATH,
|
|
239
|
+
app_name : 'PM2',
|
|
240
|
+
type : 'PM2'
|
|
241
|
+
}], lines, raw, function() {
|
|
242
|
+
Log.tail(files_list, lines, raw, function() {
|
|
243
|
+
Log.stream(that.Client, id, raw, timestamp, exclusive, highlight);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
Log.tail(files_list, lines, raw, function() {
|
|
249
|
+
if(regexList.length > 0) {
|
|
250
|
+
regexList.forEach(function(id) {
|
|
251
|
+
Log.stream(that.Client, id, raw, timestamp, exclusive, highlight);
|
|
252
|
+
})
|
|
253
|
+
}
|
|
254
|
+
else if(namespaceList.length > 0) {
|
|
255
|
+
namespaceList.forEach(function(id) {
|
|
256
|
+
Log.stream(that.Client, id, raw, timestamp, exclusive, highlight);
|
|
257
|
+
})
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
Log.stream(that.Client, id, raw, timestamp, exclusive, highlight);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Description
|
|
269
|
+
* @method printLogs
|
|
270
|
+
* @param {String} id
|
|
271
|
+
* @param {Number} lines
|
|
272
|
+
* @param {Boolean} raw
|
|
273
|
+
* @return
|
|
274
|
+
*/
|
|
275
|
+
CLI.prototype.printLogs = function(id, lines, raw, timestamp, exclusive) {
|
|
276
|
+
var that = this;
|
|
277
|
+
var files_list = [];
|
|
278
|
+
|
|
279
|
+
// If no argument is given, we stream logs for all running apps
|
|
280
|
+
id = id || 'all';
|
|
281
|
+
lines = lines !== undefined ? lines : 20;
|
|
282
|
+
lines = lines < 0 ? -(lines) : lines;
|
|
283
|
+
|
|
284
|
+
// Avoid duplicates and check if path is different from '/dev/null'
|
|
285
|
+
var pushIfUnique = function(entry) {
|
|
286
|
+
var exists = false;
|
|
287
|
+
|
|
288
|
+
if (entry.path.toLowerCase
|
|
289
|
+
&& entry.path.toLowerCase() !== '/dev/null') {
|
|
290
|
+
|
|
291
|
+
files_list.some(function(file) {
|
|
292
|
+
if (file.path === entry.path)
|
|
293
|
+
exists = true;
|
|
294
|
+
return exists;
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
if (exists)
|
|
298
|
+
return;
|
|
299
|
+
|
|
300
|
+
files_list.push(entry);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Get the list of all running apps
|
|
305
|
+
that.Client.executeRemote('getMonitorData', {}, function(err, list) {
|
|
306
|
+
if (err) {
|
|
307
|
+
Common.printError(err);
|
|
308
|
+
that.exitCli(cst.ERROR_EXIT);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (lines <= 0) {
|
|
312
|
+
return that.exitCli(cst.SUCCESS_EXIT)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
Common.printOut(chalk.bold.gray(util.format.call(this, '[TAILING] Tailing last %d lines for [%s] process%s (change the value with --lines option)', lines, id, id === 'all' ? 'es' : '')));
|
|
316
|
+
|
|
317
|
+
// Populate the array `files_list` with the paths of all files we need to tail
|
|
318
|
+
list.forEach(function(proc) {
|
|
319
|
+
if (proc.pm2_env && (id === 'all' ||
|
|
320
|
+
proc.pm2_env.name == id ||
|
|
321
|
+
proc.pm2_env.pm_id == id)) {
|
|
322
|
+
if (proc.pm2_env.pm_out_log_path && exclusive !== 'err')
|
|
323
|
+
pushIfUnique({
|
|
324
|
+
path : proc.pm2_env.pm_out_log_path,
|
|
325
|
+
app_name :proc.pm2_env.pm_id + '|' + proc.pm2_env.name,
|
|
326
|
+
type : 'out'});
|
|
327
|
+
if (proc.pm2_env.pm_err_log_path && exclusive !== 'out')
|
|
328
|
+
pushIfUnique({
|
|
329
|
+
path : proc.pm2_env.pm_err_log_path,
|
|
330
|
+
app_name : proc.pm2_env.pm_id + '|' + proc.pm2_env.name,
|
|
331
|
+
type : 'err'
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
// Populate the array `files_list` with the paths of all files we need to tail, when log in put is a regex
|
|
335
|
+
else if(proc.pm2_env && (isNaN(id) && id[0] === '/' && id[id.length - 1] === '/')) {
|
|
336
|
+
var regex = new RegExp(id.replace(/\//g, ''));
|
|
337
|
+
if(regex.test(proc.pm2_env.name)) {
|
|
338
|
+
if (proc.pm2_env.pm_out_log_path && exclusive !== 'err')
|
|
339
|
+
pushIfUnique({
|
|
340
|
+
path : proc.pm2_env.pm_out_log_path,
|
|
341
|
+
app_name : proc.pm2_env.pm_id + '|' + proc.pm2_env.name,
|
|
342
|
+
type : 'out'});
|
|
343
|
+
if (proc.pm2_env.pm_err_log_path && exclusive !== 'out')
|
|
344
|
+
pushIfUnique({
|
|
345
|
+
path : proc.pm2_env.pm_err_log_path,
|
|
346
|
+
app_name : proc.pm2_env.pm_id + '|' + proc.pm2_env.name,
|
|
347
|
+
type : 'err'
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
if (!raw && (id === 'all' || id === 'PM2') && exclusive === false) {
|
|
354
|
+
Log.tail([{
|
|
355
|
+
path : cst.PM2_LOG_FILE_PATH,
|
|
356
|
+
app_name : 'PM2',
|
|
357
|
+
type : 'PM2'
|
|
358
|
+
}], lines, raw, function() {
|
|
359
|
+
Log.tail(files_list, lines, raw, function() {
|
|
360
|
+
that.exitCli(cst.SUCCESS_EXIT);
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
Log.tail(files_list, lines, raw, function() {
|
|
366
|
+
that.exitCli(cst.SUCCESS_EXIT);
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
|
|
2
|
+
var path = require('path');
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var os = require('os');
|
|
5
|
+
var spawn = require('child_process').spawn;
|
|
6
|
+
var chalk = require('ansis');
|
|
7
|
+
var parallel = require('async/parallel');
|
|
8
|
+
|
|
9
|
+
var Configuration = require('../../Configuration.js');
|
|
10
|
+
var cst = require('../../../constants.js');
|
|
11
|
+
var Common = require('../../Common');
|
|
12
|
+
var Utility = require('../../Utility.js');
|
|
13
|
+
var readline = require('readline')
|
|
14
|
+
|
|
15
|
+
var INTERNAL_MODULES = {
|
|
16
|
+
'deep-monitoring': {
|
|
17
|
+
dependencies: [{name: 'v8-profiler-node8'}, {name: 'gc-stats'}, {name: 'event-loop-inspector'}]
|
|
18
|
+
},
|
|
19
|
+
'gc-stats': {name: 'gc-stats'},
|
|
20
|
+
'event-loop-inspector': {name: 'event-loop-inspector'},
|
|
21
|
+
'v8-profiler': {name: 'v8-profiler-node8'},
|
|
22
|
+
'profiler': {name: 'v8-profiler-node8'},
|
|
23
|
+
'typescript': {dependencies: [{name: 'typescript'}, {name: 'ts-node@latest'}]},
|
|
24
|
+
'livescript': {name: 'livescript'},
|
|
25
|
+
'coffee-script': {name: 'coffee-script', message: 'Coffeescript v1 support'},
|
|
26
|
+
'coffeescript': {name: 'coffeescript', message: 'Coffeescript v2 support'}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
module.exports = {
|
|
30
|
+
install,
|
|
31
|
+
INTERNAL_MODULES,
|
|
32
|
+
installMultipleModules
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
function install(module, cb, verbose) {
|
|
37
|
+
if (!module || !module.name || module.name.length === 0) {
|
|
38
|
+
return cb(new Error('No module name !'));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (typeof verbose === 'undefined') {
|
|
42
|
+
verbose = true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
installLangModule(module.name, function (err) {
|
|
46
|
+
var display = module.message || module.name;
|
|
47
|
+
if (err) {
|
|
48
|
+
if (verbose) { Common.printError(cst.PREFIX_MSG_MOD_ERR + chalk.bold.green(display + ' installation has FAILED (checkout previous logs)')); }
|
|
49
|
+
return cb(err);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (verbose) { Common.printOut(cst.PREFIX_MSG + chalk.bold.green(display + ' ENABLED')); }
|
|
53
|
+
return cb();
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function installMultipleModules(modules, cb, post_install) {
|
|
58
|
+
var functionList = [];
|
|
59
|
+
for (var i = 0; i < modules.length; i++) {
|
|
60
|
+
functionList.push((function (index) {
|
|
61
|
+
return function (callback) {
|
|
62
|
+
var module = modules[index];
|
|
63
|
+
if (typeof modules[index] === 'string') {
|
|
64
|
+
module = {name: modules[index]};
|
|
65
|
+
}
|
|
66
|
+
install(module, function ($post_install, err, $index, $modules) {
|
|
67
|
+
try {
|
|
68
|
+
var install_instance = spawn(post_install[modules[index]], {
|
|
69
|
+
stdio : 'inherit',
|
|
70
|
+
windowsHide: true,
|
|
71
|
+
env: process.env,
|
|
72
|
+
shell : true,
|
|
73
|
+
cwd : process.cwd()
|
|
74
|
+
});
|
|
75
|
+
Common.printOut(cst.PREFIX_MSG_MOD + 'Running configuraton script.');
|
|
76
|
+
}
|
|
77
|
+
catch(e)
|
|
78
|
+
{
|
|
79
|
+
Common.printOut(cst.PREFIX_MSG_MOD + 'No configuraton script found.');
|
|
80
|
+
}
|
|
81
|
+
callback(null, { module: module, err: err });
|
|
82
|
+
}, false);
|
|
83
|
+
};
|
|
84
|
+
})(i));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
parallel(functionList, function (err, results) {
|
|
88
|
+
for (var i = 0; i < results.length; i++) {
|
|
89
|
+
var display = results[i].module.message || results[i].module.name;
|
|
90
|
+
if (results[i].err) {
|
|
91
|
+
err = results[i].err;
|
|
92
|
+
Common.printError(cst.PREFIX_MSG_MOD_ERR + chalk.bold.green(display + ' installation has FAILED (checkout previous logs)'));
|
|
93
|
+
} else {
|
|
94
|
+
Common.printOut(cst.PREFIX_MSG + chalk.bold.green(display + ' ENABLED'));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if(cb) cb(err);
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
function installLangModule(module_name, cb) {
|
|
103
|
+
var node_module_path = path.resolve(path.join(__dirname, '../../../'));
|
|
104
|
+
Common.printOut(cst.PREFIX_MSG_MOD + 'Calling ' + chalk.bold.red('[NPM]') + ' to install ' + module_name + ' ...');
|
|
105
|
+
|
|
106
|
+
var install_instance = spawn(cst.IS_WINDOWS ? 'npm.cmd' : 'npm', ['install', module_name, '--loglevel=error'], {
|
|
107
|
+
stdio : 'inherit',
|
|
108
|
+
env: process.env,
|
|
109
|
+
shell : true,
|
|
110
|
+
cwd : node_module_path
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
install_instance.on('close', function(code) {
|
|
114
|
+
if (code > 0)
|
|
115
|
+
return cb(new Error('Module install failed'));
|
|
116
|
+
return cb(null);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
install_instance.on('error', function (err) {
|
|
120
|
+
console.error(err.stack || err);
|
|
121
|
+
});
|
|
122
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
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
|
+
var path = require('path');
|
|
7
|
+
var eachLimit = require('async/eachLimit');
|
|
8
|
+
var forEachLimit = require('async/forEachLimit');
|
|
9
|
+
|
|
10
|
+
var Configuration = require('../../Configuration.js');
|
|
11
|
+
var cst = require('../../../constants.js');
|
|
12
|
+
var Common = require('../../Common');
|
|
13
|
+
var NPM = require('./NPM.js')
|
|
14
|
+
var TAR = require('./TAR.js')
|
|
15
|
+
var LOCAL = require('./LOCAL.js')
|
|
16
|
+
|
|
17
|
+
var Modularizer = module.exports = {};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* PM2 Module System.
|
|
21
|
+
*/
|
|
22
|
+
Modularizer.install = function (CLI, module_name, opts, cb) {
|
|
23
|
+
module_name = module_name.replace(/[;`|]/g, "");
|
|
24
|
+
if (typeof(opts) == 'function') {
|
|
25
|
+
cb = opts;
|
|
26
|
+
opts = {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (LOCAL.INTERNAL_MODULES.hasOwnProperty(module_name)) {
|
|
30
|
+
Common.logMod(`Adding dependency ${module_name} to PM2 Runtime`);
|
|
31
|
+
var currentModule = LOCAL.INTERNAL_MODULES[module_name];
|
|
32
|
+
if (currentModule && currentModule.hasOwnProperty('dependencies')) {
|
|
33
|
+
LOCAL.installMultipleModules(currentModule.dependencies, cb);
|
|
34
|
+
} else {
|
|
35
|
+
LOCAL.install(currentModule, cb);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else if (module_name == '.') {
|
|
39
|
+
Common.logMod(`Installing local NPM module`);
|
|
40
|
+
return NPM.localStart(CLI, opts, cb)
|
|
41
|
+
}
|
|
42
|
+
else if (opts.tarball || /\.tar\.gz$/i.test(module_name)) {
|
|
43
|
+
Common.logMod(`Installing TAR module`);
|
|
44
|
+
TAR.install(CLI, module_name, opts, cb)
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
Common.logMod(`Installing NPM ${module_name} module`);
|
|
48
|
+
NPM.install(CLI, module_name, opts, cb)
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Launch All Modules
|
|
54
|
+
* Used PM2 at startup
|
|
55
|
+
*/
|
|
56
|
+
Modularizer.launchModules = function(CLI, cb) {
|
|
57
|
+
var modules = Modularizer.listModules();
|
|
58
|
+
|
|
59
|
+
if (!modules) return cb();
|
|
60
|
+
|
|
61
|
+
// 1#
|
|
62
|
+
function launchNPMModules(cb) {
|
|
63
|
+
if (!modules.npm_modules) return launchTARModules(cb)
|
|
64
|
+
|
|
65
|
+
eachLimit(Object.keys(modules.npm_modules), 1, function(module_name, next) {
|
|
66
|
+
NPM.start(CLI, modules, module_name, next)
|
|
67
|
+
}, function() {
|
|
68
|
+
launchTARModules(cb)
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 2#
|
|
73
|
+
function launchTARModules(cb) {
|
|
74
|
+
if (!modules.tar_modules) return cb()
|
|
75
|
+
|
|
76
|
+
eachLimit(Object.keys(modules.tar_modules), 1, function(module_name, next) {
|
|
77
|
+
TAR.start(CLI, module_name, next)
|
|
78
|
+
}, function() {
|
|
79
|
+
return cb ? cb(null) : false;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
launchNPMModules(cb)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
Modularizer.package = function(CLI, module_path, cb) {
|
|
87
|
+
var fullpath = process.cwd()
|
|
88
|
+
if (module_path)
|
|
89
|
+
fullpath = require('path').resolve(module_path)
|
|
90
|
+
TAR.packager(fullpath, process.cwd(), cb)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Uninstall module
|
|
95
|
+
*/
|
|
96
|
+
Modularizer.uninstall = function(CLI, module_name, cb) {
|
|
97
|
+
Common.printOut(cst.PREFIX_MSG_MOD + 'Uninstalling module ' + module_name);
|
|
98
|
+
var modules_list = Modularizer.listModules();
|
|
99
|
+
|
|
100
|
+
if (module_name == 'all') {
|
|
101
|
+
if (!modules_list) return cb();
|
|
102
|
+
|
|
103
|
+
return forEachLimit(Object.keys(modules_list.npm_modules), 1, function(module_name, next) {
|
|
104
|
+
NPM.uninstall(CLI, module_name, next)
|
|
105
|
+
}, () => {
|
|
106
|
+
forEachLimit(Object.keys(modules_list.tar_modules), 1, function(module_name, next) {
|
|
107
|
+
TAR.uninstall(CLI, module_name, next)
|
|
108
|
+
}, cb)
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (modules_list.npm_modules[module_name]) {
|
|
113
|
+
NPM.uninstall(CLI, module_name, cb)
|
|
114
|
+
} else if (modules_list.tar_modules[module_name]) {
|
|
115
|
+
TAR.uninstall(CLI, module_name, cb)
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
Common.errMod('Unknown module')
|
|
119
|
+
CLI.exitCli(1)
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* List modules based on modules present in ~/.pm2/modules/ folder
|
|
125
|
+
*/
|
|
126
|
+
Modularizer.listModules = function() {
|
|
127
|
+
return {
|
|
128
|
+
npm_modules: Configuration.getSync(cst.MODULE_CONF_PREFIX) || {},
|
|
129
|
+
tar_modules: Configuration.getSync(cst.MODULE_CONF_PREFIX_TAR) || {}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
Modularizer.getAdditionalConf = function(app_name) {
|
|
134
|
+
return NPM.getModuleConf(app_name)
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
Modularizer.publish = function(PM2, folder, opts, cb) {
|
|
138
|
+
if (opts.npm == true) {
|
|
139
|
+
NPM.publish(opts, cb)
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
TAR.publish(PM2, folder, cb)
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
Modularizer.generateSample = function(app_name, cb) {
|
|
147
|
+
NPM.generateSample(app_name, cb)
|
|
148
|
+
};
|