node.jsstdionode-streams

Transform stream to prepend string to each line


I spawn a child process like so:

const n = cp.spawn('bash');

n.stdout.pipe(process.stdout);
n.stderr.pipe(process.stderr);

I am looking for a transform stream so that I can prepend something like '[child process]' to the beginning of each line from the child, so I know that the stdio is coming from the child versus the parent process.

So it would look like:

const getTransformPrepender = function() : Transform {
   return ...
}

n.stdout.pipe(getTransformPrepender('[child]')).pipe(process.stdout);
n.stderr.pipe(getTransformPrepender('[child]')).pipe(process.stderr);

does anyone know if there is an existing transform package like this or how to write one?

I have this:

import * as stream from 'stream';


export default function(pre: string){

  let saved = '';

  return new stream.Transform({

    transform(chunk, encoding, cb) {

      cb(null, String(pre) + String(chunk));
    },

    flush(cb) {
      this.push(saved);
      cb();
    }

  });

}

but I am afraid it won't work in edge cases - where one chunk burst may not comprise an entire line (for very long lines).

It looks like the answer to this is here: https://strongloop.com/strongblog/practical-examples-of-the-new-node-js-streams-api/

but with this addendum: https://twitter.com/the1mills/status/886340747275812865


Solution

  • You can prepend to a stream using:

    https://github.com/ORESoftware/prepend-transform

    but it's designed to solve the problem at hand like so:

    import pt from 'prepend-transform';
    import * as cp from 'child_process';
    
    const n = cp.spawn('bash');
    
    n.stdout.pipe(pt('child stdout: ')).pipe(process.stdout);
    n.stderr.pipe(pt('child stderr: ')).pipe(process.stderr);