1 | var chalk = require('chalk');
|
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 |
|
15 |
|
16 |
|
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.grey(' 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 |
|
107 |
|
108 |
|
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 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 | CLI.prototype.streamLogs = function(id, lines, raw, timestamp, exclusive, highlight) {
|
133 | var that = this;
|
134 | var files_list = [];
|
135 |
|
136 |
|
137 | id = id || 'all';
|
138 | lines = lines !== undefined ? lines : 20;
|
139 | lines = lines < 0 ? -(lines) : lines;
|
140 |
|
141 |
|
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 |
|
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.grey(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 |
|
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 |
|
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 |
|
231 | |
232 |
|
233 |
|
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 |
|
269 |
|
270 |
|
271 |
|
272 |
|
273 |
|
274 |
|
275 | CLI.prototype.printLogs = function(id, lines, raw, timestamp, exclusive) {
|
276 | var that = this;
|
277 | var files_list = [];
|
278 |
|
279 |
|
280 | id = id || 'all';
|
281 | lines = lines !== undefined ? lines : 20;
|
282 | lines = lines < 0 ? -(lines) : lines;
|
283 |
|
284 |
|
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 |
|
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.grey(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 |
|
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 |
|
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 | };
|