2011-04-19 99 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

相關問題