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

Observe data emitted through stdout and stderr #8033

Closed
medikoo opened this issue Aug 9, 2016 · 15 comments
Closed

Observe data emitted through stdout and stderr #8033

medikoo opened this issue Aug 9, 2016 · 15 comments
Labels
feature request Issues that request new features to be added to Node.js. process Issues and PRs related to the process subsystem. stalled Issues and PRs that are stalled.

Comments

@medikoo
Copy link

medikoo commented Aug 9, 2016

Currently without hacking of process.stdout.write there's no way to observe what data do process logs to console, and even through hacking 100% coverage seems not possible

It would be great if such functionality is easily accessible in Node.js without a need for tweaking node internals

@bnoordhuis
Copy link
Member

What exactly are you proposing? You are saying "x doesn't work" but you are not saying what should be fixed in order to make x work.

@vkurchatkin
Copy link
Contributor

Is there an example of such feature in any runtime?

@ChALkeR ChALkeR added the feature request Issues that request new features to be added to Node.js. label Aug 9, 2016
@medikoo
Copy link
Author

medikoo commented Aug 9, 2016

@bnoordhuis I want to do something as:

process.on('stdout', function (data) {
 // `data` is what was output through stdout
});

Use case is that I want to log all stdout and stderr to the file, and as that process is run by process manager (which has limited logging capabilities) it would be best if functionality could be configured from within the process that emits the output.

@addaleax
Copy link
Member

addaleax commented Aug 9, 2016

I know this might not really what you are looking for, but you could hook into the child_process internals to intercept child processes’ I/O… it’s hacky but basically not any more or less hacky than overriding process.stdout internals.

@medikoo
Copy link
Author

medikoo commented Aug 9, 2016

@addaleax I've looked in to that, and when inherit option is used for stdio, there seems no way to intercept their I/O.

I can surely do it if pipe option is used, but then child process looses terminal context (originally inherited from main process), and that in turn makes some logging utilities (which run within that child process) behave differently (produce different output). I wanted to avoid that.

@addaleax
Copy link
Member

addaleax commented Aug 9, 2016

@medikoo Makes sense.

If you’re spawning non-Node.js child processes, you might really just be out of luck here. If you’re talking about Node.js child processes… you might be able to get something working by using spawn-wrap to set up hooks for process.stdout/process.stderr in the child processes.

Either way, I don’t think this is something which can really be reliably implemented in Node core. When a child is spawned with inherited stdio, the parent process generally has no ability to influence or intercept the child’s stdio.

@vkurchatkin
Copy link
Contributor

@mscdex mscdex added the process Issues and PRs related to the process subsystem. label Aug 9, 2016
@medikoo
Copy link
Author

medikoo commented Aug 10, 2016

@vkurchatkin thanks, looks interesting, I'll look into that

@sindresorhus
Copy link

sindresorhus commented Aug 10, 2016

the parent process generally has no ability to influence or intercept the child’s stdio.

Not even just listen to it? That's usually all I need.

The common answer to this that I've seen is to use a PTY implementation, but those use native bindings, so can't really use it for anything. Wish Node.js had PTY support built-in.

@addaleax
Copy link
Member

the parent process generally has no ability to influence or intercept the child’s stdio.

Not even just listen to it? That's usually all I need.

With inherit, the child process and the parent process end up with independent file descriptors pointing to the same resource, so yeah, I don’t really think that’s possible. Unless, of course, the parent process is also the one listening at the other end of the pty/pipe/socket/whatever…

Wish Node.js had PTY support built-in.

+1 for that wish, but I can’t say how practical that is for Windows. There’s https://www.npmjs.org/package/pty.js (native) which seems kind of usable, but they do some stuff on Windows that would be pretty uncommon for Node itself to do (like spawn extra binaries?) if I’m understanding it correctly.

@Trott
Copy link
Member

Trott commented Jul 9, 2017

This issue has been inactive for sufficiently long that it seems like perhaps it should be closed. Feel free to re-open (or leave a comment requesting that it be re-opened) if you disagree. I'm just tidying up and not acting on a super-strong opinion or anything like that.

@gajus
Copy link

gajus commented May 11, 2018

Can we re-open this issue?

I was inspecting for hours whats the reason my logs are missing certain messages.

Turns out that the logger that I am using binds to the the stdout at the initialisation stage:

const log = process.stdout.write.bind(process.stdout);

This makes it impossible to bind to the stdout later in the code, i.e. this is not going to intercept the output:

// @flow

const originalStdoutWrite = process.stdout.write.bind(process.stdout);

let activeIntercept = false;
let taskOutput: string = '';

const intercept = default () => {
  if (activeIntercept) {
    throw new Error('Unexpected initilization of multiple concurrent stdout interceptors.');
  }

  // $FlowFixMe
  process.stdout.write = (chunk, encoding, callback) => {
    if (activeIntercept && typeof chunk === 'string') {
      taskOutput += chunk;
    }

    return originalStdoutWrite(chunk, encoding, callback);
  };

  activeIntercept = true;

  return (): string => {
    const result = taskOutput;

    activeIntercept = false;
    taskOutput = '';

    return result;
  };
};

const flush = intercept();

// This will get captured.
console.log('foo 0');
process.stdout.write('foo 1');

// This will not get captured.
log('bar');

console.log(flush());

@Trott Trott reopened this May 11, 2018
@Aghassi
Copy link

Aghassi commented Jul 9, 2018

This would be a nice to have feature. Sometimes calling code programatically that is not your own can add to things like console.log without you wanting it. Would be nice to have some reactive functionality around that to do a process.on(stdout) or something, and then redirect it via a callback/promise.

@bengl bengl added the stalled Issues and PRs that are stalled. label Nov 29, 2018
@bengl
Copy link
Member

bengl commented Nov 29, 2018

Realistically, I don't see this happening as Node.js can't really support every monkey-patching. That being said, it could happen in this case. Nevertheless conversation has stalled, so I'm marking it as such, closing the issue, and adding to the feature-request backlog.

If that doesn't seem appropriate, feel free to comment or reopen.

@bengl bengl closed this as completed Nov 29, 2018
@bengl bengl added this to backlog/orphan in feature requests via automation Nov 29, 2018
@Trott
Copy link
Member

Trott commented Nov 29, 2018

For the record, the feature request backlog is https://github.com/nodejs/node/projects/13.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js. process Issues and PRs related to the process subsystem. stalled Issues and PRs that are stalled.
Projects
No open projects
feature requests
  
backlog/orphan
Development

No branches or pull requests