Hi, I am trying to log messages to a database by adding a jdbc appender to the log4j xml file and adding the appender to the root logger and I am unable to get it to work. There are no messages from Servoy indicating why it is failing. Is there any kind of sample solution or resource you can point me to to help get this configured or debug what the issue is?
If your logging fails it doesn’t show up in the servoy-log or under /var/log/tomcat/… but rather in the syslog / journal.
If you are on a linux-system, do you see errors in /var/log/syslog or in the output of sudo journalctl -u tomcat9
If somethin goes wrong on our side with gelf it looks like this:
Dec 18 21:56:19 bpc3-test tomcat9[23424]: 2024-12-18T21:56:19.265634034Z ServoyServerScheduler-1-thread-2 ERROR An exception occurred processing Appender grayloggelf org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to TCP:192.168.1.202:12201: socket not available
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.net.TcpSocketManager.write(TcpSocketManager.java:264)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.appender.OutputStreamManager.write(OutputStreamManager.java:202)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.writeByteArrayToManager(AbstractOutputStreamAppender.java:236)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.appender.SocketAppender.directEncodeEvent(SocketAppender.java:598)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:220)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:211)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:160)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:133)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:124)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:88)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:705)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:663)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:639)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:575)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:92)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.core.Logger.log(Logger.java:169)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2906)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2859)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2841)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:2625)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:2373)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at org.apache.logging.slf4j.Log4jLogger.warn(Log4jLogger.java:233)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at com.servoy.j2db.server.persistence.Zs.Za(Zs.java:31)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at com.servoy.j2db.server.persistence.Zs.loadServerSettings(Zs.java:76)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at com.servoy.j2db.server.persistence.Zc.Za(Zc.java:37)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at com.servoy.j2db.server.persistence.Zc.getServerSettings(Zc.java:614)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at com.servoy.j2db.server.persistence.Zn.getSettings(Zn.java:120)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at com.servoy.j2db.server.main.Zq.run(Zq.java:19)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
Dec 18 21:56:19 bpc3-test tomcat9[23424]: at java.base/java.lang.Thread.run(Thread.java:1583)
Do you see something similar on your system? Perhaps in the event viewer on windows?
I am testing on my local machine for now. I searched and I can’t find any relevant log files in the file system or in the windows event viewer.
I was able to get a log file(showed up under servoyInstall/developer folder) be setting the “dest” attribute in the xml Configuration element. Initially I got the following error “ERROR StatusConsoleListener JNDI must be enabled by setting log4j2.enableJndiJdbc=true”. After setting the enableJndiJdbc attribute I am getting the following error “ERROR StatusConsoleListener No ConnectionSource provided
ERROR StatusConsoleListener 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’”
So looks like I need to properly define the connection to the database. If I encounter any roadblocks doing this I will post another reply.
Thanks,
I am getting the following error, " JDBC connection not available". I can’t figure out what is wrong with my connection. I am logging to a database with a single column, level.
org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to JDBC Manager 'JdbcManager{name=dbAppender, bufferSize=1, tableName=application_logs, columnConfigs=[], columnMappings=[ColumnMapping [name=level, source=null, literalValue=null, parameter=null, type=class java.lang.String, layout=%level]]}': JDBC connection not available [columnConfigs=[], sqlStatement=insert into application_logs (level) values (?), factoryData=FactoryData [connectionSource=jdbc:postgresql://dev.myroute.amazonaws.com:100/dbname, tableName=application_logs, columnConfigs=[], columnMappings=[ColumnMapping [name=level, source=null, literalValue=null, parameter=null, type=class java.lang.String, layout=%level]], immediateFail=false, retry=true, reconnectIntervalMillis=5000, truncateStrings=true], connection=null, statement=null, reconnector=Reconnector [latch=java.util.concurrent.CountDownLatch@7a6a9242[Count = 0], shutdown=false], isBatchSupported=false, columnMetaData=null]
Here is my XML
<JDBC name="dbAppender" tableName="application_logs" bufferSize="1">
<DriverManager
connectionString="jdbc:postgresql://dev.myroute.amazonaws.com:100/dbname"
driverClassName="org.postgresql.Driver"
password="mypassword"
userName="myuser">
</DriverManager>
<ColumnMapping name="level" pattern="%level"/>
</JDBC>
Any suggestions would be appreciated.
I got it to work, somehow. I’m not sure what’s wrong on your side, I had this error you had when I had the configuration of the connection wrong, so I’m not sure, the port of 100 seems awful low (below 1024), so that could be an issue, or there are problems with the ids on the postgres side:
database on PostgreSQL:
create sequence if not exists public.error_id AS INTEGER increment by 1 minvalue 1;
alter sequence public.error_id owner to postgres;
create table error_log
(
error_log_id integer default nextval('error_id'::regclass) not null
primary key,
level varchar(255),
message varchar(10000),
clientid varchar(255),
solution varchar(255),
username varchar(255),
useruuid varchar(255),
clienttype varchar(255),
hostname varchar(255),
hostaddress varchar(255),
sessionkey varchar(255),
log_datetime timestamp
);
alter table error_log
owner to postgres;
log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration debug="false" status="INFO">
<Appenders>
<Console name="stdout" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p [%t] %c - %m%n" />
</Console>
<DebugConsole name="debugconsole">
<PatternLayout pattern="%p %c - %m" />
</DebugConsole>
<SlidingWindow name="configservlet" windowSize="1000" dateTimeFormat="yyyy-MM-dd HH:mm" />
<RollingFile name="file" fileName="${web:attr.servoy.application_server.dir}/servoy_log.txt" filePattern="${web:attr.servoy.application_server.dir}/servoy_log-%i.txt.zip" immediateFlush="true" append="true">
<Policies>
<SizeBasedTriggeringPolicy size="10MB" />
</Policies>
<PatternLayout pattern="%d %p [%t] %c - %m [${servoy:clientid:-} ${servoy:solution:-}]%n" />
</RollingFile>
<Async name="asyncfile">
<AppenderRef ref="file" />
</Async>
<JDBC name="dbAppender" tableName="error_log" bufferSize="1">
<DriverManager
connectionString="jdbc:postgresql://192.168.1.196:5432/bauprocheck_errors"
driverClassName="org.postgresql.Driver"
password="myPassword"
userName="myUsername">
</DriverManager>
<ColumnMapping name="level" pattern="%level"/>
<ColumnMapping name="message" pattern="%mm%ex%n"/>
<ColumnMapping name="log_datetime" type="java.sql.Timestamp" pattern="%d"/>
<ColumnMapping name="clientid" pattern="${servoy:clientid:-(NO CLIENTID)}"/>
<ColumnMapping name="solution" pattern="${servoy:solution:-(NO SOLUTION)}"/>
<ColumnMapping name="username" pattern="${servoy:username:-(NO USERNAME)}"/>
<ColumnMapping name="useruuid" pattern="${servoy:useruuid:-(NO USERUUID)}"/>
<ColumnMapping name="clienttype" pattern="${servoy:clienttype:-(NO CLIENTTYPE)}"/>
<ColumnMapping name="hostname" pattern="${servoy:hostname:-(NO HOSTNAME)}"/>
<ColumnMapping name="hostaddress" pattern="${servoy:hostaddress:-(NO HOSTADDRESS)}"/>
<ColumnMapping name="sessionkey" pattern="${servoy:sessionkey:-(NO SESSIONKEY)}"/>
</JDBC>
</Appenders>
<Loggers>
<Logger name="org.sablo.BrowserConsole" level="INFO">
<AppenderRef ref="dbAppender" />
</Logger>
<Logger name="com.servoy.j2db.util.Debug" level="WARN" />
<Logger name="com.servoy.j2db.dataprocessing.editedRecords" level="WARN" />
<Logger name="persistence.Server" level="WARN" />
<Logger name="com.servoy.j2db.persistence.XMLInMemoryImportHandlerVersions11AndHigher" level="WARN" />
<Logger name="com.servoy.j2db.persistence.XMLExporter" level="WARN" />
<Logger name="com.servoy.j2db.server" level="WARN" />
<Logger name="WebServer" level="WARN" />
<Logger name="com.servoy.j2db.datasource" level="WARN" />
<Logger name="ClientManager" level="WARN" />
<Logger name="org.sablo" level="WARN" />
<Logger name="org.sablo.specification.property" level="WARN" />
<Logger name="org.sablo.websocket" level="WARN" />
<Logger name="com.servoy.j2db.server.ngclient.property.types" level="WARN" />
<Logger name="org.apache.wicket" level="WARN" />
<Logger name="org.apache.wicket.request.target.component.listener.BehaviorRequestTarget" level="ERROR" />
<Logger name="com.servoy.automation.jsunit.runner.ImportClient" level="INFO" />
<Logger name="com.servoy.automation.jsunit.SolutionJSTestSuite" level="INFO" />
<Logger name="logger.org.hibernate.dialect.function.TemplateRenderer.level" level="ERROR" />
<Root level="WARN">
<AppenderRef ref="dbAppender" />
<AppenderRef ref="asyncfile" />
<AppenderRef ref="configservlet" />
<AppenderRef ref="debugconsole" />
</Root>
</Loggers>
</Configuration>
What didn’t work for me is the timestam-column, which only get’s transfered as sting, so I commented it for the time being, error was
> Caused by: org.postgresql.util.PSQLException: Can’t infer the SQL type to use for an instance of java.util.Date. Use setObject() with an explicit Types value to specify the type to use.
Fixed that, timestamps get logged correctly, correct type is java.sql.Timestamp
Hope this helps you a bit along.
I still can’t get it to work. I noticed if I set the ignoreExceptions property on the JDBC element to false I get the following error in the log. I also get the same error if I use an invalid database connection so I don’t know if this is the root cause or not.
Caused by: java.sql.SQLException: The DriverManagerConnectionSource could not load the JDBC driver org.postgresql.Driver: java.lang.ClassNotFoundException: org.postgresql.Driver cannot be found by org.apache.logging.log4j.core_2.20.0
at org.apache.logging.log4j.core.appender.db.jdbc.AbstractDriverManagerConnectionSource.loadDriver(AbstractDriverManagerConnectionSource.java:202)
at org.apache.logging.log4j.core.appender.db.jdbc.AbstractDriverManagerConnectionSource.loadDriver(AbstractDriverManagerConnectionSource.java:184)
at org.apache.logging.log4j.core.appender.db.jdbc.AbstractDriverManagerConnectionSource.getConnection(AbstractDriverManagerConnectionSource.java:146)
at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.connectAndPrepare(JdbcDatabaseManager.java:592)
at org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.connectAndStart(JdbcDatabaseManager.java:613)
... 26 more
Caused by: java.lang.ClassNotFoundException: org.postgresql.Driver cannot be found by org.apache.logging.log4j.core_2.20.0
at org.eclipse.osgi.internal.loader.BundleLoader.generateException(BundleLoader.java:541)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:536)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:416)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:168)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Unknown Source)
at org.apache.logging.log4j.core.appender.db.jdbc.AbstractDriverManagerConnectionSource.loadDriver(AbstractDriverManagerConnectionSource.java:200)
... 30 more
I don’t know why it wouldn’t be able to find the driver. I tried putting the postgre jar in various plugin folders and nothing worked. Do you have any ideas?
no really, i only found a posgresql.jar in the application dir of the add-server under lib, which should be correct according to a cursory glance at google / stackoverflow. Perhaps someone at Servoy has more infos about this?
Alternatively, which versions (servoy, tomcat, os) are you using?
We are using Servoy 2023.9.1.3903 and Tomcat 9
this will not work in developer
But i guess that is also not something you really want?
What you really want is that it works like that deploy time?
In a WAR you should have that class not found problem as long as you have the logging jars and the postgresql.jar in the WEB-INF/lib dir (which is default)
But in a developer this will not work because the log4j jdbc appender will not be able to find the postgresql driver on the classpath. those are handled in different classloaders.
I was able to get it working on a local tomcat instance.
Thanks for all your help guys!