1

So, what I want to do is basically filter everything that is passed through System.out and System.err, is it possible to apply a filter of some sort or to create my own OutputStream to divert System.out with, and then process it normally?

Edit for clarity: To clarify, I need to read what goes out of System.out from other programs and manipulate it how I see fit, so a logger is not really an option as I do not have control over what the other program will use.

Edit for more clarity: I am creating a plugin for a larger program that needs to read everything written to System.out from other plugins. Because it is a plugin-based system the process my plugin is running on will always be the same one other plugins are running on.

Socratic Phoenix
  • 556
  • 1
  • 7
  • 19
  • 1
    You can use loggers (log4j) instead of system.out/err where you can add some filtering. – Eranda May 06 '15 at 02:17
  • possible duplicate of [How to get name of output stream (i.e, stderr, or stdout) in java?](http://stackoverflow.com/questions/13476375/how-to-get-name-of-output-stream-i-e-stderr-or-stdout-in-java) – Kick Buttowski May 06 '15 at 02:19
  • 2
    @KickButtowski Edited to clarify why its not :) – Socratic Phoenix May 06 '15 at 02:37
  • Do you want to read the STDOUT from another program, or manipulate `System.out` so that another program can read that? In other words, is your program reading or writing the stream you want to filter? – Kevin May 06 '15 at 02:40
  • I want to read what the other program is writing to System.out. – Socratic Phoenix May 06 '15 at 09:28

3 Answers3

5

Something I am not clear: you have mentioned that you want to "read what goes out of System.out from other programs". Are your application creating the process and want to monitor its standard out/err, or you want to monitor the standard out/err of your process itself?

For former case, after you created the process, you can get its output, input and error stream.

For latter case, you can replace the standard out of your Java process by System.setOut(yourOwnOutputStream);

However, if you are trying to deal with streams of totally irrelevant process, I believe there is no way doing so without having the caller pipe the stdout/stderr to your process (unless through some platform specific methods)


Update:

In order to "intercept" the standard out, it is nothing different from all those classic "filter outputstreams". What you can do is something like this:

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

class AnalyzingOutputStream extends FilterOutputStream {

    public AnalyzingOutputStream (OutputStream out) {
        super(out);
    }

    @Override
    public void write(int b) throws IOException {
          // do whatever analysis you want
          super.write(b);  // delegate to super class' write, which will 
                           // delegate to the filtered outputstream
    }
    // other overrides
}

In order to use it, your main logic should do something like:

AnalyzingOutputStream analyzingOutputStream = new AnalyzingOutputStream(System.out);
System.setOut(analyzingOutputStream );

// then you can call your methods of AnalyzingOutputStream to do whatever you want
umunBeing
  • 514
  • 1
  • 5
  • 15
Adrian Shum
  • 38,812
  • 10
  • 83
  • 131
  • No, I"m sorry for being unclear, the program I"m working with is a plugin-based system and I need to read the System.out calls from other plugins. Therefore I only need to read the local process"s System.out. I feel like your second solution would work, but does that completley divert the System.out? Because I only want to read it, not keep it from the console. – Socratic Phoenix May 06 '15 at 09:33
  • It will of course divert everything to your stream. Therefore, the stream that you are using should also keep the original output stream, and after you analyze the data from stream, you should delegate it to the original stream for normal display – Adrian Shum May 06 '15 at 09:43
  • How do i go about rewriting it to the original stream? I can"t call System.out, because that would just re-write it through my stream. Should I save System.out before setting it? Is that even possible? – Socratic Phoenix May 06 '15 at 09:56
  • I'm sorry, its probably just me, but I cannot find anything different about this answer since you posted the above comment. – Socratic Phoenix May 06 '15 at 10:05
0

You should use a logger but if you don't want to you van create your own PrintStream which holds the System.out. Then call System.setOut(yourPrintStream).

TameHog
  • 950
  • 11
  • 23
  • TameHog and others. The thing I am trying to accomplish is reading the System.out calls from other programs, so TameHog, would calling System.setOut change the behavior of out, or simply write a copy of what was written to System.out to my own print stream? – Socratic Phoenix May 06 '15 at 02:34
0

To capture all output from another process in Java, the simplest way is to launch the process yourself using Runtime.exec which will give you a Process object which has getOutputStream. Reading off that stream will give you the stdout for the launched process.

If you're trying to capture the output of an arbitrary process, you've got a bigger task ahead of you - and it's probably not a good idea. I have no idea how it works on Windows. Under Linux, you'll need to be running under the same user as the process you want to investigate or (more likely) root. You can look at the file descriptors for any given process under /proc/<process id>/fd/<file descriptor>. The file descriptors for stdin, stdout and stderr are 0, 1 and 2 respectively. I would recommend you stop at this point and re-think what you're trying to do.

Alex Taylor
  • 8,343
  • 4
  • 25
  • 40
  • Perhaps this will make it easier, and I will edit to clarify, what I am working on is a plugin for a larger program, therefore I only need to read the local System.out because it is not a whole other process. – Socratic Phoenix May 06 '15 at 09:29