Starting node.js app as a background process - node.js

I have a node.js app which runs until user quits the process. I'm trying to run this app as a background process with forever, however, my app originally outputs something to stdout:
process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write('...');
and if I run this app with forever
forever start -l forever.log -o out.log -e err.log app.js
it does run in the background but there's nothing in out.log file. If I look at err.log I see that problem is in printing something to stdout:
$ cat err.log
/Users/err/Sites/js/test/app.js:105
process.stdout.clearLine();
^
TypeError: Object #<Socket> has no method 'clearLine'
at null.<anonymous> (/Users/err/Sites/js/test/app.js:105:20)
at wrapper [as _onTimeout] (timers.js:252:14)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
I also tried to use forever-monitor and wrote a small script:
var config = require('./config');
if (config.runInBackground) {
var forever = require('forever-monitor');
var child = new (forever.Monitor)('app.js', {
max: 1,
silent: true,
outFile: 'monitor.out.log',
errFile: 'monitor.err.log'
});
child.on('stdout', function(e) {
console.log(e);
});
child.on('exit', function () {
console.log('exited.');
});
child.start();
} else {
// do the regular process.stdout.write('...');
}
But my script exists without writing any file or starting a background process.
How can I run my node app in the background and write the original stdout to some log file? Or even better, is it possible to have an option (let's say in config.js file) to run this app as a background process or not, and if so, all stdout stuff should be written to a file?

You may need to specify an absolute path for your files.
That said, there are alternatives to forever that might work depending on your operating system. node-windows and node-mac both offer what you're looking for. node-linux isn't ready yet, but the project has some init.d scripts that could be configured to run processes with logging.
Disclosure: I am the author of all three of these.

Related

Forked electron process requires "empty" electron

I'm building a command line interface in node which connects to a background command line daemon. If no daemon is running, the first time the cli is called it will fork off the daemon using child_process.fork
The daemon needs to launch instances of electron BrowserWindow, but requiring electron is showing unusual behavior.
If running the daemon on it's own in the foreground, everything works smoothly; however in the background I get an empty module when requiring electron.
Printing Object.keys(require('electron')) to console shows the number sequence 0..84, and printing the results of require('electron') shows the string /path/to/electron/dist/electron
Printing out process.argv shows that the forked script is definitely being executed with electron.
I'm stumped. Any direction would be greatly appreciated.
Example:
launcher
#!/usr/local/bin/electron
const cp = require('child_process');
console.log();
const cld = cp.fork(__dirname+'/daemon',{
stdio:['inherit','inherit','inherit','ipc']
});
cld.on('message', (code) => {
code = parseInt(code);
cld.disconnect();
process.exit(code);
});
daemon
#!/usr/local/bin/electron
const fs=require('fs');
const log = (x)=>fs.appendFileSync('log',x+'\n\n');
log('');
if(!process.send) process.send = console.log;
log(process.argv);
const e = require('electron');
log(e);
log(Object.keys(e));
log(e.app);
process.send(0);
Resulting log file
*removed*/lib/thirdparty/node_modules/electron/dist/electron,*removed*/tmp/daemon
*removed*/lib/thirdparty/node_modules/electron/dist/electron
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84
undefined
Log file from running just daemon
*removed*/lib/thirdparty/node_modules/electron/dist/electron,./daemon
[object Object]
clipboard,nativeImage,shell,app,autoUpdater,BrowserView,BrowserWindow,contentTracing,crashReporter,dialog,globalShortcut,ipcMain,inAppPurchase,Menu,MenuItem,net,netLog,Notification,powerMonitor,powerSaveBlocker,protocol,screen,session,systemPreferences,TopLevelWindow,TouchBar,Tray,View,webContents,WebContentsView
[object App]
forked process by default set ELECTRON_RUN_AS_NODE=1 and will not expose any electron specific modules:
as https://github.com/electron/electron/issues/6656 says, you may need workaround by explicitly invoke process separately vice versa.

node.js child process change a directory and run the process

I try to run external application in node.js with child process like the following
var cp = require("child_process");
cp.exec("cd "+path+" && ./run.sh",function(error,stdout,stderr){
})
However when I try to run it stuck, without entering the callback
run.sh starts a server, when I execute it with cp.exec I expect it run asynchronously, such that my application doesn't wait until server termination. In callback I want to work with server.
Please help me to solve this.
cp.exec get the working directory in parameter options
http://nodejs.org/docs/latest/api/child_process.html#child_process_child_process_exec_command_options_callback
Use
var cp = require("child_process");
cp.exec("./run.sh", {cwd: path}, function(error,stdout,stderr){
});
for running script in the "path" directory.
The quotes are interpreted by the shell, you cannot see them if you just look at ps output.

NodeJS: exit parent, leave child alive

i am writing an utility. One command of this utility is to run an external application.
var child_process = require('child_process');
var fs = require('fs');
var out = fs.openSync('.../../log/out.log', 'a');
var err = fs.openSync('.../../log/err.log', 'a');
exports.Unref = function(app, argv) {
var child = child_process.spawn(app, argv, {
detached: true,
stdio: [ 'ignore', out, err ]
});
child.unref();
//process.exit(0);
};
Currently:
$ utility run app --some-args // run external app
// cant enter next command while app is running
My Problem is that if i run this command, the terminal is locked while the "external" Application is running.
But the terminal window shouldn't be locked by the child_process.
i wanna run:
$ utility run app --some-args
$ next-command
$ next-command
The external Application (a desktop application) will be closed by hisself.
Like this:
$ subl server.js // this runs Sublime Text and passes a file to the editor
$ npm start // The terminal does not locked - i can execute next command while Sublime is still running
You know what i mean ^^?
Appending ['>>../../log/out.log', '2>>../../log/err.log'] to the end of argv instead of leaving two files open should work since it's the open file handles that are keeping the process alive.
Passing opened file descriptors in stdio in addition to detached: true will not work the way you expect because there is no way to unref() the file descriptors in the parent process and have it still work for the child process. Even if there was a way, I believe that when the parent process exited, the OS would clean up (close) the file descriptors it had open, which would cause problems for the detached child process.
The only possible way that this might have been able to work would have been by passing file descriptors to child processes, but that functionality was dropped several stable branches ago because the same functionality did not exist on some other platforms (read: Windows).

node.js forever daemon, how to exit properly?

When using forever to run a node.js program as a daemon
i.e.
forever start myNodeTask
If the daemon (myNodeTask) decides it needs to exit, what is the correct way to do so?
If I just call process.exit() the program does terminate but it doesn't delete the forever log file, which leads me to believe that I need the program to exit in a more forever-friendly manner.
The node tasks I'm running are plain tcp servers that stream data to connected clients, not web servers.
The forever module always keeps the log files, even after a process has finished. There is no forever-friendly manner to delete those files.
But, you could use the forever-monitor module, which allow you to programatically use forever (from the docs):
var forever = require('forever-monitor'),
fs = require('fs');
var child = new (forever.Monitor)('your-filename.js', {
max: 3,
silent: true,
options: []
});
child.on('exit', function () {
console.log('your-filename.js has exited after 3 restarts');
// here you can delete your log file
fs.unlink('path_to_your_log_file', function (err) {
// do something amazing
});
});
child.start();

configure monitrc to monitor node js app process, can't find node app pidfile running with screen ec2 linux

I run my app.js (node js application) via screen on my ec2 linux instance.
I'm trying to config my monitrc file and I need the app pidfile.
It's not in :
/var/run
(and there isn't a /var/www)
Would really appreciate it if someone has any idea where the pidfile is or how can I find it out..
Thank you!
in your app you can get the current pid number with process.pid so
var fs = require('fs');
fs.writeFile("/tmp/pidfile", process.pid);
and you get a pidfile in tmp
seems like there isn't a pid file created so I used forever-monitor in order to restart my app.js script in case of an error.
Looks like it is working.
What you need to do is npm install forever
and write server.js :
var forever = require('forever'),
child = new(forever.Monitor)('app.js', {
'silent': false,
'pidFile': '/var/run/app.pid',
'watch': false,
'options': ['8383'], // Additional arguments to pass to the script,
'sourceDir': '.', // Directory that the source script is in
'watchDirectory': '.', // Top-level directory to watch from.
'watchIgnoreDotFiles': true, // whether to ignore dot files
'watchIgnorePatterns': [], // array of glob patterns to ignore, merged with contents of watchDirectory + '/.foreverignore' file
'logFile': 'logs/forever.log', // Path to log output from forever process (when daemonized)
'outFile': 'logs/forever.out', // Path to log output from child stdout
'errFile': 'logs/forever.err'
});
child.start();
forever.startServer(child);
and then run it with - node server.js (I run it from ~/nodejs directory)
Still the pid file that supposed to be in /var/run isn't there, weird but I don't need monit anymore.
I still don't understand why I should additionally use upstart (like all the posts related suggested) anyhow when I tried to run upstart it didn't work

Resources