killbill-aplcache

jdbc: integrate log4jdbc-log4j2 Update to the latest platform

8/7/2014 4:45:58 PM

Details

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index 746e0fa..4151d5c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>org.kill-bill.billing</groupId>
-        <version>0.7.19</version>
+        <version>0.7.20-SNAPSHOT</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.11.9-SNAPSHOT</version>
diff --git a/profiles/killbill/pom.xml b/profiles/killbill/pom.xml
index 7bf2e62..c7d415b 100644
--- a/profiles/killbill/pom.xml
+++ b/profiles/killbill/pom.xml
@@ -29,6 +29,18 @@
     <name>killbill-profiles-killbill</name>
     <dependencies>
         <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
             <scope>compile</scope>
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
index 43f9c56..21dfe24 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
@@ -18,6 +18,9 @@
 
 package org.killbill.billing.server.listeners;
 
+import java.io.IOException;
+import java.net.URISyntaxException;
+
 import javax.servlet.ServletContext;
 
 import org.killbill.billing.jaxrs.resources.JaxRsResourceBase;
@@ -73,7 +76,7 @@ public class KillbillGuiceListener extends KillbillPlatformGuiceListener {
     }
 
     @Override
-    protected KillbillConfigSource getConfigSource() {
+    protected KillbillConfigSource getConfigSource() throws IOException, URISyntaxException {
         final ImmutableMap<String, String> defaultProperties = ImmutableMap.<String, String>of("org.killbill.server.updateCheck.url",
                                                                                                "https://raw.github.com/killbill/killbill/master/profiles/killbill/src/main/resources/update-checker/killbill-server-update-list.properties");
         return new DefaultKillbillConfigSource(defaultProperties);
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/log/ThreadNameBasedDiscriminator.java b/profiles/killbill/src/main/java/org/killbill/billing/server/log/ThreadNameBasedDiscriminator.java
new file mode 100644
index 0000000..50ddf2f
--- /dev/null
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/log/ThreadNameBasedDiscriminator.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.server.log;
+
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.sift.Discriminator;
+
+public class ThreadNameBasedDiscriminator implements Discriminator<ILoggingEvent> {
+
+    private static final String KEY = "threadName";
+
+    private boolean started;
+
+    @Override
+    public String getDiscriminatingValue(final ILoggingEvent iLoggingEvent) {
+        return Thread.currentThread().getName();
+    }
+
+    @Override
+    public String getKey() {
+        return KEY;
+    }
+
+    public void start() {
+        started = true;
+    }
+
+    public void stop() {
+        started = false;
+    }
+
+    public boolean isStarted() {
+        return started;
+    }
+}
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/security/KillbillJdbcRealm.java b/profiles/killbill/src/main/java/org/killbill/billing/server/security/KillbillJdbcRealm.java
index 694f1aa..a968295 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/security/KillbillJdbcRealm.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/security/KillbillJdbcRealm.java
@@ -18,6 +18,8 @@
 
 package org.killbill.billing.server.security;
 
+import javax.sql.DataSource;
+
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
@@ -25,6 +27,7 @@ import org.apache.shiro.authc.SimpleAuthenticationInfo;
 import org.apache.shiro.codec.Base64;
 import org.apache.shiro.realm.jdbc.JdbcRealm;
 import org.apache.shiro.util.ByteSource;
+import org.killbill.billing.platform.jndi.ReferenceableDataSourceSpy;
 import org.killbill.billing.tenant.security.KillbillCredentialsMatcher;
 import org.killbill.commons.jdbi.guice.DaoConfig;
 import org.killbill.commons.jdbi.guice.DataSourceProvider;
@@ -69,7 +72,8 @@ public class KillbillJdbcRealm extends JdbcRealm {
     }
 
     private void configureDataSource() {
-        final DataSourceProvider dataSourceProvider = new DataSourceProvider(config);
-        setDataSource(dataSourceProvider.get());
+        final DataSource realDataSource = new DataSourceProvider(config).get();
+        final DataSource dataSource = new ReferenceableDataSourceSpy<DataSource>(realDataSource);
+        setDataSource(dataSource);
     }
 }
diff --git a/profiles/killbill/src/main/resources/logback.xml b/profiles/killbill/src/main/resources/logback.xml
index 7de0d93..d753641 100644
--- a/profiles/killbill/src/main/resources/logback.xml
+++ b/profiles/killbill/src/main/resources/logback.xml
@@ -15,22 +15,175 @@
   -->
 
 <configuration>
-  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-    <!-- encoders are assigned the type
-         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
-    <encoder>
-      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
-    </encoder>
-  </appender>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <!-- encoders are assigned the type
+             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
+        <encoder>
+            <pattern>%date [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
 
-  <!-- Silence verbose loggers in DEBUG mode -->
-  <logger name="com.dmurph" level="INFO"/>
-  <logger name="org.killbill.billing.notificationq" level="INFO"/>
-  <logger name="org.killbill.billing.queue" level="INFO"/>
-  <logger name="org.killbill.billing.server.updatechecker" level="INFO"/>
-  <logger name="org.eclipse" level="INFO"/>
+    <!-- JDBC appenders -->
+    <appender name="SIFT-jdbc-sqlonly" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator class="org.killbill.billing.server.log.ThreadNameBasedDiscriminator"/>
+        <sift>
+            <appender name="jdbc-sqlonly-${threadName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
+                <file>${LOGS_DIR:-./logs}/jdbc-sqlonly.${threadName}.out</file>
+                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                    <!-- rollover daily -->
+                    <fileNamePattern>jdbc-sqlonly-%d{yyyy-MM-dd}.%i.${threadName}.out</fileNamePattern>
+                    <maxHistory>3</maxHistory>
+                    <cleanHistoryOnStart>true</cleanHistoryOnStart>
+                    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                        <!-- or whenever the file size reaches 100MB -->
+                        <maxFileSize>100MB</maxFileSize>
+                    </timeBasedFileNamingAndTriggeringPolicy>
+                </rollingPolicy>
+                <encoder>
+                    <pattern>%date [%thread] %msg%n</pattern>
+                </encoder>
+            </appender>
+        </sift>
+    </appender>
+    <appender name="SIFT-jdbc-sqltiming" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator class="org.killbill.billing.server.log.ThreadNameBasedDiscriminator"/>
+        <sift>
+            <appender name="jdbc-sqltiming-${threadName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
+                <file>${LOGS_DIR:-./logs}/jdbc-sqltiming.${threadName}.out</file>
+                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                    <!-- rollover daily -->
+                    <fileNamePattern>jdbc-sqltiming-%d{yyyy-MM-dd}.%i.${threadName}.out</fileNamePattern>
+                    <maxHistory>3</maxHistory>
+                    <cleanHistoryOnStart>true</cleanHistoryOnStart>
+                    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                        <!-- or whenever the file size reaches 100MB -->
+                        <maxFileSize>100MB</maxFileSize>
+                    </timeBasedFileNamingAndTriggeringPolicy>
+                </rollingPolicy>
+                <encoder>
+                    <pattern>%date [%thread] %msg%n</pattern>
+                </encoder>
+            </appender>
+        </sift>
+    </appender>
+    <appender name="SIFT-jdbc-audit" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator class="org.killbill.billing.server.log.ThreadNameBasedDiscriminator"/>
+        <sift>
+            <appender name="jdbc-audit-${threadName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
+                <file>${LOGS_DIR:-./logs}/jdbc-audit.${threadName}.out</file>
+                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                    <!-- rollover daily -->
+                    <fileNamePattern>jdbc-audit-%d{yyyy-MM-dd}.%i.${threadName}.out</fileNamePattern>
+                    <maxHistory>3</maxHistory>
+                    <cleanHistoryOnStart>true</cleanHistoryOnStart>
+                    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                        <!-- or whenever the file size reaches 100MB -->
+                        <maxFileSize>100MB</maxFileSize>
+                    </timeBasedFileNamingAndTriggeringPolicy>
+                </rollingPolicy>
+                <encoder>
+                    <pattern>%date [%thread] %msg%n</pattern>
+                </encoder>
+            </appender>
+        </sift>
+    </appender>
+    <appender name="SIFT-jdbc-resultset" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator class="org.killbill.billing.server.log.ThreadNameBasedDiscriminator"/>
+        <sift>
+            <appender name="jdbc-resultset-${threadName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
+                <file>${LOGS_DIR:-./logs}/jdbc-resultset.${threadName}.out</file>
+                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                    <!-- rollover daily -->
+                    <fileNamePattern>jdbc-resultset-%d{yyyy-MM-dd}.%i.${threadName}.out</fileNamePattern>
+                    <maxHistory>3</maxHistory>
+                    <cleanHistoryOnStart>true</cleanHistoryOnStart>
+                    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                        <!-- or whenever the file size reaches 100MB -->
+                        <maxFileSize>100MB</maxFileSize>
+                    </timeBasedFileNamingAndTriggeringPolicy>
+                </rollingPolicy>
+                <encoder>
+                    <pattern>%date [%thread] %msg%n</pattern>
+                </encoder>
+            </appender>
+        </sift>
+    </appender>
+    <appender name="SIFT-jdbc-resultsettable" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator class="org.killbill.billing.server.log.ThreadNameBasedDiscriminator"/>
+        <sift>
+            <appender name="jdbc-resultsettable-${threadName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
+                <file>${LOGS_DIR:-./logs}/jdbc-resultsettable.${threadName}.out</file>
+                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                    <!-- rollover daily -->
+                    <fileNamePattern>jdbc-resultsettable-%d{yyyy-MM-dd}.%i.${threadName}.out</fileNamePattern>
+                    <maxHistory>3</maxHistory>
+                    <cleanHistoryOnStart>true</cleanHistoryOnStart>
+                    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                        <!-- or whenever the file size reaches 100MB -->
+                        <maxFileSize>100MB</maxFileSize>
+                    </timeBasedFileNamingAndTriggeringPolicy>
+                </rollingPolicy>
+                <encoder>
+                    <pattern>%date [%thread] %msg%n</pattern>
+                </encoder>
+            </appender>
+        </sift>
+    </appender>
+    <appender name="SIFT-jdbc-connection" class="ch.qos.logback.classic.sift.SiftingAppender">
+        <discriminator class="org.killbill.billing.server.log.ThreadNameBasedDiscriminator"/>
+        <sift>
+            <appender name="jdbc-connection-${threadName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
+                <file>${LOGS_DIR:-./logs}/jdbc-connection.${threadName}.out</file>
+                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+                    <!-- rollover daily -->
+                    <fileNamePattern>jdbc-connection-%d{yyyy-MM-dd}.%i.${threadName}.out</fileNamePattern>
+                    <maxHistory>3</maxHistory>
+                    <cleanHistoryOnStart>true</cleanHistoryOnStart>
+                    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                        <!-- or whenever the file size reaches 100MB -->
+                        <maxFileSize>100MB</maxFileSize>
+                    </timeBasedFileNamingAndTriggeringPolicy>
+                </rollingPolicy>
+                <encoder>
+                    <pattern>%date [%thread] %msg%n</pattern>
+                </encoder>
+            </appender>
+        </sift>
+    </appender>
 
-  <root level="INFO">
-    <appender-ref ref="STDOUT" />
-  </root>
+    <!-- Logs only SQL. SQL executed within a prepared statement is automatically shown with it's bind arguments replaced with the data bound at that position, for greatly increased readability. -->
+    <logger name="jdbc.sqlonly" level="ERROR" additivity="false">
+        <appender-ref ref="SIFT-jdbc-sqlonly"/>
+    </logger>
+    <!-- Logs the SQL, post-execution, including timing statistics on how long the SQL took to execute. -->
+    <logger name="jdbc.sqltiming" level="INFO" additivity="false">
+        <appender-ref ref="SIFT-jdbc-sqltiming"/>
+    </logger>
+    <!-- Logs ALL JDBC calls except for ResultSets. This is a very voluminous output, and is not normally needed unless tracking down a specific JDBC problem. -->
+    <logger name="jdbc.audit" level="OFF" additivity="false">
+        <appender-ref ref="SIFT-jdbc-audit"/>
+    </logger>
+    <!-- Even more voluminous, because all calls to ResultSet objects are logged. -->
+    <logger name="jdbc.resultset" level="OFF" additivity="false">
+        <appender-ref ref="SIFT-jdbc-resultset"/>
+    </logger>
+    <!-- Log the jdbc results as a table. Level debug will fill in unread values in the result set. -->
+    <logger name="jdbc.resultsettable" level="OFF" additivity="false">
+        <appender-ref ref="SIFT-jdbc-resultsettable"/>
+    </logger>
+    <!-- Logs connection open and close events as well as dumping all open connection numbers. This is very useful for hunting down connection leak problems. -->
+    <logger name="jdbc.connection" level="OFF" additivity="false">
+        <appender-ref ref="SIFT-jdbc-connection"/>
+    </logger>
+
+    <!-- Silence verbose loggers in DEBUG mode -->
+    <logger name="com.dmurph" level="INFO"/>
+    <logger name="org.killbill.billing.notificationq" level="INFO"/>
+    <logger name="org.killbill.billing.queue" level="INFO"/>
+    <logger name="org.killbill.billing.server.updatechecker" level="INFO"/>
+    <logger name="org.eclipse" level="INFO"/>
+
+    <root level="INFO">
+        <appender-ref ref="STDOUT"/>
+    </root>
 </configuration>
diff --git a/profiles/killpay/src/main/java/org/killbill/billing/server/listeners/KillpayGuiceListener.java b/profiles/killpay/src/main/java/org/killbill/billing/server/listeners/KillpayGuiceListener.java
index 081c7d2..81a0ef6 100644
--- a/profiles/killpay/src/main/java/org/killbill/billing/server/listeners/KillpayGuiceListener.java
+++ b/profiles/killpay/src/main/java/org/killbill/billing/server/listeners/KillpayGuiceListener.java
@@ -17,6 +17,9 @@
 
 package org.killbill.billing.server.listeners;
 
+import java.io.IOException;
+import java.net.URISyntaxException;
+
 import javax.servlet.ServletContext;
 
 import org.killbill.billing.platform.api.KillbillConfigSource;
@@ -34,7 +37,7 @@ public class KillpayGuiceListener extends KillbillGuiceListener {
     }
 
     @Override
-    protected KillbillConfigSource getConfigSource() {
+    protected KillbillConfigSource getConfigSource() throws IOException, URISyntaxException {
         final ImmutableMap<String, String> defaultProperties = ImmutableMap.<String, String>of("org.killbill.server.updateCheck.url",
                                                                                                "https://raw.github.com/killbill/killbill/master/profiles/killpay/src/main/resources/update-checker/killbill-server-update-list.properties");
         return new DefaultKillbillConfigSource(defaultProperties);
diff --git a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java
index 4d8e795..7debdc2 100644
--- a/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java
+++ b/util/src/test/java/org/killbill/billing/GuicyKillbillTestSuite.java
@@ -69,8 +69,7 @@ public class GuicyKillbillTestSuite {
 
     protected KillbillConfigSource getConfigSource() {
         try {
-            return new TestKillbillConfigSource(DBTestingHelper.get().getInstance().getJdbcConnectionString(),
-                                                DBTestingHelper.get().getInstance().getUsername(), DBTestingHelper.get().getInstance().getPassword());
+            return new TestKillbillConfigSource(DBTestingHelper.class);
         } catch (final Exception e) {
             final AssertionError assertionError = new AssertionError("Initialization error");
             assertionError.initCause(e);
@@ -84,9 +83,7 @@ public class GuicyKillbillTestSuite {
 
     protected KillbillConfigSource getConfigSource(final String file, final ImmutableMap<String, String> extraProperties) {
         try {
-            return new TestKillbillConfigSource(file, DBTestingHelper.get().getInstance().getJdbcConnectionString(),
-                                                DBTestingHelper.get().getInstance().getUsername(), DBTestingHelper.get().getInstance().getPassword(),
-                                                extraProperties);
+            return new TestKillbillConfigSource(file, DBTestingHelper.class, extraProperties);
         } catch (final Exception e) {
             final AssertionError assertionError = new AssertionError("Initialization error");
             assertionError.initCause(e);
diff --git a/util/src/test/java/org/killbill/billing/GuicyKillbillTestWithEmbeddedDBModule.java b/util/src/test/java/org/killbill/billing/GuicyKillbillTestWithEmbeddedDBModule.java
index c698b6f..bb6516e 100644
--- a/util/src/test/java/org/killbill/billing/GuicyKillbillTestWithEmbeddedDBModule.java
+++ b/util/src/test/java/org/killbill/billing/GuicyKillbillTestWithEmbeddedDBModule.java
@@ -18,18 +18,9 @@
 
 package org.killbill.billing;
 
-import java.io.IOException;
-
-import javax.sql.DataSource;
-
 import org.killbill.billing.platform.api.KillbillConfigSource;
 import org.killbill.billing.platform.test.config.TestKillbillConfigSource;
 import org.killbill.billing.platform.test.glue.TestPlatformModuleWithEmbeddedDB;
-import org.killbill.commons.embeddeddb.EmbeddedDB;
-import org.killbill.queue.DefaultQueueLifecycle;
-import org.skife.jdbi.v2.IDBI;
-
-import com.google.inject.name.Names;
 
 public class GuicyKillbillTestWithEmbeddedDBModule extends GuicyKillbillTestModule {
 
@@ -59,16 +50,7 @@ public class GuicyKillbillTestWithEmbeddedDBModule extends GuicyKillbillTestModu
 
         protected void configureEmbeddedDB() {
             final DBTestingHelper dbTestingHelper = DBTestingHelper.get();
-            final EmbeddedDB instance = dbTestingHelper.getInstance();
-            bind(EmbeddedDB.class).toInstance(instance);
-
-            try {
-                bind(DataSource.class).toInstance(instance.getDataSource());
-                bind(IDBI.class).toInstance(dbTestingHelper.getDBI());
-                bind(IDBI.class).annotatedWith(Names.named(DefaultQueueLifecycle.QUEUE_NAME)).toInstance(dbTestingHelper.getDBI());
-            } catch (final IOException e) {
-                throw new RuntimeException(e);
-            }
+            configureEmbeddedDB(dbTestingHelper);
         }
     }
 }