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.