Repository: tomee Updated Branches: refs/heads/master d9428dd45 -> 983a67ed5
TOMEE-1528 LogSqlPackages config Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/983a67ed Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/983a67ed Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/983a67ed Branch: refs/heads/master Commit: 983a67ed54ad3d002c0a7d6f56f4150e647886d9 Parents: d9428dd Author: Romain Manni-Bucau <[email protected]> Authored: Wed Mar 18 17:42:38 2015 +0100 Committer: Romain Manni-Bucau <[email protected]> Committed: Wed Mar 18 17:42:38 2015 +0100 ---------------------------------------------------------------------- .../resource/jdbc/DataSourceFactory.java | 10 ++- .../logging/LoggingCallableSqlStatement.java | 4 +- .../logging/LoggingPreparedSqlStatement.java | 6 +- .../jdbc/logging/LoggingSqlConnection.java | 12 +-- .../jdbc/logging/LoggingSqlDataSource.java | 6 +- .../jdbc/logging/LoggingSqlStatement.java | 8 +- .../jdbc/logging/TimeWatcherExecutor.java | 21 +++++ .../managed/JTADataSourceWrapperFactory.java | 7 +- .../resource/jdbc/logging/LoggingSqlTest.java | 94 ++++++++++++++++++++ 9 files changed, 150 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/983a67ed/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java index 50c1b04..6f4f113 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java @@ -63,8 +63,10 @@ public class DataSourceFactory { private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB, DataSourceFactory.class); public static final String LOG_SQL_PROPERTY = "LogSql"; + public static final String LOG_SQL_PACKAGE_PROPERTY = "LogSqlPackages"; public static final String FLUSHABLE_PROPERTY = "Flushable"; public static final String GLOBAL_LOG_SQL_PROPERTY = "openejb.jdbc.log"; + public static final String GLOBAL_LOG_SQL_PACKAGE_PROPERTY = "openejb.jdbc.log.packages"; public static final String GLOBAL_FLUSH_PROPERTY = "openejb.jdbc.flushable"; public static final String POOL_PROPERTY = "openejb.datasource.pool"; public static final String DATA_SOURCE_CREATOR_PROP = "DataSourceCreator"; @@ -135,6 +137,7 @@ public class DataSourceFactory { final boolean logSql = SystemInstance.get().getOptions().get(GLOBAL_LOG_SQL_PROPERTY, "true".equalsIgnoreCase((String) properties.remove(LOG_SQL_PROPERTY))); + final String logPackages = SystemInstance.get().getProperty(GLOBAL_LOG_SQL_PACKAGE_PROPERTY, (String) properties.remove(LOG_SQL_PACKAGE_PROPERTY)); final DataSourceCreator creator = creator(properties.remove(DATA_SOURCE_CREATOR_PROP), logSql); boolean useContainerLoader = "true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.resources.use-container-loader", "true")) && (impl == null || impl.getClassLoader() == DataSourceFactory.class.getClassLoader()); @@ -204,7 +207,7 @@ public class DataSourceFactory { } if (logSql) { - ds = makeItLogging(ds); + ds = makeItLogging(ds, logPackages); } if (flushable) { ds = makeFlushable(ds, flushConfig); @@ -257,9 +260,10 @@ public class DataSourceFactory { creatorByDataSource.put(ds, creator); } - public static DataSource makeItLogging(final CommonDataSource ds) { + public static DataSource makeItLogging(final CommonDataSource ds, final String packagesStr) { + final String[] pck = packagesStr == null ? null : packagesStr.split(" *, *"); return (DataSource) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), - new Class<?>[]{DataSource.class, Serializable.class}, new LoggingSqlDataSource(ds)); + new Class<?>[]{DataSource.class, Serializable.class}, new LoggingSqlDataSource(ds, pck)); } private static void normalizeJdbcUrl(final Properties properties) { http://git-wip-us.apache.org/repos/asf/tomee/blob/983a67ed/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingCallableSqlStatement.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingCallableSqlStatement.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingCallableSqlStatement.java index 6945a66..4bc42ad 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingCallableSqlStatement.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingCallableSqlStatement.java @@ -20,8 +20,8 @@ package org.apache.openejb.resource.jdbc.logging; import java.sql.PreparedStatement; public class LoggingCallableSqlStatement extends LoggingPreparedSqlStatement { - public LoggingCallableSqlStatement(final PreparedStatement result, final String query) { - super(result, query); + public LoggingCallableSqlStatement(final PreparedStatement result, final String query, final String[] debugPackages) { + super(result, query, debugPackages); } // TODO: manage in/out parameters http://git-wip-us.apache.org/repos/asf/tomee/blob/983a67ed/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingPreparedSqlStatement.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingPreparedSqlStatement.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingPreparedSqlStatement.java index 3731684..9500366 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingPreparedSqlStatement.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingPreparedSqlStatement.java @@ -36,12 +36,14 @@ public class LoggingPreparedSqlStatement implements InvocationHandler { private final PreparedStatement delegate; private final String sql; private final List<Parameter> parameters = new ArrayList<Parameter>(); + private final String[] packages; private int parameterIndex; - public LoggingPreparedSqlStatement(final PreparedStatement result, final String query) { + public LoggingPreparedSqlStatement(final PreparedStatement result, final String query, final String[] debugPackages) { delegate = result; sql = query; parameterIndex = 0; + packages = debugPackages; } @Override @@ -112,7 +114,7 @@ public class LoggingPreparedSqlStatement implements InvocationHandler { } } } - LOGGER.info(result.format(str)); + LOGGER.info(result.format(str) + (packages != null ? " - stack:" + TimeWatcherExecutor.inlineStack(packages) : "")); } else if ("clearParameters".equals(mtdName)) { parameters.clear(); parameterIndex = 0; http://git-wip-us.apache.org/repos/asf/tomee/blob/983a67ed/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlConnection.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlConnection.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlConnection.java index 3c33c24..74ad1d6 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlConnection.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlConnection.java @@ -32,9 +32,11 @@ public class LoggingSqlConnection implements InvocationHandler { private static final Class<?>[] INTERFACES_CALLABLE = new Class<?>[]{CallableStatement.class}; private final Connection delegate; + private final String[] packages; - public LoggingSqlConnection(final Connection connection) { - delegate = connection; + public LoggingSqlConnection(final Connection connection, final String[] debugPackages) { + this.delegate = connection; + this.packages = debugPackages; } @Override @@ -50,17 +52,17 @@ public class LoggingSqlConnection implements InvocationHandler { if ("createStatement".equals(mtd)) { return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), INTERFACES_STATEMENT, - new LoggingSqlStatement((Statement) result)); + new LoggingSqlStatement((Statement) result, packages)); } if ("prepareStatement".equals(mtd)) { return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), INTERFACES_PREPARED, - new LoggingPreparedSqlStatement((PreparedStatement) result, (String) args[0])); + new LoggingPreparedSqlStatement((PreparedStatement) result, (String) args[0], packages)); } if ("prepareCall".equals(mtd)) { return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), INTERFACES_CALLABLE, - new LoggingCallableSqlStatement((CallableStatement) result, (String) args[0])); + new LoggingCallableSqlStatement((CallableStatement) result, (String) args[0], packages)); } return result; http://git-wip-us.apache.org/repos/asf/tomee/blob/983a67ed/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlDataSource.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlDataSource.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlDataSource.java index a6cc4e7..8dbc3d7 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlDataSource.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlDataSource.java @@ -28,9 +28,11 @@ public class LoggingSqlDataSource implements InvocationHandler { private static final Class<?>[] INTERFACES = new Class<?>[]{Connection.class}; private final CommonDataSource delegate; + private final String[] packages; - public LoggingSqlDataSource(final CommonDataSource ds) { + public LoggingSqlDataSource(final CommonDataSource ds, final String[] debugPackages) { delegate = ds; + packages = debugPackages; } @Override @@ -44,7 +46,7 @@ public class LoggingSqlDataSource implements InvocationHandler { if ("getConnection".equals(method.getName())) { return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), - INTERFACES, new LoggingSqlConnection((Connection) result)); + INTERFACES, new LoggingSqlConnection((Connection) result, packages)); } return result; } http://git-wip-us.apache.org/repos/asf/tomee/blob/983a67ed/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlStatement.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlStatement.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlStatement.java index 4a6d3a7..1c6b513 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlStatement.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlStatement.java @@ -28,9 +28,11 @@ public class LoggingSqlStatement implements InvocationHandler { private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_SQL, LoggingSqlStatement.class); private final Statement delegate; + private final String[] packages; - public LoggingSqlStatement(final Statement result) { - delegate = result; + public LoggingSqlStatement(final Statement result, final String[] debugPackages) { + this.delegate = result; + this.packages = debugPackages; } @Override @@ -40,7 +42,7 @@ public class LoggingSqlStatement implements InvocationHandler { final TimeWatcherExecutor.TimerWatcherResult result = TimeWatcherExecutor.execute(method, delegate, args, execute); if (execute) { - LOGGER.info(result.format((String) args[0])); + LOGGER.info(result.format((String) args[0]) + (packages != null ? " - stack:" + TimeWatcherExecutor.inlineStack(packages) : "")); } if (result.getThrowable() != null) { http://git-wip-us.apache.org/repos/asf/tomee/blob/983a67ed/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/TimeWatcherExecutor.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/TimeWatcherExecutor.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/TimeWatcherExecutor.java index 2de1317..5bfea65 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/TimeWatcherExecutor.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/logging/TimeWatcherExecutor.java @@ -26,6 +26,27 @@ public final class TimeWatcherExecutor { // no-op } + public static String inlineStack(final String[] acceptedPackages) { + if (acceptedPackages == null) { + return ""; + } + + final Throwable t = new Exception().fillInStackTrace(); + final StringBuilder inlinedStack = new StringBuilder(); + for (final StackTraceElement elt : t.getStackTrace()) { + final String className = elt.getClassName(); + for (final String p : acceptedPackages) { + if (className.startsWith(p)) { + inlinedStack.append(" -> ") + .append(className).append('.') + .append(elt.getMethodName()).append(':').append(elt.getLineNumber()); + break; + } + } + } + return inlinedStack.toString(); + } + public static TimerWatcherResult execute(final Method mtd, final Object instance, final Object[] args, final boolean watch) { final long start = (watch) ? System.nanoTime() : 0; http://git-wip-us.apache.org/repos/asf/tomee/blob/983a67ed/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java index 4a849d5..48e29fc 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java @@ -34,6 +34,7 @@ import javax.transaction.TransactionManager; public class JTADataSourceWrapperFactory { private String delegate = "datasource"; private boolean logSql; + private String logPackages; public CommonDataSource create() { final TransactionManager transactionManager = OpenEJB.getTransactionManager(); @@ -46,7 +47,7 @@ public class JTADataSourceWrapperFactory { } if (logSql) { - cds = DataSourceFactory.makeItLogging(cds); + cds = DataSourceFactory.makeItLogging(cds, logPackages); } return cds; } @@ -67,4 +68,8 @@ public class JTADataSourceWrapperFactory { public void setLogSql(final boolean logSql) { this.logSql = logSql; } + + public void setLogPackages(final String logPackages) { + this.logPackages = logPackages; + } } http://git-wip-us.apache.org/repos/asf/tomee/blob/983a67ed/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlTest.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlTest.java b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlTest.java new file mode 100644 index 0000000..1bb15d4 --- /dev/null +++ b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/logging/LoggingSqlTest.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.apache.openejb.resource.jdbc.logging; + +import org.apache.openejb.junit.ApplicationComposer; +import org.apache.openejb.log.LoggerCreator; +import org.apache.openejb.testing.Classes; +import org.apache.openejb.testing.ContainerProperties; +import org.apache.openejb.util.JuliLogStream; +import org.apache.openejb.util.LogCategory; +import org.apache.openejb.util.Logger; +import org.apache.openejb.util.reflection.Reflections; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.util.Collection; +import java.util.LinkedList; +import java.util.logging.Handler; +import java.util.logging.LogRecord; +import javax.annotation.Resource; +import javax.sql.DataSource; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +@Classes +@ContainerProperties({ + @ContainerProperties.Property(name = "db", value = "new://Resource?type=DataSource"), + @ContainerProperties.Property(name = "db.LogSql", value = "true"), + // cheating the package to the class to really identity the filtering + @ContainerProperties.Property(name = "db.LogSqlPackages", value = "org.apache.openejb.resource.jdbc.logging.LoggingSqlTest"), + // let it be sync to avoid timing issues + @ContainerProperties.Property(name = "openejb.log.async", value = "false") +}) +@RunWith(ApplicationComposer.class) +public class LoggingSqlTest { + @Resource + private DataSource ds; + + @Test + public void checkOutput() throws Exception { + final Logger logger = Logger.getInstance(LogCategory.OPENEJB_SQL, LoggingPreparedSqlStatement.class); + final JuliLogStream stream = JuliLogStream.class.cast(Reflections.get(logger, "logStream")); + final LoggerCreator julCreator = LoggerCreator.class.cast(Reflections.get(stream, "logger")); + final java.util.logging.Logger actualLogger = julCreator.call(); + final Collection<String> msgs = new LinkedList<>(); + final Handler handler = new Handler() { + @Override + public void publish(final LogRecord record) { + msgs.add(record.getMessage()); + } + + @Override + public void flush() { + // no-op + } + + @Override + public void close() throws SecurityException { + // no-op + } + }; + actualLogger.addHandler(handler); + + final Connection c = ds.getConnection(); + final PreparedStatement preparedStatement = c.prepareStatement("select 1 from INFORMATION_SCHEMA.SYSTEM_USERS"); + preparedStatement.execute(); + preparedStatement.close(); + c.close(); + + actualLogger.removeHandler(handler); + assertEquals(1, msgs.size()); + + final String msg = msgs.iterator().next(); + assertTrue(msg.contains("select 1 from INFORMATION_SCHEMA.SYSTEM_USERS")); + assertTrue(msg.contains("stack: -> org.apache.openejb.resource.jdbc.logging.LoggingSqlTest.checkOutput:83")); + } +}
