Как использовать компонент Spring BoneCPDataSource в качестве источника данных для приложения JDBC Log4j 2?

Я хотел бы регистрировать сообщения log4j2 в реляционной базе данных.

Документация для приложения JDBC находится здесь. Я могу использовать в качестве поставщика подключения к базе данных следующие источники:

  • ConnectionFactory
  • Источник данных
  • DriverManager

но есть ли способ использовать компонент источника данных (com.jolbox.bonecp.BoneCPDataSource), который мы используем во всем приложении?


person user2148736    schedule 11.07.2013    source источник
comment
Вы не можете этого сделать. Log4j запускается до обработки контекстов Spring. Вы должны иметь возможность поставить BoneCPDataSource, но это будет другой экземпляр, чем ваш Spring.   -  person Sotirios Delimanolis    schedule 11.07.2013
comment
Я так понимаю, а что с ConnectionFactory? У вас есть пример? Не могли бы вы дать ответ?   -  person user2148736    schedule 11.07.2013
comment
У меня нет примера.   -  person Sotirios Delimanolis    schedule 11.07.2013


Ответы (1)


Вы можете сделать это за 4 шага (шаги 2 и 3 - это конфигурация log4j2 для веб-приложения):

Шаг 1. Создайте файл log4j2.xml (без приложения JDBC) и поместите его в папку WEB-INF

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">

    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>

    </Appenders>

    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>

</Configuration>

Шаг 2. Добавьте log4j2-web-2.x.jar в WEB-INF / lib.

Вот репозиторий maven, вы можете скачать jar из туда или скопируйте и вставьте зависимость в свой pom.xml, если вы используете maven.

Шаг 3. Настройте web.xml в зависимости от версии api сервлета

Дополнительные сведения см. В документации log4j2. Вот как вы настраиваете log4j в веб-приложении сервлета 2.5.

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">

<!-- Logg -->
<listener>
    <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
    <filter-name>log4jServletFilter</filter-name>
    <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>log4jServletFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>
<!-- /Logg -->

<!-- ... -->
</web-app>

Шаг 4. Создайте компонент Spring, вставьте компонент DataSource и динамически добавьте конфигурацию JDBC Appender в методе @PostConstruct

Вот пример кода (протестирован с log4j 2.1 и spring 3.5)

import java.sql.Connection;
import java.sql.SQLException;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
import org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource;
import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Component
public class LogUtils{

  @Autowired
  private DataSource dataSource;

  //inner class
  class Connect implements ConnectionSource {
    private DataSource dsource;
    public Connect(DataSource dsource) {
        this.dsource = dsource;
    }
    @Override
    public Connection getConnection() throws SQLException {
        return this.dsource.getConnection();
    }
    
  }

  public LogUtils() {
    System.out.println("LogUtils");     
  }

  @PostConstruct
  private void init(){
    System.out.println("init LogUtils");    
    final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
    final Configuration config = ctx.getConfiguration();
    ColumnConfig[] cc = {
            ColumnConfig.createColumnConfig(config, "date", null, null, "true", null, null),
            ColumnConfig.createColumnConfig(config, "level", "%level", null, null, null, null),
            ColumnConfig.createColumnConfig(config, "logger", "%logger", null, null, null, null),
            ColumnConfig.createColumnConfig(config, "message", "%message", null, null, null, null),
            ColumnConfig.createColumnConfig(config, "throwable", "%ex{short}", null, null, null, null),
            ColumnConfig.createColumnConfig(config, "salarie_id", "%X{SALARIE_ID}", null, null, null, null)
    } ;     
    Appender appender = JdbcAppender.createAppender("databaseAppender", "true", null, new Connect(dataSource), "0", "sicdb.bo_log", cc);
    appender.start();
    config.addAppender(appender);
    LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
    loggerConfig.addAppender(appender, null, null);
    ctx.updateLoggers();        
  }

  public DataSource getDataSource() {
    return dataSource;
  }

  public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
  }


}

** Ограничения: ссылка на документ **

Иногда приложениям необходимо настроить ведение журнала отдельно от фактической конфигурации. Log4j позволяет это, хотя имеет несколько ограничений:

  1. Если файл конфигурации будет изменен, конфигурация будет перезагружена, а внесенные вручную изменения будут потеряны.
  2. Для изменения текущей конфигурации требуется, чтобы все вызываемые методы (addAppender и addLogger) были синхронизированы. Таким образом, рекомендуемый подход к настройке конфигурации заключается в расширении одного из стандартных классов конфигурации, переопределении метода настройки, чтобы сначала выполнить super.setup (), а затем добавить пользовательские приложения, фильтры и LoggerConfigs в конфигурацию, прежде чем она будет зарегистрирована для использовать.
person Mohamed Ramrami    schedule 02.06.2015