aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java2
-rw-r--r--sonar-batch/src/main/resources/org/sonar/batch/bootstrapper/logback.xml13
-rw-r--r--sonar-batch/src/main/resources/org/sonar/batch/logback.xml3
-rw-r--r--sonar-core/src/main/java/org/sonar/core/config/Logback.java13
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java109
-rw-r--r--sonar-core/src/test/java/org/sonar/core/persistence/AbstractDaoTestCase.java3
-rw-r--r--sonar-core/src/test/java/org/sonar/core/persistence/MyBatisTest.java38
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/Platform.java2
8 files changed, 99 insertions, 84 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java
index 61a01cb36cf..11adc8adcd3 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java
@@ -29,6 +29,7 @@ import org.sonar.batch.RemoteServerMetadata;
import org.sonar.batch.ServerMetadata;
import org.sonar.batch.config.BatchDatabaseSettingsLoader;
import org.sonar.batch.config.BatchSettings;
+import org.sonar.core.config.Logback;
import org.sonar.core.i18n.I18nManager;
import org.sonar.core.i18n.RuleI18nManager;
import org.sonar.core.persistence.DaoUtils;
@@ -59,6 +60,7 @@ public class BootstrapModule extends Module {
addCoreSingleton(new PropertiesConfiguration());
addCoreSingleton(BatchSettings.class);
addCoreSingleton(DryRun.class);
+ addCoreSingleton(Logback.class);
addCoreSingleton(ServerMetadata.class);// registered here because used by BootstrapClassLoader
addCoreSingleton(TempDirectories.class);// registered here because used by BootstrapClassLoader
addCoreSingleton(HttpDownloader.class);// registered here because used by BootstrapClassLoader
diff --git a/sonar-batch/src/main/resources/org/sonar/batch/bootstrapper/logback.xml b/sonar-batch/src/main/resources/org/sonar/batch/bootstrapper/logback.xml
index 13135d01be9..12a7e1db673 100644
--- a/sonar-batch/src/main/resources/org/sonar/batch/bootstrapper/logback.xml
+++ b/sonar-batch/src/main/resources/org/sonar/batch/bootstrapper/logback.xml
@@ -42,15 +42,10 @@
<logger name="org.hibernate.SQL">
<level value="${SQL_LOGGER_LEVEL:-ERROR}"/>
</logger>
- <logger name="org.apache.ibatis">
- <level value="${SQL_LOGGER_LEVEL:-WARN}"/>
- </logger>
- <logger name="java.sql">
- <level value="${SQL_LOGGER_LEVEL:-WARN}"/>
- </logger>
- <logger name="java.sql.ResultSet">
- <level value="${SQL_RESULTS_LOGGER_LEVEL:-WARN}"/>
- </logger>
+ <logger name="org.mybatis">
+ <level value="${SQL_LOGGER_LEVEL:-WARN}"/>
+ </logger>
+ <!-- see also org.sonar.core.persistence.MyBatis#configureLogback() -->
<root>
<!-- sonar.verbose -->
diff --git a/sonar-batch/src/main/resources/org/sonar/batch/logback.xml b/sonar-batch/src/main/resources/org/sonar/batch/logback.xml
index 8c2d0cefc91..4171dcb6e34 100644
--- a/sonar-batch/src/main/resources/org/sonar/batch/logback.xml
+++ b/sonar-batch/src/main/resources/org/sonar/batch/logback.xml
@@ -41,6 +41,9 @@
<logger name="org.apache.ibatis">
<level value="${SQL_LOGGER_LEVEL:-WARN}"/>
</logger>
+ <logger name="org.mybatis">
+ <level value="${SQL_LOGGER_LEVEL:-WARN}"/>
+ </logger>
<logger name="java.sql">
<level value="${SQL_LOGGER_LEVEL:-WARN}"/>
</logger>
diff --git a/sonar-core/src/main/java/org/sonar/core/config/Logback.java b/sonar-core/src/main/java/org/sonar/core/config/Logback.java
index df2892ceaf4..fc4569378ea 100644
--- a/sonar-core/src/main/java/org/sonar/core/config/Logback.java
+++ b/sonar-core/src/main/java/org/sonar/core/config/Logback.java
@@ -19,6 +19,7 @@
*/
package org.sonar.core.config;
+import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
@@ -26,6 +27,8 @@ import ch.qos.logback.core.util.StatusPrinter;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.LoggerFactory;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.ServerComponent;
import java.io.File;
import java.io.FileInputStream;
@@ -38,11 +41,7 @@ import java.util.Map;
*
* @since 2.12
*/
-public final class Logback {
-
- private Logback() {
- // only static methods
- }
+public class Logback implements BatchComponent, ServerComponent {
public static void configure(String classloaderPath, Map<String, String> substitutionVariables) {
InputStream input = Logback.class.getResourceAsStream(classloaderPath);
@@ -85,4 +84,8 @@ public final class Logback {
}
return context;
}
+
+ public void setLoggerLevel(String loggerName, Level level) {
+ ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(loggerName)).setLevel(level);
+ }
}
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
index 0eb09205458..d5c23809301 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
@@ -19,55 +19,36 @@
*/
package org.sonar.core.persistence;
-import org.apache.ibatis.type.JdbcType;
-
+import ch.qos.logback.classic.Level;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.Environment;
-import org.apache.ibatis.session.Configuration;
-import org.apache.ibatis.session.ExecutorType;
-import org.apache.ibatis.session.SqlSession;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.apache.ibatis.session.SqlSessionFactoryBuilder;
+import org.apache.ibatis.session.*;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
+import org.apache.ibatis.type.JdbcType;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
+import org.sonar.api.config.Settings;
import org.sonar.api.database.model.MeasureMapper;
import org.sonar.api.database.model.MeasureModel;
-import org.sonar.core.dashboard.ActiveDashboardDto;
-import org.sonar.core.dashboard.ActiveDashboardMapper;
-import org.sonar.core.dashboard.DashboardDto;
-import org.sonar.core.dashboard.DashboardMapper;
-import org.sonar.core.dashboard.WidgetDto;
-import org.sonar.core.dashboard.WidgetMapper;
-import org.sonar.core.dashboard.WidgetPropertyDto;
-import org.sonar.core.dashboard.WidgetPropertyMapper;
+import org.sonar.core.config.Logback;
+import org.sonar.core.dashboard.*;
import org.sonar.core.dependency.DependencyDto;
import org.sonar.core.dependency.DependencyMapper;
import org.sonar.core.dependency.ResourceSnapshotDto;
import org.sonar.core.dependency.ResourceSnapshotMapper;
import org.sonar.core.duplication.DuplicationMapper;
import org.sonar.core.duplication.DuplicationUnitDto;
-import org.sonar.core.filter.CriterionDto;
-import org.sonar.core.filter.CriterionMapper;
-import org.sonar.core.filter.FilterColumnDto;
-import org.sonar.core.filter.FilterColumnMapper;
-import org.sonar.core.filter.FilterDto;
-import org.sonar.core.filter.FilterMapper;
+import org.sonar.core.filter.*;
import org.sonar.core.properties.PropertiesMapper;
import org.sonar.core.properties.PropertyDto;
import org.sonar.core.purge.PurgeMapper;
import org.sonar.core.purge.PurgeVendorMapper;
import org.sonar.core.purge.PurgeableSnapshotDto;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceIndexDto;
-import org.sonar.core.resource.ResourceIndexerMapper;
-import org.sonar.core.resource.ResourceKeyUpdaterMapper;
-import org.sonar.core.resource.ResourceMapper;
-import org.sonar.core.resource.SnapshotDto;
+import org.sonar.core.resource.*;
import org.sonar.core.review.ReviewCommentDto;
import org.sonar.core.review.ReviewCommentMapper;
import org.sonar.core.review.ReviewDto;
@@ -76,24 +57,21 @@ import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleMapper;
import org.sonar.core.template.LoadedTemplateDto;
import org.sonar.core.template.LoadedTemplateMapper;
-import org.sonar.core.user.AuthorDto;
-import org.sonar.core.user.AuthorMapper;
-import org.sonar.core.user.GroupDto;
-import org.sonar.core.user.GroupRoleDto;
-import org.sonar.core.user.RoleMapper;
-import org.sonar.core.user.UserDto;
-import org.sonar.core.user.UserMapper;
-import org.sonar.core.user.UserRoleDto;
+import org.sonar.core.user.*;
import java.io.InputStream;
public class MyBatis implements BatchComponent, ServerComponent {
private final Database database;
+ private final Settings settings;
+ private final Logback logback;
private SqlSessionFactory sessionFactory;
- public MyBatis(Database database) {
+ public MyBatis(Database database, Settings settings, Logback logback) {
this.database = database;
+ this.settings = settings;
+ this.logback = logback;
}
public MyBatis start() {
@@ -133,32 +111,13 @@ public class MyBatis implements BatchComponent, ServerComponent {
loadAlias(conf, "WidgetProperty", WidgetPropertyDto.class);
loadAlias(conf, "MeasureModel", MeasureModel.class);
- loadMapper(conf, ActiveDashboardMapper.class);
- loadMapper(conf, AuthorMapper.class);
- loadMapper(conf, FilterMapper.class);
- loadMapper(conf, CriterionMapper.class);
- loadMapper(conf, FilterColumnMapper.class);
- loadMapper(conf, DashboardMapper.class);
- loadMapper(conf, DependencyMapper.class);
- loadMapper(conf, DuplicationMapper.class);
- loadMapper(conf, LoadedTemplateMapper.class);
- loadMapper(conf, PropertiesMapper.class);
- loadMapper(conf, PurgeMapper.class);
- loadMapper(conf, PurgeVendorMapper.class);
- loadMapper(conf, ResourceKeyUpdaterMapper.class);
- loadMapper(conf, ResourceIndexerMapper.class);
- loadMapper(conf, ResourceMapper.class);
- loadMapper(conf, ResourceSnapshotMapper.class);
- loadMapper(conf, ReviewCommentMapper.class);
- loadMapper(conf, ReviewMapper.class);
- loadMapper(conf, RoleMapper.class);
- loadMapper(conf, RuleMapper.class);
- loadMapper(conf, SchemaMigrationMapper.class);
- loadMapper(conf, UserMapper.class);
- loadMapper(conf, WidgetMapper.class);
- loadMapper(conf, WidgetPropertyMapper.class);
- loadMapper(conf, MeasureMapper.class);
-
+ Class[] mappers = {ActiveDashboardMapper.class, AuthorMapper.class, FilterMapper.class, CriterionMapper.class, FilterColumnMapper.class, DashboardMapper.class,
+ DependencyMapper.class, DuplicationMapper.class, LoadedTemplateMapper.class, PropertiesMapper.class, PurgeMapper.class, PurgeVendorMapper.class,
+ ResourceKeyUpdaterMapper.class, ResourceIndexerMapper.class, ResourceMapper.class, ResourceSnapshotMapper.class, ReviewCommentMapper.class,
+ ReviewMapper.class, RoleMapper.class, RuleMapper.class, SchemaMigrationMapper.class, UserMapper.class, WidgetMapper.class, WidgetPropertyMapper.class,
+ MeasureMapper.class};
+ loadMappers(conf, mappers);
+ configureLogback(mappers);
sessionFactory = new SqlSessionFactoryBuilder().build(conf);
return this;
}
@@ -187,13 +146,31 @@ public class MyBatis implements BatchComponent, ServerComponent {
}
}
- private void loadMapper(Configuration conf, Class mapperClass) {
+ private void loadMappers(Configuration mybatisConf, Class... mapperClasses) {
+ for (Class mapperClass : mapperClasses) {
+ loadMapper(mybatisConf, mapperClass);
+ }
+ }
+
+ /**
+ * See http://www.mybatis.org/core/logging.html :
+ */
+ private void configureLogback(Class[] mapperClasses) {
+ if (settings.getBoolean("sonar.showSql")) {
+ Level level = (settings.getBoolean("sonar.showSqlResults") ? Level.TRACE : Level.DEBUG);
+ for (Class mapperClass : mapperClasses) {
+ logback.setLoggerLevel(mapperClass.getName(), level);
+ }
+ }
+ }
+
+ private void loadMapper(Configuration mybatisConf, Class mapperClass) {
// trick to use database-specific XML files for a single Mapper Java interface
InputStream input = getPathToMapper(mapperClass);
try {
- XMLMapperBuilder mapperParser = new XMLMapperBuilder(input, conf, mapperClass.getName(), conf.getSqlFragments());
+ XMLMapperBuilder mapperParser = new XMLMapperBuilder(input, mybatisConf, mapperClass.getName(), mybatisConf.getSqlFragments());
mapperParser.parse();
- conf.addLoadedResource(mapperClass.getName());
+ mybatisConf.addLoadedResource(mapperClass.getName());
} finally {
IOUtils.closeQuietly(input);
@@ -202,7 +179,7 @@ public class MyBatis implements BatchComponent, ServerComponent {
private InputStream getPathToMapper(Class mapperClass) {
InputStream input = getClass().getResourceAsStream(
- "/" + StringUtils.replace(mapperClass.getName(), ".", "/") + "-" + database.getDialect().getId() + ".xml");
+ "/" + StringUtils.replace(mapperClass.getName(), ".", "/") + "-" + database.getDialect().getId() + ".xml");
if (input == null) {
input = getClass().getResourceAsStream("/" + StringUtils.replace(mapperClass.getName(), ".", "/") + ".xml");
}
diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/AbstractDaoTestCase.java b/sonar-core/src/test/java/org/sonar/core/persistence/AbstractDaoTestCase.java
index 39926b21b6f..b7646afb3cd 100644
--- a/sonar-core/src/test/java/org/sonar/core/persistence/AbstractDaoTestCase.java
+++ b/sonar-core/src/test/java/org/sonar/core/persistence/AbstractDaoTestCase.java
@@ -35,6 +35,7 @@ import org.dbunit.dataset.filter.DefaultColumnFilter;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.junit.*;
import org.sonar.api.config.Settings;
+import org.sonar.core.config.Logback;
import java.io.InputStream;
import java.sql.SQLException;
@@ -61,7 +62,7 @@ public abstract class AbstractDaoTestCase {
}
database.start();
- myBatis = new MyBatis(database);
+ myBatis = new MyBatis(database, settings, new Logback());
myBatis.start();
databaseCommands = DatabaseCommands.forDialect(database.getDialect());
diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/MyBatisTest.java b/sonar-core/src/test/java/org/sonar/core/persistence/MyBatisTest.java
index bff3c199a5e..fff30b032a7 100644
--- a/sonar-core/src/test/java/org/sonar/core/persistence/MyBatisTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/persistence/MyBatisTest.java
@@ -19,27 +19,30 @@
*/
package org.sonar.core.persistence;
+import ch.qos.logback.classic.Level;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.hamcrest.core.Is;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.core.config.Logback;
import org.sonar.core.rule.RuleMapper;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
public class MyBatisTest {
- private static MyBatis myBatis;
private static H2Database database;
@BeforeClass
public static void start() {
database = new H2Database();
- myBatis = new MyBatis(database.start());
- myBatis.start();
+ database.start();
}
@AfterClass
@@ -49,6 +52,9 @@ public class MyBatisTest {
@Test
public void shouldConfigureMyBatis() {
+ MyBatis myBatis = new MyBatis(database, new Settings(), new Logback());
+ myBatis.start();
+
Configuration conf = myBatis.getSessionFactory().getConfiguration();
assertThat(conf.isUseGeneratedKeys(), Is.is(true));
assertThat(conf.hasMapper(RuleMapper.class), Is.is(true));
@@ -57,6 +63,9 @@ public class MyBatisTest {
@Test
public void shouldOpenBatchSession() {
+ MyBatis myBatis = new MyBatis(database, new Settings(), new Logback());
+ myBatis.start();
+
SqlSession session = myBatis.openBatchSession();
try {
assertThat(session.getConnection(), notNullValue());
@@ -65,4 +74,27 @@ public class MyBatisTest {
session.close();
}
}
+
+ @Test
+ public void log_sql_requests() {
+ Logback logback = mock(Logback.class);
+ Settings settings = new Settings();
+ settings.setProperty("sonar.showSql", true);
+ MyBatis myBatis = new MyBatis(database, settings, logback);
+ myBatis.start();
+
+ verify(logback).setLoggerLevel("org.sonar.core.resource.ResourceIndexerMapper", Level.DEBUG);
+ }
+
+ @Test
+ public void log_sql_requests_and_responses() {
+ Logback logback = mock(Logback.class);
+ Settings settings = new Settings();
+ settings.setProperty("sonar.showSql", true);
+ settings.setProperty("sonar.showSqlResults", true);
+ MyBatis myBatis = new MyBatis(database, settings, logback);
+ myBatis.start();
+
+ verify(logback).setLoggerLevel("org.sonar.core.resource.ResourceIndexerMapper", Level.TRACE);
+ }
}
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
index e318db2b625..2ce18b2e881 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
@@ -38,6 +38,7 @@ import org.sonar.api.utils.IocContainer;
import org.sonar.api.utils.TimeProfiler;
import org.sonar.api.workflow.internal.DefaultWorkflow;
import org.sonar.core.PicoUtils;
+import org.sonar.core.config.Logback;
import org.sonar.core.i18n.GwtI18n;
import org.sonar.core.i18n.I18nManager;
import org.sonar.core.i18n.RuleI18nManager;
@@ -158,6 +159,7 @@ public final class Platform {
rootContainer.addSingleton(new BaseConfiguration());
rootContainer.addSingleton(ServerSettings.class);
rootContainer.addSingleton(ServerImpl.class);
+ rootContainer.addSingleton(Logback.class);
rootContainer.addSingleton(EmbeddedDatabaseFactory.class);
rootContainer.addSingleton(DefaultDatabase.class);
rootContainer.addSingleton(MyBatis.class);