Логбэк по умолчанию в режиме отладки для некоторых сторонних библиотек

Мы используем slf4j и logback для входа в наше веб-приложение java ee. Недавно, чтобы переместить эти библиотеки в общее место на сервере приложений Glassfish (в частности, в каталог Glassfish\lib), мы внесли несколько изменений в конфигурацию. Мы внесли изменения в файл web.xml, чтобы добавить записи JNDI и переименовали logback.xml в logback-<context-name>.xml, как указано в здесь. . logback-<context-name>.xml находится в каталоге WEB-INF\classes.

После этого изменения ведение журнала для библиотек hibernate и http-client по умолчанию переходит в режим отладки, и, следовательно, ведется много журналов. Корневой регистратор имеет уровень журнала INFO, и для библиотек hibernate и http-client не определены специальные регистраторы.

Если я отменю это изменение, т. е. удалю запись jndi в web.xml и переименую файл конфигурации в logback.xml, как и ожидалось, будут регистрироваться только журналы INFO.

Любые предложения о том, что может быть проблемой?

Спасибо.

Обновить

При дальнейшем устранении неполадок я сообщил, что клиентские библиотеки hibernate и apache используют контекст регистратора по умолчанию, созданный во время инициализации. Этот контекст средства ведения журнала имеет корневой уровень журнала, установленный на DEBUG. Мы используем JNDI в качестве селектора контекста.

Странно, что имя контекста не найдено во время выполнения, когда класс ConnectionManager (класс hibernate — org.hibernate.jdbc.ConnectionManager) пытается создать экземпляр регистратора. Создание экземпляра регистратора вызывает метод ContextJNDISelector.getLoggerContext(). Этот метод выполняет поиск JNDI, но не находит запись.

Я устранил неполадки, создав поток в прослушивателе контекста сервлета для печати записи JNDI (java:comp/env/logback/context-name) каждые 3 секунды. В журналах потока указано, что записи JNDI всегда присутствуют.

Любые идеи, почему contextName не найдено в JNDI при запросе ContextJNDISelector?


person Andy Dufresne    schedule 12.07.2013    source источник


Ответы (1)


Это казалось проблемой, потому что приложение использовало 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);
    }


person Andy Dufresne    schedule 03.09.2013