#90: Neuer technischer Prüfpunkt LOG_DIRECTORY_USABLE (12. Checkpoint): - Zeigt konfigurierten log.directory-Wert und aufgelösten absoluten Pfad - Prüft ob Verzeichnis beschreibbar/anlegbar ist (WARNING, kein ERROR) - Liest tatsächlichen Log-Datei-Pfad via Log4j2 LoggerContext → RollingFileAppender - LogDiagnosticsPort als neuer Outbound-Port (application-Modul) - Log4jLogDiagnosticsAdapter als Implementierung im bootstrap-Modul - TechnicalTestRequest erhält logDirectory-Feld - GuiTechnicalTestCoordinator erhält logDirectoryProvider-Supplier #89: docs/betrieb.md – MSI-Betrieb um Pfadwarnungen erweitert: - Warnung: relative Pfade lösen sich in schreibgeschütztes C:\Program Files\ auf - Warnung: Backslashes in .properties werden als Java-Escape-Sequenzen interpretiert - Betroffene Parameter mit Empfehlung zu absoluten Forward-Slash-Pfaden - Beschreibung des neuen Log-Verzeichnis-Prüfpunkts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+3
-1
@@ -109,6 +109,7 @@ import de.gecheckt.pdf.umbenenner.application.validation.technicaltest.ProviderT
|
||||
import de.gecheckt.pdf.umbenenner.application.validation.technicaltest.TechnicalTestOrchestrator;
|
||||
import de.gecheckt.pdf.umbenenner.bootstrap.adapter.AiModelCatalogDispatcher;
|
||||
import de.gecheckt.pdf.umbenenner.bootstrap.adapter.GuiConfigurationPropertiesWriter;
|
||||
import de.gecheckt.pdf.umbenenner.bootstrap.adapter.Log4jLogDiagnosticsAdapter;
|
||||
import de.gecheckt.pdf.umbenenner.bootstrap.adapter.Log4jProcessingLogger;
|
||||
import de.gecheckt.pdf.umbenenner.bootstrap.singleinstance.AnotherInstanceRunningException;
|
||||
import de.gecheckt.pdf.umbenenner.bootstrap.singleinstance.SingleInstanceGuard;
|
||||
@@ -807,7 +808,8 @@ public class BootstrapRunner {
|
||||
TechnicalTestOrchestrator technicalTestOrchestrator = new TechnicalTestOrchestrator(
|
||||
new EditorConfigurationValidator(),
|
||||
pathCheckPort,
|
||||
providerTechnicalTestService);
|
||||
providerTechnicalTestService,
|
||||
new Log4jLogDiagnosticsAdapter());
|
||||
de.gecheckt.pdf.umbenenner.application.validation.technicaltest.CorrectionExecutionService correctionExecutionService =
|
||||
new de.gecheckt.pdf.umbenenner.application.validation.technicaltest.CorrectionExecutionService(
|
||||
new de.gecheckt.pdf.umbenenner.adapter.out.resourcecreation.FilesystemResourceCreationAdapter());
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package de.gecheckt.pdf.umbenenner.bootstrap.adapter;
|
||||
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.core.LoggerContext;
|
||||
import org.apache.logging.log4j.core.appender.RollingFileAppender;
|
||||
|
||||
import de.gecheckt.pdf.umbenenner.application.validation.technicaltest.LogDiagnosticsPort;
|
||||
|
||||
/**
|
||||
* Log4j2-basierte Implementierung von {@link LogDiagnosticsPort}.
|
||||
* <p>
|
||||
* Liest den aktiven {@link RollingFileAppender} aus dem laufenden {@link LoggerContext}
|
||||
* und gibt dessen absoluten Dateipfad zurück. Diese Information zeigt, wo Log-Einträge
|
||||
* tatsächlich landen – unabhängig vom konfigurierten {@code log.directory}-Wert in der
|
||||
* Properties-Datei.
|
||||
* <p>
|
||||
* Gibt einen leeren {@link Optional} zurück, wenn kein dateibasierter Appender aktiv ist,
|
||||
* der Kontext nicht auslesbar ist oder der Pfad nicht zu einem absoluten Pfad aufgelöst
|
||||
* werden kann.
|
||||
*/
|
||||
public class Log4jLogDiagnosticsAdapter implements LogDiagnosticsPort {
|
||||
|
||||
/**
|
||||
* Erstellt einen neuen {@code Log4jLogDiagnosticsAdapter}.
|
||||
*/
|
||||
public Log4jLogDiagnosticsAdapter() {
|
||||
// zustandslos
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt den absoluten Pfad der aktiven Log-Datei aus dem laufenden Log4j2-Kontext.
|
||||
* <p>
|
||||
* Durchsucht die Appender-Liste des aktiven {@link LoggerContext} nach dem ersten
|
||||
* {@link RollingFileAppender} und gibt dessen {@code fileName} als absoluten Pfad zurück.
|
||||
* Alle Ausnahmen werden abgefangen und als leeres Ergebnis zurückgegeben.
|
||||
*
|
||||
* @return absoluter Pfad der aktiven Log-Datei; leer wenn nicht bestimmbar
|
||||
*/
|
||||
@Override
|
||||
public Optional<String> resolveActiveLogFilePath() {
|
||||
try {
|
||||
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
|
||||
return ctx.getConfiguration().getAppenders().values().stream()
|
||||
.filter(a -> a instanceof RollingFileAppender)
|
||||
.map(a -> (RollingFileAppender) a)
|
||||
.map(RollingFileAppender::getFileName)
|
||||
.filter(name -> name != null && !name.isBlank())
|
||||
.map(this::toAbsolutePath)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst();
|
||||
} catch (Exception e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<String> toAbsolutePath(String path) {
|
||||
try {
|
||||
return Optional.of(Paths.get(path).toAbsolutePath().toString());
|
||||
} catch (InvalidPathException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user