Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the Spring dataSource in a logback DBAppender

I have a webapp that uses Spring to setup a connection-pooled datasource like so:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driverClassName}" />
    <property name="jdbcUrl" value="${jdbc.url}" />
    <property name="user" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />

The app also uses logback for logging events directly to the database. Logback is configured in a logback.xml file with a DBAppender:

  <appender name="eventsDB" class="ch.qos.logback.classic.db.DBAppender">
    <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
      <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <driverClass>${jdbc.driverClassName}</driverClass>
        <jdbcUrl>${jdbc.url}</jdbcUrl>
        <user>${jdbc.username}</user>
        <password>${jdbc.password}</password>
      </dataSource>
    </connectionSource>
  </appender>

As you can see we're setting up the dataSource twice, and requiring separate property substitutions in each case. It would be far better to simply let Spring create the dataSource and pass it off to the logback DBAppender.

Can anyone suggest the best way to do this?

like image 673
JMB Avatar asked Oct 18 '13 21:10

JMB


1 Answers

One option is to configure it programmatically as a bean:

@Bean
public DBAppender dbAppender(DataSource dataSource){
    DBAppender dbAppender = new DBAppender();
    DataSourceConnectionSource connectionSource = new DataSourceConnectionSource();
    connectionSource.setDataSource(dataSource);
    connectionSource.start();
    dbAppender.setConnectionSource(connectionSource);
    dbAppender.start();

    LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
    Logger logger = loggerContext.getLogger("ROOT");
    logger.addAppender(dbAppender);

    return dbAppender;
}

This of course means that it will not log any events which happened before this bean was created.

like image 144
jihor Avatar answered Oct 31 '22 18:10

jihor