将System.out.println重定向到日志

Vir*_*raj 10 java logging

在我的项目测试套件中有很大的用途

System.out.println 
Run Code Online (Sandbox Code Playgroud)

我正在尝试将这些输出重定向到日志文件(通过配置或单点而不重构整个项目),以便在必要时可以禁用以提高性能.我正在使用log4j进行日志记录.有人知道这可能吗?如果是这样怎么办?提前致谢.

Fab*_*nte 5

鉴于最好替换System.out.println(),有时我们别无选择。无论如何,我为此做了一个小实用程序:

SystemOutToSlf4j.enableForClass(MyClass.class)
Run Code Online (Sandbox Code Playgroud)

然后,所有源自MyClass的println将被重定向到记录器。 有关更多详细信息,请参见此帖子...

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;
  }

}
Run Code Online (Sandbox Code Playgroud)


raj*_*esh 3

我的建议是如果可能的话进行重构。对于可能的解决方案,请检查这些类似的问题

log4j 将 stdout 重定向到 DailyRollingFileAppender

将 System.out.println 重定向到 Log4J,同时保留类名信息