diff options
author | Julien Camus <julien.camus@sonarsource.com> | 2024-12-27 15:22:10 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-12-27 20:03:07 +0000 |
commit | 643821403bceec551ad5305d80fd43bc63895e4f (patch) | |
tree | b5523e048ea76741412391be28a6625369afdf76 | |
parent | 670f4a2337ceeb3cce78cbff249a5b3ba6f3e319 (diff) | |
download | sonarqube-643821403bceec551ad5305d80fd43bc63895e4f.tar.gz sonarqube-643821403bceec551ad5305d80fd43bc63895e4f.zip |
SONAR-24021 Invoke method(s) only conditionally
77 files changed, 509 insertions, 282 deletions
diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/azure/AzureDevOpsHttpClient.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/azure/AzureDevOpsHttpClient.java index 80c9bd0ae91..dab314de2f5 100644 --- a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/azure/AzureDevOpsHttpClient.java +++ b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/azure/AzureDevOpsHttpClient.java @@ -141,21 +141,19 @@ public class AzureDevOpsHttpClient { protected static void checkResponseIsSuccessful(Response response) throws IOException { if (!response.isSuccessful()) { if (response.code() == HttpURLConnection.HTTP_UNAUTHORIZED) { - LOG.error(String.format(UNABLE_TO_CONTACT_AZURE_SERVER + " for request [%s]: Invalid personal access token", - response.request().url())); + LOG.error("{} for request [{}]: Invalid personal access token", UNABLE_TO_CONTACT_AZURE_SERVER, response.request().url()); throw new AzureDevopsServerException(response.code(), "Invalid personal access token"); } if (response.code() == HttpURLConnection.HTTP_NOT_FOUND) { - LOG.error(String.format(UNABLE_TO_CONTACT_AZURE_SERVER + " for request [%s]: URL Not Found", - response.request().url())); + LOG.error("{} for request [{}]: URL Not Found", UNABLE_TO_CONTACT_AZURE_SERVER, response.request().url()); throw new AzureDevopsServerException(response.code(), "Invalid Azure URL"); } ResponseBody responseBody = response.body(); String body = responseBody == null ? "" : responseBody.string(); String errorMessage = generateErrorMessage(body, UNABLE_TO_CONTACT_AZURE_SERVER); - LOG.error(String.format("Azure API call to [%s] failed with %s http code. Azure response content : [%s]", response.request().url(), response.code(), body)); + LOG.error("Azure API call to [{}] failed with {} http code. Azure response content : [{}]", response.request().url(), response.code(), body); throw new AzureDevopsServerException(response.code(), errorMessage); } } diff --git a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/bitbucket/bitbucketcloud/BitbucketCloudRestClient.java b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/bitbucket/bitbucketcloud/BitbucketCloudRestClient.java index 6737e8e5b3d..3d1b04b2657 100644 --- a/server/sonar-alm-client/src/main/java/org/sonar/alm/client/bitbucket/bitbucketcloud/BitbucketCloudRestClient.java +++ b/server/sonar-alm-client/src/main/java/org/sonar/alm/client/bitbucket/bitbucketcloud/BitbucketCloudRestClient.java @@ -22,12 +22,12 @@ package org.sonar.alm.client.bitbucket.bitbucketcloud; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonParseException; +import jakarta.inject.Inject; import java.io.IOException; import java.util.Objects; import java.util.function.Function; import java.util.function.UnaryOperator; import javax.annotation.Nullable; -import jakarta.inject.Inject; import okhttp3.Credentials; import okhttp3.FormBody; import okhttp3.HttpUrl; @@ -37,9 +37,9 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; -import org.sonar.api.server.ServerSide; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.server.ServerSide; import org.sonar.server.exceptions.NotFoundException; import static org.apache.commons.lang3.StringUtils.removeEnd; @@ -67,7 +67,6 @@ public class BitbucketCloudRestClient { private final String bitbucketCloudEndpoint; private final String accessTokenEndpoint; - @Inject public BitbucketCloudRestClient(OkHttpClient bitBucketCloudHttpClient) { this(bitBucketCloudHttpClient, ENDPOINT, ACCESS_TOKEN_ENDPOINT); @@ -86,7 +85,10 @@ public class BitbucketCloudRestClient { Token token = validateAccessToken(clientId, clientSecret); if (token.getScopes() == null || !token.getScopes().contains("pullrequest")) { - LOG.info(MISSING_PULL_REQUEST_READ_PERMISSION + String.format(SCOPE, token.getScopes())); + LOG.atInfo() + .addArgument(MISSING_PULL_REQUEST_READ_PERMISSION) + .addArgument(() -> String.format(SCOPE, token.getScopes())) + .log("{}{}"); throw new IllegalArgumentException(ERROR_BBC_SERVERS + ": " + MISSING_PULL_REQUEST_READ_PERMISSION); } @@ -117,7 +119,7 @@ public class BitbucketCloudRestClient { ErrorDetails errorMsg = getTokenError(response.body()); if (errorMsg.body != null) { - LOG.info(String.format(BBC_FAIL_WITH_RESPONSE, response.request().url(), response.code(), errorMsg.body)); + LOG.atInfo().log(() -> String.format(BBC_FAIL_WITH_RESPONSE, response.request().url(), response.code(), errorMsg.body)); switch (errorMsg.body) { case "invalid_grant": throw new IllegalArgumentException(UNABLE_TO_CONTACT_BBC_SERVERS + ": " + OAUTH_CONSUMER_NOT_PRIVATE); @@ -131,7 +133,7 @@ public class BitbucketCloudRestClient { } } } else { - LOG.info(String.format(BBC_FAIL_WITH_RESPONSE, response.request().url(), response.code(), response.message())); + LOG.atInfo().log(() -> String.format(BBC_FAIL_WITH_RESPONSE, response.request().url(), response.code(), response.message())); } throw new IllegalArgumentException(UNABLE_TO_CONTACT_BBC_SERVERS); @@ -194,7 +196,7 @@ public class BitbucketCloudRestClient { private static void handleError(Response response) throws IOException { ErrorDetails error = getError(response.body()); - LOG.info(String.format(BBC_FAIL_WITH_RESPONSE, response.request().url(), response.code(), error.body)); + LOG.atInfo().log(() -> String.format(BBC_FAIL_WITH_RESPONSE, response.request().url(), response.code(), error.body)); if (error.parsedErrorMsg != null) { throw new IllegalStateException(ERROR_BBC_SERVERS + ": " + error.parsedErrorMsg); } else { diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ScmAccountToUserLoader.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ScmAccountToUserLoader.java index a81b4311676..b7e050b9417 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ScmAccountToUserLoader.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ScmAccountToUserLoader.java @@ -55,9 +55,10 @@ public class ScmAccountToUserLoader implements CacheLoader<String, UserIdDto> { .map(UserIdDto::getLogin) .sorted() .toList(); - if (LOGGER.isWarnEnabled()) { - LOGGER.warn(String.format("Multiple users share the SCM account '%s': %s", scmAccount, Joiner.on(", ").join(logins))); - } + LOGGER.atWarn() + .addArgument(scmAccount) + .addArgument(Joiner.on(", ").join(logins)) + .log("Multiple users share the SCM account '{}': {}"); } return null; } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/purge/ProjectCleaner.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/purge/ProjectCleaner.java index 68816223400..b34d8b8d3ec 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/purge/ProjectCleaner.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/purge/ProjectCleaner.java @@ -71,7 +71,9 @@ public class ProjectCleaner { if (config.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY).orElse(false)) { long duration = System.currentTimeMillis() - start; LOG.info(""); - LOG.atInfo().setMessage(" -------- Profiling for purge: {} --------").addArgument(() -> TimeUtils.formatDuration(duration)).log(); + LOG.atInfo() + .addArgument(() -> TimeUtils.formatDuration(duration)) + .log(" -------- Profiling for purge: {} --------"); LOG.info(""); for (String line : profiler.getProfilingResult(duration)) { LOG.info(line); diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java index 39ac9561d1c..e38438a1959 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitor.java @@ -163,7 +163,7 @@ public class NewMaintainabilityMeasuresVisitor extends PathAwareVisitorAdapter<N Optional<Set<Integer>> changedLines = newLinesRepository.getNewLines(file); if (!changedLines.isPresent()) { - LOG.trace(String.format("No information about changed lines is available for file '%s'. Dev cost will be zero.", file.getKey())); + LOG.trace("No information about changed lines is available for file '{}'. Dev cost will be zero.", file.getKey()); return; } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/QualityGateEventsStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/QualityGateEventsStep.java index 59bde0b2302..c90adcacc54 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/QualityGateEventsStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/QualityGateEventsStep.java @@ -23,9 +23,9 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.sonar.api.measures.CoreMetrics; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.measures.CoreMetrics; import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.ce.task.projectanalysis.analysis.Branch; import org.sonar.ce.task.projectanalysis.component.Component; @@ -95,7 +95,7 @@ public class QualityGateEventsStep implements ComputationStep { } if (!baseMeasure.get().hasQualityGateStatus()) { - LOGGER.warn(String.format("Previous Quality gate status for project %s is not a supported value. Can not compute Quality Gate event", project.getKey())); + LOGGER.warn("Previous Quality gate status for project {} is not a supported value. Can not compute Quality Gate event", project.getKey()); checkNewQualityGate(project, rawStatus); return; } diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectexport/steps/DumpWriterImpl.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectexport/steps/DumpWriterImpl.java index 0bf9d511332..e682aa098be 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectexport/steps/DumpWriterImpl.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectexport/steps/DumpWriterImpl.java @@ -25,8 +25,8 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; -import org.sonar.api.utils.TempFolder; import org.slf4j.LoggerFactory; +import org.sonar.api.utils.TempFolder; import org.sonar.ce.task.projectexport.taskprocessor.ProjectDescriptor; import org.sonar.ce.task.projectexport.util.ProjectExportDumpFS; @@ -88,7 +88,10 @@ public class DumpWriterImpl implements DumpWriter { FILES2.deleteIfExists(targetZip); FILES2.moveFile(zip, targetZip); FILES2.deleteIfExists(rootDir); - LoggerFactory.getLogger(getClass()).info("Dump file published | size={} | path={}", humanReadableByteCountSI(sizeOf(targetZip)), targetZip.getAbsolutePath()); + LoggerFactory.getLogger(getClass()).atInfo() + .addArgument(humanReadableByteCountSI(sizeOf(targetZip))) + .addArgument(targetZip.getAbsolutePath()) + .log("Dump file published | size={} | path={}"); published.set(true); } diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java index 0550bead69c..699b0a4d866 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java @@ -226,8 +226,9 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { level4.startComponents(); PlatformEditionProvider editionProvider = level4.getComponentByType(PlatformEditionProvider.class); - LoggerFactory.getLogger(ComputeEngineContainerImpl.class) - .info("Running {} edition", editionProvider.get().map(EditionProvider.Edition::getLabel).orElse("")); + LoggerFactory.getLogger(ComputeEngineContainerImpl.class).atInfo() + .addArgument(() -> editionProvider.get().map(EditionProvider.Edition::getLabel).orElse("")) + .log("Running {} edition"); } private void startupTasks() { diff --git a/server/sonar-db-core/src/main/java/org/sonar/db/DefaultDatabase.java b/server/sonar-db-core/src/main/java/org/sonar/db/DefaultDatabase.java index b29d832f23e..365232f6e85 100644 --- a/server/sonar-db-core/src/main/java/org/sonar/db/DefaultDatabase.java +++ b/server/sonar-db-core/src/main/java/org/sonar/db/DefaultDatabase.java @@ -96,8 +96,7 @@ public class DefaultDatabase implements Database { JDBC_MAX_LIFETIME.getKey(), "sonar.jdbc.leakDetectionThreshold", JDBC_MAX_KEEP_ALIVE_TIME.getKey(), - JDBC_MAX_IDLE_TIMEOUT.getKey() - ); + JDBC_MAX_IDLE_TIMEOUT.getKey()); private static final Map<String, String> SONAR_JDBC_TO_HIKARI_PROPERTY_MAPPINGS = Map.of( JDBC_USERNAME.getKey(), "dataSource.user", @@ -144,7 +143,9 @@ public class DefaultDatabase implements Database { } private void initDataSource() { - LOG.info("Create JDBC data source for {}", properties.getProperty(JDBC_URL.getKey(), DEFAULT_URL)); + LOG.atInfo() + .addArgument(() -> properties.getProperty(JDBC_URL.getKey(), DEFAULT_URL)) + .log("Create JDBC data source for {}"); HikariDataSource ds = createHikariDataSource(); datasource = new ProfiledDataSource(ds, NullConnectionInterceptor.INSTANCE); enableSqlLogging(datasource, logbackHelper.getLoggerLevel("sql") == Level.TRACE); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java index 36bf5417a30..11dfc09803b 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java @@ -249,19 +249,20 @@ public class PurgeDao implements Dao { } private static void logProfiling(PurgeProfiler profiler, long start) { - if (!LOG.isDebugEnabled()) { - return; - } - long duration = System.currentTimeMillis() - start; - LOG.debug(""); - LOG.atDebug().setMessage(" -------- Profiling for project deletion: {} --------").addArgument(() -> TimeUtils.formatDuration(duration)).log(); - LOG.debug(""); - for (String line : profiler.getProfilingResult(duration)) { - LOG.debug(line); + if (LOG.isDebugEnabled()) { + long duration = System.currentTimeMillis() - start; + LOG.debug(""); + LOG.atDebug() + .addArgument(() -> TimeUtils.formatDuration(duration)) + .log(" -------- Profiling for project deletion: {} --------"); + LOG.debug(""); + for (String line : profiler.getProfilingResult(duration)) { + LOG.debug(line); + } + LOG.debug(""); + LOG.debug(" -------- End of profiling for project deletion--------"); + LOG.debug(""); } - LOG.debug(""); - LOG.debug(" -------- End of profiling for project deletion--------"); - LOG.debug(""); } private static void deleteBranch(String branchUuid, PurgeCommands commands) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/DefaultPeriodCleaner.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/DefaultPeriodCleaner.java index 3ff2c9f4995..174d4ea5c89 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/DefaultPeriodCleaner.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/DefaultPeriodCleaner.java @@ -59,12 +59,12 @@ public class DefaultPeriodCleaner { } private List<PurgeableAnalysisDto> delete(String rootUuid, List<PurgeableAnalysisDto> snapshots, DbSession session) { - if (LOG.isDebugEnabled()) { - LOG.debug("<- Delete analyses of component {}: {}", - rootUuid, - snapshots.stream().map(snapshot -> snapshot.getAnalysisUuid() + "@" + DateUtils.formatDateTime(snapshot.getDate())) - .collect(Collectors.joining(", "))); - } + LOG.atDebug() + .addArgument(rootUuid) + .addArgument(() -> snapshots.stream() + .map(snapshot -> snapshot.getAnalysisUuid() + "@" + DateUtils.formatDateTime(snapshot.getDate())) + .collect(Collectors.joining(", "))) + .log("<- Delete analyses of component {}: {}"); purgeDao.deleteAnalyses( session, profiler, snapshots.stream().map(PurgeableAnalysisDto::getAnalysisUuid).toList()); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/DeleteAllFilter.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/DeleteAllFilter.java index 67a442175e3..52c50b33ea3 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/DeleteAllFilter.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/DeleteAllFilter.java @@ -22,8 +22,8 @@ package org.sonar.db.purge.period; import java.util.ArrayList; import java.util.Date; import java.util.List; -import org.sonar.api.utils.DateUtils; import org.slf4j.LoggerFactory; +import org.sonar.api.utils.DateUtils; import org.sonar.db.purge.PurgeableAnalysisDto; class DeleteAllFilter implements Filter { @@ -46,6 +46,8 @@ class DeleteAllFilter implements Filter { @Override public void log() { - LoggerFactory.getLogger(getClass()).debug("-> Delete data prior to: {}", DateUtils.formatDate(before)); + LoggerFactory.getLogger(getClass()).atDebug() + .addArgument(() -> DateUtils.formatDate(before)) + .log("-> Delete data prior to: {}"); } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/KeepOneFilter.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/KeepOneFilter.java index 2cba7950452..5de52dc824d 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/KeepOneFilter.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/KeepOneFilter.java @@ -23,8 +23,8 @@ import com.google.common.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.Date; import java.util.List; -import org.sonar.api.utils.DateUtils; import org.slf4j.LoggerFactory; +import org.sonar.api.utils.DateUtils; import org.sonar.db.purge.PurgeableAnalysisDto; class KeepOneFilter implements Filter { @@ -54,7 +54,11 @@ class KeepOneFilter implements Filter { @Override public void log() { - LoggerFactory.getLogger(getClass()).debug("-> Keep one snapshot per {} between {} and {}", label, DateUtils.formatDate(start), DateUtils.formatDate(end)); + LoggerFactory.getLogger(getClass()).atDebug() + .addArgument(label) + .addArgument(() -> DateUtils.formatDate(start)) + .addArgument(() -> DateUtils.formatDate(end)) + .log("-> Keep one snapshot per {} between {} and {}"); } private static void appendSnapshotsToDelete(Interval interval, List<PurgeableAnalysisDto> toDelete) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/KeepWithVersionFilter.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/KeepWithVersionFilter.java index 06aedd1ba02..9b6bacd8229 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/KeepWithVersionFilter.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/period/KeepWithVersionFilter.java @@ -44,7 +44,9 @@ class KeepWithVersionFilter implements Filter { @Override public void log() { - LoggerFactory.getLogger(getClass()).debug("-> Keep analyses with a version prior to {}", DateUtils.formatDate(before)); + LoggerFactory.getLogger(getClass()).atDebug() + .addArgument(() -> DateUtils.formatDate(before)) + .log("-> Keep analyses with a version prior to {}"); } private static boolean isDeletable(PurgeableAnalysisDto snapshot) { diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/DeleteAllFilterTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/DeleteAllFilterTest.java index bade600449e..0744d249be7 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/DeleteAllFilterTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/DeleteAllFilterTest.java @@ -22,6 +22,9 @@ package org.sonar.db.purge.period; import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.event.Level; +import org.sonar.api.testfixtures.log.LogTesterJUnit5; import org.sonar.api.utils.DateUtils; import org.sonar.db.purge.DbCleanerTestUtils; import org.sonar.db.purge.PurgeableAnalysisDto; @@ -30,6 +33,9 @@ import static org.assertj.core.api.Assertions.assertThat; class DeleteAllFilterTest { + @RegisterExtension + private final LogTesterJUnit5 logs = new LogTesterJUnit5(); + @Test void shouldDeleteAllSnapshotsPriorToDate() { Filter filter = new DeleteAllFilter(DateUtils.parseDate("2011-12-25")); @@ -41,4 +47,21 @@ class DeleteAllFilterTest { assertThat(toDelete).extracting("analysisUuid").containsOnly("u1", "u2"); } + + @Test + void log_should_log_debug_message_when_debug_enabled() { + DeleteAllFilter filter = new DeleteAllFilter(DateUtils.parseDate("2011-12-25")); + logs.setLevel(Level.DEBUG); + filter.log(); + assertThat(logs.logs(Level.DEBUG)).contains("-> Delete data prior to: 2011-12-25"); + } + + @Test + void log_should_not_log_debug_message_when_debug_disabled() { + DeleteAllFilter filter = new DeleteAllFilter(DateUtils.parseDate("2011-12-25")); + logs.setLevel(Level.INFO); + filter.log(); + assertThat(logs.logs()).isEmpty(); + } + } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/KeepOneFilterTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/KeepOneFilterTest.java index 00dfa99f709..3f3ae1f6857 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/KeepOneFilterTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/KeepOneFilterTest.java @@ -23,6 +23,9 @@ import java.util.Arrays; import java.util.Calendar; import java.util.List; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.event.Level; +import org.sonar.api.testfixtures.log.LogTesterJUnit5; import org.sonar.api.utils.DateUtils; import org.sonar.db.purge.DbCleanerTestUtils; import org.sonar.db.purge.PurgeableAnalysisDto; @@ -35,6 +38,9 @@ class KeepOneFilterTest { return snapshotDtos.stream().map(PurgeableAnalysisDto::getAnalysisUuid).toList(); } + @RegisterExtension + private final LogTesterJUnit5 logs = new LogTesterJUnit5(); + @Test void shouldOnlyOneSnapshotPerInterval() { Filter filter = new KeepOneFilter(DateUtils.parseDate("2011-03-25"), DateUtils.parseDate("2011-08-25"), Calendar.MONTH, "month"); @@ -76,4 +82,20 @@ class KeepOneFilterTest { assertThat(KeepOneFilter.isDeletable(DbCleanerTestUtils.createAnalysisWithDate("u1", "2011-05-01").setHasEvents(true))).isFalse(); } + @Test + void log_should_log_debug_message_when_debug_enabled() { + KeepOneFilter filter = new KeepOneFilter(DateUtils.parseDate("2011-03-25"), DateUtils.parseDate("2011-08-25"), Calendar.MONTH, "month"); + logs.setLevel(Level.DEBUG); + filter.log(); + assertThat(logs.logs(Level.DEBUG)).contains("-> Keep one snapshot per month between 2011-03-25 and 2011-08-25"); + } + + @Test + void log_should_not_log_debug_message_when_debug_disabled() { + KeepOneFilter filter = new KeepOneFilter(DateUtils.parseDate("2011-03-25"), DateUtils.parseDate("2011-08-25"), Calendar.MONTH, "month"); + logs.setLevel(Level.INFO); + filter.log(); + assertThat(logs.logs()).isEmpty(); + } + } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/KeepWithVersionFilterTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/KeepWithVersionFilterTest.java index e6e7a435293..50cb3655ae1 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/KeepWithVersionFilterTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/KeepWithVersionFilterTest.java @@ -22,6 +22,9 @@ package org.sonar.db.purge.period; import java.util.Arrays; import java.util.List; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.event.Level; +import org.sonar.api.testfixtures.log.LogTesterJUnit5; import org.sonar.db.purge.DbCleanerTestUtils; import org.sonar.db.purge.PurgeableAnalysisDto; @@ -30,6 +33,9 @@ import static org.sonar.api.utils.DateUtils.parseDate; class KeepWithVersionFilterTest { + @RegisterExtension + private final LogTesterJUnit5 logs = new LogTesterJUnit5(); + @Test void keep_only_analyses_with_a_version() { Filter underTest = new KeepWithVersionFilter(parseDate("2015-10-18")); @@ -41,4 +47,21 @@ class KeepWithVersionFilterTest { assertThat(result).extracting(PurgeableAnalysisDto::getAnalysisUuid).containsExactlyInAnyOrder("u2"); } + + @Test + void log_should_log_debug_message_when_debug_enabled() { + KeepWithVersionFilter filter = new KeepWithVersionFilter(parseDate("2015-10-18")); + logs.setLevel(Level.DEBUG); + filter.log(); + assertThat(logs.logs(Level.DEBUG)).contains("-> Keep analyses with a version prior to 2015-10-18"); + } + + @Test + void log_should_not_log_debug_message_when_debug_disabled() { + KeepWithVersionFilter filter = new KeepWithVersionFilter(parseDate("2015-10-18")); + logs.setLevel(Level.INFO); + filter.log(); + assertThat(logs.logs()).isEmpty(); + } + } diff --git a/server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java b/server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java index 6981b552f94..fc9a62caf4b 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java +++ b/server/sonar-main/src/main/java/org/sonar/application/ProcessLauncherImpl.java @@ -231,12 +231,11 @@ public class ProcessLauncherImpl implements ProcessLauncher { } private static <T extends AbstractCommand> void logLaunchedCommand(AbstractCommand<T> command, ProcessBuilder processBuilder) { - if (LOG.isInfoEnabled()) { - LOG.info("Launch process[{}] from [{}]: {}", - command.getProcessId(), - command.getWorkDir().getAbsolutePath(), - String.join(" ", processBuilder.command())); - } + LOG.atInfo() + .addArgument(command::getProcessId) + .addArgument(() -> command.getWorkDir().getAbsolutePath()) + .addArgument(() -> String.join(" ", processBuilder.command())) + .log("Launch process[{}] from [{}]: {}"); } private <T extends JvmOptions> ProcessBuilder create(JavaCommand<T> javaCommand) { diff --git a/server/sonar-main/src/main/java/org/sonar/application/SchedulerImpl.java b/server/sonar-main/src/main/java/org/sonar/application/SchedulerImpl.java index 32ca4242755..44ee21d8e4a 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/SchedulerImpl.java +++ b/server/sonar-main/src/main/java/org/sonar/application/SchedulerImpl.java @@ -46,9 +46,9 @@ import static org.sonar.application.NodeLifecycle.State.RESTARTING; import static org.sonar.application.NodeLifecycle.State.STOPPED; import static org.sonar.application.NodeLifecycle.State.STOPPING; import static org.sonar.application.process.ManagedProcessHandler.Timeout.newTimeout; +import static org.sonar.process.ProcessProperties.parseTimeoutMs; import static org.sonar.process.ProcessProperties.Property.CE_GRACEFUL_STOP_TIMEOUT; import static org.sonar.process.ProcessProperties.Property.WEB_GRACEFUL_STOP_TIMEOUT; -import static org.sonar.process.ProcessProperties.parseTimeoutMs; public class SchedulerImpl implements Scheduler, ManagedProcessEventListener, ProcessLifecycleListener, AppStateListener { @@ -168,7 +168,6 @@ public class SchedulerImpl implements Scheduler, ManagedProcessEventListener, Pr } } - /** * Tries to start the web leader process. If the process fails to start, the web leader lock is released. If we would not release the lock * then all nodes would need to be stopped and restarted. @@ -319,10 +318,7 @@ public class SchedulerImpl implements Scheduler, ManagedProcessEventListener, Pr // prevent current thread from interrupting itself if (thread != null && currentThread != thread) { thread.interrupt(); - if (LOG.isTraceEnabled()) { - Exception e = new Exception("(capturing stacktrace for debugging purpose)"); - LOG.trace("{} interrupted {}", currentThread.getName(), thread.getName(), e); - } + LOG.trace("{} interrupted {}", currentThread.getName(), thread.getName(), new Exception("(capturing stacktrace for debugging purpose)")); } } @@ -438,11 +434,12 @@ public class SchedulerImpl implements Scheduler, ManagedProcessEventListener, Pr } private static void logThreadRecreated(String threadType, Thread existingThread) { - if (LOG.isDebugEnabled()) { - Exception e = new Exception("(capturing stack trace for debugging purpose)"); - LOG.debug("{} thread was not null (currentThread={},existingThread={})", - threadType, Thread.currentThread().getName(), existingThread.getName(), e); - } + LOG.atDebug() + .addArgument(threadType) + .addArgument(Thread.currentThread().getName()) + .addArgument(existingThread.getName()) + .addArgument(new Exception("(capturing stack trace for debugging purpose)")) + .log("{} thread was not null (currentThread={},existingThread={})"); } private void restartAsync() { diff --git a/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java b/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java index cfef96fe4be..2d82dea7ccb 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java +++ b/server/sonar-main/src/main/java/org/sonar/application/es/EsConnectorImpl.java @@ -65,7 +65,7 @@ public class EsConnectorImpl implements EsConnector { private final String keyStorePassword; public EsConnectorImpl(Set<HostAndPort> hostAndPorts, @Nullable String searchPassword, @Nullable Path keyStorePath, - @Nullable String keyStorePassword) { + @Nullable String keyStorePassword) { this.hostAndPorts = hostAndPorts; this.searchPassword = searchPassword; this.keyStorePath = keyStorePath; @@ -112,12 +112,11 @@ public class EsConnectorImpl implements EsConnector { .map(this::toHttpHost) .toArray(HttpHost[]::new); - if (LOG.isDebugEnabled()) { - String addresses = Arrays.stream(httpHosts) + LOG.atDebug() + .addArgument(Arrays.stream(httpHosts) .map(t -> t.getHostName() + ":" + t.getPort()) - .collect(Collectors.joining(", ")); - LOG.debug("Connected to Elasticsearch node: [{}]", addresses); - } + .collect(Collectors.joining(", "))) + .log("Connected to Elasticsearch node: [{}]"); RestClientBuilder builder = RestClient.builder(httpHosts) .setHttpClientConfigCallback(httpClientBuilder -> { diff --git a/server/sonar-main/src/main/java/org/sonar/application/es/EsSettings.java b/server/sonar-main/src/main/java/org/sonar/application/es/EsSettings.java index 6367ab7d506..891c5de3c2d 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/es/EsSettings.java +++ b/server/sonar-main/src/main/java/org/sonar/application/es/EsSettings.java @@ -101,9 +101,11 @@ public class EsSettings { configureCluster(builder); configureSecurity(builder); configureOthers(builder); - LOGGER.info("Elasticsearch listening on [HTTP: {}:{}, TCP: {}:{}]", - builder.get(ES_HTTP_HOST_KEY), builder.get(ES_HTTP_PORT_KEY), - builder.get(ES_TRANSPORT_HOST_KEY), builder.get(ES_TRANSPORT_PORT_KEY)); + LOGGER.atInfo() + .addArgument(() -> builder.get(ES_HTTP_HOST_KEY)) + .addArgument(() -> builder.get(ES_HTTP_PORT_KEY)) + .addArgument(() -> builder.get(ES_TRANSPORT_HOST_KEY)) + .log("Elasticsearch listening on [HTTP: {}:{}, TCP: {}:{}]"); return builder; } diff --git a/server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcessHandler.java b/server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcessHandler.java index 0baaa5dd98f..908faf87ec0 100644 --- a/server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcessHandler.java +++ b/server/sonar-main/src/main/java/org/sonar/application/process/ManagedProcessHandler.java @@ -211,10 +211,7 @@ public class ManagedProcessHandler { // prevent current thread from interrupting itself if (thread != null && currentThread != thread) { thread.interrupt(); - if (LOG.isTraceEnabled()) { - Exception e = new Exception("(capturing stack trace for debugging purpose)"); - LOG.trace("{} interrupted {}", currentThread.getName(), thread.getName(), e); - } + LOG.trace("{} interrupted {}", currentThread.getName(), thread.getName(), new Exception("(capturing stack trace for debugging purpose)")); } } diff --git a/server/sonar-main/src/test/java/org/sonar/application/AppLoggingTest.java b/server/sonar-main/src/test/java/org/sonar/application/AppLoggingTest.java index 9992ba882fb..348c41fa634 100644 --- a/server/sonar-main/src/test/java/org/sonar/application/AppLoggingTest.java +++ b/server/sonar-main/src/test/java/org/sonar/application/AppLoggingTest.java @@ -240,8 +240,7 @@ public class AppLoggingTest { settings.getProps().set(CLUSTER_ENABLED.getKey(), "true"); underTest.configure(); - assertThat( - LoggerFactory.getLogger("com.hazelcast").isInfoEnabled()).isFalse(); + assertThat(LoggerFactory.getLogger("com.hazelcast").isInfoEnabled()).isFalse(); } @Test @@ -250,10 +249,10 @@ public class AppLoggingTest { LoggerContext ctx = underTest.configure(); Logger rootLogger = ctx.getLogger(ROOT_LOGGER_NAME); - ConsoleAppender appender = (ConsoleAppender<ILoggingEvent>)rootLogger.getAppender("APP_CONSOLE"); + ConsoleAppender appender = (ConsoleAppender<ILoggingEvent>) rootLogger.getAppender("APP_CONSOLE"); Encoder<ILoggingEvent> encoder = appender.getEncoder(); assertThat(encoder).isInstanceOf(LayoutWrappingEncoder.class); - assertThat(((LayoutWrappingEncoder)encoder).getLayout()).isInstanceOf(LogbackJsonLayout.class); + assertThat(((LayoutWrappingEncoder) encoder).getLayout()).isInstanceOf(LogbackJsonLayout.class); } private void emulateRunFromCommandLine(boolean withAllLogsPrintedToConsole) { diff --git a/server/sonar-process/src/main/java/org/sonar/process/cluster/health/SharedHealthStateImpl.java b/server/sonar-process/src/main/java/org/sonar/process/cluster/health/SharedHealthStateImpl.java index 4bf7b88a33d..c5531e4e25e 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/cluster/health/SharedHealthStateImpl.java +++ b/server/sonar-process/src/main/java/org/sonar/process/cluster/health/SharedHealthStateImpl.java @@ -30,9 +30,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.process.cluster.hz.HazelcastMember; import org.sonar.process.cluster.hz.HazelcastObjects; +import org.springframework.beans.factory.annotation.Autowired; import static java.util.Objects.requireNonNull; -import org.springframework.beans.factory.annotation.Autowired; public class SharedHealthStateImpl implements SharedHealthState { private static final Logger LOG = LoggerFactory.getLogger(SharedHealthStateImpl.class); @@ -55,9 +55,10 @@ public class SharedHealthStateImpl implements SharedHealthState { requireNonNull(nodeHealth, "nodeHealth can't be null"); Map<UUID, TimestampedNodeHealth> sqHealthState = readReplicatedMap(); - if (LOG.isTraceEnabled()) { - LOG.trace("Reading {} and adding {}", new HashMap<>(sqHealthState), nodeHealth); - } + LOG.atTrace() + .addArgument(() -> new HashMap<>(sqHealthState)) + .addArgument(nodeHealth) + .log("Reading {} and adding {}"); sqHealthState.put(hzMember.getUuid(), new TimestampedNodeHealth(nodeHealth, hzMember.getClusterTime())); } @@ -65,9 +66,10 @@ public class SharedHealthStateImpl implements SharedHealthState { public void clearMine() { Map<UUID, TimestampedNodeHealth> sqHealthState = readReplicatedMap(); UUID clientUUID = hzMember.getUuid(); - if (LOG.isTraceEnabled()) { - LOG.trace("Reading {} and clearing for {}", new HashMap<>(sqHealthState), clientUUID); - } + LOG.atTrace() + .addArgument(() -> new HashMap<>(sqHealthState)) + .addArgument(clientUUID) + .log("Reading {} and clearing for {}"); sqHealthState.remove(clientUUID); } @@ -82,9 +84,7 @@ public class SharedHealthStateImpl implements SharedHealthState { .filter(ofNonExistentMember(hzMemberUUIDs)) .map(entry -> entry.getValue().getNodeHealth()) .collect(Collectors.toSet()); - if (LOG.isTraceEnabled()) { - LOG.trace("Reading {} and keeping {}", new HashMap<>(sqHealthState), existingNodeHealths); - } + LOG.trace("Reading {} and keeping {}", new HashMap<>(sqHealthState), existingNodeHealths); return ImmutableSet.copyOf(existingNodeHealths); } diff --git a/server/sonar-process/src/test/java/org/sonar/process/cluster/health/SharedHealthStateImplTest.java b/server/sonar-process/src/test/java/org/sonar/process/cluster/health/SharedHealthStateImplTest.java index 85f151bce87..eee5578af19 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/cluster/health/SharedHealthStateImplTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/cluster/health/SharedHealthStateImplTest.java @@ -37,8 +37,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.sonar.process.cluster.health.NodeDetails.newNodeDetailsBuilder; import static org.sonar.process.cluster.health.NodeHealth.newNodeHealthBuilder; @@ -206,15 +204,16 @@ public class SharedHealthStateImplTest { @Test public void clearMine_clears_entry_into_map_sq_health_state_under_current_client_uuid() { - Map<UUID, TimestampedNodeHealth> map = mock(Map.class); - doReturn(map).when(hazelcastMember).getReplicatedMap(MAP_SQ_HEALTH_STATE); + Map<UUID, TimestampedNodeHealth> map = new HashMap<>(); UUID uuid = UUID.randomUUID(); + map.put(uuid, new TimestampedNodeHealth()); + + doReturn(map).when(hazelcastMember).getReplicatedMap(MAP_SQ_HEALTH_STATE); when(hazelcastMember.getUuid()).thenReturn(uuid); underTest.clearMine(); - verify(map).remove(uuid); - verifyNoMoreInteractions(map); + assertThat(map).doesNotContainKey(uuid); assertThat(logging.getLogs()).isEmpty(); } diff --git a/server/sonar-server-common/src/it/java/org/sonar/server/es/BulkIndexerIT.java b/server/sonar-server-common/src/it/java/org/sonar/server/es/BulkIndexerIT.java index 7e6d66546e3..30304b8a2d9 100644 --- a/server/sonar-server-common/src/it/java/org/sonar/server/es/BulkIndexerIT.java +++ b/server/sonar-server-common/src/it/java/org/sonar/server/es/BulkIndexerIT.java @@ -179,7 +179,6 @@ public class BulkIndexerIT { .stream() .filter(log -> log.contains("Bulk[2 index requests on fakes/_doc, 1 delete requests on fakes/_doc]")) .count()).isNotZero(); - } private static class FakeListener implements IndexingListener { diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/es/BulkIndexer.java b/server/sonar-server-common/src/main/java/org/sonar/server/es/BulkIndexer.java index dfdb12d3070..1ec2c60d33c 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/es/BulkIndexer.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/es/BulkIndexer.java @@ -241,7 +241,7 @@ public class BulkIndexer { @Override public void afterBulk(long executionId, BulkRequest request, Throwable e) { - LOGGER.error("Fail to execute bulk index request: " + request, e); + LOGGER.error("Fail to execute bulk index request: {}", request, e); stopProfiler(request); } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/es/EsClientProvider.java b/server/sonar-server-common/src/main/java/org/sonar/server/es/EsClientProvider.java index f4c573faeb6..bb133511d21 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/es/EsClientProvider.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/es/EsClientProvider.java @@ -28,11 +28,11 @@ import java.util.List; import java.util.stream.Collectors; import org.apache.http.HttpHost; import org.elasticsearch.common.settings.Settings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.config.Configuration; import org.sonar.api.server.ServerSide; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.sonar.process.cluster.NodeType; import org.springframework.context.annotation.Bean; @@ -65,14 +65,18 @@ public class EsClientProvider { if (clusterEnabled && !searchNode) { httpHosts = getHttpHosts(config); - LOGGER.info("Connected to remote Elasticsearch: [{}]", displayedAddresses(httpHosts)); + LOGGER.atInfo() + .addArgument(() -> displayedAddresses(httpHosts)) + .log("Connected to remote Elasticsearch: [{}]"); } else { // defaults provided in: // * in org.sonar.process.ProcessProperties.Property.SEARCH_HOST // * in org.sonar.process.ProcessProperties.Property.SEARCH_PORT HostAndPort host = HostAndPort.fromParts(config.get(SEARCH_HOST.getKey()).get(), config.getInt(SEARCH_PORT.getKey()).get()); httpHosts = Collections.singletonList(toHttpHost(host, config)); - LOGGER.info("Connected to local Elasticsearch: [{}]", displayedAddresses(httpHosts)); + LOGGER.atInfo() + .addArgument(() -> displayedAddresses(httpHosts)) + .log("Connected to local Elasticsearch: [{}]"); } return new EsClient(config.get(CLUSTER_SEARCH_PASSWORD.getKey()).orElse(null), diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java index ced84b1042e..ba683aa5b00 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java @@ -31,14 +31,14 @@ import javax.annotation.Nullable; import org.apache.ibatis.cursor.Cursor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.db.component.ComponentQualifiers; -import org.sonar.db.component.ComponentScopes; import org.sonar.api.rules.CleanCodeAttribute; import org.sonar.api.rules.RuleType; import org.sonar.api.server.rule.RulesDefinition.StigVersion; import org.sonar.db.DatabaseUtils; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.component.ComponentQualifiers; +import org.sonar.db.component.ComponentScopes; import org.sonar.db.issue.IndexedIssueDto; import org.sonar.server.security.SecurityStandards; @@ -183,7 +183,7 @@ class IssueIteratorForSingleChunk implements IssueIterator { try { indexCursor.close(); } catch (IOException e) { - LOG.atWarn().setMessage("unable to close the cursor, this may lead to database connexion leak. error is : {}").addArgument(e).log(); + LOG.atWarn().addArgument(e).log("Unable to close the cursor, this may lead to database connexion leak. Error is: {}"); } session.close(); } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/notification/email/EmailNotificationChannel.java b/server/sonar-server-common/src/main/java/org/sonar/server/notification/email/EmailNotificationChannel.java index 5144721d60d..99fe1b9e9ac 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/notification/email/EmailNotificationChannel.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/notification/email/EmailNotificationChannel.java @@ -28,8 +28,8 @@ import java.util.Set; import java.util.regex.Pattern; import javax.annotation.CheckForNull; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.mail2.jakarta.Email; import org.apache.commons.mail2.core.EmailException; +import org.apache.commons.mail2.jakarta.Email; import org.apache.commons.mail2.jakarta.HtmlEmail; import org.apache.commons.mail2.jakarta.SimpleEmail; import org.slf4j.Logger; @@ -225,9 +225,9 @@ public class EmailNotificationChannel extends NotificationChannel { Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); try { - LOG.atTrace().setMessage("Sending email: {}") + LOG.atTrace() .addArgument(() -> sanitizeLog(emailMessage.getMessage())) - .log(); + .log("Sending email: {}"); String host = resolveHost(); Email email = createEmailWithMessage(emailMessage); diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexer.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexer.java index 934835ea78b..f9c22c303d5 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexer.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexer.java @@ -151,19 +151,18 @@ public class RuleIndexer implements ResilientIndexer { private static RuleDoc ruleDocOf(RuleForIndexingDto dto) { SecurityStandards securityStandards = SecurityStandards.fromSecurityStandards(dto.getSecurityStandards()); if (!securityStandards.getIgnoredSQCategories().isEmpty()) { - LOG.debug( - "Rule {} with CWEs '{}' maps to multiple SQ Security Categories: {}", - dto.getRuleKey(), - String.join(", ", securityStandards.getCwe()), - concat(Stream.of(securityStandards.getSqCategory()), securityStandards.getIgnoredSQCategories().stream()) + LOG.atDebug() + .addArgument(dto::getRuleKey) + .addArgument(() -> String.join(", ", securityStandards.getCwe())) + .addArgument(() -> concat(Stream.of(securityStandards.getSqCategory()), securityStandards.getIgnoredSQCategories().stream()) .map(SecurityStandards.SQCategory::getKey) .sorted(SQ_CATEGORY_KEYS_ORDERING) - .collect(joining(", "))); + .collect(joining(", "))) + .log("Rule {} with CWEs '{}' maps to multiple SQ Security Categories: {}"); } return RuleDoc.createFrom(dto, securityStandards); } - private BulkIndexer createBulkIndexer(Size bulkSize, IndexingListener listener) { return new BulkIndexer(esClient, TYPE_RULE, bulkSize, listener); } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/util/AbstractStoppableExecutorService.java b/server/sonar-server-common/src/main/java/org/sonar/server/util/AbstractStoppableExecutorService.java index 28f0c6268c6..bd1c2a54b7f 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/util/AbstractStoppableExecutorService.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/util/AbstractStoppableExecutorService.java @@ -19,8 +19,6 @@ */ package org.sonar.server.util; -import org.slf4j.LoggerFactory; - import java.util.Collection; import java.util.List; import java.util.concurrent.Callable; @@ -29,8 +27,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; - -import static java.lang.String.format; +import org.slf4j.LoggerFactory; /** * Abstract implementation of StoppableExecutorService that implements the @@ -54,11 +51,11 @@ public abstract class AbstractStoppableExecutorService<D extends ExecutorService delegate.shutdownNow(); // Wait a while for tasks to respond to being canceled if (!delegate.awaitTermination(5, TimeUnit.SECONDS)) { - LoggerFactory.getLogger(getClass()).warn(format("Pool %s did not terminate", getClass().getSimpleName())); + LoggerFactory.getLogger(getClass()).warn("Pool {} did not terminate", getClass().getSimpleName()); } } } catch (InterruptedException ie) { - LoggerFactory.getLogger(getClass()).warn(format("Termination of pool %s failed", getClass().getSimpleName()), ie); + LoggerFactory.getLogger(getClass()).warn("Termination of pool {} failed", getClass().getSimpleName(), ie); // (Re-)Cancel if current thread also interrupted delegate.shutdownNow(); } diff --git a/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java b/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java index a1259e43d78..eda02deb70c 100644 --- a/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java +++ b/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java @@ -79,16 +79,16 @@ public class UpdateCenterClient { private UpdateCenter pluginCenter = null; private long lastRefreshDate = 0; - public UpdateCenterClient(UriReader uriReader, Configuration config) throws URISyntaxException { this.uriReader = uriReader; this.uri = new URI(config.get(URL_PROPERTY).get()); this.isActivated = config.getBoolean(ProcessProperties.Property.SONAR_UPDATECENTER_ACTIVATE.getKey()).get(); this.periodInMilliseconds = Long.parseLong(config.get(CACHE_TTL_PROPERTY).get()); - this.product = MetadataLoader.loadEdition(System2.INSTANCE) == SonarEdition.COMMUNITY ? - Product.SONARQUBE_COMMUNITY_BUILD : Product.SONARQUBE_SERVER; + this.product = MetadataLoader.loadEdition(System2.INSTANCE) == SonarEdition.COMMUNITY ? Product.SONARQUBE_COMMUNITY_BUILD : Product.SONARQUBE_SERVER; - LOG.info("Update center: {}", uriReader.description(uri)); + LOG.atInfo() + .addArgument(() -> uriReader.description(uri)) + .log("Update center: {}"); } public Optional<UpdateCenter> getUpdateCenter() { diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/event/AuthenticationEventImpl.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/event/AuthenticationEventImpl.java index 73818378dc7..ac4305a295f 100644 --- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/event/AuthenticationEventImpl.java +++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/authentication/event/AuthenticationEventImpl.java @@ -37,14 +37,14 @@ public class AuthenticationEventImpl implements AuthenticationEvent { public void loginSuccess(HttpRequest request, @Nullable String login, Source source) { checkRequest(request); requireNonNull(source, "source can't be null"); - LOGGER.atDebug().setMessage("login success [method|{}][provider|{}|{}][IP|{}|{}][login|{}]") + LOGGER.atDebug() .addArgument(source::getMethod) .addArgument(source::getProvider) .addArgument(source::getProviderName) .addArgument(request::getRemoteAddr) .addArgument(() -> getAllIps(request)) .addArgument(() -> preventLogFlood(sanitizeLog(emptyIfNull(login)))) - .log(); + .log("login success [method|{}][provider|{}|{}][IP|{}|{}][login|{}]"); } private static String getAllIps(HttpRequest request) { @@ -55,38 +55,35 @@ public class AuthenticationEventImpl implements AuthenticationEvent { public void loginFailure(HttpRequest request, AuthenticationException e) { checkRequest(request); requireNonNull(e, "AuthenticationException can't be null"); - if (!LOGGER.isDebugEnabled()) { - return; + if (LOGGER.isDebugEnabled()) { + Source source = e.getSource(); + LOGGER.debug("login failure [cause|{}][method|{}][provider|{}|{}][IP|{}|{}][login|{}]", + emptyIfNull(e.getMessage()), + source.getMethod(), source.getProvider(), source.getProviderName(), + request.getRemoteAddr(), getAllIps(request), + preventLogFlood(emptyIfNull(e.getLogin()))); } - Source source = e.getSource(); - LOGGER.debug("login failure [cause|{}][method|{}][provider|{}|{}][IP|{}|{}][login|{}]", - emptyIfNull(e.getMessage()), - source.getMethod(), source.getProvider(), source.getProviderName(), - request.getRemoteAddr(), getAllIps(request), - preventLogFlood(emptyIfNull(e.getLogin()))); } @Override public void logoutSuccess(HttpRequest request, @Nullable String login) { checkRequest(request); - if (!LOGGER.isDebugEnabled()) { - return; - } - LOGGER.debug("logout success [IP|{}|{}][login|{}]", - request.getRemoteAddr(), getAllIps(request), - preventLogFlood(emptyIfNull(login))); + LOGGER.atDebug() + .addArgument(request::getRemoteAddr) + .addArgument(() -> getAllIps(request)) + .addArgument(() -> preventLogFlood(emptyIfNull(login))) + .log("logout success [IP|{}|{}][login|{}]"); } @Override public void logoutFailure(HttpRequest request, String errorMessage) { checkRequest(request); requireNonNull(errorMessage, "error message can't be null"); - if (!LOGGER.isDebugEnabled()) { - return; - } - LOGGER.debug("logout failure [error|{}][IP|{}|{}]", - emptyIfNull(errorMessage), - request.getRemoteAddr(), getAllIps(request)); + LOGGER.atDebug() + .addArgument(() -> emptyIfNull(errorMessage)) + .addArgument(request::getRemoteAddr) + .addArgument(() -> getAllIps(request)) + .log("logout failure [error|{}][IP|{}|{}]"); } private static void checkRequest(HttpRequest request) { diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/issue/index/AsyncIssueIndexingImpl.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/issue/index/AsyncIssueIndexingImpl.java index a4421c3b2e1..89d4b9f0ffd 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/issue/index/AsyncIssueIndexingImpl.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/issue/index/AsyncIssueIndexingImpl.java @@ -162,16 +162,16 @@ public class AsyncIssueIndexingImpl implements AsyncIssueIndexing { } private void removeIndexationTasks(DbSession dbSession, Set<String> ceQueueUuids, Set<String> ceActivityUuids) { - LOG.atInfo().setMessage("{} pending indexing task found to be deleted...") - .addArgument(ceQueueUuids.size()) - .log(); + LOG.atInfo() + .addArgument(ceQueueUuids::size) + .log("{} pending indexing task found to be deleted..."); for (String uuid : ceQueueUuids) { dbClient.ceQueueDao().deleteByUuid(dbSession, uuid); } - LOG.atInfo().setMessage("{} completed indexing task found to be deleted...") - .addArgument(ceQueueUuids.size()) - .log(); + LOG.atInfo() + .addArgument(ceQueueUuids::size) + .log("{} completed indexing task found to be deleted..."); dbClient.ceActivityDao().deleteByUuids(dbSession, ceActivityUuids); LOG.info("Indexing task deletion complete."); diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/LogServerVersion.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/LogServerVersion.java index 14682908ded..d55b4668c75 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/LogServerVersion.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/LogServerVersion.java @@ -23,11 +23,11 @@ import com.google.common.base.Joiner; import java.io.IOException; import java.io.InputStream; import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.api.Startable; import org.sonar.api.server.ServerSide; import org.sonar.api.utils.Version; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.sonar.core.platform.SonarQubeVersion; @ServerSide @@ -44,7 +44,9 @@ public class LogServerVersion implements Startable { public void start() { String scmRevision = read("/build.properties").getProperty("Implementation-Build"); Version version = sonarQubeVersion.get(); - LOG.info("SonarQube {}", Joiner.on(" / ").skipNulls().join("Server", version, scmRevision)); + LOG.atInfo() + .addArgument(Joiner.on(" / ").skipNulls().join("Server", version, scmRevision)) + .log("SonarQube {}"); } @Override @@ -52,7 +54,7 @@ public class LogServerVersion implements Startable { // nothing to do } - private static Properties read(String filePath) { + static Properties read(String filePath) { try (InputStream stream = LogServerVersion.class.getResourceAsStream(filePath)) { Properties properties = new Properties(); properties.load(stream); diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/db/CheckAnyonePermissionsAtStartup.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/db/CheckAnyonePermissionsAtStartup.java index 986c6c7e4c8..b4afd0b8687 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/db/CheckAnyonePermissionsAtStartup.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/db/CheckAnyonePermissionsAtStartup.java @@ -19,12 +19,11 @@ */ package org.sonar.server.platform.db; -import java.util.List; import java.util.Optional; -import org.sonar.api.Startable; -import org.sonar.api.config.Configuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.Startable; +import org.sonar.api.config.Configuration; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -64,10 +63,11 @@ public class CheckAnyonePermissionsAtStartup implements Startable { int total = dbClient.groupPermissionDao().countEntitiesWithAnyonePermissions(dbSession); if (total > 0) { - List<String> list = dbClient.groupPermissionDao().selectProjectKeysWithAnyonePermissions(dbSession, 3); - LOG.warn("Authentication is not enforced, and project permissions assigned to the 'Anyone' group expose {} " + - "public project(s) to security risks, including: {}. Unauthenticated visitors have permissions on these project(s).", - total, String.join(", ", list)); + LOG.atWarn() + .addArgument(total) + .addArgument(String.join(", ", dbClient.groupPermissionDao().selectProjectKeysWithAnyonePermissions(dbSession, 3))) + .log("Authentication is not enforced, and project permissions assigned to the 'Anyone' group expose {} " + + "public project(s) to security risks, including: {}. Unauthenticated visitors have permissions on these project(s)."); } } } diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/db/EmbeddedDatabase.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/db/EmbeddedDatabase.java index 6d3a94305d5..922a7e030d8 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/db/EmbeddedDatabase.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/db/EmbeddedDatabase.java @@ -80,10 +80,10 @@ public class EmbeddedDatabase implements Startable { server = Server.createTcpServer("-tcpPort", port, "-ifExists", "-baseDir", dbHome.getAbsolutePath()); } - LOG.info("Starting embedded database on port " + server.getPort() + " with url " + url); + LOG.info("Starting embedded database on port {} with url {}", server.getPort(), url); server.start(); - LOG.info("Embedded database started. Data stored in: " + dbHome.getAbsolutePath()); + LOG.info("Embedded database started. Data stored in: {}", dbHome.getAbsolutePath()); } catch (SQLException e) { throw new IllegalStateException("Unable to start database", e); } diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/RulesKeyVerifier.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/RulesKeyVerifier.java index 829cae887b9..8b344e23790 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/RulesKeyVerifier.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/registration/RulesKeyVerifier.java @@ -52,12 +52,12 @@ public class RulesKeyVerifier { // Find duplicates in declared deprecated rule keys Set<RuleKey> duplicates = findDuplicates(definedDeprecatedRuleKeys); checkState(duplicates.isEmpty(), "The following deprecated rule keys are declared at least twice [%s]", - duplicates.stream().map(RuleKey::toString).collect(Collectors.joining(","))); + duplicates.isEmpty() ? "" : duplicates.stream().map(RuleKey::toString).collect(Collectors.joining(","))); // Find rule keys that are both deprecated and used Set<RuleKey> intersection = intersection(new HashSet<>(definedRuleKeys), new HashSet<>(definedDeprecatedRuleKeys)).immutableCopy(); checkState(intersection.isEmpty(), "The following rule keys are declared both as deprecated and used key [%s]", - intersection.stream().map(RuleKey::toString).collect(Collectors.joining(","))); + intersection.isEmpty() ? "" : intersection.stream().map(RuleKey::toString).collect(Collectors.joining(","))); // Find incorrect usage of deprecated keys Map<RuleKey, SingleDeprecatedRuleKey> dbDeprecatedRuleKeysByOldRuleKey = rulesRegistrationContext.getDbDeprecatedKeysByOldRuleKey(); @@ -68,7 +68,7 @@ public class RulesKeyVerifier { .collect(Collectors.toSet()); checkState(incorrectRuleKeyMessage.isEmpty(), "An incorrect state of deprecated rule keys has been detected.\n %s", - String.join("\n", incorrectRuleKeyMessage)); + incorrectRuleKeyMessage.isEmpty() ? "" : String.join("\n", incorrectRuleKeyMessage)); } private static Stream<String> filterInvalidDeprecatedRuleKeys(Map<RuleKey, SingleDeprecatedRuleKey> dbDeprecatedRuleKeysByOldRuleKey, RulesDefinition.Rule rule) { diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/platform/LogServerVersionTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/platform/LogServerVersionTest.java new file mode 100644 index 00000000000..868e3e38990 --- /dev/null +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/platform/LogServerVersionTest.java @@ -0,0 +1,59 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info 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.platform; + +import java.util.Properties; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mockito.MockedStatic; +import org.slf4j.event.Level; +import org.sonar.api.testfixtures.log.LogTesterJUnit5; +import org.sonar.api.utils.Version; +import org.sonar.core.platform.SonarQubeVersion; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mockStatic; + +class LogServerVersionTest { + + @RegisterExtension + private final LogTesterJUnit5 logs = new LogTesterJUnit5(); + + private final Version version = Version.create(7, 9); + private final SonarQubeVersion sonarQubeVersion = new SonarQubeVersion(version); + private final LogServerVersion logServerVersion = new LogServerVersion(sonarQubeVersion); + + @Test + void start_should_log_info_message_when_info_enabled() { + try (MockedStatic<LogServerVersion> mockedStatic = mockStatic(LogServerVersion.class)) { + Properties properties = new Properties(); + properties.setProperty("Implementation-Build", "42"); + + mockedStatic.when(() -> LogServerVersion.read("/build.properties")).thenReturn(properties); + + logs.setLevel(Level.INFO); + + logServerVersion.start(); + + assertThat(logs.logs(Level.INFO)).contains("SonarQube Server / 7.9 / 42"); + } + } + +} diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/es/IndexCreator.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/es/IndexCreator.java index 4d613f04d93..b08141a70af 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/es/IndexCreator.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/es/IndexCreator.java @@ -131,7 +131,7 @@ public class IndexCreator implements Startable { private void createIndex(BuiltIndex<?> builtIndex, boolean useMetadata) { Index index = builtIndex.getMainType().getIndex(); - LOGGER.info(String.format("Create index [%s]", index.getName())); + LOGGER.info("Create index [{}]", index.getName()); Settings.Builder settings = Settings.builder(); settings.put(builtIndex.getSettings()); if (useMetadata) { diff --git a/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/ServerPushClient.java b/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/ServerPushClient.java index ba267fa952b..59ca8f17640 100644 --- a/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/ServerPushClient.java +++ b/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/ServerPushClient.java @@ -19,14 +19,14 @@ */ package org.sonar.server.pushapi; +import jakarta.servlet.AsyncContext; +import jakarta.servlet.AsyncListener; +import jakarta.servlet.ServletOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import jakarta.servlet.AsyncContext; -import jakarta.servlet.AsyncListener; -import jakarta.servlet.ServletOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -84,7 +84,7 @@ public abstract class ServerPushClient { private void handleIOException(IOException e) { String remoteAddr = asyncContext.getRequest().getRemoteAddr(); - LOG.debug(String.format("The server push client %s gone without notice, closing the connection (%s)", remoteAddr, e.getMessage())); + LOG.debug("The server push client {} gone without notice, closing the connection ({})", remoteAddr, e.getMessage()); throw new IllegalStateException(e.getMessage()); } diff --git a/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/scheduler/purge/PushEventsPurgeScheduler.java b/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/scheduler/purge/PushEventsPurgeScheduler.java index 458b5303f11..2e75882733e 100644 --- a/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/scheduler/purge/PushEventsPurgeScheduler.java +++ b/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/scheduler/purge/PushEventsPurgeScheduler.java @@ -23,12 +23,12 @@ import com.google.common.annotations.VisibleForTesting; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.api.Startable; import org.sonar.api.config.Configuration; import org.sonar.api.server.ServerSide; import org.sonar.api.utils.System2; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.server.util.GlobalLockManager; @@ -83,7 +83,7 @@ public class PushEventsPurgeScheduler implements Startable { private void purgeExpiredPushEvents() { try (DbSession dbSession = dbClient.openSession(false)) { Set<String> uuids = dbClient.pushEventDao().selectUuidsOfExpiredEvents(dbSession, getExpiredTimestamp()); - LOG.debug(String.format("%s push events to be deleted...", uuids.size())); + LOG.debug("{} push events to be deleted...", uuids.size()); dbClient.pushEventDao().deleteByUuids(dbSession, uuids); dbSession.commit(); } diff --git a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandler.java b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandler.java index a045d70365f..d88cb8cc281 100644 --- a/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandler.java +++ b/server/sonar-webserver-webapi-v2/src/main/java/org/sonar/server/v2/common/RestResponseEntityExceptionHandler.java @@ -65,9 +65,7 @@ public class RestResponseEntityExceptionHandler { String validationErrors = ex.getFieldErrors().stream() .map(RestResponseEntityExceptionHandler::handleFieldError) .collect(Collectors.joining()); - LOGGER.atInfo() - .setMessage(ErrorMessages.VALIDATION_ERROR.getMessage() + "\n" + validationErrors) - .log(); + LOGGER.info("{}\n{}", ErrorMessages.VALIDATION_ERROR.getMessage(), validationErrors); return buildResponse(HttpStatus.BAD_REQUEST, validationErrors); } @@ -112,9 +110,7 @@ public class RestResponseEntityExceptionHandler { String validationErrors = ex.getFieldErrors().stream() .map(RestResponseEntityExceptionHandler::handleFieldError) .collect(Collectors.joining()); - LOGGER.atInfo() - .setMessage(ErrorMessages.BIND_ERROR.getMessage() + "\n" + validationErrors) - .log(); + LOGGER.info("{}\n{}", ErrorMessages.BIND_ERROR.getMessage(), validationErrors); return buildResponse(HttpStatus.BAD_REQUEST, validationErrors); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/azure/SearchAzureReposAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/azure/SearchAzureReposAction.java index 97d102ba8ae..e4334132cf0 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/azure/SearchAzureReposAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/azure/SearchAzureReposAction.java @@ -28,15 +28,14 @@ import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nullable; - +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.alm.client.azure.AzureDevOpsHttpClient; import org.sonar.alm.client.azure.GsonAzureRepo; import org.sonar.alm.client.azure.GsonAzureRepoList; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.alm.pat.AlmPatDto; @@ -135,7 +134,7 @@ public class SearchAzureReposAction implements AlmIntegrationsWsAction { .sorted(comparing(AzureRepo::getName, String::compareToIgnoreCase)) .toList(); - LOG.debug(repositories.toString()); + LOG.atDebug().log(repositories::toString); return SearchAzureReposWsResponse.newBuilder() .addAllRepositories(repositories) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileRepositoryImpl.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileRepositoryImpl.java index 68d1018a9eb..eebd13f1ae9 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileRepositoryImpl.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/builtin/BuiltInQProfileRepositoryImpl.java @@ -107,7 +107,7 @@ public class BuiltInQProfileRepositoryImpl implements BuiltInQProfileRepository .collect(Collectors.toSet()); checkState(languagesWithoutBuiltInQProfiles.isEmpty(), "The following languages have no built-in quality profiles: %s", - String.join("", languagesWithoutBuiltInQProfiles)); + languagesWithoutBuiltInQProfiles.isEmpty() ? "" : String.join("", languagesWithoutBuiltInQProfiles)); } private Map<String, Map<String, BuiltInQualityProfile>> validateAndClean(BuiltInQualityProfilesDefinition.Context context) { diff --git a/server/sonar-webserver-ws/src/main/java/org/sonar/server/ws/WebServiceEngine.java b/server/sonar-webserver-ws/src/main/java/org/sonar/server/ws/WebServiceEngine.java index 1c51990cc48..78b4543ca06 100644 --- a/server/sonar-webserver-ws/src/main/java/org/sonar/server/ws/WebServiceEngine.java +++ b/server/sonar-webserver-ws/src/main/java/org/sonar/server/ws/WebServiceEngine.java @@ -147,7 +147,7 @@ public class WebServiceEngine implements LocalConnector, Startable { if (isRequestAbortedByClient(exception)) { // do not pollute logs. We can't do anything -> use DEBUG level // see org.sonar.server.ws.ServletResponse#output() - LOGGER.debug(String.format("Request %s has been aborted by client", request), exception); + LOGGER.debug("Request {} has been aborted by client", request, exception); if (!isResponseCommitted(response)) { // can be useful for access.log response.stream().setStatus(299); @@ -158,13 +158,13 @@ public class WebServiceEngine implements LocalConnector, Startable { if (status == 500) { // Sending exception message into response is a vulnerability. Error must be // displayed only in logs. - LOGGER.error("Fail to process request " + request, exception); + LOGGER.error("Fail to process request {}", request, exception); } Response.Stream stream = response.stream(); if (isResponseCommitted(response)) { // status can't be changed - LOGGER.debug(String.format("Request %s failed during response streaming", request), exception); + LOGGER.debug("Request {} failed during response streaming", request, exception); return; } diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java index d3c3159dcab..1cb20eae6b1 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/web/MasterServletFilter.java @@ -21,13 +21,6 @@ package org.sonar.server.platform.web; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; -import java.io.IOException; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; import jakarta.servlet.Filter; import jakarta.servlet.FilterChain; import jakarta.servlet.FilterConfig; @@ -36,10 +29,17 @@ import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.api.server.http.HttpRequest; import org.sonar.api.server.http.HttpResponse; -import org.slf4j.LoggerFactory; import org.sonar.api.web.HttpFilter; import org.sonar.server.http.JakartaHttpRequest; import org.sonar.server.http.JakartaHttpResponse; @@ -89,7 +89,10 @@ public class MasterServletFilter implements Filter { LinkedList<HttpFilter> filterList = new LinkedList<>(); for (HttpFilter extension : filterExtensions) { try { - LOG.info(String.format("Initializing servlet filter %s [pattern=%s]", extension, extension.doGetPattern().label())); + LOG.atInfo() + .addArgument(extension) + .addArgument(() -> extension.doGetPattern().label()) + .log("Initializing servlet filter {} [pattern={}]"); extension.init(); // As for scim we need to intercept traffic to URLs with path parameters // and that use is not properly handled when dealing with inclusions/exclusions of the WebServiceFilter, diff --git a/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsInstaller.java b/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsInstaller.java index cbd04f866a2..778352269d8 100644 --- a/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsInstaller.java +++ b/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsInstaller.java @@ -24,12 +24,12 @@ import java.util.Arrays; import java.util.Collection; import java.util.Optional; import java.util.function.Predicate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.api.SonarRuntime; import org.sonar.api.config.Configuration; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.utils.AnnotationUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.sonar.core.platform.ExtensionContainer; import static java.util.Objects.requireNonNull; @@ -72,7 +72,7 @@ public abstract class CoreExtensionsInstaller { try { addDeclaredExtensions(container, extensionFilter, additionalSideFilter, coreExtension); - LOG.debug("Installed core extension: " + coreExtensionName); + LOG.debug("Installed core extension: {}", coreExtensionName); coreExtensionRepository.installed(coreExtension); } catch (Exception e) { throw new RuntimeException("Failed to load core extension " + coreExtensionName, e); diff --git a/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsLoader.java b/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsLoader.java index 1dfdcb96604..cfe454775c8 100644 --- a/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsLoader.java +++ b/sonar-core/src/main/java/org/sonar/core/extension/CoreExtensionsLoader.java @@ -19,10 +19,10 @@ */ package org.sonar.core.extension; +import jakarta.inject.Inject; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import jakarta.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,7 +53,9 @@ public class CoreExtensionsLoader { coreExtensionRepository.setLoadedCoreExtensions(coreExtensions); if (!coreExtensions.isEmpty()) { - LOG.info("Loaded core extensions: {}", coreExtensions.stream().map(CoreExtension::getName).collect(Collectors.joining(", "))); + LOG.atInfo() + .addArgument(coreExtensions.stream().map(CoreExtension::getName).collect(Collectors.joining(", "))) + .log("Loaded core extensions: {}"); } } @@ -67,6 +69,6 @@ public class CoreExtensionsLoader { .collect(Collectors.toSet()); checkState(duplicatedNames.isEmpty(), "Multiple core extensions declare the following names: %s", - duplicatedNames.stream().sorted().collect(Collectors.joining(", "))); + duplicatedNames.isEmpty() ? "" : duplicatedNames.stream().sorted().collect(Collectors.joining(", "))); } } diff --git a/sonar-core/src/main/java/org/sonar/core/platform/ComponentKeys.java b/sonar-core/src/main/java/org/sonar/core/platform/ComponentKeys.java index 63486420c65..9196094dd88 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/ComponentKeys.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/ComponentKeys.java @@ -22,9 +22,9 @@ package org.sonar.core.platform; import java.util.HashSet; import java.util.Set; import java.util.regex.Pattern; -import org.sonar.core.util.Uuids; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.core.util.Uuids; public class ComponentKeys { private static final Logger LOG = LoggerFactory.getLogger(ComponentKeys.class); @@ -54,7 +54,7 @@ public class ComponentKeys { String key = component.toString(); if (IDENTITY_HASH_PATTERN.matcher(key).matches()) { if (!objectsWithoutToString.add(component.getClass())) { - log.warn(String.format("Bad component key: %s. Please implement toString() method on class %s", key, component.getClass().getName())); + log.warn("Bad component key: {}. Please implement toString() method on class {}", key, component.getClass().getName()); } key += Uuids.create(); } diff --git a/sonar-core/src/main/java/org/sonar/core/util/ProgressLogger.java b/sonar-core/src/main/java/org/sonar/core/util/ProgressLogger.java index d52650435b0..762537bd85b 100644 --- a/sonar-core/src/main/java/org/sonar/core/util/ProgressLogger.java +++ b/sonar-core/src/main/java/org/sonar/core/util/ProgressLogger.java @@ -106,7 +106,11 @@ public class ProgressLogger { private void log() { long current = counter.get(); - logger.info(String.format("%d %s processed (%d items/sec)", current, pluralLabel, 1000 * (current - previousCounter) / periodMs)); + logger.atInfo() + .addArgument(current) + .addArgument(pluralLabel) + .addArgument(() -> 1000 * (current - previousCounter) / periodMs) + .log("{} {} processed ({} items/sec)"); previousCounter = current; } } diff --git a/sonar-core/src/test/java/org/sonar/core/platform/ComponentKeysTest.java b/sonar-core/src/test/java/org/sonar/core/platform/ComponentKeysTest.java index 9e847841d09..20612e226f2 100644 --- a/sonar-core/src/test/java/org/sonar/core/platform/ComponentKeysTest.java +++ b/sonar-core/src/test/java/org/sonar/core/platform/ComponentKeysTest.java @@ -23,10 +23,12 @@ import org.junit.Test; import org.slf4j.Logger; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.startsWith; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; public class ComponentKeysTest { @@ -50,12 +52,13 @@ public class ComponentKeysTest { @Test public void should_log_warning_if_toString_is_not_overridden() { Logger log = mock(Logger.class); + when(log.isWarnEnabled()).thenReturn(true); keys.of(new Object(), log); verifyNoInteractions(log); // only on non-first runs, to avoid false-positives on singletons keys.of(new Object(), log); - verify(log).warn(startsWith("Bad component key")); + verify(log).warn(startsWith("Bad component key"), any(), any()); } @Test diff --git a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java index b6c3d2668de..80b2165f062 100644 --- a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java +++ b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java @@ -52,7 +52,7 @@ public abstract class PathPattern { public static PathPattern create(String s) { String trimmed = StringUtils.trim(s); if (StringUtils.startsWithIgnoreCase(trimmed, ABSOLUTE_PATH_PATTERN_PREFIX)) { - LOG.warn("Using absolute path pattern is deprecated. Please use relative path instead of '" + trimmed + "'"); + LOG.warn("Using absolute path pattern is deprecated. Please use relative path instead of '{}'", trimmed); return new AbsolutePathPattern(StringUtils.substring(trimmed, ABSOLUTE_PATH_PATTERN_PREFIX.length())); } return new RelativePathPattern(trimmed); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java index a6193218f31..782eaa9364a 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringGlobalContainer.java @@ -19,10 +19,10 @@ */ package org.sonar.scanner.bootstrap; +import jakarta.annotation.Priority; import java.time.Clock; import java.util.List; import java.util.Map; -import jakarta.annotation.Priority; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -141,7 +141,9 @@ public class SpringGlobalContainer extends SpringComponentContainer { } new SpringScannerContainer(this).execute(); - LOG.info("Analysis total time: {}", formatTime(System.currentTimeMillis() - startTime)); + if (LOG.isInfoEnabled()) { + LOG.info("Analysis total time: {}", formatTime(System.currentTimeMillis() - startTime)); + } } private void installRequiredPlugins() { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringScannerContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringScannerContainer.java index c368316f7fb..a0df8c926ed 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringScannerContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/SpringScannerContainer.java @@ -19,8 +19,8 @@ */ package org.sonar.scanner.bootstrap; -import javax.annotation.Nullable; import jakarta.annotation.Priority; +import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.fs.internal.FileMetadata; @@ -160,10 +160,12 @@ public class SpringScannerContainer extends SpringComponentContainer { private void addSuffixesDeprecatedProperties() { add( - /* This is needed to support properly the deprecated sonar.rpg.suffixes property when the download optimization feature is enabled. - The value of the property is needed at the preprocessing stage, but being defined by an optional analyzer means that at preprocessing - it won't be properly available. This will be removed in SQ 11.0 together with the drop of the property from the rpg analyzer. - See SONAR-21514 */ + /* + * This is needed to support properly the deprecated sonar.rpg.suffixes property when the download optimization feature is enabled. + * The value of the property is needed at the preprocessing stage, but being defined by an optional analyzer means that at preprocessing + * it won't be properly available. This will be removed in SQ 11.0 together with the drop of the property from the rpg analyzer. + * See SONAR-21514 + */ PropertyDefinition.builder("sonar.rpg.file.suffixes") .deprecatedKey("sonar.rpg.suffixes") .multiValues(true) @@ -308,8 +310,7 @@ public class SpringScannerContainer extends SpringComponentContainer { GitlabCi.class, Jenkins.class, SemaphoreCi.class, - TravisCi.class - ); + TravisCi.class); add(GitScmSupport.getObjects()); add(SvnScmSupport.getObjects()); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java index d83ad4114e1..6560a4c5520 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java @@ -19,6 +19,7 @@ */ package org.sonar.scanner.cpd; +import jakarta.inject.Inject; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -31,7 +32,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Function; import java.util.function.Predicate; -import jakarta.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.fs.InputComponent; @@ -103,7 +103,7 @@ public class CpdExecutor { } int filesWithoutBlocks = index.noIndexedFiles() - index.noResources(); - if (filesWithoutBlocks > 0) { + if (filesWithoutBlocks > 0 && LOG.isInfoEnabled()) { LOG.info("CPD Executor {} {} had no CPD blocks", filesWithoutBlocks, pluralize(filesWithoutBlocks)); } @@ -128,7 +128,9 @@ public class CpdExecutor { } void runCpdAnalysis(ExecutorService executorService, DefaultInputFile inputFile, Collection<Block> fileBlocks, long timeout) { - LOG.debug("Detection of duplications for {}", inputFile.absolutePath()); + if (LOG.isDebugEnabled()) { + LOG.debug("Detection of duplications for {}", inputFile.absolutePath()); + } progressReport.message(String.format("%d/%d - current file: %s", count, total, inputFile.absolutePath())); List<CloneGroup> duplications; @@ -199,9 +201,8 @@ public class CpdExecutor { if (!duplicate.equals(originBlock)) { clonePartCount++; if (clonePartCount > MAX_CLONE_PART_PER_GROUP) { - LOG.warn("Too many duplication references on file " + component + " for block at line " + - originBlock.getStartLine() + ". Keep only the first " - + MAX_CLONE_PART_PER_GROUP + " references."); + LOG.warn("Too many duplication references on file {} for block at line {}. Keep only the first {} references.", + component, originBlock.getStartLine(), MAX_CLONE_PART_PER_GROUP); break; } blockBuilder.clear(); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java index dbc5eb1f711..996d6a19cb5 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java @@ -71,7 +71,7 @@ public class SonarCpdBlockIndex extends AbstractCloneIndex { for (Block block : blocks) { mem.insert(block); } - if (blocks.isEmpty()) { + if (blocks.isEmpty() && LOG.isDebugEnabled()) { LOG.debug("Not enough content in '{}' to have CPD blocks, it will not be part of the duplication detection", inputFile.relativePath()); } indexedFiles.add(inputFile); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/genericcoverage/GenericCoverageSensor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/genericcoverage/GenericCoverageSensor.java index d09949b9be7..3d9b5370992 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/genericcoverage/GenericCoverageSensor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/genericcoverage/GenericCoverageSensor.java @@ -77,11 +77,10 @@ public class GenericCoverageSensor implements ProjectSensor { parser.parse(reportFile, context); LOG.info("Imported coverage data for {} files", parser.numberOfMatchedFiles()); int numberOfUnknownFiles = parser.numberOfUnknownFiles(); - if (numberOfUnknownFiles > 0) { - LOG.info("Coverage data ignored for " + numberOfUnknownFiles + " unknown files, including:\n" + parser.firstUnknownFiles().stream().collect(Collectors.joining("\n"))); + if (numberOfUnknownFiles > 0 && LOG.isInfoEnabled()) { + LOG.info("Coverage data ignored for {} unknown files, including:\n{}", numberOfUnknownFiles, parser.firstUnknownFiles().stream().collect(Collectors.joining("\n"))); } } - } Set<String> loadReportPaths() { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensor.java index 6615372735b..7faffe640a2 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/genericcoverage/GenericTestExecutionSensor.java @@ -87,7 +87,7 @@ public class GenericTestExecutionSensor implements Sensor { parser.parse(reportFile, context); LOG.info("Imported test execution data for {} files", parser.numberOfMatchedFiles()); int numberOfUnknownFiles = parser.numberOfUnknownFiles(); - if (numberOfUnknownFiles > 0) { + if (numberOfUnknownFiles > 0 && LOG.isInfoEnabled()) { LOG.info("Test execution data ignored for {} unknown files, including:\n{}", numberOfUnknownFiles, parser.firstUnknownFiles().stream().collect(Collectors.joining("\n"))); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/http/DefaultScannerWsClient.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/http/DefaultScannerWsClient.java index 0532b691e36..7a11df24669 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/http/DefaultScannerWsClient.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/http/DefaultScannerWsClient.java @@ -130,12 +130,11 @@ public class DefaultScannerWsClient implements ScannerWsClient { } private static void logResponseDetailsIfDebug(WsResponse response) { - if (!LOG.isDebugEnabled()) { - return; + if (LOG.isDebugEnabled()) { + String content = response.hasContent() ? response.content() : "<no content>"; + Map<String, List<String>> headers = response.headers(); + LOG.debug("Error response content: {}, headers: {}", content, headers); } - String content = response.hasContent() ? response.content() : "<no content>"; - Map<String, List<String>> headers = response.headers(); - LOG.debug("Error response content: {}, headers: {}", content, headers); } private void checkAuthenticationWarnings(WsResponse response) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java index de70d2c7186..b0c88f5860b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsRegexpScanner.java @@ -88,7 +88,9 @@ public class IssueExclusionsRegexpScanner extends CharHandler { fileLength = lineIndex; if (!lineExclusions.isEmpty()) { Set<LineRange> lineRanges = convertLineExclusionsToLineRanges(); - LOG.debug(" - Line exclusions found: {}", lineRanges.stream().map(LineRange::toString).collect(Collectors.joining(","))); + if (LOG.isDebugEnabled()) { + LOG.debug(" - Line exclusions found: {}", lineRanges.stream().map(LineRange::toString).collect(Collectors.joining(","))); + } inputFile.addIgnoreIssuesOnLineRanges(lineRanges.stream().map(r -> new int[] {r.from(), r.to()}).toList()); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobsExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobsExecutor.java index 1613e1fd911..582ebd63d53 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobsExecutor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/PostJobsExecutor.java @@ -51,8 +51,6 @@ public class PostJobsExecutor { } private static void logPostJobs(Collection<PostJobWrapper> postJobs) { - if (LOG.isDebugEnabled()) { - LOG.debug(() -> "Post-jobs : " + postJobs.stream().map(Object::toString).collect(Collectors.joining(" -> "))); - } + LOG.debug(() -> "Post-jobs : " + postJobs.stream().map(Object::toString).collect(Collectors.joining(" -> "))); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java index 15f12eef49d..80b0ccb138f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java @@ -43,10 +43,10 @@ import org.sonar.api.utils.MessageException; import org.sonar.api.utils.TempFolder; import org.sonar.api.utils.ZipUtils; import org.sonar.core.ce.CeTaskCharacteristics; -import org.sonar.scanner.http.DefaultScannerWsClient; import org.sonar.scanner.bootstrap.GlobalAnalysisMode; import org.sonar.scanner.ci.CiConfiguration; import org.sonar.scanner.fs.InputModuleHierarchy; +import org.sonar.scanner.http.DefaultScannerWsClient; import org.sonar.scanner.protocol.output.FileStructure; import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.protocol.output.ScannerReportWriter; @@ -157,7 +157,7 @@ public class ReportPublisher implements Startable { logDeprecationWarningIf32bitJava(); File report = generateReportFile(); if (properties.shouldKeepReport()) { - LOG.info("Analysis report generated in " + reportDir); + LOG.info("Analysis report generated in {}", reportDir); } if (!analysisMode.isMediumTest()) { String taskId = upload(report); @@ -181,13 +181,17 @@ public class ReportPublisher implements Startable { publisher.publish(writer); } long stopTime = System.currentTimeMillis(); - LOG.info("Analysis report generated in {}ms, dir size={}", stopTime - startTime, humanReadableByteCountSI(FileUtils.sizeOfDirectory(reportDir.toFile()))); + if (LOG.isInfoEnabled()) { + LOG.info("Analysis report generated in {}ms, dir size={}", stopTime - startTime, humanReadableByteCountSI(FileUtils.sizeOfDirectory(reportDir.toFile()))); + } startTime = System.currentTimeMillis(); File reportZip = temp.newFile("scanner-report", ".zip"); ZipUtils.zipDir(reportDir.toFile(), reportZip); stopTime = System.currentTimeMillis(); - LOG.info("Analysis report compressed in {}ms, zip size={}", stopTime - startTime, humanReadableByteCountSI(FileUtils.sizeOf(reportZip))); + if (LOG.isInfoEnabled()) { + LOG.info("Analysis report compressed in {}ms, zip size={}", stopTime - startTime, humanReadableByteCountSI(FileUtils.sizeOf(reportZip))); + } return reportZip; } catch (IOException e) { throw new IllegalStateException("Unable to prepare analysis report", e); @@ -218,7 +222,7 @@ public class ReportPublisher implements Startable { .setPart("report", filePart); ciConfiguration.getDevOpsPlatformInfo().ifPresent(devOpsPlatformInfo -> { - post.setParam(CHARACTERISTIC, buildCharacteristicParam(DEVOPS_PLATFORM_URL ,devOpsPlatformInfo.getUrl())); + post.setParam(CHARACTERISTIC, buildCharacteristicParam(DEVOPS_PLATFORM_URL, devOpsPlatformInfo.getUrl())); post.setParam(CHARACTERISTIC, buildCharacteristicParam(DEVOPS_PLATFORM_PROJECT_IDENTIFIER, devOpsPlatformInfo.getProjectIdentifier())); }); String branchName = branchConfiguration.branchName(); @@ -250,7 +254,7 @@ public class ReportPublisher implements Startable { throw new RuntimeException(e); } finally { long stopTime = System.currentTimeMillis(); - LOG.info("Analysis report uploaded in " + (stopTime - startTime) + "ms"); + LOG.info("Analysis report uploaded in {}ms", (stopTime - startTime)); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java index d818f0b91f1..1610cc640a6 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputModuleHierarchyProvider.java @@ -22,11 +22,11 @@ package org.sonar.scanner.scan; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.DefaultInputProject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.sonar.scanner.scan.filesystem.ScannerComponentIdGenerator; import org.springframework.context.annotation.Bean; @@ -62,9 +62,11 @@ public class InputModuleHierarchyProvider { private static DefaultInputModule createModule(ProjectDefinition def, int scannerComponentId) { LOG.debug(" Init module '{}'", def.getName()); DefaultInputModule module = new DefaultInputModule(def, scannerComponentId); - LOG.debug(" Base dir: {}", module.getBaseDir().toAbsolutePath().toString()); - LOG.debug(" Working dir: {}", module.getWorkDir().toAbsolutePath().toString()); - LOG.debug(" Module global encoding: {}, default locale: {}", module.getEncoding().displayName(), Locale.getDefault()); + if (LOG.isDebugEnabled()) { + LOG.debug(" Base dir: {}", module.getBaseDir().toAbsolutePath()); + LOG.debug(" Working dir: {}", module.getWorkDir().toAbsolutePath()); + LOG.debug(" Module global encoding: {}, default locale: {}", module.getEncoding().displayName(), Locale.getDefault()); + } return module; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java index 4b000374101..d25f05cbbdb 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/InputProjectProvider.java @@ -20,10 +20,10 @@ package org.sonar.scanner.scan; import java.util.Locale; -import org.sonar.api.batch.bootstrap.ProjectReactor; -import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.batch.bootstrap.ProjectReactor; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.scanner.scan.filesystem.ScannerComponentIdGenerator; import org.springframework.context.annotation.Bean; @@ -44,9 +44,11 @@ public class InputProjectProvider { workDirectoriesInit.execute(project); LOG.info("Project key: {}", project.key()); - LOG.info("Base dir: {}", project.getBaseDir().toAbsolutePath().toString()); - LOG.info("Working dir: {}", project.getWorkDir().toAbsolutePath().toString()); - LOG.debug("Project global encoding: {}, default locale: {}", project.getEncoding().displayName(), Locale.getDefault()); + LOG.info("Base dir: {}", project.getBaseDir().toAbsolutePath()); + LOG.info("Working dir: {}", project.getWorkDir().toAbsolutePath()); + if (LOG.isDebugEnabled()) { + LOG.debug("Project global encoding: {}, default locale: {}", project.getEncoding().displayName(), Locale.getDefault()); + } return project; } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractCoverageAndDuplicationExclusions.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractCoverageAndDuplicationExclusions.java index b5d6b4c1e0d..74ce7717f61 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractCoverageAndDuplicationExclusions.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractCoverageAndDuplicationExclusions.java @@ -84,7 +84,7 @@ public abstract class AbstractCoverageAndDuplicationExclusions { } private static void log(String title, Collection<WildcardPattern> patterns, String ident) { - if (!patterns.isEmpty()) { + if (!patterns.isEmpty() && LOG.isInfoEnabled()) { LOG.info("{}{} {}", ident, title, patterns.stream().map(WildcardPattern::toString).collect(Collectors.joining(", "))); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFilters.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFilters.java index 48ef929337b..15ff0342e6c 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFilters.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AbstractExclusionFilters.java @@ -162,7 +162,7 @@ public abstract class AbstractExclusionFilters { } private static void log(String title, PathPattern[] patterns, String indent) { - if (patterns.length > 0) { + if (patterns.length > 0 && LOG.isInfoEnabled()) { LOG.info("{}{} {}", indent, title, Arrays.stream(patterns).map(PathPattern::toString).collect(Collectors.joining(", "))); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java index 6afd6163619..a97d782d83f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java @@ -102,8 +102,7 @@ public class FileIndexer { language != null ? language.key() : null, scannerComponentIdGenerator.getAsInt(), sensorStrategy, - scmChangedFiles.getOldRelativeFilePath(sourceFile) - ); + scmChangedFiles.getOldRelativeFilePath(sourceFile)); DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.setMetadata(module.key(), f, module.getEncoding()), f -> f.setStatus(statusDetection.findStatusFromScm(f))); @@ -117,9 +116,7 @@ public class FileIndexer { componentStore.put(module.key(), inputFile); issueExclusionsLoader.addMulticriteriaPatterns(inputFile); String langStr = inputFile.language() != null ? format("with language '%s'", inputFile.language()) : "with no language"; - if (LOG.isDebugEnabled()) { - LOG.debug("'{}' indexed {}{}", inputFile, type == Type.TEST ? "as test " : "", langStr); - } + LOG.debug("'{}' indexed {}{}", inputFile, type == Type.TEST ? "as test " : "", langStr); evaluateCoverageExclusions(moduleCoverageAndDuplicationExclusions, inputFile); evaluateDuplicationExclusions(moduleCoverageAndDuplicationExclusions, inputFile); if (properties.preloadFileMetadata()) { @@ -204,5 +201,4 @@ public class FileIndexer { return count == 1 ? "file" : "files"; } - } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java index 8873d79c60e..fad668d2c14 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java @@ -87,7 +87,9 @@ public class LanguageDetection { PathPattern[] defaultLanguagePatterns = Stream.concat(fileSuffixes, filenamePatterns) .distinct() .toArray(PathPattern[]::new); - LOG.debug("Declared patterns of language {} were converted to {}", language, getDetails(language, defaultLanguagePatterns)); + if (LOG.isDebugEnabled()) { + LOG.debug("Declared patterns of language {} were converted to {}", language, getDetails(language, defaultLanguagePatterns)); + } return defaultLanguagePatterns; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFilePreprocessor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFilePreprocessor.java index 4f2b9570860..40d604fb082 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFilePreprocessor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ProjectFilePreprocessor.java @@ -171,8 +171,7 @@ public class ProjectFilePreprocessor { List<Path> processedFiles = new ArrayList<>(); Files.walkFileTree(path.normalize(), Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new DirectoryFileVisitor(file -> filePreprocessor.processFile(module, moduleExclusionFilters, file, type, exclusionCounter, - ignoreCommand).ifPresent(processedFiles::add), module, moduleExclusionFilters, inputModuleHierarchy, type) - ); + ignoreCommand).ifPresent(processedFiles::add), module, moduleExclusionFilters, inputModuleHierarchy, type)); return processedFiles; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java index 75ae9a29db5..b7a3f67bb43 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/DefaultBlameOutput.java @@ -139,7 +139,7 @@ class DefaultBlameOutput implements BlameOutput { if (success && !allFilesToBlame.isEmpty()) { LOG.warn("Missing blame information for the following files:"); for (InputFile f : allFilesToBlame) { - LOG.warn(" * " + f); + LOG.warn(" * {}", f); } LOG.warn("This may lead to missing/broken features in SonarQube"); String docUrl = documentationLinkGenerator.getDocumentationLink(SCM_INTEGRATION_DOCUMENTATION_SUFFIX); @@ -155,4 +155,3 @@ class DefaultBlameOutput implements BlameOutput { return filesCount == 1 ? "source file" : "source files"; } } - diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java index be3311e69d7..59c1422e8e8 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java @@ -81,7 +81,7 @@ public final class ScmPublisher { List<InputFile> filesToBlame = collectFilesToBlame(writer); if (!filesToBlame.isEmpty()) { String key = provider.key(); - LOG.info("SCM Publisher SCM provider for this project is: " + key); + LOG.info("SCM Publisher SCM provider for this project is: {}", key); DefaultBlameOutput output = new DefaultBlameOutput(writer, analysisWarnings, filesToBlame, documentationLinkGenerator); try { provider.blameCommand().blame(new DefaultBlameInput(fs, filesToBlame), output); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorsExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorsExecutor.java index a7a1c91a73f..fb814b421f9 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorsExecutor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorsExecutor.java @@ -42,9 +42,11 @@ public class ProjectSensorsExecutor { public void execute() { List<ProjectSensorWrapper> sensors = selector.selectSensors(); - LOG.debug("Sensors : {}", sensors.stream() - .map(Object::toString) - .collect(Collectors.joining(" -> "))); + if (LOG.isDebugEnabled()) { + LOG.debug("Sensors : {}", sensors.stream() + .map(Object::toString) + .collect(Collectors.joining(" -> "))); + } for (ProjectSensorWrapper sensor : sensors) { SensorId sensorId = getSensorId(sensor); executingSensorCtx.setSensorExecuting(sensorId); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmProvider.java index 80b42a45bc5..a85d891c830 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmProvider.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmProvider.java @@ -63,13 +63,13 @@ import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.treewalk.filter.PathFilterGroup; import org.eclipse.jgit.treewalk.filter.TreeFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.api.batch.scm.BlameCommand; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.System2; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.sonar.core.documentation.DocumentationLinkGenerator; import static java.lang.String.format; @@ -150,7 +150,9 @@ public class GitScmProvider extends ScmProvider { Optional<RevCommit> mergeBaseCommit = findMergeBase(repo, targetRef); if (mergeBaseCommit.isEmpty()) { - LOG.warn(composeNoMergeBaseFoundWarning(targetRef.getName())); + if (LOG.isWarnEnabled()) { + LOG.warn(composeNoMergeBaseFoundWarning(targetRef.getName())); + } return null; } AbstractTreeIterator mergeBaseTree = prepareTreeParser(repo, mergeBaseCommit.get()); @@ -240,7 +242,9 @@ public class GitScmProvider extends ScmProvider { Optional<RevCommit> mergeBaseCommit = findMergeBase(repo, targetRef); if (mergeBaseCommit.isEmpty()) { - LOG.warn(composeNoMergeBaseFoundWarning(targetRef.getName())); + if (LOG.isWarnEnabled()) { + LOG.warn(composeNoMergeBaseFoundWarning(targetRef.getName())); + } return null; } @@ -343,7 +347,7 @@ public class GitScmProvider extends ScmProvider { targetRef = getFirstExistingRef(repo, localRef, originRef, upstreamRef, remotesRef); } - if (targetRef == null) { + if (targetRef == null && LOG.isWarnEnabled()) { LOG.warn(String.format(COULD_NOT_FIND_REF, targetBranchName)); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageSensorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageSensorTest.java index be46d38ab9e..1c7423ba340 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageSensorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageSensorTest.java @@ -19,19 +19,28 @@ */ package org.sonar.scanner.genericcoverage; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.junit.Rule; import org.junit.Test; +import org.slf4j.event.Level; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; +import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.internal.Encryption; -import org.sonar.api.utils.System2; import org.sonar.api.testfixtures.log.LogTester; +import org.sonar.api.utils.System2; import org.sonar.scanner.config.DefaultConfiguration; import org.sonar.scanner.scan.ProjectConfiguration; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class GenericCoverageSensorTest { @@ -49,4 +58,38 @@ public class GenericCoverageSensorTest { assertThat(reportPaths).containsOnly("report.xml", "report2.xml"); } + + @Test + public void should_log_info_message_when_unknown_files_exist() throws Exception { + logTester.setLevel(Level.INFO); + DefaultConfiguration config = mock(DefaultConfiguration.class); + + // Create a temporary file to simulate the report file + Path tempReportFile = Files.createTempFile("report", ".xml"); + // Write valid content with version information to the temporary file + Files.write(tempReportFile, "<coverage version=\"1\"><file path=\"unknownFile\"/></coverage>".getBytes()); + + // Use the temporary file path in the configuration mock + when(config.getStringArray(GenericCoverageSensor.REPORT_PATHS_PROPERTY_KEY)).thenReturn(new String[] {tempReportFile.toString()}); + + GenericCoverageSensor sensor = new GenericCoverageSensor(config); + SensorContextTester context = SensorContextTester.create(new File(".")); + DefaultFileSystem fileSystem = context.fileSystem(); + + // Mock the input file instead of using DefaultInputFile + InputFile inputFile = mock(InputFile.class); + when(inputFile.language()).thenReturn("java"); + when(inputFile.type()).thenReturn(InputFile.Type.MAIN); + when(inputFile.filename()).thenReturn("unknownFile"); + + fileSystem.add(inputFile); + + sensor.execute(context); + + assertThat(logTester.logs(Level.INFO)).contains("Coverage data ignored for 1 unknown files, including:\nunknownFile"); + + // Clean up the temporary file + Files.delete(tempReportFile); + } + } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java index 884253a7e4f..7c49df72d8f 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java @@ -52,6 +52,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.slf4j.event.Level; import org.sonar.api.config.Configuration; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.scan.filesystem.PathResolver; @@ -246,6 +247,36 @@ public class GitScmProviderTest { } @Test + public void branchChangedLinesWithFileMovementDetection_should_return_null_when_mergeBaseCommit_is_empty() throws IOException, GitAPIException { + logs.setLevel(Level.WARN); + + git.checkout().setOrphan(true).setName("orphan-branch").call(); + createAndCommitFile("file3.txt"); + + Map<Path, ChangedFile> changedFiles = Map.of( + worktree.resolve("file1.txt"), ChangedFile.of(worktree.resolve("file1.txt"), null), + worktree.resolve("file2-renamed.txt"), ChangedFile.of(worktree.resolve("file2-renamed.txt"), "file2.txt")); + + Map<Path, Set<Integer>> result = newScmProvider().branchChangedLinesWithFileMovementDetection("master", worktree, changedFiles); + + assertThat(logs.logs(Level.WARN)).contains("No merge base found between HEAD and refs/heads/master"); + assertThat(result).isNull(); + } + + @Test + public void branchChangedFilesWithFileMovementDetection_should_return_null_when_mergeBaseCommit_is_empty() throws IOException, GitAPIException { + logs.setLevel(Level.WARN); + + git.checkout().setOrphan(true).setName("orphan-branch").call(); + createAndCommitFile("file3.txt"); + + Set<ChangedFile> result = newScmProvider().branchChangedFilesWithFileMovementDetection("master", worktree); + + assertThat(logs.logs(Level.WARN)).contains("No merge base found between HEAD and refs/heads/master"); + assertThat(result).isNull(); + } + + @Test public void branchChangedFiles_should_not_fail_with_patience_diff_algo() throws IOException { Path gitConfig = worktree.resolve(".git").resolve("config"); Files.write(gitConfig, "[diff]\nalgorithm = patience\n".getBytes(StandardCharsets.UTF_8)); |