Почему при настройке журнала из XML DriverManagerConnectionSource не запускается, что приводит к сбоям подключения?

После обновления до slf4j 2.0.13, logback 1.5.6 и logback-db 1.2.11.1 конфигурация XML для logback, которая раньше работала нормально, дает сбой. Насколько я могу судить, платформа пытается инициализировать средства ведения журнала до инициализации DriverManagerConnectionSource. Я подозреваю, что я пропустил новое требование к конфигурации.

Я сравнил файл конфигурации с примером DBAppender по адресу https://logback.qos.ch/manual/appenders.html

Когда я отслеживаю исходный код, DBAppenderBase.start() содержит следующую строку:

DBUtil.getDialectFromCode(connectionSource.getSQLDialectCode());

ConnectionSource (экземпляр DriverManagerConnectionSource) содержит значение null в качестве SQLDialectCode. Если копнуть глубже, то DriverManagerConnectionSource должен установить SQLDialectCode в своем методе start() на основе URL-адреса, указанного в теге ConnectionSource.url. Я использовал точку останова в отладчике, чтобы убедиться, что DriverManagerConnectionSource.start() никогда не вызывается.

Я не могу быть единственным человеком, который когда-либо использовал DBAppender, поэтому мне интересно, какие требования к конфигурации изменились с тех пор, как мы в последний раз обновляли наши ссылки POM для входа в систему.

пом.xml:

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.13</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.5.6</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.5.6</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
            <version>1.4.14</version>
        </dependency>
        <dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
            <version>7.4</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback.db</groupId>
            <artifactId>logback-classic-db</artifactId>
            <version>1.2.11.1</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback.db</groupId>
            <artifactId>logback-core-db</artifactId>
            <version>1.2.11.1</version>
        </dependency>

Java-код:

package com.me.myApp;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@WebListener
public class MyContextListener implements ServletContextListener  {
    
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.setProperty("my.web.container", sce.getServletContext().getServerInfo());
    
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        logger.info("Shutting down.");
    }

}

XML-конфигурация:

<?xml version = "1.0" encoding = "UTF-8"?>
<configuration scan = "true" scanPeriod = "30 seconds">

    <contextListener class = "ch.qos.logback.classic.jul.LevelChangePropagator">
        <resetJUL>true</resetJUL>
    </contextListener>
    
    <property file = "/my/properties/my-datastore.properties"/>
    <!-- To enable JMX Management -->
    <jmxConfigurator />
  
    <!-- Notification Appender -->
    <appender name = "me.notification.appender" class = "ch.qos.logback.classic.db.DBAppender">
        <filter class = "ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <connectionSource class = "ch.qos.logback.core.db.DriverManagerConnectionSource">
            <driverClass>org.postgresql.Driver</driverClass>
            <url>jdbc:postgresql://me.myapp.com:5432/mydb</url>
            <user>postgres</user>
            <password>postgres</password>
        </connectionSource>
        <encoder>
            <pattern>%-5level %logger{0} - %msg%n</pattern>
            <pattern>Id : %X{Id},Name : %X{Name},ModelName : %X{ModelName} %thread %date{ISO8601} %-5level %logger{5} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name = "me.notification" level = "info">
        <appender-ref ref = "me.notification.appender" />
        <appender-ref ref = "logFile" />
    </logger>
</configuration>

Код журнала регистрации, который не делает того, что я ожидаю, исходя из этой конфигурации XML:

public abstract class DBAppenderBase<E> extends UnsynchronizedAppenderBase<E> {

    protected ConnectionSource connectionSource;
    protected boolean cnxSupportsGetGeneratedKeys = false;
    protected boolean cnxSupportsBatchUpdates = false;
    protected SQLDialect sqlDialect;

    protected abstract Method getGeneratedKeysMethod();

    protected abstract String getInsertSQL();

    @Override
    public void start() {

        if (connectionSource == null) {
            throw new IllegalStateException("DBAppender cannot function without a connection source");
        }

        sqlDialect = DBUtil.getDialectFromCode(connectionSource.getSQLDialectCode());
        if (getGeneratedKeysMethod() != null) {
            cnxSupportsGetGeneratedKeys = connectionSource.supportsGetGeneratedKeys();
        } else {
            cnxSupportsGetGeneratedKeys = false;
        }
        cnxSupportsBatchUpdates = connectionSource.supportsBatchUpdates();
        if (!cnxSupportsGetGeneratedKeys && (sqlDialect == null)) {
            throw new IllegalStateException(
                            "DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method *and* without a specific SQL dialect");
        }
...
        // all nice and dandy on the eastern front
        super.start();
    }

Измените это на <configuration debug = "true" scan = "true" scanPeriod = "30 seconds"> Что происходит? Код возврата, который не делает того, что я ожидаю, исходя из этой конфигурации XML: я не вижу там никакого входа в систему...

g00se 22.05.2024 23:11

Сообщение об ошибке: «DBAppender не может работать, если драйвер JDBC не поддерживает метод getGeneratedKeys и без определенного диалекта SQL». Регистратору не удается инициализироваться, поэтому приложение вообще не запускается. Этот фрагмент кода минимально воспроизводит основную проблему: DBAppender инициализируется перед DriverManagerConnectionSource.

pojo-guy 23.05.2024 17:32

Обнаруженные проблемы (множественное число): загрузчик классов, eclipse + tomcat, перспектива отладки Eclipse и ложный файл конфигурации был зарегистрирован в пути к классам. Logback не очень дружелюбен, когда он не может начать работу.

pojo-guy 23.05.2024 21:24
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Было несколько взаимодействующих проблем, каждая из которых (индивидуально) приводила к одному и тому же симптому (DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method and without a specific SQL dialect), который мне удалось отследить с помощью отладчика.

  1. Была ссылка на неправильный файл logback.xml. В пути к классам был фиктивный файл.
  2. Когда плохой файл конфигурации был удален, загрузчик классов не нашел драйвер jdbc. Очистка Maven + перестройка Maven + сборка Eclipse, а затем перспектива сброса Eclipse.
  3. Когда использовался правильный файл конфигурации и загрузчик классов находил драйвер jdbc, пароль jdbc был неверным, поэтому соединение не было получено.

Другие вопросы по теме