moved from log4j to logback

This commit is contained in:
Sebastian Stenzel
2017-05-16 17:13:03 +02:00
parent 05cc248417
commit 2d68e27d3d
9 changed files with 51 additions and 264 deletions

View File

@@ -42,16 +42,12 @@
<!-- Logging -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jul</artifactId>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,132 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 Sebastian Stenzel and others.
* This file is licensed under the terms of the MIT license.
* See the LICENSE.txt file for more info.
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
*******************************************************************************/
package org.cryptomator.logging;
import java.io.IOException;
import java.io.Serializable;
import java.net.URISyntaxException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.regex.Pattern;
import org.apache.commons.lang3.SystemUtils;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender;
import org.apache.logging.log4j.core.appender.FileManager;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
import org.apache.logging.log4j.util.Strings;
/**
* A preconfigured FileAppender only relying on a configurable system property, e.g. <code>-Dcryptomator.logPath=/var/log/cryptomator.log</code>.<br/>
* Other than the normal {@link org.apache.logging.log4j.core.appender.FileAppender} paths can be resolved relative to the users home directory.
*/
@Plugin(name = ConfigurableFileAppender.PLUGIN_NAME, category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
public class ConfigurableFileAppender extends AbstractOutputStreamAppender<FileManager> {
static final String PLUGIN_NAME = "ConfigurableFile";
private static final Pattern DRIVE_LETTER_WITH_PRECEEDING_SLASH = Pattern.compile("^/[A-Z]:", Pattern.CASE_INSENSITIVE);
private ConfigurableFileAppender(String name, Layout<? extends Serializable> layout, Filter filter, boolean ignoreExceptions, boolean immediateFlush, FileManager manager) {
super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
LOGGER.info("Logging to " + manager.getFileName());
}
@PluginBuilderFactory
public static <B extends Builder<B>> B newBuilder() {
return new Builder<B>().asBuilder();
}
/**
* Builds ConfigurableFileAppender instances.
*
* @param <B>
* The type to build
*/
public static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B> //
implements org.apache.logging.log4j.core.util.Builder<ConfigurableFileAppender> {
@Required(message = "No system property name containing the log file path provided.")
@PluginBuilderAttribute("pathPropertyName")
private String pathPropertyName;
@PluginBuilderAttribute
private boolean append = true;
@Override
public ConfigurableFileAppender build() {
final String pathProperty = System.getProperty(pathPropertyName);
if (Strings.isEmpty(pathProperty)) {
LOGGER.warn("No log file location provided in system property \"" + pathPropertyName + "\"");
return null;
}
final Path filePath = parsePath(pathProperty);
if (filePath == null) {
LOGGER.warn("Invalid path \"" + pathProperty + "\"");
return null;
}
if (!Files.exists(filePath.getParent())) {
try {
Files.createDirectories(filePath.getParent());
} catch (IOException e) {
LOGGER.error("Could not create parent directories for log file located at " + filePath.toString(), e);
return null;
}
}
FileManager manager = FileManager.getFileManager(filePath.toString(), append, false, isBufferedIo(), true, null, getOrCreateLayout(), getBufferSize(), getConfiguration());
return new ConfigurableFileAppender(getName(), getLayout(), getFilter(), isIgnoreExceptions(), isImmediateFlush(), manager);
}
public B withPathPropertyName(String pathPropertyName) {
this.pathPropertyName = pathPropertyName;
return asBuilder();
}
public B withAppend(boolean append) {
this.append = append;
return asBuilder();
}
}
private static Path parsePath(String path) {
if (path.startsWith("~/")) {
// home-dir-relative Path:
final Path userHome = FileSystems.getDefault().getPath(SystemUtils.USER_HOME);
return userHome.resolve(path.substring(2));
} else if (path.startsWith("/")) {
// absolute Path:
return FileSystems.getDefault().getPath(path);
} else {
// relative Path:
try {
String jarFileLocation = ConfigurableFileAppender.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
if (SystemUtils.IS_OS_WINDOWS && DRIVE_LETTER_WITH_PRECEEDING_SLASH.matcher(jarFileLocation).find()) {
// on windows we need to remove a preceeding slash from "/C:/foo/bar":
jarFileLocation = jarFileLocation.substring(1);
}
final Path workingDir = FileSystems.getDefault().getPath(jarFileLocation).getParent();
return workingDir.resolve(path);
} catch (URISyntaxException e) {
LOGGER.error("Unable to resolve working directory ", e);
return null;
}
}
}
}

View File

@@ -6,29 +6,27 @@
package org.cryptomator.logging;
import static java.util.Arrays.asList;
import static org.apache.logging.log4j.LogManager.ROOT_LOGGER_NAME;
import java.util.Collection;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.cryptomator.common.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.ILoggerFactory;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
@Singleton
public class DebugMode {
private static final Logger LOG = LoggerFactory.getLogger(DebugMode.class);
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(DebugMode.class);
private static final Collection<LoggerUpgrade> LOGGER_UPGRADES = asList( //
loggerUpgrade(ROOT_LOGGER_NAME, Level.INFO), //
loggerUpgrade(org.slf4j.Logger.ROOT_LOGGER_NAME, Level.INFO), //
loggerUpgrade("org.cryptomator", Level.TRACE), //
loggerUpgrade("org.eclipse.jetty.server.Server", Level.DEBUG) //
);
@@ -48,10 +46,13 @@ public class DebugMode {
}
private void enable() {
LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration config = context.getConfiguration();
LOGGER_UPGRADES.forEach(loggerUpgrade -> loggerUpgrade.execute(config));
context.updateLoggers();
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
if (loggerFactory instanceof LoggerContext) {
LoggerContext context = (LoggerContext) loggerFactory;
LOGGER_UPGRADES.forEach(loggerUpgrade -> loggerUpgrade.execute(context));
} else {
LOG.warn("SLF4J not bound to Logback.");
}
}
private static LoggerUpgrade loggerUpgrade(String loggerName, Level minLevel) {
@@ -68,10 +69,10 @@ public class DebugMode {
this.level = minLevel;
}
public void execute(Configuration config) {
LoggerConfig loggerConfig = config.getLoggerConfig(loggerName);
if (loggerConfig.getLevel().isMoreSpecificThan(level)) {
loggerConfig.setLevel(level);
public void execute(LoggerContext context) {
Logger logger = context.getLogger(loggerName);
if (logger.getLevel().isGreaterOrEqual(level)) {
logger.setLevel(level);
}
}

View File

@@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright (c) 2014 Markus Kreusch
This file is licensed under the terms of the MIT license.
See the LICENSE.txt file for more info.
Contributors:
Markus Kreusch - switched to log4j 2
-->
<Configuration status="WARN" packages="org.cryptomator.logging">
<Appenders>
<Console name="StdOut" target="SYSTEM_OUT">
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT" />
</Console>
<Console name="StdErr" target="SYSTEM_ERR">
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY" />
</Console>
<ConfigurableFile name="DefaultLog" pathPropertyName="cryptomator.logPath" append="false">
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
</ConfigurableFile>
<ConfigurableFile name="UpgradeLog" pathPropertyName="cryptomator.upgradeLogPath" append="true">
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
</ConfigurableFile>
</Appenders>
<Loggers>
<!--
= NOTE =
All loggers below are set to info.
This is required to allow changing the levels of the loggers programmatically.
-->
<Logger name="org.cryptomator" level="INFO" />
<Logger name="org.eclipse.jetty.server.Server" level="INFO" />
<Logger name="org.cryptomator.ui.model" level="INFO">
<AppenderRef ref="UpgradeLog" />
</Logger>
<!-- defaults: -->
<Root level="INFO">
<AppenderRef ref="StdOut" />
<AppenderRef ref="StdErr" />
<AppenderRef ref="DefaultLog" />
</Root>
</Loggers>
</Configuration>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright (c) 2014 Markus Kreusch
This file is licensed under the terms of the MIT license.
See the LICENSE.txt file for more info.
Contributors:
Markus Kreusch - switched to log4j 2
-->
<Configuration status="WARN" packages="org.cryptomator.logging">
<Appenders>
<Console name="StdOut" target="SYSTEM_OUT">
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT" />
</Console>
<Console name="StdErr" target="SYSTEM_ERR">
<PatternLayout pattern="%16d %-5p [%c{1}:%L] %m%n" />
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY" />
</Console>
</Appenders>
<Loggers>
<Logger name="org.cryptomator" level="DEBUG" />
<!-- defaults: -->
<Root level="INFO">
<AppenderRef ref="StdOut" />
<AppenderRef ref="StdErr" />
</Root>
</Loggers>
</Configuration>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE xml>
<!-- log config used during unit tests and starts from IDE. For production please specify -Dlogback.configurationFile=/path/to/config -->
<configuration scan="true" debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.cryptomator" level="INFO" />
<logger name="org.eclipse.jetty.server.Server" level="INFO" />
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@@ -31,8 +31,8 @@
<cryptomator.cryptofs.version>1.2.2</cryptomator.cryptofs.version>
<cryptomator.webdav.version>0.6.0</cryptomator.webdav.version>
<cryptomator.jni.version>1.0.2</cryptomator.jni.version>
<log4j.version>2.8.1</log4j.version> <!-- keep in sync with https://github.com/edwgiz/maven-shaded-log4j-transformer (used in uber-jar), or wait for https://issues.apache.org/jira/browse/LOG4J2-954 fix -->
<slf4j.version>1.7.25</slf4j.version>
<logback.version>1.2.2</logback.version>
<junit.version>4.12</junit.version>
<junit.hierarchicalrunner.version>4.12.1</junit.hierarchicalrunner.version>
<hamcrest.version>1.3</hamcrest.version> <!-- keep in sync with version required by JUnit -->
@@ -119,19 +119,14 @@
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jul</artifactId>
<version>${log4j.version}</version>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- commons -->

View File

@@ -41,17 +41,8 @@
<Implementation-Version>${project.version}</Implementation-Version>
</manifestEntries>
</transformer>
<transformer implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer">
</transformer>
</transformers>
</configuration>
<dependencies>
<dependency>
<groupId>com.github.edwgiz</groupId>
<artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

View File

@@ -46,21 +46,21 @@ public class Localization extends ResourceBundle {
String language = Locale.getDefault().getLanguage();
String region = Locale.getDefault().getCountry();
LOG.info("Detected language \"{}\" and region \"{}\"", language, region);
LOG.debug("Detected language \"{}\" and region \"{}\"", language, region);
ResourceBundle localizationBundle = null;
if (StringUtils.isNotEmpty(language) && StringUtils.isNotEmpty(region)) {
String file = String.format(LOCALIZATION_FILENAME_FMT, language + "_" + region);
LOG.info("Attempting to load localization from: {}", file);
LOG.trace("Attempting to load localization from: {}", file);
localizationBundle = loadLocalizationFile(file);
}
if (StringUtils.isNotEmpty(language) && localizationBundle == null) {
String file = String.format(LOCALIZATION_FILENAME_FMT, language);
LOG.info("Attempting to load localization from: {}", file);
LOG.trace("Attempting to load localization from: {}", file);
localizationBundle = loadLocalizationFile(file);
}
if (localizationBundle == null) {
LOG.info("No localization found. Falling back to default language.");
LOG.debug("No localization found. Falling back to default language.");
localizationBundle = this.fallback;
}
this.localized = Objects.requireNonNull(localizationBundle);