I am writing a small Spring boot app that I want to read some properties from Hashi Corp Vault which will ultimately be run in a Kubernetes environment. I'm doing this by using the spring.cloud.vault libraries and the use of multiple spring.config.import statements to read various secret paths from Vault.
I have the following in my application.yaml
spring:
cloud:
vault:
uri: http://vault.vault.svc.cluster.local:8200
connection-timeout: 5000
read-timeout: 15000
authentication: kubernetes
kubernetes:
role: ${vault.role.name}
kubernetes-path: kubernetes
service-account-token-file: /var/run/secrets/kubernetes.io/serviceaccount/token
config:
import:
- vault://${secrets.engine.path}/${path1}
- vault://${secrets.engine.path}/${path1}/${subpath}
In situations where there is something wrong the spring cloud vault library will fail to retrieve the secrets silently and the corresponding PropertySources will be empty, this is fine and is desirable in this case. However I would like to be able to have the failure reasons written to the log to make it easier to debug.
There is suitable debugging within the org.springframework.vault.core.env.LeaseAwareVaultPropertySource
class which would write out the load errors that I have been trying to enable:
private void loadProperties() {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Requesting secrets from Vault at %s using %s", this.requestedSecret.getPath(),
this.requestedSecret.getMode()));
}
this.secretLeaseContainer.addLeaseListener(this.leaseListener);
this.secretLeaseContainer.addErrorListener(this.leaseListener);
this.secretLeaseContainer.addRequestedSecret(this.requestedSecret);
Exception loadError = this.loadError;
if (this.notFound || loadError != null) {
String msg = String.format("Vault location [%s] not resolvable", this.requestedSecret.getPath());
if (this.ignoreSecretNotFound) {
if (logger.isInfoEnabled()) {
logger.info(String.format("%s: %s", msg, loadError != null ? loadError.getMessage() : "Not found"));
}
}
else {
if (loadError != null) {
throw new VaultPropertySourceNotFoundException(msg, loadError);
}
throw new VaultPropertySourceNotFoundException(msg);
}
}
}
Most of the articles I came across were suggesting that logging contexts could be enabled via the application.yaml, but this was not working for me in this case. I then tried setting it as a system property when starting the application with:
-Dlogging.level.org.springframework.vault.core.env.LeaseAwareVaultPropertySource=DEBUG
and even going wider and setting -Dlogging.level.org.springframework=TRACE
After some debugging I could see that with the system property the logger was having it's level set correctly but the log statements were not being written out.
I now believe after further debugging the problem is because the spring.config.imports are processed very early in the Spring application startup when preparing the environment and it is only after this that the LogbackLoggingSystem is initialized, meaning no logging is written out before this point.
So my question is am I completely stuck, is there no way to actually get the logging in the LeaseAwareVaultPropertySource to appear in the logs? Is it possible to configure Spring boot to setup the Logging system earlier in the application startup before it has fully prepared the environment? Or conversely to delay the point at which those imports are processed such that the logging system is initialized first?