123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- /**
- * Copyright 2013-2022 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.
- *
- * This file wrap target application
- * - redirect stdin, stderr to bus + log files
- * - rename process
- * - pid
- */
- var p = require('path');
- var cst = require('../constants');
- var Utility = require('./Utility.js');
- var ProcessUtils = require('./ProcessUtils');
- // Load all env-vars from master.
- var pm2_env = JSON.parse(process.env.pm2_env);
- for(var k in pm2_env) {
- process.env[k] = pm2_env[k];
- }
- // Rename process
- process.title = process.env.PROCESS_TITLE || 'node ' + pm2_env.pm_exec_path;
- delete process.env.pm2_env;
- /**
- * Main entrance to wrap the desired code
- */
- (function ProcessContainer() {
- var fs = require('fs');
- ProcessUtils.injectModules()
- var stdFile = pm2_env.pm_log_path;
- var outFile = pm2_env.pm_out_log_path;
- var errFile = pm2_env.pm_err_log_path;
- var pidFile = pm2_env.pm_pid_path;
- var script = pm2_env.pm_exec_path;
- var original_send = process.send;
- if (typeof(process.env.source_map_support) != 'undefined' &&
- process.env.source_map_support !== 'false') {
- require('source-map-support').install();
- }
- process.send = function() {
- if (process.connected)
- original_send.apply(this, arguments);
- };
- //send node version
- if (process.versions && process.versions.node) {
- process.send({
- 'node_version': process.versions.node
- });
- }
- if (cst.MODIFY_REQUIRE)
- require.main.filename = pm2_env.pm_exec_path;
- // Resets global paths for require()
- require('module')._initPaths();
- try {
- var pid = process.pid
- if (typeof(pid) !== 'undefined')
- fs.writeFileSync(pidFile, process.pid.toString());
- } catch (e) {
- console.error(e.stack || e);
- }
- // Add args to process if args specified on start
- if (process.env.args != null)
- process.argv = process.argv.concat(pm2_env.args);
- // stdio, including: out, err and entire (both out and err if necessary).
- var stds = {
- out: outFile,
- err: errFile
- };
- stdFile && (stds.std = stdFile);
- // uid/gid management
- if (pm2_env.uid || pm2_env.gid) {
- try {
- if (process.env.gid)
- process.setgid(pm2_env.gid);
- if (pm2_env.uid)
- process.setuid(pm2_env.uid);
- } catch(e) {
- setTimeout(function() {
- console.error('%s on call %s', e.message, e.syscall);
- console.error('%s is not accessible', pm2_env.uid);
- return process.exit(1);
- }, 100);
- }
- }
- exec(script, stds);
- })();
- /**
- * Description
- * @method exec
- * @param {} script
- * @param {} stds
- * @return
- */
- function exec(script, stds) {
- if (p.extname(script) == '.coffee') {
- try {
- require('coffee-script/register');
- } catch (e) {
- console.error('Failed to load CoffeeScript interpreter:', e.message || e);
- }
- }
- if (p.extname(script) == '.ls') {
- try {
- require('livescript');
- } catch (e) {
- console.error('Failed to load LiveScript interpreter:', e.message || e);
- }
- }
- if (p.extname(script) == '.ts' || p.extname(script) == '.tsx') {
- try {
- require('ts-node/register');
- } catch (e) {
- console.error('Failed to load Typescript interpreter:', e.message || e);
- }
- }
- process.on('message', function (msg) {
- if (msg.type === 'log:reload') {
- for (var k in stds){
- if (typeof stds[k] == 'object' && !isNaN(stds[k].fd)){
- if (stds[k].destroy) stds[k].destroy();
- else if (stds[k].end) stds[k].end();
- else if (stds[k].close) stds[k].close();
- stds[k] = stds[k]._file;
- }
- }
- Utility.startLogging(stds, function (err) {
- if (err)
- return console.error('Failed to reload logs:', err.stack);
- console.log('Reloading log...');
- });
- }
- });
- var dayjs = null;
- if (pm2_env.log_date_format)
- dayjs = require('dayjs');
- Utility.startLogging(stds, function (err) {
- if (err) {
- process.send({
- type : 'process:exception',
- data : {
- message: err.message,
- syscall: 'ProcessContainer.startLogging'
- }
- });
- throw err;
- return;
- }
- process.stderr.write = (function(write) {
- return function(string, encoding, cb) {
- var log_data = null;
- // Disable logs if specified
- if (pm2_env.disable_logs === true) {
- return cb ? cb() : false;
- }
- if (pm2_env.log_type && pm2_env.log_type === 'json') {
- log_data = JSON.stringify({
- message : string.toString(),
- timestamp : pm2_env.log_date_format && dayjs ?
- dayjs().format(pm2_env.log_date_format) : new Date().toISOString(),
- type : 'err',
- process_id : pm2_env.pm_id,
- app_name : pm2_env.name
- }) + '\n';
- }
- else if (pm2_env.log_date_format && dayjs)
- log_data = `${dayjs().format(pm2_env.log_date_format)}: ${string.toString()}`;
- else
- log_data = string.toString();
- process.send({
- type : 'log:err',
- topic : 'log:err',
- data : log_data
- });
- if (Utility.checkPathIsNull(pm2_env.pm_err_log_path) &&
- (!pm2_env.pm_log_path || Utility.checkPathIsNull(pm2_env.pm_log_path)))
- return cb ? cb() : false;
- stds.std && stds.std.write && stds.std.write(log_data, encoding);
- stds.err && stds.err.write && stds.err.write(log_data, encoding, cb);
- };
- })(process.stderr.write);
- process.stdout.write = (function(write) {
- return function(string, encoding, cb) {
- var log_data = null;
- // Disable logs if specified
- if (pm2_env.disable_logs === true) {
- return cb ? cb() : false;
- }
- if (pm2_env.log_type && pm2_env.log_type === 'json') {
- log_data = JSON.stringify({
- message : string.toString(),
- timestamp : pm2_env.log_date_format && dayjs ?
- dayjs().format(pm2_env.log_date_format) : new Date().toISOString(),
- type : 'out',
- process_id : pm2_env.pm_id,
- app_name : pm2_env.name
- }) + '\n';
- }
- else if (pm2_env.log_date_format && dayjs)
- log_data = `${dayjs().format(pm2_env.log_date_format)}: ${string.toString()}`;
- else
- log_data = string.toString();
- process.send({
- type : 'log:out',
- data : log_data
- });
- if (Utility.checkPathIsNull(pm2_env.pm_out_log_path) &&
- (!pm2_env.pm_log_path || Utility.checkPathIsNull(pm2_env.pm_log_path)))
- return cb ? cb() : null;
- stds.std && stds.std.write && stds.std.write(log_data, encoding);
- stds.out && stds.out.write && stds.out.write(log_data, encoding, cb);
- };
- })(process.stdout.write);
- function getUncaughtExceptionListener(listener) {
- return function uncaughtListener(err) {
- var error = err && err.stack ? err.stack : err;
- if (listener === 'unhandledRejection') {
- error = 'You have triggered an unhandledRejection, you may have forgotten to catch a Promise rejection:\n' + error;
- }
- logError(['std', 'err'], error);
- // Notify master that an uncaughtException has been catched
- try {
- if (err) {
- var errObj = {};
- Object.getOwnPropertyNames(err).forEach(function(key) {
- errObj[key] = err[key];
- });
- }
- process.send({
- type : 'log:err',
- topic : 'log:err',
- data : '\n' + error + '\n'
- });
- process.send({
- type : 'process:exception',
- data : errObj !== undefined ? errObj : {message: 'No error but ' + listener + ' was caught!'}
- });
- } catch(e) {
- logError(['std', 'err'], 'Channel is already closed can\'t broadcast error:\n' + e.stack);
- }
- if (!process.listeners(listener).filter(function (listener) {
- return listener !== uncaughtListener;
- }).length) {
- if (listener == 'uncaughtException') {
- process.emit('disconnect');
- process.exit(cst.CODE_UNCAUGHTEXCEPTION);
- }
- }
- }
- }
- process.on('uncaughtException', getUncaughtExceptionListener('uncaughtException'));
- process.on('unhandledRejection', getUncaughtExceptionListener('unhandledRejection'));
- // Change dir to fix process.cwd
- process.chdir(pm2_env.pm_cwd || process.env.PWD || p.dirname(script));
- if (ProcessUtils.isESModule(script) === true)
- import(process.env.pm_exec_path);
- else
- require('module')._load(script, null, true);
- function logError(types, error){
- try {
- types.forEach(function(type){
- stds[type] && typeof stds[type].write == 'function' && stds[type].write(error + '\n');
- });
- } catch(e) { }
- }
- });
- }
|