Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Piping stdout from child process into main process #2151

Open
derN3rd opened this issue Sep 2, 2021 · 6 comments
Open

Comments

@derN3rd
Copy link

derN3rd commented Sep 2, 2021

While working with sub-process workers (sandboxed job processors) I tried to find a good way to get debug information within the job code and in general from the process. (Same as #1021)

The easiest way I came up with is to patch the lib/process/child-pool.js with:

@@ -4,7 +4,6 @@
@@ -4,6 +4,7 @@
 const path = require('path');
 const _ = require('lodash');
 const getPort = require('get-port');
+const { Transform } = require('stream');
 
 const ChildPool = function ChildPool() {
   if (!(this instanceof ChildPool)) {
@@ -47,8 +48,21 @@
 
   return convertExecArgv(process.execArgv).then(execArgv => {
     child = fork(path.join(__dirname, './master.js'), {
-      execArgv
+      execArgv,
+      stdio: 'pipe',
     });
+
+    // main folder that includes the node_modules
+    const projectFolder = __dirname.split('node_modules/').shift()
+    const readableProcessName = processFile.replace(projectFolder, '')
+
+    const processNamePrependTransform = new Transform({
+      transform: (chunk, encoding, done) => {
+          const result = `[${readableProcessName}] ${chunk.toString()}`
+          done(null, result)
+      }
+  })
+
+    child.stdout.pipe(processNamePrependTransform).pipe(process.stdout);
+    
     child.processFile = processFile;

this will pipe any child stdout into the main process stdout with its processFile (e.g. [src/jobs/processImage.js] found invalid image file '/tmp/x.png'). (Obviously the transform part is not needed and only adds from which process the output came. This could also be extended with the process pid etc)

I think this could be useful for other people as well e.g. behind a config or environment flag.

As I didn't work with fork before I don't know about negative side effects for this in production environments, but in my local dev setup it worked and helped me a lot already.

@phips28
Copy link

phips28 commented Sep 16, 2021

I like this idea, that would also support pm2 logs then

@stale
Copy link

stale bot commented Nov 15, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Nov 15, 2021
@derN3rd
Copy link
Author

derN3rd commented Nov 15, 2021

Don't you dare to close a Feature Request, Stale Bot 🧐

@stale stale bot removed the wontfix label Nov 15, 2021
@stale
Copy link

stale bot commented Jan 14, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added wontfix and removed wontfix labels Jan 14, 2022
@bugs181
Copy link

bugs181 commented Sep 10, 2022

This is a nifty trick. I solved it a different way by using Event hooks.

rsyncQueue.process(function(job, done) {
  const rsync = new Rsync(job.data)
  rsync.on('log', (message) => job.log(message))`
})

Then inside the Rsync class:

class Rsync extends EventEmitter {
  ...
  child.stdout.on('data', (dataObj) => {
     const data = dataObj.toString()
     this.emit('log', data)
  }
}

@TheArhaam
Copy link

Have there been any developments on this? I would much rather have this coming from the package itself than have to set up some custom config for handling the logs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants