diff --git a/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/PdfUmbenennerApplication.java b/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/PdfUmbenennerApplication.java index e2da4d9..9977157 100644 --- a/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/PdfUmbenennerApplication.java +++ b/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/PdfUmbenennerApplication.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import de.gecheckt.pdf.umbenenner.bootstrap.startup.CliArgumentParser; +import de.gecheckt.pdf.umbenenner.bootstrap.startup.EarlyLogDirectoryInitializer; import de.gecheckt.pdf.umbenenner.bootstrap.startup.StartupArguments; import de.gecheckt.pdf.umbenenner.bootstrap.startup.StartupArgumentsParseResult; @@ -28,18 +29,22 @@ import de.gecheckt.pdf.umbenenner.bootstrap.startup.StartupArgumentsParseResult; */ public class PdfUmbenennerApplication { - private static final Logger LOG = LogManager.getLogger(PdfUmbenennerApplication.class); - /** * Application entry point. *
* Parses the command-line arguments and delegates to {@link BootstrapRunner}. * If the arguments cannot be parsed, an error is logged and the process exits * with code 1 before any further initialisation takes place. + *
+ * Vor jeder Logger-Nutzung wird {@link EarlyLogDirectoryInitializer} aufgerufen, + * damit die Property {@code log.directory} aus der aktiven Konfigurationsdatei + * bereits vor der einmaligen Log4j2-Initialisierung gesetzt ist. * * @param args command-line arguments; see class JavaDoc for supported options */ public static void main(String[] args) { + EarlyLogDirectoryInitializer.applyFromArgs(args); + Logger LOG = LogManager.getLogger(PdfUmbenennerApplication.class); LOG.info("Starting PDF Umbenenner application..."); try { StartupArgumentsParseResult parseResult = new CliArgumentParser().parse(args); diff --git a/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/startup/EarlyLogDirectoryInitializer.java b/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/startup/EarlyLogDirectoryInitializer.java new file mode 100644 index 0000000..f4f5475 --- /dev/null +++ b/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/startup/EarlyLogDirectoryInitializer.java @@ -0,0 +1,87 @@ +package de.gecheckt.pdf.umbenenner.bootstrap.startup; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; + +/** + * Liest die Log-Verzeichnis-Angabe so früh wie möglich aus der aktiven Konfigurationsdatei + * und setzt sie als System-Property {@code log.directory}, bevor Log4j2 zum ersten Mal + * initialisiert wird. + *
+ * Hintergrund: {@code log4j2.xml} referenziert {@code ${sys:log.directory}} für den + * Pfad der Rolling-File-Datei. Da Log4j2 sich beim ersten {@code LogManager}-Aufruf + * einmalig konfiguriert, muss die System-Property bereits vorher gesetzt sein. Greift + * die Property nicht, fällt {@code log4j2.xml} auf ein nutzerschreibbares + * Default-Verzeichnis zurück, damit auch im MSI-Betrieb (Arbeitsverzeichnis unter + * {@code Program Files}, typischerweise nicht beschreibbar) eine Log-Datei entsteht. + *
+ * Diese Klasse vermeidet bewusst jede Logger-Nutzung und schluckt sämtliche Fehler: + * Sie soll niemals den Programmstart verhindern, sondern lediglich einen frühen + * Best-Effort-Hinweis an Log4j2 liefern. + */ +public final class EarlyLogDirectoryInitializer { + + private static final String SYSTEM_PROPERTY_KEY = "log.directory"; + private static final String CONFIG_OPTION = "--config"; + private static final Path DEFAULT_CONFIG_PATH = Paths.get("config/application.properties"); + private static final String CONFIG_PROPERTY_KEY = "log.directory"; + + private EarlyLogDirectoryInitializer() { + // utility + } + + /** + * Versucht, aus der aktiven Konfigurationsdatei den Wert von {@code log.directory} + * zu lesen, und setzt ihn als System-Property, sofern er ein nicht-leerer String ist. + *
+ * Greift {@code --config