Skip to content

JdbcAppender using DataSourceConnectionSource could not append log event in embedded WAS #3128

Open
@minseo300

Description

@minseo300

Description

I'm trying to configure JdbcAppender using DataSourceConnectionSource(jndi) in embedded Tomcat(I create application with Springboot)

I defined data source in application.yml, and using jndi-name in log4j2.xml.

[log4j2.xml]

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
    <Appenders>
        <JDBC name="databaseAppender" tableName="logging_event">
            <DataSource jndiName="jndi/mysql" />
            <Column name="log_event_date" pattern="%d" />
            <Column name="logger_name" pattern="%c" />
            <Column name="log_level" pattern="%p"/>
            <Column name="thread_name" pattern="%t"/>
            <Column name="message" pattern="%message" isClob="true"/>
        </JDBC>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="databaseAppender"/>
        </Root>
    </Loggers>
</Configuration>

[jndi configuration class]

@Configuration
public class JndiResource {
    @Bean
    TomcatServletWebServerFactory tomcatFactory() {
        return new TomcatServletWebServerFactory() {
            @Override
            protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
                tomcat.enableNaming();
                return super.getTomcatWebServer(tomcat);
            }

            @Override
            protected void postProcessContext(Context context) {
                context.getNamingResources().addResource(getResource());
            }
        };
    }

    public ContextResource getResource() {
        ContextResource resource = new ContextResource();
        resource.setName("jndi/mysql");
        resource.setType("javax.sql.DataSource");
        resource.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
        resource.setProperty("url", "jdbc:mysql://localhost:3306/logging_test");
        resource.setProperty("username", "root");
        resource.setProperty("password", "1234");
        return resource;
    }
}

As I analyzed JdbcAppender class, ConnectionSource in JdbcAppender is required, so if ConnectionSource is null, the exception is thrown while configuring log4j2 configuration.

In Spring boot application, log4j2 configuration is configured before embedded Tomcat loading jndi resource, so JdbcAppender isn't created and unable to locate appender for logger config.

Is there any plan to support log4j2 JdbcAppender with DataSourceConnectionSource with embedded WAS?

Configuration

**Version: 2.17.1

**Operating system: any

**JDK: 1.8

Logs

2024-10-28 15:17:16,545 main ERROR No ConnectionSource provided: connectionSource
2024-10-28 15:17:16,546 main ERROR Could not create plugin of type class org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender for element JDBC org.apache.logging.log4j.core.config.ConfigurationException: Arguments given for element JDBC are invalid: field 'connectionSource' has invalid value 'null'
	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.injectFields(PluginBuilder.java:208)
	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:121)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:1002)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:942)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:934)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:552)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:241)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:288)
	at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:618)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:691)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:708)
	at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.reinitialize(Log4J2LoggingSystem.java:207)
	at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:73)
	at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:60)
	at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.initialize(Log4J2LoggingSystem.java:163)
	at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:312)
	at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:281)
	at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:239)
	at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:216)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131)
	at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:82)
	at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:63)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117)
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:111)
	at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:62)
	at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:375)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:333)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1340)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1329)
	at org.example.MainApplication.main(MainApplication.java:9)

2024-10-28 15:17:16,546 main ERROR Null object returned for JDBC in Appenders.
2024-10-28 15:17:16,547 main ERROR Unable to locate appender "databaseAppender" for logger config "root"

Reproduction

[An isolated test reproducing the test.
JUnit tests similar to the ones in the code base are extremely appreciated.]

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    To triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions