mirror of
https://github.com/Unitech/pm2.git
synced 2025-12-08 20:35:53 +00:00
182 lines
5.0 KiB
JavaScript
182 lines
5.0 KiB
JavaScript
/**
|
|
* Copyright 2013 the PM2 project authors. All rights reserved.
|
|
* Use of this source code is governed by a license that
|
|
* can be found in the LICENSE file.
|
|
*/
|
|
|
|
var clone = require('./tools/safeclonedeep.js');
|
|
var fs = require('fs');
|
|
var path = require('path');
|
|
var cst = require('../constants.js');
|
|
var async = require('async');
|
|
var util = require('util');
|
|
var yamljs = require('yamljs');
|
|
var vm = require('vm');
|
|
var semver = require('semver');
|
|
|
|
var Utility = module.exports = {
|
|
getDate : function() {
|
|
return Date.now();
|
|
},
|
|
formatCLU : function(process) {
|
|
if (!process.pm2_env) {
|
|
return process;
|
|
}
|
|
|
|
var obj = Utility.clone(process.pm2_env);
|
|
delete obj.env;
|
|
|
|
return obj;
|
|
},
|
|
whichFileExists : function(file_arr) {
|
|
var f = null;
|
|
|
|
file_arr.some(function(file) {
|
|
try {
|
|
fs.statSync(file);
|
|
} catch(e) {
|
|
return false;
|
|
}
|
|
f = file;
|
|
return true;
|
|
});
|
|
return f;
|
|
},
|
|
clone : function(obj) {
|
|
if (obj === null || obj === undefined) return {};
|
|
return clone(obj);
|
|
},
|
|
overrideConsole : function(bus) {
|
|
if (cst.PM2_LOG_DATE_FORMAT && typeof cst.PM2_LOG_DATE_FORMAT == 'string'){
|
|
var moment = require('moment');
|
|
|
|
// Generate timestamp prefix
|
|
function timestamp(){
|
|
return moment().format(cst.PM2_LOG_DATE_FORMAT) + ': ';
|
|
}
|
|
|
|
var hacks = ['info', 'log', 'error', 'warn'], consoled = {};
|
|
|
|
// store console functions.
|
|
hacks.forEach(function(method){
|
|
consoled[method] = console[method];
|
|
});
|
|
|
|
hacks.forEach(function(k){
|
|
console[k] = function(){
|
|
if (bus) {
|
|
bus.emit('log:PM2', {
|
|
process : {
|
|
pm_id : 'PM2',
|
|
name : 'PM2',
|
|
rev : null
|
|
},
|
|
at : Utility.getDate(),
|
|
data : util.format.apply(this, arguments) + '\n'
|
|
});
|
|
}
|
|
// do not destroy variable insertion
|
|
arguments[0] && (arguments[0] = timestamp() + arguments[0]);
|
|
consoled[k].apply(console, arguments);
|
|
};
|
|
});
|
|
}
|
|
},
|
|
startLogging : function(stds, callback) {
|
|
/**
|
|
* Start log outgoing messages
|
|
* @method startLogging
|
|
* @param {} callback
|
|
* @return
|
|
*/
|
|
// Make sure directories of `logs` and `pids` exist.
|
|
try {
|
|
['logs', 'pids'].forEach(function(n){
|
|
(function(_path){
|
|
!fs.existsSync(_path) && fs.mkdirSync(_path, '0755');
|
|
})(path.resolve(cst.PM2_ROOT_PATH, n));
|
|
});
|
|
} catch(err) {
|
|
return callback(new Error('can not create directories (logs/pids):' + err.message));
|
|
}
|
|
|
|
// waterfall.
|
|
var flows = [];
|
|
// types of stdio, should be sorted as `std(entire log)`, `out`, `err`.
|
|
var types = Object.keys(stds).sort(function(x, y){
|
|
return -x.charCodeAt(0) + y.charCodeAt(0);
|
|
});
|
|
|
|
// Create write streams.
|
|
(function createWS(io){
|
|
if(io.length != 1){
|
|
return false;
|
|
}
|
|
io = io[0];
|
|
|
|
// If `std` is a Stream type, try next `std`.
|
|
// compatible with `pm2 reloadLogs`
|
|
if(typeof stds[io] == 'object' && !isNaN(stds[io].fd)){
|
|
return createWS(types.splice(0, 1));
|
|
}
|
|
|
|
flows.push(function(next){
|
|
var file = stds[io];
|
|
|
|
stds[io] = fs.createWriteStream(file, {flags: 'a'})
|
|
.on('error', function(err){
|
|
next(err);
|
|
})
|
|
.on('open', function(){
|
|
next();
|
|
});
|
|
stds[io]._file = file;
|
|
});
|
|
return createWS(types.splice(0, 1));
|
|
})(types.splice(0, 1));
|
|
|
|
async.waterfall(flows, callback);
|
|
},
|
|
/**
|
|
* Check if filename is a configuration file
|
|
* @param {string} filename
|
|
* @return {mixed} null if not conf file, json or yaml if conf
|
|
*/
|
|
isConfigFile : function(filename) {
|
|
if (typeof(filename) != 'string')
|
|
return null;
|
|
if (filename.indexOf('.json') != -1)
|
|
return 'json';
|
|
if (filename.indexOf('.yml') > -1 || filename.indexOf('.yaml') > -1)
|
|
return 'yaml';
|
|
return null;
|
|
},
|
|
/**
|
|
* Parses a config file like ecosystem.json. Supported formats: JS, JSON, JSON5, YAML.
|
|
* @param {string} confString contents of the config file
|
|
* @param {string} filename path to the config file
|
|
* @return {Object} config object
|
|
*/
|
|
parseConfig : function(confObj, filename) {
|
|
if (!filename || filename == 'pipe' || filename == 'none' ||
|
|
filename.indexOf('.json') > -1) {
|
|
var code = '(' + confObj + ')';
|
|
var sandbox = {};
|
|
if (semver.satisfies(process.version, '>= 0.12.0')) {
|
|
return vm.runInThisContext(code, sandbox, {
|
|
filename: path.resolve(filename),
|
|
displayErrors: false,
|
|
timeout: 1000
|
|
});
|
|
} else {
|
|
// Use the Node 0.10 API
|
|
return vm.runInNewContext(code, sandbox, filename);
|
|
}
|
|
}
|
|
else if (filename.indexOf('.yml') > -1 ||
|
|
filename.indexOf('.yaml') > -1) {
|
|
return yamljs.parse(confObj.toString());
|
|
}
|
|
}
|
|
};
|