--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.core.profiling;
+
+import org.slf4j.Logger;
+
+class LoggingWatch extends StopWatch {
+
+ private Logger logger;
+ private long startTimeInMillis;
+
+ LoggingWatch(Logger logger) {
+ this.logger = logger;
+ this.startTimeInMillis = System.currentTimeMillis();
+ }
+
+ @Override
+ public void stop(String message, Object... args) {
+ long endTimeInMillis = System.currentTimeMillis();
+ logger.info("{}ms {}", Long.valueOf(endTimeInMillis - startTimeInMillis), String.format(message, args));
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.core.profiling;
+
+
+class NoopWatch extends StopWatch {
+
+ @Override
+ public void stop(String message, Object... args) {
+ // Nothing logged
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.core.profiling;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.ServerExtension;
+import org.sonar.api.config.Settings;
+
+/**
+ * @since 4.1
+ */
+public final class Profiling implements ServerExtension {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Profiling.class);
+
+ private Settings settings;
+ private ProfilingLogFactory logFactory;
+
+ public enum Level {
+ NONE, BASIC, FULL;
+ }
+
+ public Profiling(Settings settings) {
+ this(settings, new ProfilingLogFactory());
+ }
+
+ Profiling(Settings settings, ProfilingLogFactory logFactory) {
+ this.settings = settings;
+ this.logFactory = logFactory;
+ }
+
+
+ public StopWatch start(String domain, Level level) {
+ StopWatch watch;
+ if (isProfilingEnabled(level)) {
+ watch = new LoggingWatch(logFactory.getLogger(domain));
+ } else {
+ watch = new NoopWatch();
+ }
+ return watch;
+ }
+
+ private boolean isProfilingEnabled(Level level) {
+ String settingsValue = settings.getString("sonar.log.profilingLevel");
+ Level settingsLevel = Level.NONE;
+ if (settingsValue != null) {
+ try {
+ settingsLevel = Level.valueOf(settingsValue);
+ } catch(IllegalArgumentException invalidSettings) {
+ LOGGER.debug("Bad profiling settings, profiling is disabled", invalidSettings);
+ }
+ }
+ return settingsLevel != Level.NONE && level.ordinal() <= settingsLevel.ordinal();
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.core.profiling;
+
+import org.slf4j.LoggerFactory;
+
+import org.slf4j.Logger;
+
+class ProfilingLogFactory {
+
+ public Logger getLogger(String domain) {
+ return LoggerFactory.getLogger(domain);
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.core.profiling;
+
+public abstract class StopWatch {
+
+ public abstract void stop(String message, Object... args);
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.core.profiling;
+
+import org.junit.Test;
+
+public class ProfilingLogFactoryTest {
+
+ @Test
+ public void just_for_coverage() throws Exception {
+ new ProfilingLogFactory().getLogger("domain");
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.core.profiling;
+
+import static org.mockito.Mockito.mock;
+
+import org.slf4j.Logger;
+
+import org.mockito.Mockito;
+import org.sonar.core.profiling.Profiling.Level;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+
+public class ProfilingTest {
+
+ private Settings settings;
+ private ProfilingLogFactory logFactory;
+ private Logger logger;
+ private Profiling profiling;
+
+ private static final String BASIC_MESSAGE = "Basic message";
+ private static final String FULL_MESSAGE = "Full message";
+
+ @Before
+ public void prepare() {
+ settings = new Settings();
+ logFactory = mock(ProfilingLogFactory.class);
+ logger = mock(Logger.class);
+ Mockito.when(logFactory.getLogger(Mockito.anyString())).thenReturn(logger);
+ profiling = new Profiling(settings, logFactory);
+ }
+
+ @Test
+ public void should_silence_all_profiling_by_default() throws Exception {
+ doProfiling();
+ Mockito.verifyZeroInteractions(logger);
+ }
+
+ @Test
+ public void should_silence_all_profiling_when_faulty_config() throws Exception {
+ settings.setProperty("sonar.log.profilingLevel", "POLOP");
+ doProfiling();
+ Mockito.verifyZeroInteractions(logger);
+ }
+
+ @Test
+ public void should_silence_all_profiling() throws Exception {
+ settings.setProperty("sonar.log.profilingLevel", "NONE");
+ doProfiling();
+ Mockito.verifyZeroInteractions(logger);
+ }
+
+ @Test
+ public void should_log_basic_level() throws Exception {
+ settings.setProperty("sonar.log.profilingLevel", "BASIC");
+ doProfiling();
+ Mockito.verify(logger).info(Mockito.eq("{}ms {}"), Mockito.anyLong(), Mockito.eq(BASIC_MESSAGE));
+ Mockito.verifyNoMoreInteractions(logger);
+ }
+
+ @Test
+ public void should_log_everything() throws Exception {
+ settings.setProperty("sonar.log.profilingLevel", "FULL");
+ doProfiling();
+ Mockito.verify(logger).info(Mockito.eq("{}ms {}"), Mockito.anyLong(), Mockito.eq(FULL_MESSAGE));
+ Mockito.verify(logger).info(Mockito.eq("{}ms {}"), Mockito.anyLong(), Mockito.eq(BASIC_MESSAGE));
+ }
+
+ private void doProfiling() throws InterruptedException {
+ StopWatch basicWatch = profiling.start("basic", Level.BASIC);
+ StopWatch fullWatch = profiling.start("full", Level.FULL);
+ Thread.sleep(42);
+ fullWatch.stop(FULL_MESSAGE);
+ basicWatch.stop(BASIC_MESSAGE);
+ }
+
+}