简体   繁体   中英

Want to make “System.out.println()” to print message to log4j

our project uses System.out.println() or System.err.println() to output debugging message. Now we want to use log4j to direct these output to log files not just console. To avoid impact or risk, we don't want to do replace all "System.out.println()" with "logger.debug" but just want to maybe write several code to make these output redirect to log4j log files that is no code change in each class still using System.out.println() (we know this is bad practice but we don't want to do global search and replace currently). Is it possible? Thanks.

I guess it is possible, though it is definitely a bad idea. You should bite the bullet and replace all of the System.out.printXXx() and System.err.printXXx() calls.

(You don't have to do this in one big change, and you don't have to do it using an automated search / replace... if these things make you feel uncomfortable.)


You can change where those streams go by using System.setOut and System.setErr to point them to a log4j log file. However:

  • you may get problems with interleaving of output and/or log file truncation, depending on exactly how the log4j appenders are implemented
  • you won't get log4j time stamps, etc
  • you won't have the ability to control the logging via the log4j configs, because your redirection is going behind the back of log4j
  • log4j logfile rotation won't work properly

A more complicated alternative would to create special OutputStream object to intercept the output and turn it into calls to a log4j Logger. But this also would have problems too:

  • it could be tricky figuring out where each "console log message" ends, especially if you want multiple lines of console output to be treated as one log event
  • you'll only have limited log4j configurability, because all "console log messages" will go through a single Logger (or maybe one for out and one for err )
  • performance will be a bigger and less tractable issue than with normal log4j logging.

You should be able to call System.setOut(new SomeCustomLog4JAdapter()); Where class SomeCustomLog4JAdapter extends PrintStream

Yes, it is. Use java.lang.System.setOut(java.io.PrintStream) and java.lang.System.setErr(java.io.PrintStream) to replace standard out and error streams.

Given your constraints, would it be sufficient to redirect stdout and stderr to files?

File outFile  = new File("/var/log/jiang/stdout.log");
PrintStream outStream = new PrintStream(new FileOutputStream(outFile));
System.setOut(outStream);

File errFile  = new File("/var/log/jiang/stderr.log");
PrintStream errStream = new PrintStream(new FileOutputStream(errFile));
System.setErr(errStream);

As per the other guys responses, yes it is possible with System.setOut(...) . But I'd really recommend you don't. You are just creating a nightmare for a future developer and not really saving any time or money. Do the work now to get it done properly and it will pay off in the long run.

Apart from that, routing text from System.out and System.err to log4j is (in my opinion) miss-using it because you will not be able to make use of the logging levels to seperate debug from info from errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM