1
0

Nachbearbeitung: Logging aus der Application-Schicht entkoppelt

This commit is contained in:
2026-04-04 14:31:14 +02:00
parent deaa8c9fa3
commit 8e6d745e4b
9 changed files with 210 additions and 55 deletions

View File

@@ -29,10 +29,12 @@ import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecordRepository;
import de.gecheckt.pdf.umbenenner.application.port.out.FingerprintPort;
import de.gecheckt.pdf.umbenenner.application.port.out.PersistenceSchemaInitializationPort;
import de.gecheckt.pdf.umbenenner.application.port.out.ProcessingAttemptRepository;
import de.gecheckt.pdf.umbenenner.application.port.out.ProcessingLogger;
import de.gecheckt.pdf.umbenenner.application.port.out.RunLockPort;
import de.gecheckt.pdf.umbenenner.application.port.out.UnitOfWorkPort;
import de.gecheckt.pdf.umbenenner.application.service.DocumentProcessingCoordinator;
import de.gecheckt.pdf.umbenenner.application.usecase.DefaultBatchRunProcessingUseCase;
import de.gecheckt.pdf.umbenenner.bootstrap.adapter.Log4jProcessingLogger;
import de.gecheckt.pdf.umbenenner.domain.model.BatchRunContext;
import de.gecheckt.pdf.umbenenner.domain.model.RunId;
@@ -171,15 +173,17 @@ public class BootstrapRunner {
new SqliteProcessingAttemptRepositoryAdapter(jdbcUrl);
UnitOfWorkPort unitOfWorkPort =
new SqliteUnitOfWorkAdapter(jdbcUrl);
ProcessingLogger logger = new Log4jProcessingLogger(DefaultBatchRunProcessingUseCase.class);
DocumentProcessingCoordinator documentProcessingCoordinator =
new DocumentProcessingCoordinator(documentRecordRepository, processingAttemptRepository, unitOfWorkPort);
new DocumentProcessingCoordinator(documentRecordRepository, processingAttemptRepository, unitOfWorkPort, logger);
return new DefaultBatchRunProcessingUseCase(
config,
lock,
new SourceDocumentCandidatesPortAdapter(config.sourceFolder()),
new PdfTextExtractionPortAdapter(),
fingerprintPort,
documentProcessingCoordinator);
documentProcessingCoordinator,
logger);
};
this.commandFactory = SchedulerBatchCommand::new;
}

View File

@@ -0,0 +1,57 @@
package de.gecheckt.pdf.umbenenner.bootstrap.adapter;
import de.gecheckt.pdf.umbenenner.application.port.out.ProcessingLogger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* Log4j-based adapter implementing the {@link ProcessingLogger} port.
* <p>
* This adapter bridges the application layer to the concrete Log4j2 framework,
* allowing the application to remain decoupled from logging technology choices.
* <p>
* The error method intelligently detects if the last argument is a Throwable
* and logs accordingly.
*/
public class Log4jProcessingLogger implements ProcessingLogger {
private final Logger log4jLogger;
/**
* Creates a logger instance for the given class.
*
* @param clazz the class to derive the logger name from; must not be null
*/
public Log4jProcessingLogger(Class<?> clazz) {
this.log4jLogger = LogManager.getLogger(clazz);
}
@Override
public void info(String message, Object... args) {
log4jLogger.info(message, args);
}
@Override
public void debug(String message, Object... args) {
log4jLogger.debug(message, args);
}
@Override
public void warn(String message, Object... args) {
log4jLogger.warn(message, args);
}
@Override
public void error(String message, Object... args) {
// If the last argument is a Throwable, extract it and pass separately
if (args.length > 0 && args[args.length - 1] instanceof Throwable throwable) {
Object[] messageArgs = new Object[args.length - 1];
System.arraycopy(args, 0, messageArgs, 0, args.length - 1);
log4jLogger.error(message, throwable, messageArgs);
} else {
log4jLogger.error(message, args);
}
}
}