Configuration 同一个Appender使用Log4J2登录到2个不同的文件中

Configuration 同一个Appender使用Log4J2登录到2个不同的文件中,configuration,log4j2,Configuration,Log4j2,我想在log4j2.xml配置文件中定义一个Appender,并使用log4j2属性替换的魔力,以某种方式登录到两个不同的文件中 我想Appender应该是这样的: <RollingFile name="Rolling-${filename}" fileName="${filename}" filePattern="${filename}.%i.log.gz"> <PatternLayout> <pattern>%d %p %c{1.} [%t]

我想在log4j2.xml配置文件中定义一个Appender,并使用log4j2属性替换的魔力,以某种方式登录到两个不同的文件中

我想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>

%d%p%c{1.}[%t]%m%n
记录器是否有方法使用此appender并传递filename属性

或者,当我们使用LogManager.getLogger获取记录器时,是否有方法传递它


请注意,这些记录器可能在同一线程中,也可能不在同一线程中,它必须支持这两种情况,因此我认为不可能使用ThreadContext或系统属性。

我能想到的最接近的事情是。RoutingAppender允许根据某些查找中的值动态选择日志文件。一种流行的内置查找是ThreadContext映射(请参见页面),但您可以创建自定义查找。示例代码:

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>

%d{ISO8601}[%t]%p%c{3}-%m%n
%d{ISO8601}[%t]%p%c{3}-%m%n

另一种方法是配置多个记录器,每个记录器指向一个单独的附加器(additivity=“false”)。这允许应用程序通过名称获取记录器来控制目标文件。然而,在这种情况下,您需要配置单独的附加器,这样就不能满足您的需求,我提到它是为了完整性

我正在使用记录器名称将参数传递给appender

它很粗糙,但很有效:

LogManager.getLogger("com.company.test.Test.logto.xyz.log")

从记录器名称中提取文件名需要自定义StrLookup。

是的,我正在查看RoutingAppender。问题是ThreadContext不允许我声明两个记录器实例,它们使用相同的appender,但在同一线程中记录到不同的文件。。。该示例使用ThreadContext映射查找,但RoutingAppender也可用于其他查找。应该可以为您的用例提供自定义查找。例如,这里有一个基于标记的自定义查找:由于标记基于LogEvents,因此在声明记录器时无法通知位置。我不认为有一种方法可以“附加”一些信息到记录器。为什么要这样做?您对定义多个
元素有何异议?