diff --git a/pom.xml b/pom.xml index 8d0af6f..86cdc51 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ tv.dotstart.beacon parent - 2.1.5 + 2.2.0 pom @@ -30,10 +30,10 @@ 2.1.2 2.9.9 - 1.3.31 - 2.5 + 1.3.41 + 2.12.0 11 - 3.8.0 + 3.9.0 @@ -84,7 +84,7 @@ tv.dotstart.beacon repository-model - 2.1.5 + 2.2.0 diff --git a/repository-compiler/pom.xml b/repository-compiler/pom.xml index c9116c7..0e53635 100644 --- a/repository-compiler/pom.xml +++ b/repository-compiler/pom.xml @@ -23,7 +23,7 @@ parent tv.dotstart.beacon - 2.1.5 + 2.2.0 repository-compiler diff --git a/repository-model/pom.xml b/repository-model/pom.xml index 9d7ebf4..f7e2df6 100644 --- a/repository-model/pom.xml +++ b/repository-model/pom.xml @@ -23,7 +23,7 @@ parent tv.dotstart.beacon - 2.1.5 + 2.2.0 repository-model diff --git a/ui/pom.xml b/ui/pom.xml index c46c51e..55fcb80 100644 --- a/ui/pom.xml +++ b/ui/pom.xml @@ -23,7 +23,7 @@ parent tv.dotstart.beacon - 2.1.5 + 2.2.0 ui diff --git a/ui/src/main/kotlin/tv/dotstart/beacon/BeaconCli.kt b/ui/src/main/kotlin/tv/dotstart/beacon/BeaconCli.kt index bcce6a4..ed0f8ff 100644 --- a/ui/src/main/kotlin/tv/dotstart/beacon/BeaconCli.kt +++ b/ui/src/main/kotlin/tv/dotstart/beacon/BeaconCli.kt @@ -22,19 +22,8 @@ import javafx.application.Application import javafx.application.Platform 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.appender.RollingFileAppender -import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy -import org.apache.logging.log4j.core.appender.rolling.OnStartupTriggeringPolicy -import org.apache.logging.log4j.core.config.Configurator -import org.apache.logging.log4j.core.layout.PatternLayout -import tv.dotstart.beacon.util.Banner -import tv.dotstart.beacon.util.Localization -import tv.dotstart.beacon.util.OperatingSystem -import tv.dotstart.beacon.util.detailedErrorDialog +import tv.dotstart.beacon.util.* import java.net.URI -import java.nio.charset.StandardCharsets -import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import java.time.Duration @@ -116,7 +105,7 @@ object BeaconCli : CliktCommand(name = "Beacon") { } override fun run() { - registerFileAppender() + configureLogStorage(this.logDirectory) val logger = LogManager.getLogger(Beacon::class.java) @@ -157,19 +146,14 @@ object BeaconCli : CliktCommand(name = "Beacon") { "System Repositories (${systemRepositories.size}): ${systemRepositories.joinToString()}") if (this.verbose || this.debug) { - Configurator.setRootLevel( - if (this.verbose) { - Level.ALL - } else { - Level.DEBUG - } - ) - - if (this.verbose) { - logger.warn("Enabled VERBOSE logging - This may cause significant log output") + val level = if (this.verbose) { + Level.ALL } else { - logger.warn("Enabled DEBUG logging") + Level.DEBUG } + + rootLevel = level + logger.info("Adjusted the application log level to $level") } if (this.disableCache) { @@ -181,30 +165,6 @@ object BeaconCli : CliktCommand(name = "Beacon") { // we do not pass any of our arguments to JavaFX since there's nothing special to handle here Application.launch(Beacon::class.java) } - - private fun registerFileAppender() { - val ctx = LoggerContext.getContext(false) - val root = ctx.rootLogger - val cfg = ctx.configuration - val layout = PatternLayout.createLayout("[%d{HH:mm:ss}] [%25.25t] [%level]: %msg%n", null, cfg, - null, StandardCharsets.UTF_8, true, false, null, null) - Files.createDirectories(this.logDirectory) - - val policy = OnStartupTriggeringPolicy.createPolicy() - val strategy = DefaultRolloverStrategy.createStrategy("10", "1", "min", null, null, true, cfg) - - val fileAppender = RollingFileAppender.createAppender( - this.logDirectory.resolve("latest.log").toAbsolutePath().toString(), - this.logDirectory.resolve("beacon.log").toAbsolutePath().toString() + ".%i", - "true", "File", null, null, "true", - policy, strategy, layout, null, null, null, null, cfg - ) - - fileAppender.start() - - cfg.addAppender(fileAppender) - root.addAppender(fileAppender) - } } /** diff --git a/ui/src/main/kotlin/tv/dotstart/beacon/exposure/PortMapper.kt b/ui/src/main/kotlin/tv/dotstart/beacon/exposure/PortMapper.kt index d309844..48823d8 100644 --- a/ui/src/main/kotlin/tv/dotstart/beacon/exposure/PortMapper.kt +++ b/ui/src/main/kotlin/tv/dotstart/beacon/exposure/PortMapper.kt @@ -114,7 +114,7 @@ object PortMapper { Model.Protocol.UDP -> PortMapping.Protocol.UDP else -> throw IllegalArgumentException("Unsupported protocol: ${port.protocol}") }, - "Beacon Service ({$service.id})" + "Beacon Service (${service.id})" ) mapping.leaseDurationSeconds = UnsignedIntegerFourBytes(LEASE_DURATION) return mapping diff --git a/ui/src/main/kotlin/tv/dotstart/beacon/util/LoggerExtensions.kt b/ui/src/main/kotlin/tv/dotstart/beacon/util/LoggerExtensions.kt index 7def3a5..ba948b5 100644 --- a/ui/src/main/kotlin/tv/dotstart/beacon/util/LoggerExtensions.kt +++ b/ui/src/main/kotlin/tv/dotstart/beacon/util/LoggerExtensions.kt @@ -16,8 +16,18 @@ */ package tv.dotstart.beacon.util +import org.apache.logging.log4j.Level import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger +import org.apache.logging.log4j.core.LoggerContext +import org.apache.logging.log4j.core.appender.RollingFileAppender +import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy +import org.apache.logging.log4j.core.appender.rolling.OnStartupTriggeringPolicy +import org.apache.logging.log4j.core.config.Configurator +import org.apache.logging.log4j.core.layout.PatternLayout +import java.nio.charset.StandardCharsets +import java.nio.file.Files +import java.nio.file.Path import kotlin.reflect.KClass /** @@ -26,6 +36,15 @@ import kotlin.reflect.KClass * @author [Johannes Donath](mailto:johannesd@torchmind.com) */ +/** + * Permits retrieving and altering of the root logger level. + */ +var rootLevel: Level + get() = LogManager.getRootLogger().level + set(value: Level) { + Configurator.setRootLevel(value) + } + /** * Retrieves the logger for a given type. * @@ -35,3 +54,56 @@ import kotlin.reflect.KClass */ inline val KClass.logger: Logger get() = LogManager.getLogger(this.java) + +/** + * Configures the root logger to write all of its logs to a given storage location. + */ +fun configureLogStorage(target: Path) { + Files.createDirectories(target) + + val ctx = LoggerContext.getContext(false) + val root = ctx.rootLogger + val cfg = ctx.configuration + + val layout = PatternLayout.newBuilder() + .withPattern("[%d{HH:mm:ss}] [%25.25t] [%level]: %msg%n") + .withCharset(StandardCharsets.UTF_8) + .withAlwaysWriteExceptions(true) + .withConfiguration(cfg) + .build() + + val policy = OnStartupTriggeringPolicy.createPolicy(0) + + val strategy = DefaultRolloverStrategy.newBuilder() + .withMax("10") + .withMin("1") + .withFileIndex("min") + .withConfig(cfg) + .build() + + val fileAppender = (RollingFileAppender.newBuilder() as RollingFileAppender.Builder).apply { + name = "File" + configuration = cfg + setLayout(layout) + + withFileName(target.resolve("latest.log").toAbsolutePath().toString()) + withFilePattern(target.resolve("lantern.log").toAbsolutePath().toString() + ".%i") + withAppend(true) + withImmediateFlush(true) + withPolicy(policy) + withStrategy(strategy) + }.build() + + fileAppender.start() + + cfg.addAppender(fileAppender) + root.addAppender(fileAppender) +} + +/** + * Utility class which works around log4j's current API issues. + * + * See https://stackoverflow.com/questions/49601627/how-to-specify-recursive-generic-parameter-in-kotlin/50565929#50565929 + * for more information on the topic. + */ +private class RollingFileAppenderBuilder : RollingFileAppender.Builder()