【问题标题】:Spring-Boot: configure Log4j2 to use Spring-Boot DataSourceSpring-Boot:配置 Log4j2 以使用 Spring-Boot 数据源
【发布时间】:2018-06-14 17:43:55
【问题描述】:

我正在使用 Spring-Boot (1.5.9-RELEASE) 构建一个应用程序,并且我想将 log4j2 与它一起使用。

我想配置 log4j2 以使用 JDBC 连接记录到数据库表。

我的问题是我无法配置 log4j2 以使用我为 Spring-Boot 配置的 DataSource

我知道 log4j2 在 Spring-Boot 之前启动,所以我放了一些代码,在加载 Spring-Boot 之后,它有 log4j2重新配置自己。

我的问题是我无法从 Spring-Boot 获取 DataSource 的实例。

我对依赖注入不是很熟悉,但我假设因为我需要 Spring-Boot 来注入 DataSource,所以我创建的方式DBUtils 的实例不起作用。 但由于 log4j2 需要一个提供 Connection 的静态方法,我不知道如何让它工作。


问题

1) 谁能解释我如何让 log4j2 使用 Spring-Boot 的数据源? 还是我必须在 DBUtils 中创建一个新的连接池并让 log4j2 使用该池?


Spring-Boot 配置

我已包含 spring-boot-starter-log4j2 依赖项并排除了默认 Spring-Boot 记录器 spring-boot-starter-logging

application.properties 的一部分

spring.datasource.name=mainDataSource
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.url=---a valid JDBC URL---
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver

spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.test-on-borrow=true

logging.config=classpath:log4j2.xml

网址是有效的,我只是没有在网上发布:p

来自 log4j2.xml 的 JDBC Appender

<Jdbc
    name="DatabaseAppender"
    tableName="pws_logs">
    <ConnectionFactory
        class="com.test.utils.DBUtils"
        method="getConnection" />
    <Column
        name="log_date"
        isEventTimestamp="true" />
    <Column
        name="log_level"
        pattern="%-5level" />
    <Column
        name="logger"
        pattern="%40.40logger" />
    <Column
        name="line_num"
        pattern="%line" />
    <Column
        name="message"
        pattern="%message" />
    <Column
        name="throwable"
        pattern="%throwable"
        isClob="true" />
</Jdbc>

DBUtils

package com.test.utils;

import java.sql.Connection;

import javax.sql.DataSource;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class DBUtils {

    private static DBUtils dbUtils = null;

    @Autowired
    @Qualifier("mainDataSource")
    private DataSource dataSource;

    public static Connection getConnection() throws Exception {
        return DBUtils.getDBUtils().getSingleConnection();
    }

    private static DBUtils getDBUtils() {
        if (DBUtils.dbUtils == null) {
            DBUtils.dbUtils = new DBUtils();
        }

        return DBUtils.dbUtils;
    }

    private DataSource getDataSource() throws Exception {
        if (this.dataSource == null) {
            logger.error("Spring-Boot failed to inject database datasource.");
        }

        return this.dataSource;
    }

    private Connection getSingleConnection() throws Exception {
        try {
            return this.getDataSource().getConnection();
        } catch (Exception e) {
            logger.error("Failed to get database connection.", e);
            throw e;
        }
    }

}

入口点类

package com.test;

import javax.annotation.PostConstruct;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class PaymentWsApplication {

    private static Logger logger = null;

    @PostConstruct
    public static void initLogger() {
        final LoggerContext loggerContext = LoggerContext.getContext(false);
        loggerContext.reconfigure();

        PaymentWsApplication.logger = LogManager.getLogger(PaymentWsApplication.class);

        logger.info("********************** Application  started-up.");
    }

    public static void main(final String[] args) {
        SpringApplication.run(PaymentWsApplication.class, args);
    }

}

【问题讨论】:

  • 这有什么更新吗?我有类似的问题..
  • 我最近发现了一篇文章,展示了如何以编程方式添加 JdbcAppender。它要求您创建自己的连接池,但效果很好。 smasue.github.io/log4j2-spring-database-appender

标签: spring-boot dependency-injection log4j2


【解决方案1】:

我找到了解决此问题的方法。它并不完美,因为它不使用 Spring Boot 连接池,但它对我有用。

http://smasue.github.io/log4j2-spring-database-appender

步骤如下:

  1. 创建在@PostConstruction 期间执行以下步骤的@Configuration 类
  2. 从 Spring Boot 属性中提取数据库配置
  3. 以编程方式创建连接池
  4. 创建 JdbcAppender 并将其添加到根记录器。

【讨论】: