Redirect System.out.println to Log4J, while keeping class name information
Solution 1
The only way I can think of would be to write your own PrintStream
implementation which created a stack trace when the println
method was called, in order to work out the class name. It would be pretty horrible, but it should work... proof of concept sample code:
import java.io.*;
class TracingPrintStream extends PrintStream {
public TracingPrintStream(PrintStream original) {
super(original);
}
// You'd want to override other methods too, of course.
@Override
public void println(String line) {
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
// Element 0 is getStackTrace
// Element 1 is println
// Element 2 is the caller
StackTraceElement caller = stack[2];
super.println(caller.getClassName() + ": " + line);
}
}
public class Test {
public static void main(String[] args) throws Exception {
System.setOut(new TracingPrintStream(System.out));
System.out.println("Sample line");
}
}
(In your code you would make it log to log4j instead of course... or possibly as well.)
Solution 2
If you can modify the source code, then have a look at the Eclipse Plugin Log4E. It provides a function to convert System.out.println into logger statements (and many other cool stuff dealing with logging).
Comments
-
David Parks almost 2 years
I have some libraries that are calling System.out.println on me, I'd like to redirect them through log4j or commons logging. But in particular I'd like to keep the fully-qualified-classname so I know what component generated the logs.
Is there a nice, orderly way to accomplish this?
UPDATE: After accomplishing this I posted the code here:
http://www.bukisa.com/articles/487009_java-how-to-redirect-stderr-and-stdout-to-commons-logging-with-the-calling-class -
David Parks about 13 yearsNope, they're 3rd party libraries that are doing it. It's not worth changing their code, and requesting them to do it may take years.
-
Liviu T. about 13 yearsThe only thing that comes to mind when you can't modify source code is byte code manipulation but you need to intercept the class loading process and create a new class file with the System.out replaced with Logger statements, but that sounds way to intensive
-
Liviu T. about 13 yearsscratch that, Jon Skeet came to the rescue :)
-
toolforger over 4 years@DavidParks a particularly annoying case of 3rd-party code is the JDK's own debug output in the HTTPS subsystem, which uses System.stdout, including the write() functions that PrintStream wrappers typically neglect to redirect.