最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - LOG4J2 Is possible to route certain log messages into a specified file by using the MDC key as a routing filter? - Stack

programmeradmin5浏览0评论

We have a java application connected to multiple services, for example email, DB etc. We'd like to still log everything into the same file just to be sure but we'd also like to route logs to certain files based onto the MDC keys that we set.

For example:

  • I get a message from the DB, said message should be also in DB.log.
  • I get an email that I should route to the email server and that should go into email.log

How can I achieve this? Is it possible just by setting the MDC keys and the appropriate log4j2.xml config?

[...]

<Property name="newPattern">%d %-5p %X{log-route} [%t]</Property>

[...]

<Routing name="RoutingAppender">
   <Routes pattern="${ctx:log-route}">
        
        <Route key="EMAIL">
          <RollingRandomAccessFile
              name="EMAILRollingFile"
              fileName="log/email/email.log"
              filePattern="log/email/email.log.%i">
            <PatternLayout>
              <Pattern>${newPattern}</Pattern>
            </PatternLayout>
            <Policies>
              <OnStartupTriggeringPolicy />
              <SizeBasedTriggeringPolicy size="50 MB"/>
            </Policies>
            <property name="createOnDemand">true</property>
            <DefaultRolloverStrategy fileIndex="min" max="100"/>
          </RollingRandomAccessFile>
        </Route>

    </Routes>
</Routing>

In java I do MDC.put("log-route","EMAIL");

I can see the correct log messages but all in the default file. The other files don't even get created.

We have a java application connected to multiple services, for example email, DB etc. We'd like to still log everything into the same file just to be sure but we'd also like to route logs to certain files based onto the MDC keys that we set.

For example:

  • I get a message from the DB, said message should be also in DB.log.
  • I get an email that I should route to the email server and that should go into email.log

How can I achieve this? Is it possible just by setting the MDC keys and the appropriate log4j2.xml config?

[...]

<Property name="newPattern">%d %-5p %X{log-route} [%t]</Property>

[...]

<Routing name="RoutingAppender">
   <Routes pattern="${ctx:log-route}">
        
        <Route key="EMAIL">
          <RollingRandomAccessFile
              name="EMAILRollingFile"
              fileName="log/email/email.log"
              filePattern="log/email/email.log.%i">
            <PatternLayout>
              <Pattern>${newPattern}</Pattern>
            </PatternLayout>
            <Policies>
              <OnStartupTriggeringPolicy />
              <SizeBasedTriggeringPolicy size="50 MB"/>
            </Policies>
            <property name="createOnDemand">true</property>
            <DefaultRolloverStrategy fileIndex="min" max="100"/>
          </RollingRandomAccessFile>
        </Route>

    </Routes>
</Routing>

In java I do MDC.put("log-route","EMAIL");

I can see the correct log messages but all in the default file. The other files don't even get created.

Share Improve this question asked Feb 7 at 16:06 Red--ManRed--Man 11 bronze badge 1
  • Is fileName and filePattern supposed to be an absolute path? With the missing leading path separator, it looks relative. Try /log/email/email.log instead. – mahbad Commented Feb 7 at 16:16
Add a comment  | 

1 Answer 1

Reset to default 0

The <Routes> element is similar to a switch statement and you only specified the EMAIL case. To specify a default case, you need to create a <Route> element without a key attribute:

<Routing name="RoutingAppender">
  <Routes pattern="$${ctx:log-route}">
    <Route>
      <RollingRandomAccessFile
          name="${ctx:log-route:-MAIN}RollingFile"
          fileName="log/${lower:${ctx:log-route:-MAIN}}/${lower:${ctx:log-route:-MAIN}}.log"
          filePattern="log/${lower:${ctx:log-route:-MAIN}}/${lower:${ctx:log-route:-MAIN}}.log.%i">
        <PatternLayout pattern="${newPattern}"/>
        <Policies>
          <OnStartupTriggeringPolicy/>
          <SizeBasedTriggeringPolicy size="50 MB"/>
        </Policies>
        <DefaultRolloverStrategy fileIndex="min" max="100"/>
      </RollingRandomAccessFile>
    </Route>
  </Routes>
</Routing>

Note: if the assignment between log statements in your code and the categories is static, you might consider using markers instead of the thread context.

If you use the thread context to decide, which log file will be used, make sure that your code does not set thread context values from user data. For example some applications set thread context values from HTTP headers; in your case that would lead to a security issue.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论