问题描述
我正在尝试使用log4j2的新RoutingAppender基于MDC(log4j2中的threadContext)路由不同的日志.我想做的是以下内容:
- 如果MDC地图具有$ contextid->附加到$ contextid appender(特定日志)
- 如果MDC没有$ contextid->附加到主appender(常规日志)
我想使用标签中的通配符模式实现此目的,然后使用for contextId($ {ctx:contextId})中的密钥参数进行过滤,并使用默认值(无密钥室)为主appender,但是i不知道那个通配符是哪个价值.
任何帮助都会受到赞赏,也许我正在从错误的道路上接近这一点.我一直在阅读有关过滤器的信息,但似乎没有我想要的.
谢谢!
推荐答案
感谢您的链接Remko,我找到了一个临时解决方案,直到该功能从Log4J2的家伙中得到改善为止.该解决方案同时使用RoutingAppender和过滤器.这就是我的log4j2配置的样子(我已经定义了属性,但我在这里没有显示它们):
<appenders> <appender name="applicationAppender" type="RollingFile" fileName="${logFileName}" filePattern="${logFileNamePattern}" bufferedIO="true" immediateFlush="true" append="true"> <layout type="PatternLayout" pattern="${logPattern}" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="${logFileSize}" /> </Policies> <DefaultRolloverStrategy max="${logFileCount}" /> </appender> <Routing name="contextSpecificAppender"> <Routes pattern="$${ctx:contextId}"> <Route> <appender name="Rolling-${ctx:contextId}" type="RollingFile" fileName="logs/${ctx:contextId}.log" filePattern="${logFileNamePattern}" bufferedIO="true" immediateFlush="true" append="true"> <layout type="PatternLayout" pattern="${logPattern}" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="${logFileSize}" /> </Policies> <DefaultRolloverStrategy max="${logFileCount}" /> </appender> </Route> </Routes> </Routing> </appenders> <loggers> <root level="info"> <appender-ref ref="contextSpecificAppender"> <ThreadContextMapFilter onMatch="DENY" onMismatch="ACCEPT"> <KeyValuePair key="contextId" value="" /> </ThreadContextMapFilter> </appender-ref> <appender-ref ref="applicationAppender"> <ThreadContextMapFilter onMatch="ACCEPT" onMismatch="DENY"> <KeyValuePair key="contextId" value="" /> </ThreadContextMapFilter> </appender-ref> </root> </loggers>
我要做的是调用threadContext.put(" contextId","")或threadContext.put(" contextId"," somings"),具体取决于我要登录的appender. 我希望野外功能能尽快实施,但是与此同时,此解决方案对我来说足够了.
谢谢!
其他推荐答案
这回答您的问题吗? https://issues.apache.org/jira/browse/browse/logse/logse/log4j2-326
remko
其他推荐答案
感谢Hveiga跟踪并发布了您的解决方案,这很有帮助.我想说的是,您可以通过添加第二个"路由"来避免过滤器解决方案,该"路由"将所有消息路由没有值为您的路由键,如下所示:logging.apache.org/log4j/2 .
因此,您更新的Log4j配置看起来像这样.
<appenders> <appender name="applicationAppender" type="RollingFile" fileName="${logFileName}" filePattern="${logFileNamePattern}" bufferedIO="true" immediateFlush="true" append="true"> <layout type="PatternLayout" pattern="${logPattern}" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="${logFileSize}" /> </Policies> <DefaultRolloverStrategy max="${logFileCount}" /> </appender> <Routing name="contextSpecificAppender"> <Routes pattern="$${ctx:contextId}"> <Route> <appender name="Rolling-${ctx:contextId}" type="RollingFile" fileName="logs/${ctx:contextId}.log" filePattern="${logFileNamePattern}" bufferedIO="true" immediateFlush="true" append="true"> <layout type="PatternLayout" pattern="${logPattern}" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="${logFileSize}" /> </Policies> <DefaultRolloverStrategy max="${logFileCount}" /> </appender> </Route> <Route ref="applicationAppender" key="$${ctx:contextId}"> </Route> </Routes> </Routing> </appenders> <loggers> <root level="info"> <appender-ref ref="contextSpecificAppender"/> </root> </loggers>
和在您的应用程序中,您只需通过调用threadcontext.put(" contextId"," somings")来设置threadContext,然后通过调用threadcontext.clear()或threadcontext.remove(" contextId"(" contextId")完成时将其清除. )
最后,我使用了
<RollingFile>
元素(如上面链接的示例),而不是
<appender type="RollingFile">
您使用的元素.我相信,当您从log4j迁移到log4j2时,这是首选.
问题描述
I am trying to use the new RoutingAppender of Log4j2 to route the different logs based on the MDC (ThreadContext in Log4j2). What I want to do is the following:
- If MDC map has $contextId -> Append to $contextId appender (specific log)
- If MDC does not have $contextId -> Append to main appender (general log)
I want to achieve this using a wildcard pattern in the tag and then filter using the key parameter in the for contextId (${ctx:contextId}) and using the default (without key paramenter) for the main appender, however I don't know which value is that wildcard.
Any help is appreciated, maybe I am approaching this from the wrong path. I have been reading about Filters but don't seem to work as I want.
Thanks!
推荐答案
Thanks for the link Remko, I have found a temporary solution until that feature gets improved from the guys of Log4j2. The solution is using both RoutingAppender and Filters. This is how my log4j2 config looks like (I have properties defined but I am not showing them here):
<appenders> <appender name="applicationAppender" type="RollingFile" fileName="${logFileName}" filePattern="${logFileNamePattern}" bufferedIO="true" immediateFlush="true" append="true"> <layout type="PatternLayout" pattern="${logPattern}" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="${logFileSize}" /> </Policies> <DefaultRolloverStrategy max="${logFileCount}" /> </appender> <Routing name="contextSpecificAppender"> <Routes pattern="$${ctx:contextId}"> <Route> <appender name="Rolling-${ctx:contextId}" type="RollingFile" fileName="logs/${ctx:contextId}.log" filePattern="${logFileNamePattern}" bufferedIO="true" immediateFlush="true" append="true"> <layout type="PatternLayout" pattern="${logPattern}" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="${logFileSize}" /> </Policies> <DefaultRolloverStrategy max="${logFileCount}" /> </appender> </Route> </Routes> </Routing> </appenders> <loggers> <root level="info"> <appender-ref ref="contextSpecificAppender"> <ThreadContextMapFilter onMatch="DENY" onMismatch="ACCEPT"> <KeyValuePair key="contextId" value="" /> </ThreadContextMapFilter> </appender-ref> <appender-ref ref="applicationAppender"> <ThreadContextMapFilter onMatch="ACCEPT" onMismatch="DENY"> <KeyValuePair key="contextId" value="" /> </ThreadContextMapFilter> </appender-ref> </root> </loggers>
What I do it is calling ThreadContext.put("contextId", "") or ThreadContext.put("contextId", "something") depending on what appender I want to log. I hope the wildward feature gets implemented soon, but for the meantime, this solution is enough for me.
Thanks!
其他推荐答案
Does this answer your question? https://issues.apache.org/jira/browse/LOG4J2-326
Remko
其他推荐答案
Thanks hveiga for following up and posting your solution, it was helpful. I wanted to say you can avoid your filter solution by adding a second 'route' that routes all messages with no value for your routing key as explained here: http://logging.apache.org/log4j/2.x/faq.html#separate_log_files
So your updated log4j config would look like this.
<appenders> <appender name="applicationAppender" type="RollingFile" fileName="${logFileName}" filePattern="${logFileNamePattern}" bufferedIO="true" immediateFlush="true" append="true"> <layout type="PatternLayout" pattern="${logPattern}" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="${logFileSize}" /> </Policies> <DefaultRolloverStrategy max="${logFileCount}" /> </appender> <Routing name="contextSpecificAppender"> <Routes pattern="$${ctx:contextId}"> <Route> <appender name="Rolling-${ctx:contextId}" type="RollingFile" fileName="logs/${ctx:contextId}.log" filePattern="${logFileNamePattern}" bufferedIO="true" immediateFlush="true" append="true"> <layout type="PatternLayout" pattern="${logPattern}" /> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="${logFileSize}" /> </Policies> <DefaultRolloverStrategy max="${logFileCount}" /> </appender> </Route> <Route ref="applicationAppender" key="$${ctx:contextId}"> </Route> </Routes> </Routing> </appenders> <loggers> <root level="info"> <appender-ref ref="contextSpecificAppender"/> </root> </loggers>
And in your application, you can just set the ThreadContext by calling ThreadContext.put("contextId", "something") and clear it when you are done by calling ThreadContext.clear() OR ThreadContext.remove("contextId")
Lastly, I used the
<RollingFile>
element (like the examples linked above) instead of
<appender type="RollingFile">
element you used. I believe this is preferred when you migrate to log4j2 from log4j.