forked from phoedos/pmd
[core] Use slf4j-api and slf4j-simple
Support "--debug" flag for slf4j-simple
This commit is contained in:
@ -75,6 +75,10 @@
|
||||
<scope>provided</scope> <!-- only needed for generating the parser via ant -->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
@ -114,6 +118,11 @@
|
||||
<artifactId>pcollections</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock</artifactId>
|
||||
|
@ -21,9 +21,10 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.event.Level;
|
||||
|
||||
import net.sourceforge.pmd.Report.GlobalReportBuilderListener;
|
||||
import net.sourceforge.pmd.benchmark.TextTimingReportRenderer;
|
||||
@ -35,6 +36,7 @@ import net.sourceforge.pmd.benchmark.TimingReportRenderer;
|
||||
import net.sourceforge.pmd.cache.NoopAnalysisCache;
|
||||
import net.sourceforge.pmd.cli.PMDCommandLineInterface;
|
||||
import net.sourceforge.pmd.cli.PmdParametersParseResult;
|
||||
import net.sourceforge.pmd.internal.Slf4jSimpleConfiguration;
|
||||
import net.sourceforge.pmd.internal.util.AssertionUtil;
|
||||
import net.sourceforge.pmd.lang.Language;
|
||||
import net.sourceforge.pmd.lang.LanguageFilenameFilter;
|
||||
@ -52,7 +54,6 @@ import net.sourceforge.pmd.util.database.DBURI;
|
||||
import net.sourceforge.pmd.util.database.SourceObject;
|
||||
import net.sourceforge.pmd.util.datasource.DataSource;
|
||||
import net.sourceforge.pmd.util.datasource.ReaderDataSource;
|
||||
import net.sourceforge.pmd.util.log.ScopedLogHandlersManager;
|
||||
|
||||
/**
|
||||
* This is the main class for interacting with PMD. The primary flow of all Rule
|
||||
@ -62,7 +63,8 @@ import net.sourceforge.pmd.util.log.ScopedLogHandlersManager;
|
||||
*/
|
||||
public final class PMD {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(PMD.class.getName());
|
||||
// not final, in order to re-initialize logging
|
||||
private static Logger log = LoggerFactory.getLogger(PMD.class);
|
||||
|
||||
/**
|
||||
* The line delimiter used by PMD in outputs. Usually the platform specific
|
||||
@ -97,19 +99,17 @@ public final class PMD {
|
||||
try {
|
||||
DBURI dbUri = new DBURI(uriString);
|
||||
DBMSMetadata dbmsMetadata = new DBMSMetadata(dbUri);
|
||||
LOG.log(Level.FINE, "DBMSMetadata retrieved");
|
||||
log.debug("DBMSMetadata retrieved");
|
||||
List<SourceObject> sourceObjectList = dbmsMetadata.getSourceObjectList();
|
||||
LOG.log(Level.FINE, "Located {0} database source objects", sourceObjectList.size());
|
||||
log.debug("Located {} database source objects", sourceObjectList.size());
|
||||
for (SourceObject sourceObject : sourceObjectList) {
|
||||
String falseFilePath = sourceObject.getPseudoFileName();
|
||||
LOG.log(Level.FINEST, "Adding database source object {0}", falseFilePath);
|
||||
log.trace("Adding database source object {}", falseFilePath);
|
||||
|
||||
try {
|
||||
dataSources.add(new ReaderDataSource(dbmsMetadata.getSourceCode(sourceObject), falseFilePath));
|
||||
} catch (SQLException ex) {
|
||||
if (LOG.isLoggable(Level.WARNING)) {
|
||||
LOG.log(Level.WARNING, "Cannot get SourceCode for " + falseFilePath + " - skipping ...", ex);
|
||||
}
|
||||
log.warn("Cannot get SourceCode for {} - skipping ...", falseFilePath, ex);
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
@ -160,14 +160,9 @@ public final class PMD {
|
||||
}
|
||||
return violationCounter.getResult();
|
||||
} catch (final Exception e) {
|
||||
String message = e.getMessage();
|
||||
if (message == null) {
|
||||
LOG.log(Level.SEVERE, "Exception during processing", e);
|
||||
} else {
|
||||
LOG.severe(message);
|
||||
}
|
||||
LOG.log(Level.FINE, "Exception during processing", e);
|
||||
LOG.info(PMDCommandLineInterface.buildUsageText());
|
||||
log.error("Exception during processing: {}", e.toString()); // only exception without stacktrace
|
||||
log.debug("Exception during processing", e); // with stacktrace
|
||||
log.info(PMDCommandLineInterface.buildUsageText());
|
||||
return PMDCommandLineInterface.NO_ERRORS_STATUS;
|
||||
} finally {
|
||||
/*
|
||||
@ -190,11 +185,11 @@ public final class PMD {
|
||||
if (isEmpty(ruleSets)) {
|
||||
String msg = "No rules found. Maybe you misspelled a rule name? ("
|
||||
+ String.join(",", rulesetPaths) + ')';
|
||||
LOG.log(Level.SEVERE, msg);
|
||||
log.error(msg);
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
} catch (RuleSetLoadException rsnfe) {
|
||||
LOG.log(Level.SEVERE, "Ruleset not found", rsnfe);
|
||||
log.error("Ruleset not found", rsnfe);
|
||||
throw rsnfe;
|
||||
}
|
||||
return ruleSets;
|
||||
@ -211,10 +206,10 @@ public final class PMD {
|
||||
* @param rulesets the RuleSets to print
|
||||
*/
|
||||
private static void printRuleNamesInDebug(List<RuleSet> rulesets) {
|
||||
if (LOG.isLoggable(Level.FINER)) {
|
||||
if (log.isDebugEnabled()) {
|
||||
for (RuleSet rset : rulesets) {
|
||||
for (Rule r : rset.getRules()) {
|
||||
LOG.finer("Loaded rule " + r.getName());
|
||||
log.debug("Loaded rule {}", r.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -335,10 +330,7 @@ public final class PMD {
|
||||
ruleSets.removeDysfunctionalRules(brokenRules);
|
||||
|
||||
for (final Rule rule : brokenRules) {
|
||||
if (LOG.isLoggable(Level.WARNING)) {
|
||||
LOG.log(Level.WARNING,
|
||||
"Removed misconfigured rule: " + rule.getName() + " cause: " + rule.dysfunctionReason());
|
||||
}
|
||||
log.warn("Removed misconfigured rule: {} cause: {}", rule.getName(), rule.dysfunctionReason());
|
||||
}
|
||||
|
||||
return brokenRules;
|
||||
@ -368,11 +360,11 @@ public final class PMD {
|
||||
private static void encourageToUseIncrementalAnalysis(final PMDConfiguration configuration) {
|
||||
if (!configuration.isIgnoreIncrementalAnalysis()
|
||||
&& configuration.getAnalysisCache() instanceof NoopAnalysisCache
|
||||
&& LOG.isLoggable(Level.WARNING)) {
|
||||
&& log.isWarnEnabled()) {
|
||||
final String version =
|
||||
PMDVersion.isUnknown() || PMDVersion.isSnapshot() ? "latest" : "pmd-" + PMDVersion.VERSION;
|
||||
LOG.warning("This analysis could be faster, please consider using Incremental Analysis: "
|
||||
+ "https://pmd.github.io/" + version + "/pmd_userdocs_incremental_analysis.html");
|
||||
log.warn("This analysis could be faster, please consider using Incremental Analysis: "
|
||||
+ "https://pmd.github.io/{}/pmd_userdocs_incremental_analysis.html", version);
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,7 +425,7 @@ public final class PMD {
|
||||
String filePaths = FileUtil.readFilelist(file);
|
||||
files.removeAll(FileUtil.collectFiles(filePaths, fileSelector));
|
||||
} catch (IOException ex) {
|
||||
LOG.log(Level.SEVERE, "Problem with Ignore File", ex);
|
||||
log.error("Problem with Ignore File", ex);
|
||||
throw new RuntimeException("Problem with Ignore File Path: " + ignoreFilePath, ex);
|
||||
}
|
||||
}
|
||||
@ -451,9 +443,7 @@ public final class PMD {
|
||||
final LanguageVersion version = discoverer.getDefaultLanguageVersion(ruleLanguage);
|
||||
if (RuleSet.applies(rule, version)) {
|
||||
languages.add(ruleLanguage);
|
||||
if (LOG.isLoggable(Level.FINE)) {
|
||||
LOG.fine("Using " + ruleLanguage.getShortName() + " version: " + version.getShortName());
|
||||
}
|
||||
log.debug("Using {} version: {}", ruleLanguage.getShortName(), version.getShortName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -506,8 +496,8 @@ public final class PMD {
|
||||
|
||||
if (!parseResult.getDeprecatedOptionsUsed().isEmpty()) {
|
||||
Entry<String, String> first = parseResult.getDeprecatedOptionsUsed().entrySet().iterator().next();
|
||||
LOG.warning("Some deprecated options were used on the command-line, including " + first.getKey());
|
||||
LOG.warning("Consider replacing it with " + first.getValue());
|
||||
log.warn("Some deprecated options were used on the command-line, including {}", first.getKey());
|
||||
log.warn("Consider replacing it with {}", first.getValue());
|
||||
}
|
||||
|
||||
if (parseResult.isVersion()) {
|
||||
@ -541,12 +531,15 @@ public final class PMD {
|
||||
TimeTracker.startGlobalTracking();
|
||||
}
|
||||
|
||||
final Level logLevel = configuration.isDebug() ? Level.FINER : Level.INFO;
|
||||
final ScopedLogHandlersManager logHandlerManager = new ScopedLogHandlersManager(logLevel, new ConsoleHandler());
|
||||
final Level oldLogLevel = LOG.getLevel();
|
||||
// Need to do this, since the static logger has already been initialized
|
||||
// at this point
|
||||
LOG.setLevel(logLevel);
|
||||
final Level logLevel = configuration.isDebug() ? Level.DEBUG : Level.INFO;
|
||||
Slf4jSimpleConfiguration.reconfigureDefaultLogLevel(logLevel);
|
||||
// need to reload the logger with the new configuration
|
||||
log = LoggerFactory.getLogger(PMD.class);
|
||||
if (configuration.isDebug()) {
|
||||
log.debug("Loglevel is at {}", logLevel);
|
||||
} else {
|
||||
log.info("Loglevel is at {}", logLevel);
|
||||
}
|
||||
|
||||
StatusCode status;
|
||||
try {
|
||||
@ -562,9 +555,6 @@ public final class PMD {
|
||||
System.err.println(e.getMessage());
|
||||
status = StatusCode.ERROR;
|
||||
} finally {
|
||||
logHandlerManager.close();
|
||||
LOG.setLevel(oldLogLevel);
|
||||
|
||||
if (configuration.isBenchmark()) {
|
||||
final TimingReport timingReport = TimeTracker.stopGlobalTracking();
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.internal;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.slf4j.ILoggerFactory;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.LoggerFactoryFriend;
|
||||
import org.slf4j.event.Level;
|
||||
|
||||
public final class Slf4jSimpleConfiguration {
|
||||
private Slf4jSimpleConfiguration() { }
|
||||
|
||||
public static void reconfigureDefaultLogLevel(Level level) {
|
||||
System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", level.toString());
|
||||
|
||||
// Call SimpleLogger.init() by reflection.
|
||||
// Alternatively: move the CLI related classes into an own module, add
|
||||
// slf4j-simple as a runtime dependency and create a PmdSlf4jSimpleFriend class in
|
||||
// the package org.slf4j.simple to gain access to this package-private init method.
|
||||
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
|
||||
Class<? extends ILoggerFactory> loggerFactoryClass = loggerFactory.getClass();
|
||||
try {
|
||||
Class<?> simpleLoggerClass = loggerFactoryClass.getClassLoader().loadClass("org.slf4j.simple.SimpleLogger");
|
||||
Method initMethod = simpleLoggerClass.getDeclaredMethod("init");
|
||||
initMethod.setAccessible(true);
|
||||
initMethod.invoke(null);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
System.err.println("Error while initializing logging: " + ex);
|
||||
}
|
||||
|
||||
LoggerFactoryFriend.reset();
|
||||
}
|
||||
}
|
@ -21,10 +21,10 @@ import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.contrib.java.lang.system.RestoreSystemProperties;
|
||||
import org.junit.contrib.java.lang.system.SystemErrRule;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import net.sourceforge.pmd.PMD;
|
||||
import net.sourceforge.pmd.junit.JavaUtilLoggingRule;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -39,7 +39,7 @@ public class CoreCliTest {
|
||||
@Rule
|
||||
public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
|
||||
@Rule
|
||||
public JavaUtilLoggingRule loggingRule = new JavaUtilLoggingRule(PMD.class.getPackage().getName()).mute();
|
||||
public SystemErrRule loggingRule = new SystemErrRule().enableLog().muteForSuccessfulTests();
|
||||
|
||||
private Path srcDir;
|
||||
|
||||
@ -163,6 +163,18 @@ public class CoreCliTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void debugLogging() {
|
||||
runPmdSuccessfully("--debug", "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET);
|
||||
loggingRule.getLog().contains("[main] DEBUG net.sourceforge.pmd.PMD - Loglevel is at DEBUG");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultLogging() {
|
||||
runPmdSuccessfully("--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET);
|
||||
loggingRule.getLog().contains("[main] INFO net.sourceforge.pmd.PMD - Loglevel is at INFO");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// utilities
|
||||
|
@ -49,6 +49,10 @@
|
||||
<artifactId>system-rules</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
|
8
pom.xml
8
pom.xml
@ -98,6 +98,7 @@
|
||||
<ant.version>1.10.12</ant.version>
|
||||
<javadoc.plugin.version>3.2.0</javadoc.plugin.version>
|
||||
<antlr.version>4.8</antlr.version>
|
||||
<slf4j.version>2.0.0-alpha6</slf4j.version>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
@ -717,7 +718,12 @@
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.32</version>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
|
Reference in New Issue
Block a user