相同的 Appender 使用 Log4J2 登录到 2 个不同的文件
Same Appender log into 2 different files with Log4J2
我想在我的 log4j2.xml 配置文件中定义 1 个 Appender,并使用 Log4J2 的 Properties Substitution 的魔力,能够以某种方式登录到 2 个不同的文件。
我想 Appender 看起来像:
<RollingFile name="Rolling-${filename}" fileName="${filename}" filePattern="${filename}.%i.log.gz">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
<SizeBasedTriggeringPolicy size="500" />
</RollingFile>
Logger 有没有办法使用此附加程序并传递文件名 属性?
或者当我们使用 LogManager.getLogger 获取 Logger 时有没有办法传递它?
请注意,这些记录器可能在也可能不在同一个线程中,它必须支持这两种情况,所以我认为不可能使用 ThreadContext 或系统属性。
我能想到的最接近的是 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 页面),但您可以创建自定义查找。示例代码:
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
动态创建日志文件的示例配置:
<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>
另一种方法是配置多个记录器,每个记录器指向一个单独的附加程序(加性="false")。这允许您的应用程序通过名称获取记录器来控制目标文件。但是,在那种情况下,您需要配置单独的附加程序,因此这不能满足您的要求,我提到它是为了完整性。
我正在使用记录器名称将参数传递给附加程序。
虽然有点笨拙,但确实有效:
LogManager.getLogger("com.company.test.Test.logto.xyz.log")
需要自定义 StrLookup 才能从记录器名称中提取文件名。
我想在我的 log4j2.xml 配置文件中定义 1 个 Appender,并使用 Log4J2 的 Properties Substitution 的魔力,能够以某种方式登录到 2 个不同的文件。
我想 Appender 看起来像:
<RollingFile name="Rolling-${filename}" fileName="${filename}" filePattern="${filename}.%i.log.gz">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
<SizeBasedTriggeringPolicy size="500" />
</RollingFile>
Logger 有没有办法使用此附加程序并传递文件名 属性?
或者当我们使用 LogManager.getLogger 获取 Logger 时有没有办法传递它?
请注意,这些记录器可能在也可能不在同一个线程中,它必须支持这两种情况,所以我认为不可能使用 ThreadContext 或系统属性。
我能想到的最接近的是 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 页面),但您可以创建自定义查找。示例代码:
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
动态创建日志文件的示例配置:
<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>
另一种方法是配置多个记录器,每个记录器指向一个单独的附加程序(加性="false")。这允许您的应用程序通过名称获取记录器来控制目标文件。但是,在那种情况下,您需要配置单独的附加程序,因此这不能满足您的要求,我提到它是为了完整性。
我正在使用记录器名称将参数传递给附加程序。
虽然有点笨拙,但确实有效:
LogManager.getLogger("com.company.test.Test.logto.xyz.log")
需要自定义 StrLookup 才能从记录器名称中提取文件名。