Can I disable c3p0 from logging to System.err?
Asked Answered
M

5

8

According to the c3p0 documentation, you can manually specify where logs should go, whether through JDK 1.4 logging, Log4j, or through System.out. I'm running SLF4J, so I've included org.slf4j.jul-to-slf4j and call SLF4JBridgeHandler.install() in my application to force all Java util logging to go through SLF4J. Additionally, I've included the following property in my c3p0.properties file:

com.mchange.v2.log.MLog = com.mchange.v2.log.jdk14logging.Jdk14MLog

This, according to the documentation, will force c3p0 to log to JDK 1.4 logging, which in turn will log things out to SLF4J. This does work somewhat, but I'm still seeing some logs hit System.err:

Example 1:

17:24:32.648 [main] INFO  com.mchange.v2.log.MLog - MLog clients using java 1.4+ standard logging.
Jul 27, 2011 5:24:32 PM com.mchange.v2.log.MLog <clinit>
INFO: MLog clients using java 1.4+ standard logging.
Jul 27, 2011 5:24:32 PM com.mchange.v2.c3p0.C3P0Registry banner
INFO: Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
17:24:32.754 [main] INFO  com.mchange.v2.c3p0.C3P0Registry - Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]

Lines 1 and 6 above are written to SLF4J, the others are written to System.err.

Example 2:

Jul 27, 2011 5:24:33 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> z8kflt8huk1hupkhyfms|13b33a0e, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> org.sqlite.JDBC, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> z8kflt8huk1hupkhyfms|13b33a0e, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:sqlite:/tmp/floodstream.db, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 1800, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 10, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
17:24:33.603 [main] INFO  com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> z8kflt8huk1hupkhyfms|13b33a0e, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> org.sqlite.JDBC, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> z8kflt8huk1hupkhyfms|13b33a0e, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:sqlite:/tmp/floodstream.db, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 1800, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 10, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]

The first two lines above are logged to System.err, which doesn't make any sense at all, since it's also logging to SLF4J as intended.

Is there a way for me to disable logging to System.err from c3p0?

Mignonne answered 28/7, 2011 at 0:36 Comment(2)
have you tried using log4j rather than JUL?Finger
@matt b, make that an answer and you win ;)Mignonne
F
9

I would suggest giving the log4j binding a try, and configuring c3p0 to use that.

java.util.logging is one of the more confusing things I've ever worked with.

Finger answered 28/7, 2011 at 1:45 Comment(0)
R
3

Adding the following depedency takes care of some of the problem, however not all of it.

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
    <version>1.7.2</version><!-- Or whatever you want/need... -->
</dependency>

In addition to that, you need to bypass the irritating logic in this file:

https://github.com/jboss-logging/jboss-logging/blob/master/src/main/java/org/jboss/logging/LoggerProviders.java#L93

By providing this empty class:

org.apache.log4j.Hierarchy

Some debate on the issue can be found here:

https://issues.jboss.org/browse/JBLOGGING-65

I plan to create a single class dependency that depends on log4j-over-slf4j for this purpose, however it's working as-is in one project. I can now switch from slf4j-nop to slf4j-simple to logback and get the expected results, both from my own code, and from Hibernate/C3P0.

Redware answered 18/2, 2013 at 9:22 Comment(1)
I tried this solution TODAY. I used to have the same annoying messages faced by OP. Right after dropping the dependency presented in this answer, all c3p0 messages simply vanish.Rebozo
G
3

Since the accepted answer was written (nearly three years ago), direct support for slf4j logging into any backend was added in version 0.2.5 of the mchange-commons-java artifact, which is what the c3p0 documentation uses.

eg: 'com.mchange.v2.log.MLog = com.mchange.v2.log.slf4j.Slf4jMLog'

However... The latest stable release in Maven Central (0.9.2.1) of c3p0 does not use that version. You would have to upgrade to at least 0.9.5-pre2 to use that configuration. The latest unreleased version is 0.9.5-pre7

This would avoid having to either:

  1. Change your overall logging backend to log4j, OR
  2. Use the 'double-hop' of routing your logging into the bridge provided in another answer.

This is what we are doing to route into slf4j and logback. In one application however we still need to use the log4j bridge until a new version of hibernate's hibernate-c3p0 is released that updates the c3p0 version.

I suspect this is one of the issues to which FredCooke's answer is referencing... but it may confusing two issues. Hibernate brings the jboss-logging dependency to the classpath, but that will intelligently use logback already if it is present. c3p0 however will need to be additionally configured with com.mchange.v2.log.MLog = com.mchange.v2.log.log4j.Log4jMLog to send its log entries into log4j which will then be caught by the 'log4j => slf4j' bridge.

Grane answered 31/3, 2014 at 3:45 Comment(1)
0.9.5 has been released.Godthaab
A
2

If you use log4j-over-slf4j, c3p0's MLog will log to that "fake" log4j, which will in turn be slf4j, then you can use whichever provider you prefer for slf4j's output.

EDIT: This worked when I used it and submitted this answer, but they specifically broke this a couple months later. See the additional modification necessary in FredCooke's answer.

Amman answered 2/4, 2012 at 1:53 Comment(0)
W
-3

You can make System.err point to another PrintStream with System.setErr(). It doesn't modify C3PO, but the logging output output will appear where you want it.

Wedurn answered 28/7, 2011 at 0:46 Comment(2)
Redirecting the output stream won't work with any logging framework I'm aware of.Usia
And if the logger is configured to log to a file? Or to some other stream?Amman

© 2022 - 2024 — McMap. All rights reserved.