<p>In Spring Boot 2.6.0 using Log4J2. I want to use env variables from external to log4j.propeties
but it is always taking local <code>application.propeties</code> file instead of real docker or Kubernetes env variables</p>
<p>File <code>application.properties</code></p>
<pre><code>spring.application.name=myapp

#Logger FilePath
log.file.path=logs/dev/my-app

</code></pre>
<p>Docker Composer File</p>
<pre><code>   version: &quot;3&quot;

services:
 
  spring-app-log4j2:
    build: ./log4j2
    ports:
      - &quot;8080:80&quot;
    environment:
      - SERVER_PORT=80
      - LOG_FILE_PATH=logs/prod/my-app
      
</code></pre>
<p>File <code>log4j2.properties</code></p>
<pre><code>name=config

#Read Properties values from application properties
property.filename = ${bundle:application:log.file.path}

property.layoutPattern = %d{MMM dd yyyy HH:mm:ss.SSS z} | ${hostName} | %-5p | %c{1}:%L  |  %M() - %m%n

appenders=console, rolling 

#log to console
appender.console.type=Console
appender.console.name=STDOUT
appender.console.layout.type=PatternLayout
appender.console.layout.pattern=${layoutPattern}


#log to file and daily rolling
appender.rolling.type = RollingFile
appender.rolling.name = roll
appender.rolling.fileName = ${filename}.log
appender.rolling.filePattern = ${filename}.%d{dd-MMM-yyyy}.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = ${layoutPattern}
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 2
appender.rolling.policies.time.modulate = true
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=100MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 5

loggers = rolling

logger.rolling.name = org.apache.logging.log4j.core.appender.rolling
logger.rolling.level = info
logger.rolling.additivity = true
logger.rolling.appenderRefs = rolling
logger.rolling.appenderRef.rolling.ref = roll


rootLogger.level=info
rootLogger.appenderRefs=stdout,rolling
rootLogger.appenderRef.stdout.ref=STDOUT
rootLogger.appenderRef.rolling.ref = roll

</code></pre>
<p>Output Tried</p>
<pre><code> property.filename = ${bundle:application:logpath}     #Output - logs/dev/app
    #(Taking values from application Properties only, not taking from Docker pod environment varibales)
    property.filename = ${sys:logpath}     #Output - ${sys:logpath}
    property.filename = ${env:logpath}   # Not Working   #Output - ${env:logpath}
    #use filename variable 
    appender.rolling.fileName = ${filename}.log
</code></pre>
<p>When Printing inside Java code</p>
<pre class="lang-java prettyprint-override"><code>@Value(&quot;${logpath}&quot;) String logpath;  #Output -logs/prod/app
# Working with Docker env
</code></pre>
<p>Problem : When log4j initiated it is not finding the file path from environment , so by default reading from application.propeties</p>
<p>How can i read from Docker environment or Kubernetes Environment</p>
<p>i need log file should &quot;logs/prod/my-app&quot; instead of &quot;logs/dev/my-app&quot;</p>
<p>Src Code : <a href="https://github.com/jeebendu/log4j2" rel="nofollow noreferrer">https://github.com/jeebendu/log4j2</a></p>

Jeebendu kumar Behera
<p>In all your attempts you use a single source for the <code>filename</code> property. You need to use one of the <em>fallback</em> features of variable substitution:</p>
<ul>
<li><p>You can add a default value to your variable substitution using the syntax <code>${variable:-default}</code>:</p>
<pre><code>property.filename = ${env:LOG_FILE_PATH:-${bundle:application:log.file.path}}
appender.rolling.fileName = ${filename}.log
</code></pre>
</li>
<li><p>or you can exploit the fact that every <code>${prefix:variable}</code> falls back to <code>${variable}</code>:</p>
<pre><code>property.LOG_FILE_PATH = ${bundle:application:log.file.path}
appender.rolling.fileName = ${env:LOG_FILE_PATH}
</code></pre>
</li>
</ul>
