Skip to content

Log4j2 JDBC Appender DriverManager write to SQLite FAIL. #2910

@life888888

Description

@life888888

Description

Log4j2 JDBC Appender DriverManager write to SQLite FAIL.

Configuration

Version: 2.21.1

Operating system: Ubuntu 20.04

JDK: OpenJDK Runtime Environment Temurin-21.0.3+9

Database: org.xerial sqlite-jdbc 3.46.0.0

Logs

DEBUG StatusLogger Acquiring JDBC connection from jdbc:sqlite:/home/demo/sqlite_data/demologs.db
DEBUG StatusLogger Loading driver class org.sqlite.JDBC
DEBUG StatusLogger DriverManagerConnectionSource getting connection for 'jdbc:sqlite:/home/demo/sqlite_data/demologs.db'
DEBUG StatusLogger DriverManagerConnectionSource acquired connection for 'jdbc:sqlite:/home/demo/sqlite_data/demologs.db': org.sqlite.jdbc4.JDBC4Connection@3359e339 (org.sqlite.jdbc4.JDBC4Connection@3359e339)
DEBUG StatusLogger Acquired JDBC connection org.sqlite.jdbc4.JDBC4Connection@3359e339
DEBUG StatusLogger Getting connection metadata org.sqlite.jdbc4.JDBC4Connection@3359e339
DEBUG StatusLogger Connection metadata org.sqlite.jdbc4.JDBC4DatabaseMetaData@4d08b6f8
DEBUG StatusLogger Connection supportsBatchUpdates: true
DEBUG StatusLogger Preparing SQL insert into logs (timestamp,loglevel,message,exception,thread) values (?,?,?,?,?)
DEBUG StatusLogger Prepared SQL insert into logs (timestamp,loglevel,message,exception,thread) values (?,?,?,?,?) 
 parameters=null
TRACE StatusLogger Appending SELECT ColumnConfig[1]: timestamp={ name=timestamp, layout=%d{yyyy-MM-dd HH:mm:ss}, literal=null, timestamp=false } 
TRACE StatusLogger Appending SELECT ColumnConfig[2]: loglevel={ name=loglevel, layout=%p, literal=null, timestamp=false } 
TRACE StatusLogger Appending SELECT ColumnConfig[3]: message={ name=message, layout=%m, literal=null, timestamp=false } 
TRACE StatusLogger Appending SELECT ColumnConfig[4]: exception={ name=exception, layout=%ex, literal=null, timestamp=false } 
TRACE StatusLogger Appending SELECT ColumnConfig[5]: thread={ name=thread, layout=%t, literal=null, timestamp=false } 
DEBUG StatusLogger Getting SQL metadata for table logs: select timestamp,loglevel,message,exception,thread from logs where 1=0
DEBUG StatusLogger SQL metadata: org.sqlite.jdbc4.JDBC4ResultSet@22a66e38
DEBUG StatusLogger Committing Connection org.sqlite.jdbc4.JDBC4Connection@3359e339
DEBUG StatusLogger Closing JDBC4PreparedStatement insert into logs (timestamp,loglevel,message,exception,thread) values (?,?,?,?,?) 
 parameters=null
DEBUG StatusLogger Closing JDBC4Connection org.sqlite.jdbc4.JDBC4Connection@3359e339
DEBUG StatusLogger Acquiring JDBC connection from jdbc:sqlite:/home/demo/sqlite_data/demologs.db
DEBUG StatusLogger Loading driver class org.sqlite.JDBC
DEBUG StatusLogger DriverManagerConnectionSource getting connection for 'jdbc:sqlite:/home/demo/sqlite_data/demologs.db'
DEBUG StatusLogger DriverManagerConnectionSource acquired connection for 'jdbc:sqlite:/home/demo/sqlite_data/demologs.db': org.sqlite.jdbc4.JDBC4Connection@4d69dcd0 (org.sqlite.jdbc4.JDBC4Connection@4d69dcd0)
DEBUG StatusLogger Acquired JDBC connection org.sqlite.jdbc4.JDBC4Connection@4d69dcd0
DEBUG StatusLogger Getting connection metadata org.sqlite.jdbc4.JDBC4Connection@4d69dcd0
DEBUG StatusLogger Connection metadata org.sqlite.jdbc4.JDBC4DatabaseMetaData@31d5ae6f
DEBUG StatusLogger Connection supportsBatchUpdates: true
DEBUG StatusLogger Preparing SQL insert into logs (timestamp,loglevel,message,exception,thread) values (?,?,?,?,?)
DEBUG StatusLogger Prepared SQL insert into logs (timestamp,loglevel,message,exception,thread) values (?,?,?,?,?) 
 parameters=null
TRACE StatusLogger Appending SELECT ColumnConfig[1]: timestamp={ name=timestamp, layout=%d{yyyy-MM-dd HH:mm:ss}, literal=null, timestamp=false } 
TRACE StatusLogger Appending SELECT ColumnConfig[2]: loglevel={ name=loglevel, layout=%p, literal=null, timestamp=false } 
TRACE StatusLogger Appending SELECT ColumnConfig[3]: message={ name=message, layout=%m, literal=null, timestamp=false } 
TRACE StatusLogger Appending SELECT ColumnConfig[4]: exception={ name=exception, layout=%ex, literal=null, timestamp=false } 
TRACE StatusLogger Appending SELECT ColumnConfig[5]: thread={ name=thread, layout=%t, literal=null, timestamp=false } 
DEBUG StatusLogger Getting SQL metadata for table logs: select timestamp,loglevel,message,exception,thread from logs where 1=0
DEBUG StatusLogger SQL metadata: org.sqlite.jdbc4.JDBC4ResultSet@39e261db
DEBUG StatusLogger Connection reestablished to FactoryData [connectionSource=jdbc:sqlite:/home/demo/sqlite_data/demologs.db, tableName=logs, columnConfigs=[{ name=timestamp, layout=%d{yyyy-MM-dd HH:mm:ss}, literal=null, timestamp=false }, { name=loglevel, layout=%p, literal=null, timestamp=false }, { name=message, layout=%m, literal=null, timestamp=false }, { name=exception, layout=%ex, literal=null, timestamp=false }, { name=thread, layout=%t, literal=null, timestamp=false }], columnMappings=[], immediateFail=false, retry=true, reconnectIntervalMillis=5000, truncateStrings=true]
DEBUG StatusLogger Committing Connection org.sqlite.jdbc4.JDBC4Connection@4d69dcd0
DEBUG StatusLogger Closing JDBC4PreparedStatement insert into logs (timestamp,loglevel,message,exception,thread) values (?,?,?,?,?) 
 parameters=null
DEBUG StatusLogger Closing JDBC4Connection org.sqlite.jdbc4.JDBC4Connection@4d69dcd0
ERROR StatusLogger Unable to write to database [JdbcManager{name=demo-db-appender, bufferSize=0, tableName=logs, columnConfigs=[{ name=timestamp, layout=%d{yyyy-MM-dd HH:mm:ss}, literal=null, timestamp=false }, { name=loglevel, layout=%p, literal=null, timestamp=false }, { name=message, layout=%m, literal=null, timestamp=false }, { name=exception, layout=%ex, literal=null, timestamp=false }, { name=thread, layout=%t, literal=null, timestamp=false }], columnMappings=[]}] for appender [demo-db-appender].
 org.apache.logging.log4j.core.appender.db.DbAppenderLoggingException: Failed to insert record for log event in JDBC manager: java.sql.SQLFeatureNotSupportedException [columnConfigs=[{ name=timestamp, layout=%d{yyyy-MM-dd HH:mm:ss}, literal=null, timestamp=false }, { name=loglevel, layout=%p, literal=null, timestamp=false }, { name=message, layout=%m, literal=null, timestamp=false }, { name=exception, layout=%ex, literal=null, timestamp=false }, { name=thread, layout=%t, literal=null, timestamp=false }], sqlStatement=insert into logs (timestamp,loglevel,message,exception,thread) values (?,?,?,?,?), factoryData=FactoryData [connectionSource=jdbc:sqlite:/home/demo/sqlite_data/demologs.db, tableName=logs, columnConfigs=[{ name=timestamp, layout=%d{yyyy-MM-dd HH:mm:ss}, literal=null, timestamp=false }, { name=loglevel, layout=%p, literal=null, timestamp=false }, { name=message, layout=%m, literal=null, timestamp=false }, { name=exception, layout=%ex, literal=null, timestamp=false }, { name=thread, layout=%t, literal=null, timestamp=false }], columnMappings=[], immediateFail=false, retry=true, reconnectIntervalMillis=5000, truncateStrings=true], connection=org.sqlite.jdbc4.JDBC4Connection@4d69dcd0, statement=insert into logs (timestamp,loglevel,message,exception,thread) values (?,?,?,?,?) 
 parameters=null, reconnector=null, isBatchSupported=true, columnMetaData={EXCEPTION=ColumnMetaData [schemaName=, catalogName=logs, tableName=logs, name=exception, nameKey=EXCEPTION, label=exception, displaySize=2147483647, type=12, typeName=TEXT, className=java.lang.Object, precision=0, scale=0, isStringType=true], MESSAGE=ColumnMetaData [schemaName=, catalogName=logs, tableName=logs, name=message, nameKey=MESSAGE, label=message, displaySize=2147483647, type=12, typeName=TEXT, className=java.lang.Object, precision=0, scale=0, isStringType=true], LOGLEVEL=ColumnMetaData [schemaName=, catalogName=logs, tableName=logs, name=loglevel, nameKey=LOGLEVEL, label=loglevel, displaySize=2147483647, type=12, typeName=VARCHAR, className=java.lang.Object, precision=10, scale=0, isStringType=true], THREAD=ColumnMetaData [schemaName=, catalogName=logs, tableName=logs, name=thread, nameKey=THREAD, label=thread, displaySize=2147483647, type=12, typeName=VARCHAR, className=java.lang.Object, precision=255, scale=0, isStringType=true], TIMESTAMP=ColumnMetaData [schemaName=, catalogName=logs, tableName=logs, name=timestamp, nameKey=TIMESTAMP, label=timestamp, displaySize=2147483647, type=93, typeName=TIMESTAMP, className=java.lang.Object, precision=0, scale=0, isStringType=false]}]
	at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:873)
	at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeThrough(JdbcDatabaseManager.java:900)
	at org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager.write(AbstractDatabaseManager.java:297)
	at org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender.append(AbstractDatabaseAppender.java:108)
	at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:161)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:134)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:125)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:89)
	at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:686)
	at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:644)
	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:620)
	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:556)
	at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:81)
	at org.apache.logging.log4j.core.Logger.log(Logger.java:163)
	at org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2165)
	at org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2119)
	at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2102)
	at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:1994)
	at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1859)
	at org.apache.logging.log4j.spi.AbstractLogger.info(AbstractLogger.java:1404)
	at com.example.HelloController.sayHello(HelloController.java:22)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.sql.SQLFeatureNotSupportedException
	at org.sqlite.jdbc4.JDBC4PreparedStatement.setNString(JDBC4PreparedStatement.java:36)
	at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:852)
	... 68 more
ERROR StatusLogger An exception occurred processing Appender demo-db-appender
 org.apache.logging.log4j.core.appender.db.DbAppenderLoggingException: Failed to insert record for log event in JDBC manager: java.sql.SQLFeatureNotSupportedException [columnConfigs=[{ name=timestamp, layout=%d{yyyy-MM-dd HH:mm:ss}, literal=null, timestamp=false }, { name=loglevel, layout=%p, literal=null, timestamp=false }, { name=message, layout=%m, literal=null, timestamp=false }, { name=exception, layout=%ex, literal=null, timestamp=false }, { name=thread, layout=%t, literal=null, timestamp=false }], sqlStatement=insert into logs (timestamp,loglevel,message,exception,thread) values (?,?,?,?,?), factoryData=FactoryData [connectionSource=jdbc:sqlite:/home/demo/sqlite_data/demologs.db, tableName=logs, columnConfigs=[{ name=timestamp, layout=%d{yyyy-MM-dd HH:mm:ss}, literal=null, timestamp=false }, { name=loglevel, layout=%p, literal=null, timestamp=false }, { name=message, layout=%m, literal=null, timestamp=false }, { name=exception, layout=%ex, literal=null, timestamp=false }, { name=thread, layout=%t, literal=null, timestamp=false }], columnMappings=[], immediateFail=false, retry=true, reconnectIntervalMillis=5000, truncateStrings=true], connection=org.sqlite.jdbc4.JDBC4Connection@4d69dcd0, statement=insert into logs (timestamp,loglevel,message,exception,thread) values (?,?,?,?,?) 
 parameters=null, reconnector=null, isBatchSupported=true, columnMetaData={EXCEPTION=ColumnMetaData [schemaName=, catalogName=logs, tableName=logs, name=exception, nameKey=EXCEPTION, label=exception, displaySize=2147483647, type=12, typeName=TEXT, className=java.lang.Object, precision=0, scale=0, isStringType=true], MESSAGE=ColumnMetaData [schemaName=, catalogName=logs, tableName=logs, name=message, nameKey=MESSAGE, label=message, displaySize=2147483647, type=12, typeName=TEXT, className=java.lang.Object, precision=0, scale=0, isStringType=true], LOGLEVEL=ColumnMetaData [schemaName=, catalogName=logs, tableName=logs, name=loglevel, nameKey=LOGLEVEL, label=loglevel, displaySize=2147483647, type=12, typeName=VARCHAR, className=java.lang.Object, precision=10, scale=0, isStringType=true], THREAD=ColumnMetaData [schemaName=, catalogName=logs, tableName=logs, name=thread, nameKey=THREAD, label=thread, displaySize=2147483647, type=12, typeName=VARCHAR, className=java.lang.Object, precision=255, scale=0, isStringType=true], TIMESTAMP=ColumnMetaData [schemaName=, catalogName=logs, tableName=logs, name=timestamp, nameKey=TIMESTAMP, label=timestamp, displaySize=2147483647, type=93, typeName=TIMESTAMP, className=java.lang.Object, precision=0, scale=0, isStringType=false]}]
	at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:873)
	at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeThrough(JdbcDatabaseManager.java:900)
	at org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager.write(AbstractDatabaseManager.java:297)
	at org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender.append(AbstractDatabaseAppender.java:108)
	at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:161)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:134)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:125)
	at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:89)
	at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:686)
	at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:644)
	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:620)
	at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:556)
	at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:81)
	at org.apache.logging.log4j.core.Logger.log(Logger.java:163)
	at org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2165)
	at org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2119)
	at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2102)
	at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:1994)
	at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1859)
	at org.apache.logging.log4j.spi.AbstractLogger.info(AbstractLogger.java:1404)
	at com.example.HelloController.sayHello(HelloController.java:22)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.sql.SQLFeatureNotSupportedException
	at org.sqlite.jdbc4.JDBC4PreparedStatement.setNString(JDBC4PreparedStatement.java:36)
	at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:852)
	... 68 more

Reproduction

log4j2.xml

<Configuration status="WARN">
    <Appenders>
        <!-- Console Appender Configuration -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
        </Console>
        <JDBC name="demo-db-appender" tableName="logs">
            <DriverManager>                
                <driverClassName>org.sqlite.JDBC</driverClassName>
                <connectionString>jdbc:sqlite:/home/demo/sqlite_data/demologs.db</connectionString>
            </DriverManager>
            <Column name="timestamp" pattern="%d{yyyy-MM-dd HH:mm:ss}"/>
            <Column name="loglevel" pattern="%p"/>
            <Column name="message" pattern="%m"/>
            <Column name="exception" pattern="%ex"/>
            <Column name="thread" pattern="%t"/>
        </JDBC>
    </Appenders>
    <Loggers>
        <!-- Root Logger Configuration -->
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
        <!-- Application Specific Logger Configuration -->
        <Logger name="com.example" level="info" additivity="false">
            <AppenderRef ref="demo-db-appender"/>
        </Logger>
        
        <Logger name="org.apache.logging.log4j" level="DEBUG">
            <AppenderRef ref="Console"/>
       </Logger>
        
    </Loggers>
</Configuration>

sqlite.sql

create SQLite db: demologs.db , execute sqlite.sql, create TABLE: logs

-- Creating the 'logs' table
CREATE TABLE logs (
    id INTEGER PRIMARY KEY AUTOINCREMENT,  -- Unique identifier for each log entry
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  -- Time the log entry was created
    loglevel VARCHAR(10),  -- Severity level of the log (e.g., INFO, WARN, ERROR)
    message TEXT,  -- Log message content
    exception TEXT,  -- Optional field to store exception details, if any
    thread VARCHAR(255)  -- Thread name that generated the log entry
);

-- Index on the timestamp column
CREATE INDEX idx_timestamp ON logs (timestamp);

Run Application , log

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
...
private static final Logger logger =  LogManager.getLogger(HelloController.class);

String msg ="Hello";

logger.info(">>>> Received request with msg: {}", msg);
...

Error Message:

java.sql.SQLFeatureNotSupportedException at org.sqlite.jdbc4.JDBC4PreparedStatement.setNString(JDBC4PreparedStatement.java:36) at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:852)

My JDBC App Test

  • PreparedStatement use setString can success write to SQLite
  • PreparedStatement use setNString will failed write to SQLite

Log4j2 JdbcDatabaseManager's use of setNString causes writing to SQLIte to fail. Is it possible to use setString for SQLIte instead of setNString?

String sql = "insert into logs (timestamp,loglevel,message,exception,thread) values (?,?,?,?,?)";

		try (Connection conn = DriverManager.getConnection(url)) {
			try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
				// Set the parameters
				Timestamp eventTime = new Timestamp(System.currentTimeMillis());

				pstmt.setTimestamp(1, eventTime);
				pstmt.setString(2, "INFO"); //loglevel
				pstmt.setString(3, "HELLO MSG"); // messag
				pstmt.setString(4, "MY EXCEPTION"); // exception
				pstmt.setString(5, "MY THREAD"); // thread

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions