2011-04-19 100 views
4

我有一些库对我调用System.out.println,我想通过log4j或commons logging重定向它们。但特别是我想保留完全限定的类名,以便我知道哪些组件生成了日志。将System.out.println重定向到Log4J,同时保留类名信息

有没有一个很好的,有序的方式来实现这一目标?


UPDATE:完成这个后,我张贴在这里的代码:
http://www.bukisa.com/articles/487009_java-how-to-redirect-stderr-and-stdout-to-commons-logging-with-the-calling-class

+0

如果我删除了实现中的锁定行为以提高应用程序的性能,那么会有什么影响? – 2017-04-29 06:49:00

回答

15

我能想到的唯一方法是编写自己的PrintStream实现,该实现在调用println方法时创建堆栈跟踪,以便计算出类名。这将是非常可怕的,但它应该工作...的概念的示例代码证明:(。在你的代码将使得其记录到的log4j而不是当然...或者可能还有)

import java.io.*; 

class TracingPrintStream extends PrintStream { 
    public TracingPrintStream(PrintStream original) { 
    super(original); 
    } 

    // You'd want to override other methods too, of course. 
    @Override 
    public void println(String line) { 
    StackTraceElement[] stack = Thread.currentThread().getStackTrace(); 
    // Element 0 is getStackTrace 
    // Element 1 is println 
    // Element 2 is the caller 
    StackTraceElement caller = stack[2]; 
    super.println(caller.getClassName() + ": " + line); 
    } 
} 

public class Test { 
    public static void main(String[] args) throws Exception { 
    System.setOut(new TracingPrintStream(System.out)); 
    System.out.println("Sample line"); 
    } 
} 

+2

那么,这是棘手的,一路上的几个陷阱,但可行。谢谢(你的)信息。我在这里发布了代码:http://www.bukisa.com/articles/487009_java-how-to-redirect-stderr-and-stdout-to-commons-logging-with-the-calling-class – 2011-04-20 04:27:39

1

如果你可以修改源代码,然后看看在Eclipse Plugin Log4E。它提供了一个将System.out.println转换为记录器语句的功能(以及许多其他处理记录的很酷的东西)。

+0

不,他们是第三方库。这不值得更改他们的代码,并且要求他们这样做可能需要几年时间。 – 2011-04-19 07:10:11

+1

当你不能修改源代码时,唯一想到的就是字节码操作,但是你需要拦截类加载过程,并用System.out创建一个新的类文件,用Logger语句替换,但这听起来很方便密集的 – 2011-04-19 07:18:01

+1

从零开始,乔恩Skeet来拯救:) – 2011-04-19 07:28:30

相关问题