Question

I have a small Java program that is being invoked with java -jar via a bash script. The program calls a SOAP webservice and I want to capture the SOAP messages in a file for future troublshooting. The only way I've found to do this in a standalone Java app is by adding this to my client class:

static
{
    // Output the SOAP message to the console
    System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");
    System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true");
}

This outputs the SOAP messages to system out. I could just redirect system out to a file, but I have other messages going to system out that I want to be displayed on the console. It's okay to include these messages in the file but the SOAP messages are just way too much to be displayed on the console.

Is there a way I can do some sort of selective redirect on console output?

Was it helpful?

Solution 3

It seems unlikely that you'll be able to do this in-app as the SOAP code will be calling System.out.print.

If your main goal is to separate your output from the output from SOAP then you could prepend your messages with a special symbol and then filter the output through an appropriate script.

If your print statements are spread across your code you could consider using AOP (i.e. AspectJ) to modify them to insert this special symbol. Personally I do all printing through my own utility methods so that I can change it all in one place if needed.

OTHER TIPS

Depends on the SOAP library you are using, but generally most SOAP libraries have some sort of logging facility they use when writing things out to the console. Typically when you use these logging facilities the SOAP library itself doesn't write directly to System.out. The logging facility is configured to write that data to System.out by default. So if you figure out which SOAP lib you're using, then figure out what logging facility it uses, then you can configure logging to write to a file instead of System.out, but still send other messages to System.out.

I think you're using Metro which is using Java Util Logging. Not as easy to configure, but it can be configured with multiple appenders and loggers. I think this will be helpful for you:

https://metro.java.net/guide/ch02.html#logging

Why not write the messages you want to capture to stderr and redirect that appropriately? One thin you should consider is that stdout is [usually] buffered and stderr is not.

You're looking for shell redirection and piping. Assuming you're using a standard-ish shell like shell, bash, csh, etc. ...

  • command >foo.txt will redirect stdout to the file foo.txt. Any existing content in the fill will be replaced.
  • command >>foo.txt will redirect stdout, appending it to the file foo.txt to the existing content, if any, of foot.txt.
  • foo | bar will pipe the content of command foo's stdout through command bar's stdin.

A *nix process has three standard i/o handles open:

  • stdin is standard input. It is file handle 0.
  • stdout is standard output. It is filehandle 1.
  • stderr is standard error. It is filehandle 2.

The redirection and pipe operators can hook specific file handles as well. So...

command >foo.txt 2>&1

does the following:

  1. Redirects standard output to the file foo.txt
  2. Redirects stderr to file handle 1, stderr, which is now opened as foo.txt.

Other shells can (and do) use different, but generally similar syntax.

You should also learn about some useful commands:

  • tee(1).

    This takes the stdin given it and writes it to file specified on the command line as well as to stdout, so a chain like this:

    some-command 2>&1 | tee some-command.log.2013-05-31.txt | less
    

    runs some-command, which presumably produces a goodly amount of output, redirecting its stderr to stdout, which is then piped through tee(1), producing a logfile, some-commmand.log.2013-05-31.txt and piping it through less(1) to page it on your console.

  • less(1)

  • more(1)

    more is usually a synonym for less(1) these days. both of these are pagers which buffer output and dispaly it a screen at a time, letting you page forwards and backward through it.

  • man(1)

  • apropos(1)

    This is *nix's online help system. To learn more about them, try running these commands:

    * `man man`
    * `man apropos`
    

    To get the man page for the man and apropos commands. You might also try man tee, or man [your-shell-name] for the specific shell you're using (e.g., man csh will get you the man page for the csh shell, whilst man sh will get you the Bourne shell (sh) man page and man bash will get you the bash man page.

This page describes the usual piping/redirection operators for the C and Bourne shell families: http://www.mathinfo.u-picardie.fr/asch/f/MeCS/courseware/users/help/general/unix/redirection.html

You should also read the appropriate O'Reilly Nutshell book:

Edited To Note: As I mentioned in the comment below, you can replace System.Out and System.Err with your own PrintStream, along these lines:

PrintStream originalStdOut = System.Out ;
PrintStream newStdout = CreateNewOutputSink() ;

System.Out.flush() ;
System.Out.setOut( newStdout ) ;

invokeSome3rdPartyCode() ;

System.Out.flush() ;
System.Out.setOut( originalStdout ) ;

This will let you hook the output from your 3rd party library and redirect it to the data sink of your choice, whilst not affecting your ordinary output. If you hook both System.Out and System.Err and redirect them to the same PrintStream you'll catch both standard and error output in the process.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top