@@ -19,6 +19,9 @@ | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import org.picocontainer.annotations.Nullable; | |||
import com.google.common.collect.Lists; | |||
import com.google.common.collect.Maps; | |||
import org.sonar.batch.bootstrap.GlobalContainer; | |||
@@ -35,7 +38,7 @@ import java.util.Map; | |||
public final class Batch { | |||
private boolean started = false; | |||
private LoggingConfiguration logging; | |||
private LoggingConfiguration loggingConfig; | |||
private List<Object> components; | |||
private Map<String, String> bootstrapProperties = Maps.newHashMap(); | |||
private GlobalContainer bootstrapContainer; | |||
@@ -50,12 +53,16 @@ public final class Batch { | |||
bootstrapProperties.putAll(builder.bootstrapProperties); | |||
} | |||
if (builder.isEnableLoggingConfiguration()) { | |||
logging = LoggingConfiguration.create(builder.environment).setProperties(bootstrapProperties); | |||
loggingConfig = new LoggingConfiguration(builder.environment).setProperties(bootstrapProperties); | |||
if (builder.listener != null) { | |||
loggingConfig.setListener(builder.listener); | |||
} | |||
} | |||
} | |||
public LoggingConfiguration getLoggingConfiguration() { | |||
return logging; | |||
return loggingConfig; | |||
} | |||
/** | |||
@@ -110,8 +117,8 @@ public final class Batch { | |||
} | |||
private void configureLogging() { | |||
if (logging != null) { | |||
logging.configure(); | |||
if (loggingConfig != null) { | |||
LoggingConfigurator.apply(loggingConfig); | |||
} | |||
} | |||
@@ -124,6 +131,7 @@ public final class Batch { | |||
private EnvironmentInformation environment; | |||
private List<Object> components = Lists.newArrayList(); | |||
private boolean enableLoggingConfiguration = true; | |||
private LogListener listener; | |||
private Builder() { | |||
} | |||
@@ -138,6 +146,11 @@ public final class Batch { | |||
return this; | |||
} | |||
public Builder setLogListener(@Nullable LogListener listener) { | |||
this.listener = listener; | |||
return this; | |||
} | |||
/** | |||
* @deprecated since 3.7 use {@link #setBootstrapProperties(Map)} | |||
*/ |
@@ -0,0 +1,60 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import ch.qos.logback.classic.Level; | |||
import ch.qos.logback.core.UnsynchronizedAppenderBase; | |||
import ch.qos.logback.classic.spi.ILoggingEvent; | |||
public class LogCallbackAppender extends UnsynchronizedAppenderBase<ILoggingEvent> { | |||
protected LogListener target; | |||
public LogCallbackAppender(LogListener target) { | |||
setTarget(target); | |||
} | |||
public void setTarget(LogListener target) { | |||
this.target = target; | |||
} | |||
@Override | |||
protected void append(ILoggingEvent event) { | |||
target.log(event.getFormattedMessage(), translate(event.getLevel())); | |||
} | |||
private LogListener.Level translate(Level level) { | |||
switch(level.toInt()) { | |||
case Level.ERROR_INT: | |||
return LogListener.Level.ERROR; | |||
case Level.WARN_INT: | |||
return LogListener.Level.WARN; | |||
case Level.INFO_INT: | |||
return LogListener.Level.INFO; | |||
case Level.DEBUG_INT: | |||
return LogListener.Level.DEBUG; | |||
case Level.TRACE_INT: | |||
return LogListener.Level.TRACE; | |||
default: | |||
return LogListener.Level.DEBUG; | |||
} | |||
} | |||
} |
@@ -19,15 +19,14 @@ | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import com.google.common.collect.Maps; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.core.config.Logback; | |||
import javax.annotation.Nullable; | |||
import java.io.File; | |||
import java.io.PrintStream; | |||
import java.util.Map; | |||
/** | |||
@@ -37,18 +36,25 @@ public final class LoggingConfiguration { | |||
public static final String PROPERTY_ROOT_LOGGER_LEVEL = "ROOT_LOGGER_LEVEL"; | |||
public static final String PROPERTY_SQL_LOGGER_LEVEL = "SQL_LOGGER_LEVEL"; | |||
public static final String PROPERTY_FORMAT = "FORMAT"; | |||
public static final String LEVEL_ROOT_VERBOSE = "DEBUG"; | |||
public static final String LEVEL_ROOT_VERBOSE = "DEBUG"; | |||
public static final String LEVEL_ROOT_DEFAULT = "INFO"; | |||
@VisibleForTesting | |||
static final String FORMAT_DEFAULT = "%d{HH:mm:ss.SSS} %-5level - %msg%n"; | |||
@VisibleForTesting | |||
static final String FORMAT_MAVEN = "[%level] [%d{HH:mm:ss.SSS}] %msg%n"; | |||
private Map<String, String> substitutionVariables = Maps.newHashMap(); | |||
Map<String, String> substitutionVariables = Maps.newHashMap(); | |||
LogListener listener = null; | |||
private LoggingConfiguration(@Nullable EnvironmentInformation environment) { | |||
public LoggingConfiguration() { | |||
this(null); | |||
} | |||
public LoggingConfiguration(@Nullable EnvironmentInformation environment) { | |||
setVerbose(false); | |||
if (environment != null && "maven".equalsIgnoreCase(environment.getKey())) { | |||
setFormat(FORMAT_MAVEN); | |||
@@ -57,25 +63,14 @@ public final class LoggingConfiguration { | |||
} | |||
} | |||
static LoggingConfiguration create(@Nullable EnvironmentInformation environment) { | |||
return new LoggingConfiguration(environment); | |||
} | |||
public LoggingConfiguration setProperties(Map<String, String> properties) { | |||
String logLevel = properties.get("sonar.log.level"); | |||
String deprecatedProfilingLevel = properties.get("sonar.log.profilingLevel"); | |||
boolean verbose = "true".equals(properties.get("sonar.verbose")) || | |||
"DEBUG".equals(logLevel) || "TRACE".equals(logLevel) || | |||
"BASIC".equals(deprecatedProfilingLevel) || "FULL".equals(deprecatedProfilingLevel); | |||
boolean sql = "TRACE".equals(logLevel) || "FULL".equals(deprecatedProfilingLevel); | |||
setShowSql(sql); | |||
setVerbose(verbose); | |||
setShowSql(properties); | |||
setVerbose(properties); | |||
return this; | |||
} | |||
public LoggingConfiguration setStreams(PrintStream out, PrintStream err) { | |||
public LoggingConfiguration setListener(@Nullable LogListener listener) { | |||
this.listener = listener; | |||
return this; | |||
} | |||
@@ -83,6 +78,16 @@ public final class LoggingConfiguration { | |||
return setRootLevel(verbose ? LEVEL_ROOT_VERBOSE : LEVEL_ROOT_DEFAULT); | |||
} | |||
public LoggingConfiguration setVerbose(Map<String, String> properties) { | |||
String logLevel = properties.get("sonar.log.level"); | |||
String deprecatedProfilingLevel = properties.get("sonar.log.profilingLevel"); | |||
boolean verbose = "true".equals(properties.get("sonar.verbose")) || | |||
"DEBUG".equals(logLevel) || "TRACE".equals(logLevel) || | |||
"BASIC".equals(deprecatedProfilingLevel) || "FULL".equals(deprecatedProfilingLevel); | |||
return setVerbose(verbose); | |||
} | |||
public LoggingConfiguration setRootLevel(String level) { | |||
return addSubstitutionVariable(PROPERTY_ROOT_LOGGER_LEVEL, level); | |||
} | |||
@@ -91,6 +96,14 @@ public final class LoggingConfiguration { | |||
return addSubstitutionVariable(PROPERTY_SQL_LOGGER_LEVEL, showSql ? "TRACE" : "WARN"); | |||
} | |||
public LoggingConfiguration setShowSql(Map<String, String> properties) { | |||
String logLevel = properties.get("sonar.log.level"); | |||
String deprecatedProfilingLevel = properties.get("sonar.log.profilingLevel"); | |||
boolean sql = "TRACE".equals(logLevel) || "FULL".equals(deprecatedProfilingLevel); | |||
return setShowSql(sql); | |||
} | |||
@VisibleForTesting | |||
LoggingConfiguration setFormat(String format) { | |||
return addSubstitutionVariable(PROPERTY_FORMAT, StringUtils.defaultIfBlank(format, FORMAT_DEFAULT)); | |||
@@ -101,22 +114,8 @@ public final class LoggingConfiguration { | |||
return this; | |||
} | |||
@VisibleForTesting | |||
String getSubstitutionVariable(String key) { | |||
return substitutionVariables.get(key); | |||
} | |||
LoggingConfiguration configure(String classloaderPath) { | |||
Logback.configure(classloaderPath, substitutionVariables); | |||
return this; | |||
} | |||
LoggingConfiguration configure(File logbackFile) { | |||
Logback.configure(logbackFile, substitutionVariables); | |||
return this; | |||
} | |||
LoggingConfiguration configure() { | |||
Logback.configure("/org/sonar/batch/bootstrapper/logback.xml", substitutionVariables); | |||
return this; | |||
} | |||
} |
@@ -0,0 +1,77 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import ch.qos.logback.core.Appender; | |||
import ch.qos.logback.classic.Level; | |||
import org.apache.commons.lang.StringUtils; | |||
import java.io.File; | |||
import ch.qos.logback.classic.Logger; | |||
import ch.qos.logback.classic.spi.ILoggingEvent; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.core.config.Logback; | |||
public class LoggingConfigurator { | |||
private LoggingConfigurator() { | |||
} | |||
public static void apply(LoggingConfiguration conf, File logbackFile) { | |||
Logback.configure(logbackFile, conf.substitutionVariables); | |||
if (conf.listener != null) { | |||
setCustomRootAppender(conf); | |||
} | |||
} | |||
public static void apply(LoggingConfiguration conf) { | |||
apply(conf, "/org/sonar/batch/bootstrapper/logback.xml"); | |||
} | |||
public static void apply(LoggingConfiguration conf, String classloaderPath) { | |||
Logback.configure(classloaderPath, conf.substitutionVariables); | |||
// if not set, keep default behavior (configured to stdout through the file in classpath) | |||
if (conf.listener != null) { | |||
setCustomRootAppender(conf); | |||
} | |||
} | |||
private static void setCustomRootAppender(LoggingConfiguration conf) { | |||
Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); | |||
String pattern = StringUtils.defaultIfBlank(conf.substitutionVariables.get(LoggingConfiguration.PROPERTY_FORMAT), LoggingConfiguration.FORMAT_DEFAULT); | |||
String level = StringUtils.defaultIfBlank(conf.substitutionVariables.get(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL), LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
logger.detachAndStopAllAppenders(); | |||
logger.addAppender(createAppender(pattern, conf.listener)); | |||
logger.setLevel(Level.toLevel(level)); | |||
} | |||
private static Appender<ILoggingEvent> createAppender(String pattern, LogListener target) { | |||
LogCallbackAppender appender = new LogCallbackAppender(target); | |||
appender.setName("custom_stream"); | |||
appender.start(); | |||
return appender; | |||
} | |||
} |
@@ -19,8 +19,12 @@ | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import org.junit.Test; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import org.sonar.home.log.LogListener; | |||
import org.junit.Test; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertNull; | |||
@@ -61,4 +65,11 @@ public class BatchTest { | |||
public void loggingConfigurationShouldBeEnabledByDefault() { | |||
assertNotNull(newBatch().getLoggingConfiguration()); | |||
} | |||
@Test | |||
public void shoudSetLogListener() { | |||
LogListener listener = mock(LogListener.class); | |||
Batch batch = Batch.builder().setLogListener(listener).build(); | |||
assertThat(batch.getLoggingConfiguration().listener).isEqualTo(listener); | |||
} | |||
} |
@@ -19,58 +19,67 @@ | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import com.google.common.collect.Maps; | |||
import org.junit.Test; | |||
import java.util.Map; | |||
import static org.mockito.Mockito.mock; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class LoggingConfigurationTest { | |||
@Test | |||
public void testSetVerbose() { | |||
assertThat(LoggingConfiguration.create(null).setVerbose(true) | |||
assertThat(new LoggingConfiguration(null).setVerbose(true) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_VERBOSE); | |||
assertThat(LoggingConfiguration.create(null).setVerbose(false) | |||
assertThat(new LoggingConfiguration(null).setVerbose(false) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
assertThat(LoggingConfiguration.create(null).setRootLevel("ERROR") | |||
assertThat(new LoggingConfiguration(null).setRootLevel("ERROR") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("ERROR"); | |||
} | |||
@Test | |||
public void shouldNotBeVerboseByDefault() { | |||
assertThat(LoggingConfiguration.create(null) | |||
assertThat(new LoggingConfiguration(null) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
} | |||
@Test | |||
public void test_log_listener_setter() { | |||
LogListener listener = mock(LogListener.class); | |||
assertThat(new LoggingConfiguration(null).setListener(listener).listener).isEqualTo(listener); | |||
} | |||
@Test | |||
public void test_deprecated_log_properties() { | |||
Map<String, String> properties = Maps.newHashMap(); | |||
assertThat(LoggingConfiguration.create(null).setProperties(properties) | |||
assertThat(new LoggingConfiguration(null).setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
properties.put("sonar.verbose", "true"); | |||
LoggingConfiguration conf = LoggingConfiguration.create(null).setProperties(properties); | |||
LoggingConfiguration conf = new LoggingConfiguration(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_VERBOSE); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
properties.put("sonar.verbose", "false"); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
properties.put("sonar.verbose", "false"); | |||
properties.put("sonar.log.profilingLevel", "FULL"); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("DEBUG"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("TRACE"); | |||
properties.put("sonar.verbose", "false"); | |||
properties.put("sonar.log.profilingLevel", "BASIC"); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("DEBUG"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
} | |||
@@ -78,53 +87,53 @@ public class LoggingConfigurationTest { | |||
@Test | |||
public void test_log_level_property() { | |||
Map<String, String> properties = Maps.newHashMap(); | |||
LoggingConfiguration conf = LoggingConfiguration.create(null).setProperties(properties); | |||
LoggingConfiguration conf = new LoggingConfiguration(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("INFO"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
properties.put("sonar.log.level", "INFO"); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("INFO"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
properties.put("sonar.log.level", "DEBUG"); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("DEBUG"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
properties.put("sonar.log.level", "TRACE"); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("DEBUG"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("TRACE"); | |||
} | |||
@Test | |||
public void testDefaultFormat() { | |||
assertThat(LoggingConfiguration.create(null) | |||
assertThat(new LoggingConfiguration(null) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
} | |||
@Test | |||
public void testMavenFormat() { | |||
assertThat(LoggingConfiguration.create(new EnvironmentInformation("maven", "1.0")) | |||
assertThat(new LoggingConfiguration(new EnvironmentInformation("maven", "1.0")) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_MAVEN); | |||
} | |||
@Test | |||
public void testSetFormat() { | |||
assertThat(LoggingConfiguration.create(null).setFormat("%d %level") | |||
assertThat(new LoggingConfiguration(null).setFormat("%d %level") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo("%d %level"); | |||
} | |||
@Test | |||
public void shouldNotSetBlankFormat() { | |||
assertThat(LoggingConfiguration.create(null).setFormat(null) | |||
assertThat(new LoggingConfiguration(null).setFormat(null) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
assertThat(LoggingConfiguration.create(null).setFormat("") | |||
assertThat(new LoggingConfiguration(null).setFormat("") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
assertThat(LoggingConfiguration.create(null).setFormat(" ") | |||
assertThat(new LoggingConfiguration(null).setFormat(" ") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
} | |||
} |
@@ -0,0 +1,139 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.PrintStream; | |||
import java.io.UnsupportedEncodingException; | |||
import java.nio.charset.StandardCharsets; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import org.junit.Test; | |||
import org.junit.Before; | |||
public class LoggingConfiguratorTest { | |||
private static final String TEST_STR = "foo"; | |||
private LoggingConfiguration conf = new LoggingConfiguration(); | |||
private ByteArrayOutputStream out; | |||
private SimpleLogListener listener; | |||
@Before | |||
public void setUp() { | |||
out = new ByteArrayOutputStream(); | |||
conf = new LoggingConfiguration(); | |||
listener = new SimpleLogListener(); | |||
} | |||
private class SimpleLogListener implements LogListener { | |||
String msg; | |||
Level level; | |||
@Override | |||
public void log(String msg, Level level) { | |||
this.msg = msg; | |||
this.level = level; | |||
} | |||
} | |||
@Test | |||
public void testCustomAppender() throws UnsupportedEncodingException { | |||
conf.setListener(listener); | |||
LoggingConfigurator.apply(conf); | |||
Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
logger.info(TEST_STR); | |||
assertThat(listener.msg).endsWith(TEST_STR); | |||
assertThat(listener.level).isEqualTo(LogListener.Level.INFO); | |||
} | |||
@Test | |||
public void testNoStdout() throws UnsupportedEncodingException { | |||
System.setOut(new PrintStream(out, false, StandardCharsets.UTF_8.name())); | |||
conf.setListener(listener); | |||
LoggingConfigurator.apply(conf); | |||
Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
logger.error(TEST_STR); | |||
logger.info(TEST_STR); | |||
logger.debug(TEST_STR); | |||
assertThat(out.size()).isEqualTo(0); | |||
} | |||
@Test | |||
public void testFormatNoEffect() throws UnsupportedEncodingException { | |||
conf.setListener(listener); | |||
conf.setFormat("%t"); | |||
LoggingConfigurator.apply(conf); | |||
Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
logger.info("info"); | |||
assertThat(listener.msg).isEqualTo("info"); | |||
} | |||
@Test | |||
public void testSqlClasspath() throws UnsupportedEncodingException { | |||
String classpath = "/org/sonar/batch/bootstrapper/logback.xml"; | |||
conf.setListener(listener); | |||
conf.setShowSql(true); | |||
LoggingConfigurator.apply(conf, classpath); | |||
Logger logger = LoggerFactory.getLogger("java.sql"); | |||
logger.info("foo"); | |||
assertThat(listener.msg).endsWith(TEST_STR); | |||
} | |||
@Test | |||
public void testNoListener() throws UnsupportedEncodingException { | |||
System.setOut(new PrintStream(out, false, StandardCharsets.UTF_8.name())); | |||
LoggingConfigurator.apply(conf); | |||
Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
logger.info("info"); | |||
assertThat(new String(out.toByteArray(), StandardCharsets.UTF_8)).contains("info"); | |||
} | |||
@Test | |||
public void testNoSqlClasspath() throws UnsupportedEncodingException { | |||
String classpath = "/org/sonar/batch/bootstrapper/logback.xml"; | |||
conf.setListener(listener); | |||
conf.setShowSql(false); | |||
LoggingConfigurator.apply(conf, classpath); | |||
Logger logger = LoggerFactory.getLogger("java.sql"); | |||
logger.info("foo"); | |||
assertThat(listener.msg).isNull(); | |||
} | |||
} |
@@ -0,0 +1,102 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import ch.qos.logback.core.encoder.EchoEncoder; | |||
import ch.qos.logback.classic.spi.ILoggingEvent; | |||
import org.mockito.Matchers; | |||
import ch.qos.logback.core.encoder.Encoder; | |||
import ch.qos.logback.core.Context; | |||
import org.junit.Test; | |||
import org.junit.Before; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import java.io.PrintStream; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.when; | |||
import static org.mockito.Mockito.verifyNoMoreInteractions; | |||
import static org.mockito.Mockito.times; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.mock; | |||
public class PrintStreamTest { | |||
private static final String TEST_STR = "foo"; | |||
private ByteArrayOutputStream os; | |||
private PrintStream stream; | |||
private PrintStreamAppender<ILoggingEvent> appender; | |||
private Context context = mock(Context.class); | |||
private Encoder<ILoggingEvent> encoder = mock(Encoder.class); | |||
private ILoggingEvent event = mock(ILoggingEvent.class); | |||
@Before | |||
public void setUp() { | |||
os = new ByteArrayOutputStream(); | |||
stream = new PrintStream(os); | |||
appender = new PrintStreamAppender<ILoggingEvent>(stream); | |||
when(event.getMessage()).thenReturn(TEST_STR); | |||
when(event.toString()).thenReturn(TEST_STR); | |||
} | |||
@Test | |||
public void testNullStream() { | |||
appender.setContext(mock(Context.class)); | |||
appender.setEncoder(encoder); | |||
appender.setTarget(null); | |||
appender.start(); | |||
appender.doAppend(event); | |||
verifyNoMoreInteractions(encoder); | |||
} | |||
@Test | |||
public void testEncoder() throws IOException { | |||
appender.setContext(mock(Context.class)); | |||
appender.setEncoder(encoder); | |||
appender.start(); | |||
appender.doAppend(event); | |||
verify(encoder, times(1)).init(Matchers.notNull(OutputStream.class)); | |||
verify(encoder, times(1)).doEncode(event); | |||
} | |||
@Test | |||
public void testWrite() { | |||
encoder = new EchoEncoder<>(); | |||
encoder.setContext(context); | |||
encoder.start(); | |||
appender.setContext(mock(Context.class)); | |||
appender.setEncoder(encoder); | |||
appender.setTarget(stream); | |||
appender.start(); | |||
appender.doAppend(event); | |||
assertThat(os.toString()).isEqualTo(TEST_STR + System.lineSeparator()); | |||
} | |||
} |
@@ -17,38 +17,12 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.api.utils; | |||
import javax.annotation.Nullable; | |||
import java.io.File; | |||
import org.sonar.api.batch.BatchSide; | |||
/** | |||
* Use this component to deal with temp files/folders that have a scope linked to each | |||
* project analysis. | |||
* Root location will typically be the working directory (see sonar.working.directory) | |||
* @since 5.2 | |||
* | |||
*/ | |||
@BatchSide | |||
public interface ProjectTempFolder { | |||
/** | |||
* Create a directory in temp folder with a random unique name. | |||
*/ | |||
File newDir(); | |||
/** | |||
* Create a directory in temp folder using provided name. | |||
*/ | |||
File newDir(String name); | |||
File newFile(); | |||
File newFile(@Nullable String prefix, @Nullable String suffix); | |||
} | |||
package org.sonar.home.log; | |||
public interface LogListener { | |||
public void log(String msg, Level level); | |||
public static enum Level { | |||
ERROR, WARN, INFO, DEBUG, TRACE; | |||
} | |||
} |