import org.sonar.process.Monitored;
import org.sonar.process.ProcessEntryPoint;
import org.sonar.process.Props;
-import org.sonar.server.app.CeProcessLogging;
+import org.sonar.ce.log.CeProcessLogging;
import static com.google.common.base.Preconditions.checkState;
import static org.sonar.process.ProcessUtils.awaitTermination;
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
import java.io.File;
-import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
return propagator;
}
- public ConsoleAppender newConsoleAppender(Context loggerContext, String name, String pattern, @Nullable Filter filter) {
+ public ConsoleAppender newConsoleAppender(Context loggerContext, String name, String pattern, Filter... filters) {
PatternLayoutEncoder consoleEncoder = new PatternLayoutEncoder();
consoleEncoder.setContext(loggerContext);
consoleEncoder.setPattern(pattern);
consoleAppender.setEncoder(consoleEncoder);
consoleAppender.setName(name);
consoleAppender.setTarget("System.out");
- if (filter != null) {
+ for (Filter filter : filters) {
consoleAppender.addFilter(filter);
}
consoleAppender.start();
@Test
public void newConsoleAppender() {
LoggerContext ctx = underTest.getRootContext();
- ConsoleAppender<?> appender = underTest.newConsoleAppender(ctx, "MY_APPENDER", "%msg%n", null);
+ ConsoleAppender<?> appender = underTest.newConsoleAppender(ctx, "MY_APPENDER", "%msg%n");
assertThat(appender.getName()).isEqualTo("MY_APPENDER");
assertThat(appender.getContext()).isSameAs(ctx);
LoggerContext ctx = helper.getRootContext();
ctx.reset();
- ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(ctx, "CONSOLE", LOG_FORMAT, null);
+ ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(ctx, "CONSOLE", LOG_FORMAT);
Logger rootLogger = helper.configureLogger(Logger.ROOT_LOGGER_NAME, Level.INFO);
rootLogger.addAppender(consoleAppender);
return ctx;
import org.slf4j.MDC;
/**
- * Keeps only the Compute Engine logs.
+ * Keeps only Compute Engine activity logs.
*/
public class CeActivityLogAcceptFilter<E> extends Filter<E> {
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ce.log;
+
+import ch.qos.logback.core.filter.Filter;
+import ch.qos.logback.core.spi.FilterReply;
+import java.util.Objects;
+import org.slf4j.MDC;
+
+/**
+ * Ignores Compute Engine activity logs.
+ */
+public class CeActivityLogDenyFilter<E> extends Filter<E> {
+
+ @Override
+ public FilterReply decide(E o) {
+ return Objects.equals("true", MDC.get(CeLogging.MDC_CE_ACTIVITY_FLAG)) ? FilterReply.DENY : FilterReply.ACCEPT;
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ce.log;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.ConsoleAppender;
+import org.sonar.process.LogbackHelper;
+import org.sonar.process.Props;
+import org.sonar.server.app.ServerProcessLogging;
+
+import static org.slf4j.Logger.ROOT_LOGGER_NAME;
+
+/**
+ * Configure logback for the Compute Engine process.
+ * Logs are written to console, which is forwarded to file logs/sonar.log by the app master process.
+ * In addition, CE writes activity logs to "logs/ce_activity.log".
+ */
+public class CeProcessLogging extends ServerProcessLogging {
+
+ public CeProcessLogging() {
+ super("ce");
+ }
+
+ @Override
+ protected void configureAppenders(String logFormat, LoggerContext ctx, LogbackHelper helper, Props props) {
+ ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(ctx, "CONSOLE", logFormat,
+ new CeTaskLogDenyFilter<ILoggingEvent>(), new CeActivityLogDenyFilter());
+ ctx.getLogger(ROOT_LOGGER_NAME).addAppender(consoleAppender);
+ ctx.getLogger(ROOT_LOGGER_NAME).addAppender(CeLogging.createPerTaskAppenderConfiguration(ctx, props));
+ ctx.getLogger(ROOT_LOGGER_NAME).addAppender(CeLogging.createCeActivityAppenderConfiguration(helper, ctx, props));
+ }
+
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.server.app;
-
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import org.sonar.ce.log.CeLogging;
-import org.sonar.process.LogbackHelper;
-import org.sonar.process.Props;
-
-/**
- * Configure logback for the Compute Engine process.
- * Logs are written to console, which is forwarded to file logs/sonar.log by the app master process.
- * In addition, CE writes activity to "logs/ce_activity.log".
- */
-public class CeProcessLogging extends ServerProcessLogging {
-
- public CeProcessLogging() {
- super("ce");
- }
-
- @Override
- protected void configureExtraAppenders(LoggerContext ctx, LogbackHelper helper, Props props) {
- ctx.getLogger(Logger.ROOT_LOGGER_NAME).addAppender(CeLogging.createPerTaskAppenderConfiguration(ctx, props));
- ctx.getLogger(Logger.ROOT_LOGGER_NAME).addAppender(CeLogging.createCeActivityAppenderConfiguration(helper, ctx, props));
- }
-
-}
*/
package org.sonar.server.app;
-import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.ConsoleAppender;
import java.util.logging.LogManager;
import org.slf4j.bridge.SLF4JBridgeHandler;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.ce.log.CeTaskLogDenyFilter;
import org.sonar.process.LogbackHelper;
import org.sonar.process.Props;
import org.sonar.server.platform.ServerLogging;
-abstract class ServerProcessLogging {
+public abstract class ServerProcessLogging {
private static final String LOG_LEVEL_PROPERTY = "sonar.log.level";
private static final String LOG_FORMAT = "%d{yyyy.MM.dd HH:mm:ss} %-5level XXXX[%logger{20}] %msg%n";
private final String processName;
private final LogbackHelper helper = new LogbackHelper();
- ServerProcessLogging(String processName) {
+ protected ServerProcessLogging(String processName) {
this.processName = processName;
}
private void configureAppenders(LoggerContext ctx, Props props) {
String logFormat = LOG_FORMAT.replace("XXXX", processName);
- ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(ctx, "CONSOLE", logFormat, new CeTaskLogDenyFilter<ILoggingEvent>());
- ctx.getLogger(Logger.ROOT_LOGGER_NAME).addAppender(consoleAppender);
- configureExtraAppenders(ctx, helper, props);
+ configureAppenders(logFormat, ctx, helper, props);
}
- protected abstract void configureExtraAppenders(LoggerContext ctx, LogbackHelper helper, Props props);
+ protected abstract void configureAppenders(String logFormat, LoggerContext ctx, LogbackHelper helper, Props props);
private void configureLevels(Props props) {
String levelCode = props.value(LOG_LEVEL_PROPERTY, "INFO");
*/
package org.sonar.server.app;
+import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.ConsoleAppender;
import org.sonar.process.LogbackHelper;
import org.sonar.process.Props;
}
@Override
- protected void configureExtraAppenders(LoggerContext ctx, LogbackHelper helper, Props props) {
- // nothing to do
+ protected void configureAppenders(String logFormat, LoggerContext ctx, LogbackHelper helper, Props props) {
+ ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(ctx, "CONSOLE", logFormat);
+ ctx.getLogger(Logger.ROOT_LOGGER_NAME).addAppender(consoleAppender);
}
}
private static Profiler startProfiler(CeTask task) {
Profiler profiler = Profiler.create(LOG);
addContext(profiler, task);
- return profiler.startInfo("Execute task");
+ return profiler.startDebug("Execute task");
}
private static Profiler startActivityProfiler(CeTask task) {
}
private static void stopProfiler(Profiler profiler, CeTask task, CeActivityDto.Status status) {
+ if (!profiler.isDebugEnabled()) {
+ return;
+ }
+
addContext(profiler, task);
if (status == CeActivityDto.Status.FAILED) {
profiler.stopError("Executed task");
} else {
- profiler.stopInfo("Executed task");
+ profiler.stopDebug("Executed task");
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ce.log;
+
+import ch.qos.logback.core.spi.FilterReply;
+import org.apache.log4j.MDC;
+import org.junit.After;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.ce.log.CeLogging.MDC_CE_ACTIVITY_FLAG;
+
+public class CeActivityLogAcceptFilterTest {
+ private static final Object UNUSED = "";
+
+ private CeActivityLogAcceptFilter underTest = new CeActivityLogAcceptFilter();
+
+ @After
+ public void tearDown() {
+ MDC.clear();
+ }
+
+ @Test
+ public void rejects_logs_when_property_is_not_set_in_MDC() {
+ assertThat(underTest.decide(UNUSED)).isEqualTo(FilterReply.DENY);
+ }
+
+ @Test
+ public void rejects_logs_when_property_is_not_true_in_MDC() {
+ MDC.put(MDC_CE_ACTIVITY_FLAG, "bla");
+ assertThat(underTest.decide(UNUSED)).isEqualTo(FilterReply.DENY);
+ }
+
+ @Test
+ public void rejects_logs_when_property_is_not_true_in_lowercase_in_MDC() {
+ MDC.put(MDC_CE_ACTIVITY_FLAG, "TrUE");
+ assertThat(underTest.decide(UNUSED)).isEqualTo(FilterReply.DENY);
+ }
+
+ @Test
+ public void accepts_logs_when_property_is_true_in_lowercase_in_MDC() {
+ MDC.put(MDC_CE_ACTIVITY_FLAG, "true");
+ assertThat(underTest.decide(UNUSED)).isEqualTo(FilterReply.ACCEPT);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ce.log;
+
+import ch.qos.logback.core.spi.FilterReply;
+import org.apache.log4j.MDC;
+import org.junit.After;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.ce.log.CeLogging.MDC_CE_ACTIVITY_FLAG;
+
+public class CeActivityLogDenyFilterTest {
+ private static final Object UNUSED = "";
+
+ private CeActivityLogDenyFilter underTest = new CeActivityLogDenyFilter();
+
+ @After
+ public void tearDown() {
+ MDC.clear();
+ }
+
+ @Test
+ public void accepts_logs_when_property_is_not_set_in_MDC() {
+ assertThat(underTest.decide(UNUSED)).isEqualTo(FilterReply.ACCEPT);
+ }
+
+ @Test
+ public void acceots_logs_when_property_is_not_true_in_MDC() {
+ MDC.put(MDC_CE_ACTIVITY_FLAG, "bla");
+ assertThat(underTest.decide(UNUSED)).isEqualTo(FilterReply.ACCEPT);
+ }
+
+ @Test
+ public void accepts_logs_when_property_is_not_true_in_lowercase_in_MDC() {
+ MDC.put(MDC_CE_ACTIVITY_FLAG, "TrUE");
+ assertThat(underTest.decide(UNUSED)).isEqualTo(FilterReply.ACCEPT);
+ }
+
+ @Test
+ public void rejects_logs_when_property_is_true_in_lowercase_in_MDC() {
+ MDC.put(MDC_CE_ACTIVITY_FLAG, "true");
+ assertThat(underTest.decide(UNUSED)).isEqualTo(FilterReply.DENY);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ce.log;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.ConsoleAppender;
+import ch.qos.logback.core.joran.spi.JoranException;
+import java.io.IOException;
+import java.util.Properties;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.process.LogbackHelper;
+import org.sonar.process.ProcessProperties;
+import org.sonar.process.Props;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CeProcessLoggingTest {
+
+ private static final String LOG_LEVEL_PROPERTY = "sonar.log.level";
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ private Props props = new Props(new Properties());
+ private CeProcessLogging underTest = new CeProcessLogging();
+
+ /**
+ * Path to data dir must be set for Compute Engine logging.
+ * @see CeFileAppenderFactory
+ * Path to log dir must be set for Compute Engine Activity logging.
+ * @see org.sonar.ce.log.CeLogging#createCeActivityAppenderConfiguration(LogbackHelper, LoggerContext, Props)
+ */
+ @Before
+ public void setUp() throws IOException {
+ props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
+ props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
+ }
+
+ @AfterClass
+ public static void resetLogback() throws JoranException {
+ new LogbackHelper().resetFromXml("/logback-test.xml");
+ }
+
+ @Test
+ public void log_to_console() {
+ LoggerContext ctx = underTest.configure(props);
+
+ Logger root = ctx.getLogger(Logger.ROOT_LOGGER_NAME);
+ Appender appender = root.getAppender("CONSOLE");
+ assertThat(appender).isInstanceOf(ConsoleAppender.class);
+
+ // default level is INFO
+ assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.INFO);
+ // change level of some loggers
+ assertThat(ctx.getLogger("java.sql").getLevel()).isEqualTo(Level.WARN);
+ }
+
+ @Test
+ public void enable_debug_logs() {
+ props.set(LOG_LEVEL_PROPERTY, "DEBUG");
+ LoggerContext ctx = underTest.configure(props);
+ assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.DEBUG);
+ }
+
+ @Test
+ public void enable_trace_logs() {
+ props.set(LOG_LEVEL_PROPERTY, "TRACE");
+ LoggerContext ctx = underTest.configure(props);
+ assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.TRACE);
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.server.app;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.ConsoleAppender;
-import ch.qos.logback.core.joran.spi.JoranException;
-import java.io.IOException;
-import java.util.Properties;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.ce.log.CeFileAppenderFactory;
-import org.sonar.process.LogbackHelper;
-import org.sonar.process.ProcessProperties;
-import org.sonar.process.Props;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class CeProcessLoggingTest {
-
- private static final String LOG_LEVEL_PROPERTY = "sonar.log.level";
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- Props props = new Props(new Properties());
- CeProcessLogging underTest = new CeProcessLogging();
-
- /**
- * Path to data dir must be set for Compute Engine logging.
- * @see CeFileAppenderFactory
- * Path to log dir must be set for Compute Engine Activity logging.
- * @see org.sonar.ce.log.CeLogging#createCeActivityAppenderConfiguration(LogbackHelper, LoggerContext, Props)
- */
- @Before
- public void setUp() throws IOException {
- props.set(ProcessProperties.PATH_DATA, temp.newFolder().getAbsolutePath());
- props.set(ProcessProperties.PATH_LOGS, temp.newFolder().getAbsolutePath());
- }
-
- @AfterClass
- public static void resetLogback() throws JoranException {
- new LogbackHelper().resetFromXml("/logback-test.xml");
- }
-
- @Test
- public void log_to_console() {
- LoggerContext ctx = underTest.configure(props);
-
- Logger root = ctx.getLogger(Logger.ROOT_LOGGER_NAME);
- Appender appender = root.getAppender("CONSOLE");
- assertThat(appender).isInstanceOf(ConsoleAppender.class);
-
- // default level is INFO
- assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.INFO);
- // change level of some loggers
- assertThat(ctx.getLogger("java.sql").getLevel()).isEqualTo(Level.WARN);
- }
-
- @Test
- public void enable_debug_logs() {
- props.set(LOG_LEVEL_PROPERTY, "DEBUG");
- LoggerContext ctx = underTest.configure(props);
- assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.DEBUG);
- }
-
- @Test
- public void enable_trace_logs() {
- props.set(LOG_LEVEL_PROPERTY, "TRACE");
- LoggerContext ctx = underTest.configure(props);
- assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.TRACE);
- }
-}
ProgrammaticLogbackValve valve = new ProgrammaticLogbackValve();
valve.setContainer(mock(Container.class));
LogbackHelper helper = new LogbackHelper();
- ConsoleAppender<IAccessEvent> appender = helper.newConsoleAppender(valve, "CONSOLE", "combined", null);
+ ConsoleAppender<IAccessEvent> appender = helper.newConsoleAppender(valve, "CONSOLE", "combined");
valve.addAppender(appender);
valve.start();
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.server.app;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.ConsoleAppender;
-import ch.qos.logback.core.joran.spi.JoranException;
-import java.util.Properties;
-import org.junit.AfterClass;
-import org.junit.Test;
-import org.sonar.process.LogbackHelper;
-import org.sonar.process.Props;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class ServerProcessLoggingTest {
-
- private static final String LOG_LEVEL_PROPERTY = "sonar.log.level";
- private static final String PROCESS_NAME = "pr1";
-
- Props props = new Props(new Properties());
- ServerProcessLogging underTest = new ServerProcessLogging(PROCESS_NAME) {
- @Override
- protected void configureExtraAppenders(LoggerContext ctx, LogbackHelper helper, Props props) {
- // nothing to do
- }
- };
-
- @AfterClass
- public static void resetLogback() throws JoranException {
- new LogbackHelper().resetFromXml("/logback-test.xml");
- }
-
- @Test
- public void log_to_console() {
- LoggerContext ctx = underTest.configure(props);
-
- Logger root = ctx.getLogger(Logger.ROOT_LOGGER_NAME);
- Appender appender = root.getAppender("CONSOLE");
- assertThat(appender).isInstanceOf(ConsoleAppender.class);
-
- // default level is INFO
- assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.INFO);
- // change level of some loggers
- assertThat(ctx.getLogger("java.sql").getLevel()).isEqualTo(Level.WARN);
- }
-
- @Test
- public void enable_debug_logs() {
- props.set(LOG_LEVEL_PROPERTY, "DEBUG");
- LoggerContext ctx = underTest.configure(props);
- assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.DEBUG);
- }
-
- @Test
- public void enable_trace_logs() {
- props.set(LOG_LEVEL_PROPERTY, "TRACE");
- LoggerContext ctx = underTest.configure(props);
- assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.TRACE);
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.app;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.ConsoleAppender;
+import ch.qos.logback.core.joran.spi.JoranException;
+import java.util.Properties;
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.sonar.process.LogbackHelper;
+import org.sonar.process.Props;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class WebServerProcessLoggingTest {
+ private WebServerProcessLogging underTest = new WebServerProcessLogging();
+
+ private static final String LOG_LEVEL_PROPERTY = "sonar.log.level";
+
+ Props props = new Props(new Properties());
+
+ @AfterClass
+ public static void resetLogback() throws JoranException {
+ new LogbackHelper().resetFromXml("/logback-test.xml");
+ }
+
+ @Test
+ public void log_to_console() {
+ LoggerContext ctx = underTest.configure(props);
+
+ Logger root = ctx.getLogger(Logger.ROOT_LOGGER_NAME);
+ Appender appender = root.getAppender("CONSOLE");
+ assertThat(appender).isInstanceOf(ConsoleAppender.class);
+
+ // default level is INFO
+ assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.INFO);
+ // change level of some loggers
+ assertThat(ctx.getLogger("java.sql").getLevel()).isEqualTo(Level.WARN);
+ }
+
+ @Test
+ public void enable_debug_logs() {
+ props.set(LOG_LEVEL_PROPERTY, "DEBUG");
+ LoggerContext ctx = underTest.configure(props);
+ assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.DEBUG);
+ }
+
+ @Test
+ public void enable_trace_logs() {
+ props.set(LOG_LEVEL_PROPERTY, "TRACE");
+ LoggerContext ctx = underTest.configure(props);
+ assertThat(ctx.getLogger(Logger.ROOT_LOGGER_NAME).getLevel()).isEqualTo(Level.TRACE);
+ }
+
+}
inOrder.verify(ceLogging).clearForTask();
}
- private void makeTaskProcessorFail(CeTask task) {
- doThrow(new IllegalStateException("simulate exception thrown by TaskProcessor#process")).when(taskProcessor).process(task);
- }
-
@Test
public void do_not_display_submitter_param_in_log_when_submitterLogin_is_not_set_in_case_of_success() throws Exception {
when(queue.peek()).thenReturn(Optional.of(createCeTask(null)));
underTest.call();
List<String> logs = logTester.logs(LoggerLevel.INFO);
- assertThat(logs).hasSize(4);
- for (int i = 0; i < 4; i++) {
+ assertThat(logs).hasSize(2);
+ for (int i = 0; i < 2; i++) {
assertThat(logs.get(i)).doesNotContain(" | submitter=");
}
}
underTest.call();
List<String> logs = logTester.logs(LoggerLevel.INFO);
+ assertThat(logs).hasSize(1);
+ assertThat(logs.get(0)).doesNotContain(" | submitter=");
+ logs = logTester.logs(LoggerLevel.ERROR);
assertThat(logs).hasSize(2);
for (int i = 0; i < 2; i++) {
assertThat(logs.get(i)).doesNotContain(" | submitter=");
}
- logs = logTester.logs(LoggerLevel.ERROR);
- assertThat(logs).hasSize(3);
- for (int i = 0; i < 3; i++) {
- assertThat(logs.get(i)).doesNotContain(" | submitter=");
- }
+ assertThat(logTester.logs(LoggerLevel.DEBUG)).isEmpty();
}
@Test
underTest.call();
List<String> logs = logTester.logs(LoggerLevel.INFO);
- assertThat(logs).hasSize(4);
- for (int i = 0; i < 2; i++) {
- assertThat(logs.get(i)).contains(" | submitter=FooBar");
- }
- for (int i = 2; i < 4; i++) {
- assertThat(logs.get(i)).contains(" | submitter=FooBar | time=");
- }
+ assertThat(logs).hasSize(2);
+ assertThat(logs.get(0)).contains(" | submitter=FooBar");
+ assertThat(logs.get(1)).contains(" | submitter=FooBar | time=");
+ assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty();
+ assertThat(logTester.logs(LoggerLevel.DEBUG)).isEmpty();
}
@Test
underTest.call();
List<String> logs = logTester.logs(LoggerLevel.INFO);
+ assertThat(logs).hasSize(1);
+ assertThat(logs.iterator().next()).contains(" | submitter=FooBar");
+ logs = logTester.logs(LoggerLevel.ERROR);
assertThat(logs).hasSize(2);
- for (int i = 0; i < 2; i++) {
- assertThat(logs.get(i)).contains(" | submitter=FooBar");
- }
+ assertThat(logs.get(0)).isEqualTo("Failed to execute task " + ceTask.getUuid());
+ assertThat(logs.get(1)).contains(" | submitter=FooBar | time=");
+ }
+
+ @Test
+ public void display_start_stop_at_debug_level_for_console_if_DEBUG_is_enabled_and_task_successful() throws Exception {
+ logTester.setLevel(LoggerLevel.DEBUG);
+
+ when(queue.peek()).thenReturn(Optional.of(createCeTask("FooBar")));
+ taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
+
+ underTest.call();
+
+ List<String> logs = logTester.logs(LoggerLevel.INFO);
+ assertThat(logs).hasSize(2);
+ assertThat(logs.get(0)).contains(" | submitter=FooBar");
+ assertThat(logs.get(1)).contains(" | submitter=FooBar | time=");
+ assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty();
+ logs = logTester.logs(LoggerLevel.DEBUG);
+ assertThat(logs).hasSize(2);
+ assertThat(logs.get(0)).contains(" | submitter=FooBar");
+ assertThat(logs.get(1)).contains(" | submitter=FooBar | time=");
+ }
+
+ @Test
+ public void display_start_at_debug_level_stop_at_error_level_for_console_if_DEBUG_is_enabled_and_task_failed() throws Exception {
+ logTester.setLevel(LoggerLevel.DEBUG);
+
+ CeTask ceTask = createCeTask("FooBar");
+ when(queue.peek()).thenReturn(Optional.of(ceTask));
+ taskProcessorRepository.setProcessorForTask(CeTaskTypes.REPORT, taskProcessor);
+ makeTaskProcessorFail(ceTask);
+
+ underTest.call();
+
+ List<String> logs = logTester.logs(LoggerLevel.INFO);
+ assertThat(logs).hasSize(1);
+ assertThat(logs.iterator().next()).contains(" | submitter=FooBar");
logs = logTester.logs(LoggerLevel.ERROR);
assertThat(logs).hasSize(3);
- for (int i = 0; i < 3; i++) {
- String log = logs.get(i);
- assertThat(log.contains(" | submitter=FooBar | time=") || log.equals("Failed to execute task " + ceTask.getUuid()))
- .isTrue();
- }
+ assertThat(logs.get(0)).isEqualTo("Failed to execute task " + ceTask.getUuid());
+ assertThat(logs.get(1)).contains(" | submitter=FooBar | time=");
+ assertThat(logs.get(2)).contains(" | submitter=FooBar | time=");
+ logs = logTester.logs(LoggerLevel.DEBUG);
+ assertThat(logs).hasSize(1);
+ assertThat(logs.get(0)).contains(" | submitter=FooBar");
}
private static CeTask createCeTask(@Nullable String submitterLogin) {
return new CeTask.Builder().setUuid("TASK_1").setType(CeTaskTypes.REPORT).setComponentUuid("PROJECT_1").setSubmitterLogin(submitterLogin).build();
}
+
+ private void makeTaskProcessorFail(CeTask task) {
+ doThrow(new IllegalStateException("simulate exception thrown by TaskProcessor#process")).when(taskProcessor).process(task);
+ }
}
}
private void configureConsole(LoggerContext loggerContext) {
- ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(loggerContext, CONSOLE_APPENDER, "%msg%n", null);
+ ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(loggerContext, CONSOLE_APPENDER, "%msg%n");
Logger consoleLogger = loggerContext.getLogger(CONSOLE_LOGGER);
consoleLogger.setAdditive(false);
consoleLogger.addAppender(consoleAppender);
}
private void configureRoot(Props props, LoggerContext loggerContext) {
- ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(loggerContext, "ROOT_CONSOLE", APP_PATTERN, null);
+ ConsoleAppender<ILoggingEvent> consoleAppender = helper.newConsoleAppender(loggerContext, "ROOT_CONSOLE", APP_PATTERN);
Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
rootLogger.setLevel(Level.toLevel(props.value("sonar.app.log.level", Level.INFO.toString()), Level.INFO));
rootLogger.addAppender(consoleAppender);