The closest thing I can think of is RoutingAppender. RoutingAppender allows the log file to be dynamically selected based on values in some lookup. A popular built-in lookup is the ThreadContext map (see the example on the FAQ page), but you can create a custom lookup. Example code:
ThreadContext.put("ROUTINGKEY", "foo");
logger.debug("This message gets sent to route foo");
// Do some work, including logging by various loggers.
// All logging done in this thread is sent to foo.
// Other threads can also log to foo at the same time by setting ROUTINGKEY=foo.
logger.debug("... and we are done");
ThreadContext.remove("ROUTINGKEY"); // this thread no longer logs to foo
Example config that creates log files on the fly:
<Routing name="Routing">
<Routes pattern="$${ctx:ROUTINGKEY}">
<!-- This route is chosen if ThreadContext has a value for ROUTINGKEY.
The value dynamically determines the name of the log file. -->
<Route>
<RollingFile name="Rolling-${ctx:ROUTINGKEY}" fileName="logs/other-${ctx:ROUTINGKEY}.log"
filePattern="./logs/${date:yyyy-MM}/${ctx:ROUTINGKEY}-other-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout>
<pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="6" modulate="true" />
<SizeBasedTriggeringPolicy size="10 MB" />
</Policies>
</RollingFile>
</Route>
</Routes>
<!-- This route is chosen if ThreadContext has no value for key ROUTINGKEY. -->
<Route key="$${ctx:ROUTINGKEY}">
<RollingFile name="Rolling-default" fileName="logs/default.log"
filePattern="./logs/${date:yyyy-MM}/default-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout>
<pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="6" modulate="true" />
<SizeBasedTriggeringPolicy size="10 MB" />
</Policies>
</RollingFile>
</Route>
</Routing>
An alternative is to configure multiple loggers, each pointing to a separate appender (with additivity="false"). This allows your application to control the destination file by obtaining a logger by its name. However, in that case you would need to configure separate appenders so this does not fulfill your requirement, I mention it for completeness.