使用Spring Boot的Log4j2 JDBC Appender“错误无法写入数据库”

问题描述 投票:0回答:1

我有一个Sprint Boot应用程序。我想实现Log4j来登录到Sql Server。我已经尝试了互联网上的每个示例,但似乎无法破解。

我已经按照以下方式实施了。我的问题是我从Log4j收到错误:

“错误无法写入数据库”

在我的连接工厂中,我可以看到正在调用getDatabaseConnection()方法。我已通过在其中运行选择来验证该连接是否有效。但是,当Log4j开始使用它时,Log4j代码中的连接对象为null,因此会引发此错误。

-用法-

public class MyLogger  {

    public MyLogger() {}

    public static  Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

    public static void info(String message){
    logger.info(message);
    }
}

-连接工厂-

public class ConnectionFactory  {

    private static interface Singleton {
        final ConnectionFactory INSTANCE = new ConnectionFactory();
    }

    private final DataSource dataSource;

    private static Properties properties;
    static {
        properties = new Properties();
            ClassLoader cl = ConnectionFactory.class.getClassLoader();
            URL url = cl.getResource("config/application.properties");
            try {
            properties.load(new FileInputStream(url.getPath()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    private ConnectionFactory() {
        dataSource=getDataSource();
    }

    public DataSource getDataSource()
    {
        String logDbServer = properties.getProperty("logDb.server");
        String logDbInstance = properties.getProperty("logDb.instance");
        String logDbDatabase = properties.getProperty("logDb.database");
        String logDbUsername = properties.getProperty("logDb.username");
        String logDbPassword = properties.getProperty("logDb.password");

        Properties properties = new Properties();
        properties.setProperty("user", logDbUsername);
        properties.setProperty("password", logDbPassword);

        GenericObjectPool<PoolableConnection> pool = new GenericObjectPool<>();

        String conn = String.format("jdbc:sqlserver://%s;instanceName=%s;database=%s;encrypt=false;trustServerCertificate=true;loginTimeout=30;user=%s;password=%s"
                , logDbServer, logDbInstance, logDbDatabase, logDbUsername, logDbPassword);
        DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(conn, properties);

        new PoolableConnectionFactory(connectionFactory, pool, null, "SELECT 1",
                false, false, Connection.TRANSACTION_READ_COMMITTED);

        PoolingDataSource p= new PoolingDataSource(pool);
        return p;
    }

    public static Connection getDatabaseConnection() throws SQLException {
        Connection conn = Singleton.INSTANCE.dataSource.getConnection();
        return conn;
    }
}

-Log4j.xml-

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration name="com.online.sync" status="WARN">
    <Properties>
        <Property name="LOG_PATTERN">
            %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${hostName} --- [%15.15t] %-40.40c{1.} : %m%n%ex
        </Property>
    </Properties>
    <Appenders>

        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>

        <!-- Database Appender -->

        <JDBC name="DatabaseAppender" tableName="Log">
            <ConnectionFactory class="au.com.online.sync.service.ConnectionFactory" method="getDatabaseConnection" />
            <Column name="eventDate" isEventTimestamp="true" />
            <Column name="level" pattern="%level" />
            <Column name="logger" pattern="%logger" />
            <Column name="message" pattern="%message" />
            <Column name="exception" pattern="%ex{full}" />
        </JDBC>

        <!-- Async Logger for Info -->
        <Async name="InfoAsync">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="DatabaseAppender" />

        </Async>

        <!-- Async Logger for Error -->
        <Async name="ErrorAsync">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="DatabaseAppender" />
        </Async>

    </Appenders>
    <Loggers>
        <Logger name="error" level ="error">
            <AppenderRef ref="ErrorAsync"/>
        </Logger>
        <Logger name="debug" level="debug">
            <AppenderRef ref="Console" />
        </Logger>
        <Root level="info">
            <AppenderRef ref="InfoAsync"/>
        </Root>
    </Loggers>

</Configuration>
java spring-boot jdbc log4j
1个回答
0
投票

发生了一件有趣的事情。花了2周的时间后,我几乎放弃了-但我只是破解了它。

我决定将Spring Boot升级到最新版本-现在一切正常。我以前一直在使用2.0.3,而我刚刚更新到2.2.5。我认为使用Log4J的那个Spring Boot版本存在问题,或者通过升级一些本身已修复的依赖关系。

© www.soinside.com 2019 - 2024. All rights reserved.