I maintain an application which acts as a container for multiple individual programs. These programs have their own dedicated logging facility, i.e. everything they log does to a special log file.
Nevertheless, application developers seem to love to throw System.out.println and e.printStackTrace calls all over, making it impossible to maintain a clean console when running the container.
How can I prevent these applications from polluting System.out and System.err?
Implementation notes:
- the applications use Log4j for logging;
- the container also uses the console for logging, but it is strictly reserved for lifecycle events and problems, so I still need the console;
- the applications are loaded using a custom classloader, but no security checks are applied.
Update:
Simply redirecting System.out would not work since it redirects all output, so something like this fails:
System.setOut(new PrintStream(new OutputStream() {
@Override
public void write(int b) {
throw new Error("Not on my watch you don't");
}
}));
Logger logger = Logger.getLogger(Runner.class);
logger.info("My log message");
This should succeed.
Update 2:
The applications are loaded and configured using code similar to
App app = new UrlClassLoader(...).loadClass(className)).newInstance();
app.setLogger(loggerForClass(app));
Log4j is loaded from the system class loader.
System.out(replace withlog.debug()), search forSystem.err(replace withlog.info()), search forprintStackTrace(delete). I even think this might be automated for svn for example (not sure how, but I think it can be done)fork(), redirect the child process's stdout and stderr, and thenexec(), but I'm not sure what the equivalent is with Java classloaders. Could you go into more detail about how you are loading the applications?log4j