I'd like to make configurable the value of my log4j2.xml
's <Pattern/>
element.
Nominally we have this pattern:
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%xEx{filters(${filters})}%n</Pattern>
</PatternLayout>
</Console>
One user of our code wants a different Pattern (they have a constraint that "log entries must not span multiple lines — even if they have stack traces"), which looks like this:
<Pattern>%replace{%d %p %c{1.} [%t] %m%xEx{filters(${filters})}}{(\n|\r)+}{, }%n</Pattern>
Each user can specify their own Environment independently, so I felt that was a good way to let them choose their Pattern.
I know that it is possible in <Pattern/>
elements to specify the pattern using Environment Variables. For example:
<Pattern>%d %p %c{1.} [%t] $${env:USER} %m%n</Pattern>
I also know that it is possible to specify a default/fallback value, like so: $${env:USER:-default}
. This is good, since I would like the nominal pattern to be the default, and work without specifying a bespoke environment.
So, I tried this pattern:
<Pattern>$${env:LOG_SYSOUT_PATTERN:-%d %p %c{1.} [%t] %m%xEx{filters(${filters})}%n}</Pattern>
My understanding was that it would allow a user to specify a pattern in LOG_SYSOUT_PATTERN
, but fallback to the usual Pattern otherwise.
I expected my log entries to look like this:
2016-09-27 10:47:32,073 INFO c.b.b.a.Engine [main] Sleeping AuditEngine for 1000 ms
But it seems to have failed. What I actually get with my pattern is this:
${env:LOG_SYSOUT_PATTERN:-2016-09-27 10:47:29,642 INFO c.b.b.a.Engine [main] Sleeping AuditEngine for 1000 ms
}
Is the use-case that I have described, beyond the limitations of log4j2's string interpolation?
Obviously it is possible for me to instead use environment variables to point to a different log4j2.xml
file altogether, but I would prefer a solution which does not involve maintaining and deploying two files for the sake of one bespoke difference for one user.
We use Log4j 2.5 and SLF4J 1.7.16.