对于某些第三方库,Logback默认为调试模式

时间:2013-07-12 09:34:08

标签: java java-ee logback

我们使用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目录中。

在此更改之后,hibernate和http-client库的日志记录默认为调试模式,因此正在进行大量日志记录。根记录器具有INFO日志级别,并且没有为hibernate和amp;定义的特定记录器。 http客户端库。

如果我还原此更改,即删除web.xml中的jndi条目并将配置文件重命名为logback.xml,则只会按预期记录INFO日志。

关于可能出现什么问题的任何建议?

感谢。

更新

在进一步排除故障后,我发布了hibernate和apache客户端库使用初始化时创建的默认记录器上下文。此记录器上下文的根日志级别设置为DEBUG。 我们使用JNDI作为上下文选择器。

奇怪的是,当ConnectionManager类(hibernate类 - org.hibernate.jdbc.ConnectionManager)尝试实例化记录器时,在运行时找不到上下文名称。 Logger实例创建调用ContextJNDISelector.getLoggerContext()方法。此方法执行JNDI查找但未找到该条目。

我通过在servlet上下文侦听器中生成一个线程来进一步排除故障,每隔3秒打印一次JNDI条目(java:comp / env / logback / context-name)。来自线程的日志表明JNDI条目始终存在。

当被ContextJNDISelector查询时,在JNDI中找不到contextName的任何想法?

1 个答案:

答案 0 :(得分: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);
    }