Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
413 views
in Technique[技术] by (71.8m points)

java - Redirect System.out.println to log

In my project test suite there is big usage of

System.out.println 

I'm trying to redirect these output to log file (through configuration or from single point without refactoring whole project ) so that can be disabled when necessary to improve performance. I'm using log4j for logging. Does any one know is this possible ? if so how to do it ? Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Given that it's better replace the System.out.println(), sometimes we have no choice. Anyway I've made a little utility for that:

SystemOutToSlf4j.enableForClass(MyClass.class)

Then all the println originated from MyClass will be redirected to the logger. See this post for more details...

public class SystemOutToSlf4j extends PrintStream {

  private static final PrintStream originalSystemOut = System.out;
  private static SystemOutToSlf4j systemOutToLogger;

  /**
   * Enable forwarding System.out.println calls to the logger if the stacktrace contains the class parameter
   * @param clazz
   */
  public static void enableForClass(Class clazz) {
    systemOutToLogger = new SystemOutToSlf4j(originalSystemOut, clazz.getName());
    System.setOut(systemOutToLogger);
  }


  /**
   * Enable forwarding System.out.println calls to the logger if the stacktrace contains the package parameter
   * @param packageToLog
   */
  public static void enableForPackage(String packageToLog) {
    systemOutToLogger = new SystemOutToSlf4j(originalSystemOut, packageToLog);
    System.setOut(systemOutToLogger);
  }

  /**
   * Disable forwarding to the logger resetting the standard output to the console
   */
  public static void disable() {
    System.setOut(originalSystemOut);
    systemOutToLogger = null;
  }

  private String packageOrClassToLog;

  private SystemOutToSlf4j(PrintStream original, String packageOrClassToLog) {
    super(original);
    this.packageOrClassToLog = packageOrClassToLog;
  }

  @Override
  public void println(String line) {
    StackTraceElement[] stack = Thread.currentThread().getStackTrace();
    StackTraceElement caller = findCallerToLog(stack);
    if (caller == null) {
      super.println(line);
      return;
    }

    org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(caller.getClass());
    log.info(line);
  }

  public StackTraceElement findCallerToLog(StackTraceElement[] stack) {
    for (StackTraceElement element : stack) {
      if (element.getClassName().startsWith(packageOrClassToLog))
        return element;
    }

    return null;
  }

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...