From ec7ad0f479c575abbd668b4e10230f26890c7931 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Thu, 11 Aug 2022 18:14:54 +0200 Subject: [PATCH] use new ServiceLoader based log configurator --- src/main/java/module-info.java | 3 + .../org/cryptomator/common/Environment.java | 18 ++- .../org/cryptomator/launcher/Cryptomator.java | 7 +- .../launcher/CryptomatorComponent.java | 3 +- .../org/cryptomator/logging/DebugMode.java | 23 +-- .../logging/LogbackConfigurator.java | 146 ++++++++++++++++++ .../logging/LogbackConfiguratorFactory.java | 12 ++ .../logging/LoggerConfiguration.java | 70 --------- .../org/cryptomator/logging/LoggerModule.java | 130 ---------------- 9 files changed, 181 insertions(+), 231 deletions(-) create mode 100644 src/main/java/org/cryptomator/logging/LogbackConfigurator.java create mode 100644 src/main/java/org/cryptomator/logging/LogbackConfiguratorFactory.java delete mode 100644 src/main/java/org/cryptomator/logging/LoggerConfiguration.java delete mode 100644 src/main/java/org/cryptomator/logging/LoggerModule.java diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index ae7408c33..82fdc7335 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,4 +1,6 @@ +import ch.qos.logback.classic.spi.Configurator; import org.cryptomator.integrations.tray.TrayMenuController; +import org.cryptomator.logging.LogbackConfiguratorFactory; import org.cryptomator.ui.traymenu.AwtTrayMenuController; open module org.cryptomator.desktop { @@ -38,6 +40,7 @@ open module org.cryptomator.desktop { exports org.cryptomator.ui.traymenu to org.cryptomator.integrations.api; provides TrayMenuController with AwtTrayMenuController; + provides Configurator with LogbackConfiguratorFactory; exports org.cryptomator.ui.keyloading.hub to com.fasterxml.jackson.databind; } \ No newline at end of file diff --git a/src/main/java/org/cryptomator/common/Environment.java b/src/main/java/org/cryptomator/common/Environment.java index 57eae5488..261750ad1 100644 --- a/src/main/java/org/cryptomator/common/Environment.java +++ b/src/main/java/org/cryptomator/common/Environment.java @@ -33,12 +33,14 @@ public class Environment { private static final String PLUGIN_DIR_PROP_NAME = "cryptomator.pluginDir"; private static final String TRAY_ICON_PROP_NAME = "cryptomator.showTrayIcon"; - public Environment() { - LOG.debug("user.home: {}", System.getProperty("user.home")); - LOG.debug("java.library.path: {}", System.getProperty("java.library.path")); - LOG.debug("user.language: {}", System.getProperty("user.language")); - LOG.debug("user.region: {}", System.getProperty("user.region")); - LOG.debug("logback.configurationFile: {}", System.getProperty("logback.configurationFile")); + private Environment() {} + + public void log() { + LOG.info("user.home: {}", System.getProperty("user.home")); + LOG.info("java.library.path: {}", System.getProperty("java.library.path")); + LOG.info("user.language: {}", System.getProperty("user.language")); + LOG.info("user.region: {}", System.getProperty("user.region")); + LOG.info("logback.configurationFile: {}", System.getProperty("logback.configurationFile")); logCryptomatorSystemProperty(SETTINGS_PATH_PROP_NAME); logCryptomatorSystemProperty(IPC_SOCKET_PATH_PROP_NAME); logCryptomatorSystemProperty(KEYCHAIN_PATHS_PROP_NAME); @@ -54,13 +56,14 @@ public class Environment { public static Environment getInstance() { final class Holder { + private static final Environment INSTANCE = new Environment(); } return Holder.INSTANCE; } private void logCryptomatorSystemProperty(String propertyName) { - LOG.debug("{}: {}", propertyName, System.getProperty(propertyName)); + LOG.info("{}: {}", propertyName, System.getProperty(propertyName)); } public boolean useCustomLogbackConfig() { @@ -97,6 +100,7 @@ public class Environment { /** * Returns the app version defined in the {@value APP_VERSION_PROP_NAME} property or returns "SNAPSHOT". + * * @return App version or "SNAPSHOT", if undefined */ public String getAppVersion() { diff --git a/src/main/java/org/cryptomator/launcher/Cryptomator.java b/src/main/java/org/cryptomator/launcher/Cryptomator.java index 08fb13185..2b066c730 100644 --- a/src/main/java/org/cryptomator/launcher/Cryptomator.java +++ b/src/main/java/org/cryptomator/launcher/Cryptomator.java @@ -12,7 +12,6 @@ import org.cryptomator.common.Environment; import org.cryptomator.common.ShutdownHook; import org.cryptomator.ipc.IpcCommunicator; import org.cryptomator.logging.DebugMode; -import org.cryptomator.logging.LoggerConfiguration; import org.cryptomator.ui.fxapp.FxApplicationComponent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +34,6 @@ public class Cryptomator { private static final CryptomatorComponent CRYPTOMATOR_COMPONENT = DaggerCryptomatorComponent.factory().create(STARTUP_TIME); private static final Logger LOG = LoggerFactory.getLogger(Cryptomator.class); - private final LoggerConfiguration logConfig; private final DebugMode debugMode; private final SupportedLanguages supportedLanguages; private final Environment env; @@ -43,8 +41,7 @@ public class Cryptomator { private final ShutdownHook shutdownHook; @Inject - Cryptomator(LoggerConfiguration logConfig, DebugMode debugMode, SupportedLanguages supportedLanguages, Environment env, Lazy ipcMessageHandler, ShutdownHook shutdownHook) { - this.logConfig = logConfig; + Cryptomator(DebugMode debugMode, SupportedLanguages supportedLanguages, Environment env, Lazy ipcMessageHandler, ShutdownHook shutdownHook) { this.debugMode = debugMode; this.supportedLanguages = supportedLanguages; this.env = env; @@ -79,7 +76,7 @@ public class Cryptomator { * @return Nonzero exit code in case of an error. */ private int run(String[] args) { - logConfig.init(); + env.log(); LOG.debug("Dagger graph initialized after {}ms", System.currentTimeMillis() - STARTUP_TIME); LOG.info("Starting Cryptomator {} on {} {} ({})", env.getAppVersion(), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH); debugMode.initialize(); diff --git a/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java b/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java index 8c6443717..72b8af80c 100644 --- a/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java +++ b/src/main/java/org/cryptomator/launcher/CryptomatorComponent.java @@ -3,14 +3,13 @@ package org.cryptomator.launcher; import dagger.BindsInstance; import dagger.Component; import org.cryptomator.common.CommonsModule; -import org.cryptomator.logging.LoggerModule; import org.cryptomator.ui.fxapp.FxApplicationComponent; import javax.inject.Named; import javax.inject.Singleton; @Singleton -@Component(modules = {CryptomatorModule.class, CommonsModule.class, LoggerModule.class}) +@Component(modules = {CryptomatorModule.class, CommonsModule.class}) public interface CryptomatorComponent { Cryptomator application(); diff --git a/src/main/java/org/cryptomator/logging/DebugMode.java b/src/main/java/org/cryptomator/logging/DebugMode.java index c15fb466b..386b0fd43 100644 --- a/src/main/java/org/cryptomator/logging/DebugMode.java +++ b/src/main/java/org/cryptomator/logging/DebugMode.java @@ -5,29 +5,24 @@ *******************************************************************************/ package org.cryptomator.logging; -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.LoggerContext; import org.cryptomator.common.settings.Settings; +import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Singleton; import javafx.beans.value.ObservableValue; -import java.util.Map; @Singleton public class DebugMode { - private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(DebugMode.class); + private static final Logger LOG = LoggerFactory.getLogger(DebugMode.class); private final Settings settings; - private final LoggerContext context; @Inject - public DebugMode(Settings settings, LoggerContext context) { + public DebugMode(Settings settings) { this.settings = settings; - this.context = context; } public void initialize() { @@ -40,19 +35,13 @@ public class DebugMode { } private void setLogLevels(boolean debugMode) { + var configurator = LogbackConfiguratorFactory.provider(); if (debugMode) { - setLogLevels(LoggerModule.DEBUG_LOG_LEVELS); + configurator.setLogLevels(LogbackConfigurator.DEBUG_LOG_LEVELS); LOG.debug("Debug mode enabled"); } else { LOG.debug("Debug mode disabled"); - setLogLevels(LoggerModule.DEFAULT_LOG_LEVELS); - } - } - - private void setLogLevels(Map logLevels) { - for (Map.Entry loglevel : logLevels.entrySet()) { - Logger logger = context.getLogger(loglevel.getKey()); - logger.setLevel(loglevel.getValue()); + configurator.setLogLevels(LogbackConfigurator.DEFAULT_LOG_LEVELS); } } diff --git a/src/main/java/org/cryptomator/logging/LogbackConfigurator.java b/src/main/java/org/cryptomator/logging/LogbackConfigurator.java new file mode 100644 index 000000000..6ecbbc294 --- /dev/null +++ b/src/main/java/org/cryptomator/logging/LogbackConfigurator.java @@ -0,0 +1,146 @@ +package org.cryptomator.logging; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.encoder.PatternLayoutEncoder; +import ch.qos.logback.classic.spi.Configurator; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.Appender; +import ch.qos.logback.core.ConsoleAppender; +import ch.qos.logback.core.FileAppender; +import ch.qos.logback.core.helpers.NOPAppender; +import ch.qos.logback.core.rolling.FixedWindowRollingPolicy; +import ch.qos.logback.core.rolling.RollingFileAppender; +import ch.qos.logback.core.spi.ContextAwareBase; +import ch.qos.logback.core.util.FileSize; +import org.cryptomator.common.Environment; + +import java.nio.file.Path; +import java.util.Map; + +public class LogbackConfigurator extends ContextAwareBase implements Configurator { + + private static final String LOG_PATTERN = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"; + private static final String UPGRADE_FILENAME = "upgrade.log"; + private static final String LOGFILE_NAME = "cryptomator0.log"; + private static final String LOGFILE_ROLLING_PATTERN = "cryptomator%i.log"; + private static final int LOGFILE_ROLLING_MIN = 1; + private static final int LOGFILE_ROLLING_MAX = 9; + private static final String LOG_MAX_SIZE = "100mb"; + + static final Map DEFAULT_LOG_LEVELS = Map.of( // + Logger.ROOT_LOGGER_NAME, Level.INFO, // + "org.cryptomator", Level.INFO // + ); + static final Map DEBUG_LOG_LEVELS = Map.of( // + Logger.ROOT_LOGGER_NAME, Level.INFO, // + "org.cryptomator", Level.TRACE // + ); + + LogbackConfigurator() {} + + /** + * Adjust the log levels + * + * @param logLevels new log levels to use + */ + void setLogLevels(Map logLevels) { + if (context instanceof LoggerContext lc) { + for (var loglevel : logLevels.entrySet()) { + Logger logger = lc.getLogger(loglevel.getKey()); + logger.setLevel(loglevel.getValue()); + } + } + } + + @Override + public void configure(LoggerContext context) { + var useCustomCfg = Environment.getInstance().useCustomLogbackConfig(); + var logDir = Environment.getInstance().getLogDir().orElse(null); + + if (useCustomCfg) { + addInfo("Using external logback configuration file."); + } else { + context.reset(); + + // configure appenders: + var stdout = stdOutAppender(context); + var noop = noopAppender(context); + var file = logDir == null ? noop : fileAppender(context, logDir); + var upgrade = logDir == null ? noop : upgradeAppender(context, logDir); + + // configure loggers: + for (var loglevel : DEFAULT_LOG_LEVELS.entrySet()) { + Logger logger = context.getLogger(loglevel.getKey()); + logger.setLevel(loglevel.getValue()); + logger.setAdditive(false); + logger.addAppender(stdout); + logger.addAppender(file); + } + + // configure upgrade logger: + Logger upgrades = context.getLogger("org.cryptomator.cryptofs.migration"); + upgrades.setLevel(Level.DEBUG); + upgrades.addAppender(stdout); + upgrades.addAppender(upgrade); + upgrades.addAppender(file); + upgrades.setAdditive(false); + } + } + + private Appender noopAppender(LoggerContext context) { + var appender = new NOPAppender(); + appender.setContext(context); + return appender; + } + + private Appender stdOutAppender(LoggerContext context) { + var appender = new ConsoleAppender(); + appender.setContext(context); + appender.setName("STDOUT"); + appender.setEncoder(encoder(context)); + appender.start(); + return appender; + } + + private Appender upgradeAppender(LoggerContext context, Path logDir) { + var appender = new FileAppender(); + appender.setContext(context); + appender.setName("UPGRADE"); + appender.setFile(logDir.resolve(UPGRADE_FILENAME).toString()); + appender.setEncoder(encoder(context)); + appender.start(); + return appender; + } + + private Appender fileAppender(LoggerContext context, Path logDir) { + var appender = new RollingFileAppender(); + appender.setContext(context); + appender.setName("FILE"); + appender.setFile(logDir.resolve(LOGFILE_NAME).toString()); + appender.setEncoder(encoder(context)); + var triggeringPolicy = new LaunchAndSizeBasedTriggeringPolicy(FileSize.valueOf(LOG_MAX_SIZE)); + triggeringPolicy.setContext(context); + triggeringPolicy.start(); + appender.setTriggeringPolicy(triggeringPolicy); + var rollingPolicy = new FixedWindowRollingPolicy(); + rollingPolicy.setContext(context); + rollingPolicy.setFileNamePattern(logDir.resolve(LOGFILE_ROLLING_PATTERN).toString()); + rollingPolicy.setMinIndex(LOGFILE_ROLLING_MIN); + rollingPolicy.setMaxIndex(LOGFILE_ROLLING_MAX); + rollingPolicy.setParent(appender); + rollingPolicy.start(); + appender.setRollingPolicy(rollingPolicy); + appender.start(); + return appender; + } + + private PatternLayoutEncoder encoder(LoggerContext context) { + var encoder = new PatternLayoutEncoder(); + encoder.setContext(context); + encoder.setPattern(LOG_PATTERN); + encoder.start(); + return encoder; + } +} diff --git a/src/main/java/org/cryptomator/logging/LogbackConfiguratorFactory.java b/src/main/java/org/cryptomator/logging/LogbackConfiguratorFactory.java new file mode 100644 index 000000000..1d796891f --- /dev/null +++ b/src/main/java/org/cryptomator/logging/LogbackConfiguratorFactory.java @@ -0,0 +1,12 @@ +package org.cryptomator.logging; + +public class LogbackConfiguratorFactory { + + public static LogbackConfigurator provider() { + final class Holder { + private static final LogbackConfigurator INSTANCE = new LogbackConfigurator(); + } + return Holder.INSTANCE; + } + +} diff --git a/src/main/java/org/cryptomator/logging/LoggerConfiguration.java b/src/main/java/org/cryptomator/logging/LoggerConfiguration.java deleted file mode 100644 index 3d8cc9216..000000000 --- a/src/main/java/org/cryptomator/logging/LoggerConfiguration.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.cryptomator.logging; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.Appender; -import org.cryptomator.common.Environment; -import org.cryptomator.common.ShutdownHook; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; -import java.util.Map; - -@Singleton -public class LoggerConfiguration { - - private final LoggerContext context; - private final Environment environment; - private final Appender stdout; - private final Appender upgrade; - private final Appender file; - private final ShutdownHook shutdownHook; - - @Inject - LoggerConfiguration(LoggerContext context, // - Environment environment, // - @Named("stdoutAppender") Appender stdout, // - @Named("upgradeAppender") Appender upgrade, // - @Named("fileAppender") Appender file, // - ShutdownHook shutdownHook) { - this.context = context; - this.environment = environment; - this.stdout = stdout; - this.upgrade = upgrade; - this.file = file; - this.shutdownHook = shutdownHook; - } - - public void init() { - if (environment.useCustomLogbackConfig()) { - Logger root = context.getLogger(Logger.ROOT_LOGGER_NAME); - root.info("Using external logback configuration file."); - } else { - context.reset(); - - // configure loggers: - for (Map.Entry loglevel : LoggerModule.DEFAULT_LOG_LEVELS.entrySet()) { - Logger logger = context.getLogger(loglevel.getKey()); - logger.setLevel(loglevel.getValue()); - logger.setAdditive(false); - logger.addAppender(stdout); - logger.addAppender(file); - } - - // configure upgrade logger: - Logger upgrades = context.getLogger("org.cryptomator.cryptofs.migration"); - upgrades.setLevel(Level.DEBUG); - upgrades.addAppender(stdout); - upgrades.addAppender(upgrade); - upgrades.addAppender(file); - upgrades.setAdditive(false); - - // add shutdown hook - shutdownHook.runOnShutdown(ShutdownHook.PRIO_LAST, context::stop); - } - } - -} diff --git a/src/main/java/org/cryptomator/logging/LoggerModule.java b/src/main/java/org/cryptomator/logging/LoggerModule.java deleted file mode 100644 index 5031fe3be..000000000 --- a/src/main/java/org/cryptomator/logging/LoggerModule.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.cryptomator.logging; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.encoder.PatternLayoutEncoder; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.Appender; -import ch.qos.logback.core.ConsoleAppender; -import ch.qos.logback.core.FileAppender; -import ch.qos.logback.core.helpers.NOPAppender; -import ch.qos.logback.core.rolling.FixedWindowRollingPolicy; -import ch.qos.logback.core.rolling.RollingFileAppender; -import ch.qos.logback.core.util.FileSize; -import dagger.Module; -import dagger.Provides; -import org.cryptomator.common.Environment; -import org.slf4j.ILoggerFactory; -import org.slf4j.LoggerFactory; - -import javax.inject.Named; -import javax.inject.Singleton; -import java.nio.file.Path; -import java.util.Map; - -@Module -public class LoggerModule { - - private static final String UPGRADE_FILENAME = "upgrade.log"; - private static final String LOGFILE_NAME = "cryptomator0.log"; - private static final String LOGFILE_ROLLING_PATTERN = "cryptomator%i.log"; - private static final int LOGFILE_ROLLING_MIN = 1; - private static final int LOGFILE_ROLLING_MAX = 9; - private static final String LOG_PATTERN = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"; - private static final String LOG_MAX_SIZE = "100mb"; - - static final Map DEFAULT_LOG_LEVELS = Map.of( // - Logger.ROOT_LOGGER_NAME, Level.INFO, // - "org.cryptomator", Level.INFO // - ); - static final Map DEBUG_LOG_LEVELS = Map.of( // - Logger.ROOT_LOGGER_NAME, Level.INFO, // - "org.cryptomator", Level.TRACE // - ); - - @Provides - @Singleton - static LoggerContext provideLoggerContext() { - ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory(); - if (loggerFactory instanceof LoggerContext context) { - return context; - } else { - throw new IllegalStateException("SLF4J not bound to Logback."); - } - } - - @Provides - @Singleton - static PatternLayoutEncoder provideLayoutEncoder(LoggerContext context) { - PatternLayoutEncoder ple = new PatternLayoutEncoder(); - ple.setPattern(LOG_PATTERN); - ple.setContext(context); - ple.start(); - return ple; - } - - @Provides - @Singleton - @Named("stdoutAppender") - static Appender provideStdoutAppender(LoggerContext context, PatternLayoutEncoder encoder) { - ConsoleAppender appender = new ConsoleAppender<>(); - appender.setContext(context); - appender.setEncoder(encoder); - appender.start(); - return appender; - } - - @Provides - @Singleton - @Named("fileAppender") - static Appender provideFileAppender(LoggerContext context, PatternLayoutEncoder encoder, Environment environment) { - var optionalLogDir = environment.getLogDir(); - if (optionalLogDir.isPresent()) { - Path logDir = optionalLogDir.get(); - RollingFileAppender appender = new RollingFileAppender<>(); - appender.setContext(context); - appender.setFile(logDir.resolve(LOGFILE_NAME).toString()); - appender.setEncoder(encoder); - LaunchAndSizeBasedTriggeringPolicy triggeringPolicy = new LaunchAndSizeBasedTriggeringPolicy(FileSize.valueOf(LOG_MAX_SIZE)); - triggeringPolicy.setContext(context); - triggeringPolicy.start(); - appender.setTriggeringPolicy(triggeringPolicy); - FixedWindowRollingPolicy rollingPolicy = new FixedWindowRollingPolicy(); - rollingPolicy.setContext(context); - rollingPolicy.setFileNamePattern(logDir.resolve(LOGFILE_ROLLING_PATTERN).toString()); - rollingPolicy.setMinIndex(LOGFILE_ROLLING_MIN); - rollingPolicy.setMaxIndex(LOGFILE_ROLLING_MAX); - rollingPolicy.setParent(appender); - rollingPolicy.start(); - appender.setRollingPolicy(rollingPolicy); - appender.start(); - return appender; - } else { - NOPAppender appender = new NOPAppender<>(); - appender.setContext(context); - return appender; - } - } - - @Provides - @Singleton - @Named("upgradeAppender") - static Appender provideUpgradeAppender(LoggerContext context, PatternLayoutEncoder encoder, Environment environment) { - var optionalLogDir = environment.getLogDir(); - if (optionalLogDir.isPresent()) { - FileAppender appender = new FileAppender<>(); - appender.setFile(optionalLogDir.get().resolve(UPGRADE_FILENAME).toString()); - appender.setContext(context); - appender.setEncoder(encoder); - appender.start(); - return appender; - } else { - NOPAppender appender = new NOPAppender<>(); - appender.setContext(context); - return appender; - } - } - - -}