2013-07-12 103 views
2

我們使用slf4j和logback登錄我們的java ee web應用程序。最近,爲了將這些庫移到glassfish應用服務器的一個常見位置(特別是glassfish \ lib目錄),我們做了一些配置更改。我們在web.xml文件中進行了更改以添加JNDI條目,並將logback.xml更名爲logback-<context-name>.xml,如here中所述。 logback-<context-name>.xml被放置在WEB-INF \ classes目錄中。Logback默認爲某些第三方庫的調試模式

在此更改之後,對hibernate和http-client庫的日誌記錄默認爲調試模式,因此有很多日誌記錄正在完成。根記錄器具有INFO日誌級別,並且沒有爲hibernate & http-client庫定義的特定記錄器。

如果我恢復此更改,即刪除web.xml中的jndi條目並將配置文件重命名爲logback.xml,則只會按預期方式記錄INFO日誌。

關於可能是什麼問題的任何建議?

謝謝。

更新

在故障排除進一步我發佈了Hibernate和Apache的客戶端庫使用在初始化時創建的默認記錄器上下文。此記錄器上下文將根日誌級別設置爲DEBUG。 我們使用JNDI作爲上下文選擇器。

奇怪的是,當ConnectionManager類(hibernate類 - org.hibernate.jdbc.ConnectionManager)嘗試實例化記錄器時,在運行時未發現上下文名稱。記錄器實例創建調用ContextJNDISelector.getLoggerContext()方法。此方法執行JNDI查找,但未找到條目。

我通過在servlet上下文偵聽器中產生線程來每3秒打印一次JNDI條目(java:comp/env/logback/context-name),從而進一步排除故障。線程中的日誌表明JNDI條目始終存在。

當通過ContextJNDISelector查詢時,任何想法爲什麼contextName在JNDI中找不到?

回答

0

這似乎是一個問題,因爲應用程序使用了EJB。應用程序服務器(glassfish)在實際設置日誌上下文之前加載了EJB。因此,一些庫的日誌消息被記錄在DEBUG級別下。在記錄器周圍使用包裝類解決了問題。包裝類將記錄器創建延遲至第一次使用。

 

public class LogWrapper { 
    private Class loggerClass; 
    private Logger logger; 

    public LogWrapper(Class loggerClass) { 
     this.loggerClass = loggerClass; //lazy logging context creation (to avoid issues with static instances in EJBs which get loaded on startup before logging ctx name is actually set) 
    } 

    /** 
    * For lazy init of logger, on first actual use, so the logger context will be correctly set even when used by EJBs (loaded by classloader too soon, before logging context is actually set) 
    */ 
    private Logger getLogger() { 
     if (logger == null) { 
      logger = LoggerFactory.getLogger(loggerClass); 
      loggerClass = null; 
     } 
     return logger; 
    } 

    public void info(String message) { 
     getLogger().info(message); 
    }