I would like to use Spring environment values as custom fields in the Logstash encoder of a Logback appender.
There is a general configuration tag to use properties
<property resource="logstash.properties" />
And there is a special configuration tag from Spring for this purpose
<springProperty name="appEnv" source="environment"/>
The properties of both tags can then be used in the custom fields of the Logstash encoder
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"application.environment":"${appEnv}"</customFields>
</encoder>
Problem is, as far as I understand, that this only works under certain circumstances. The problem is probably that Logback has already finished configuring when the Spring environment is built.
It seems to work when
- The property is local and static (available on configuration time)
- The property is in bootstrap.properties
It seems NOT to work when
- The property is dynamic as when retrieved from Spring config server
My property values delivered from config server are null
when Logback is configured and therefore the log shows them as appEnv_IS_UNDEFINED
for a property called appEnv
.
Because most examples just use the spring.application.name
this seems to be mostly unnoticed.
To solve the timing problem, I searched for a way to reload the Logback configuration onApplicationEvent
. I found this answer that confirms my problem and offers a skeleton solution.
I found other solutions where the Logback appender that uses the Logstash encoder is completely programmatically built and added to the LoggerContext
.
However, I wonder if there is also a way to stick with the XML configuration of the appender and "just reload" the config programmatically when the Spring environment is ready. How would I do this?
I found this answer to do the reload, but it does not work for my case. The appEnv_IS_UNDEFINED
continue to appear in the log file.