I am using a Spring batch job to load a file into database. The file contains sensitive customer data. On any parsing error, Spring batch logs the exception along with the file line content.
Parsing error at line: 1 in resource=[file [/path/file.txt]], input=[sensitive data]
I would like to avoid the possibility of those with access to copy paste the log in their communications with parties not authorized for this particular piece of data. Hence I disabled the Spring batch log using application.properties
setting
logging.level.org.springframework.batch: OFF
However I still need to log the file name, line number and the cause of error. Thought of something like below in StepExecutionListener::afterStep
, but this may not be foolproof/future-proof.
stepExecution.getFailureExceptions()
.forEach(e -> log.error(e.getMessage().replaceAll("[, ]*input=\\[.*?]", "") " - " e.getCause()));
What other approaches can I try? Is there a setting to instruct Spring batch to mask/exclude the file content in the exception message?
CodePudding user response:
I would not disable logs at a global level because this might be needed elsewhere in the app.
The extension point your are looking for is the ExceptionHandler API. This is where you can customize exception handling during any phase of the chunk processing. In your case, you can catch flat file parsing exceptions and do whatever you need with them (log sensitive data to a secure source, customize the log by removing sensitive data, etc).
Here is a quick example:
class MyCustomExceptionHandler implements ExceptionHandler {
@Override
public void handleException(RepeatContext repeatContext, Throwable throwable) {
if (throwable instanceof FlatFileParseException) {
FlatFileParseException exception = (FlatFileParseException) throwable;
// customize the exception handling as needed
System.err.println("Error while parsing line " exception.getLineNumber());
}
}
}
Once that in place, you can register your exception handler in your step with org.springframework.batch.core.step.builder.AbstractTaskletStepBuilder#exceptionHandler
, something like:
@Bean
public Step myStep(StepBuilderFactory stepBuilderFactory) {
return stepBuilderFactory.get("myStep")
.<Person, Person>chunk(2)
.reader(itemReader())
.writer(itemWriter())
.exceptionHandler(new MyCustomExceptionHandler())
.build();
}