You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by Thorsten Schöning <Th...@veda.net> on 2025/05/06 07:46:51 UTC
Do Route-keys of Routing appender of Log4j2 need to use "$$" or "$" for unresolved expressions?
Hi everyone,
the docs contain the following warning, with the emphasizes taken from the official docs:
> Lookups in the **children** of the Route component are not evaluated at configuration time. The substitution is delayed until the Route element is evaluated. This means that ${...} expression **should not** be escaped as $${...}.
https://logging.apache.org/log4j/2.x/manual/appenders/delegating.html#Route
I have the following two configs, which seem to behave the same:
```xml
<Routing name="[...]">
<Routes pattern="$${ctx:foo}">
<Route key="true" ref="RollingFileFoo" />
<Route key="$${ctx:foo}" ref="RollingFile" />
</Routes>
</Routing>
```
vs.
```xml
<Routing name="[...]">
<Routes pattern="$${ctx:foo}">
<Route key="true" ref="RollingFileFoo" />
<Route key="${ctx:foo}" ref="RollingFile" />
</Routes>
</Routing>
```
The behaviour from my understanding is that `pattern` gets an expression configured and that expression is interpolated at config time, why `$$` is needed for escaping reasons. So at runtime the pattern actually is `${ctx:foo}` and evaluated for each and every log statement passing the appender.
Step 2: If the expression doesn't find a key of the given name `foo`, then the result of the pattern is kept as the pattern itself. That's why there's an additional `key` with the pattern itself as a value to match against. And this is where things become interesting:
**Is that result now expected to be with `$$` like configured in the file or `$` only like taken at runtime?**
I'm a bit confused which the correct value is because both seem to work exactly the same. Which shouldn't happen if the `key` attribute implements an equals comparison to it's value.
```java
public Route getRoute(final String key) {
for (final Route route : routes) {
if (Objects.equals(route.getKey(), key)) {
return route;
}
}
return null;
}
```
https://github.com/apache/logging-log4j2/blob/9176b44193b107b1a6c1ca9efda22f79fa20db3a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/routing/Routes.java#L198C1-L205C6
From my understanding, the escaping using `$$` in `pattern` is necessary because that pattern otherwise gets resolved already at config time, but it needs to be forwarded into runtime. If the difference is that `key` is simply NEVER resolved at all at config time and really only taken as string as-is, then I would have expected `$$` to fail, because that value is not available at runtime?
Thanks for your help!
PS: Kennen Sie schon die VEDA Care Services? Interesse? Dann sprechen Sie uns gerne persönlich an. Weitere Infos finden Sie hier.
____________________________________________________________
Thorsten Schöning
Software Developer
VEDA GmbH
Carl-Zeiss-Straße 14
52477 Alsdorf
Tel.: +49 2404 5507-1345
Thorsten.Schoening@veda.net
www.veda.net
VEDA GmbH, Amtsgericht Aachen HRB 1501
Geschäftsführer: Dr. Ralf Gräßler
Sitz der Gesellschaft: Alsdorf
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org
AW: Do Route-keys of Routing appender of Log4j2 need to use "$$" or "$" for unresolved expressions?
Posted by Thorsten Schöning <Th...@veda.net>.
Von: Piotr P. Karwasz <pi...@mailing.copernik.eu>
Gesendet: Dienstag, 6. Mai 2025 15:29
An: log4j-user@logging.apache.org
Betreff: Re: Do Route-keys of Routing appender of Log4j2 need to use "$$" or "$" for unresolved expressions?
> * In the first case the value of `key` will always be a literal
> `${ctx:foo}`.
> * In the second case Log4j Core will expand `${ctx:foo}` at
> configuration time. Since the configuration of Log4j Core happens
> very early in the startup sequence, `foo` will almost certainly be
> undefined, so `key` will be a literal `${ctx:foo}`. In the very
> unlikely case `foo` is defined at configuration time, however, the
> value of `foo` will be substituted and your configuration will not
> work as expected.
Thanks Piotr! So "$$" at both places is correct in my case and "children" really refers to the body of the "Route".
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org
Re: Do Route-keys of Routing appender of Log4j2 need to use "$$" or "$" for unresolved expressions?
Posted by "Piotr P. Karwasz" <pi...@mailing.copernik.eu>.
Hi Thorsten,
On 6.05.2025 09:46, Thorsten Schöning wrote:
> I have the following two configs, which seem to behave the same:
>
> ```xml
> <Routing name="[...]">
> <Routes pattern="$${ctx:foo}">
> <Route key="true" ref="RollingFileFoo" />
> <Route key="$${ctx:foo}" ref="RollingFile" />
> </Routes>
> </Routing>
> ```
>
> vs.
>
> ```xml
> <Routing name="[...]">
> <Routes pattern="$${ctx:foo}">
> <Route key="true" ref="RollingFileFoo" />
> <Route key="${ctx:foo}" ref="RollingFile" />
> </Routes>
> </Routing>
> ```
>
> I'm a bit confused which the correct value is because both seem to work exactly the same. Which shouldn't happen if the `key` attribute implements an equals comparison to it's value.
There is subtle difference between the two configurations:
* In the first case the value of `key` will always be a literal
`${ctx:foo}`.
* In the second case Log4j Core will expand `${ctx:foo}` at
configuration time. Since the configuration of Log4j Core happens
very early in the startup sequence, `foo` will almost certainly be
undefined, so `key` will be a literal `${ctx:foo}`. In the very
unlikely case `foo` is defined at configuration time, however, the
value of `foo` will be substituted and your configuration will not
work as expected.
To see the difference, try adding:
static {
ThreadContext.put("foo", "true");
}
private static final Logger logger = LogManager.getLogger();
at the very beginning of the main class of your application.
Piotr