2011-10-17 52 views
1

我想在我的程序中將日誌記錄添加到很少的類。我是否需要添加命令行來定義一個記錄器每個需要一個記錄器類(我想避免將記錄對象在我的計劃。將Log4j記錄器放入多個類

public class SomeClass { 
    static Logger logger = Logger.getLogger(SomeClass.class); 
    ....... 

如果我這樣做,我能得到這個呼叫「知道」它的類(類似this.class 還是有替代這樣做

+1

使用Eclipse代碼模板:http://stackoverflow.com/questions/1028858/useful-eclipse-java-code-templates/1029304#1029304 – palacsint

回答

1

是需要行添加到每個班。 如果你的記錄是靜態的方式(如你的例子),你需要每次都喜歡到指定類你做了(SomeClass.class)。如果你讓你的記錄器不是靜態的,那麼你可以使用this.getClass(),這會更貼切友好:

public class SomeClass { 
    private Logger logger = Logger.getLogger(this.getClass()); 
    ....... 
+0

注意這如果某人創建了一個'公共類SubClass extends SomeClass',那麼'SubClass'從'SomeClass'繼承的每一個方法都會得到'SubClass'的記錄器 - 這可能是也可能不是期望的結果。 –

+0

你不得不將它添加到每個類中。事實上,有這麼多upvotes似乎表明,這不是常識。 –

1

不,你不需要需要這樣做,但這是一個習慣做法,並且是一個好習慣。 Log4j是圍繞這個假設而構建的,人們會以這種方式使用它。它可以免費提供日誌事件發佈地點的位置,以及整個日誌記錄器日誌級別的簡單管理。

從理論上講,您可以在多個類中共享一個記錄器,或者甚至只有一個全局; Logger是線程安全的,它需要在追加對象時進行同步,所以你的性能不會受到影響。你也可以將它命名爲任何你想要的,不需要使用類名。不過,並不建議,因爲我上面提到的原因。

此外,由於log4j認爲只能創建一個具有給定名稱的記錄器,因此不需要編寫參考static,因爲它不會因存儲在實例變量中而浪費內存。

2

一個選擇,我覺得方便的是使爲您創建記錄器的抽象類:

public abstract class AbstractLoggingThing { 
    private final Logger log = LoggerFactory.getLogger(this.getClass()); 

    protected Logger getLog() { 
     return log; 
    } 
} 
按照慣例

然後,每一個從它繼承有一個正確配置的Logger類,而你不知道不得不在整個地方都有相同的,愚蠢的代碼。項目中的大多數類都可以很容易地將其包含在其繼承層次中,對於那些不能,無論出於何種原因,您仍然可以回到舊式。您還可以添加漂亮的便捷方法,如:

protected void info(String message, Object... args) { 
     // What goes here depends on your logging library 
    } 
+0

我不會那樣做。它可能在多語言繼承的語言中表現良好,但在Java中,它導致創建上帝對象和與基類緊密耦合的代碼。作爲一個包中的便捷方法可能沒問題,但肯定不適用於整個應用程序。 – MaDa

+0

@MaDa:完全沒有。如果它適合一個包裝,爲什麼不在更廣的範圍內?把它看作是一個窮人的混蛋。如果我使用的是AspectJ,我可能會編寫這些代碼而不是繼承它。此外,我成功地將這種方法用於大型項目,並且沒有任何有害的副作用。它被視爲比對象更多的替代物。這非常有用,並且具有所有(大多數)記錄集中管理的額外好處。對於那些仍然使用commons logging或log4j的人來說,它也可以不需要那些瘋狂的'if(log.isXxxEnabled()'調用... –

+0

我們也在一個Java項目中使用了這種模式,該模式對使用外部庫有極大的限制 - 它工作得很好,但多年來,爲這個超級基礎類添加另一個方法的誘惑是不可抗拒的,並且它變得非常龐大,我肯定會反對這種模式的不受歡迎的使用方式。相當先進。 – MaDa