2013-08-16 28 views
5

我正在嘗試使用Log4j2的新RoutingAppender根據MDC(Log4j2中的ThreadContext)路由不同的日誌。我想要做的是以下幾點:Log4j2的RoutingAppender的通配符模式

  • 如果MDC地圖有$ CONTEXTID - >附加到$ CONTEXTID附加器(具體日誌)
  • 如果MDC沒有$ CONTEXTID - >附加到主附加器(一般日誌)

我想要實現這個標籤中使用通配符模式,然後使用關鍵參數過濾的CONTEXTID($ {CTX:CONTEXTID}),並使用用於默認的(無鑰匙paramenter)主appender,但是我不知道哪個值是通配符。

任何幫助表示讚賞,也許我是從錯誤的路徑接近這一點。我一直在閱讀有關過濾器,但似乎沒有工作,因爲我想。

謝謝!

回答

1

感謝您的鏈接的Remko,我已經找到了一個臨時解決方案,直到該功能會從Log4j2的傢伙改善。解決方案是使用RoutingAppender和Filters。這是我的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」,「something」),取決於我想記錄的appender。 我希望很快得到實施,但同時,這個解決方案對我來說已經足夠了。

謝謝!

+1

我找到了一個解決方案,以便您不必使用兩個路由通過使用兩個路由來切換從填充的ThreadContext鍵到空的結合處的過濾器。就像這個例子所解釋的那樣http://logging.apache.org/log4j/2.x/faq.html#separate_log_files 如果ThreadContext沒有值的話,你可以使用路由上的key屬性來創建一個被選擇的路由鍵。然後我用這條路線來引用我的主要appender。如果你設置了第二個「路由」,你根本不必使用ThreadContextMapFilter。此外,您只需要在根記錄器中使用一個appender-ref。 – Alex

0

感謝hveiga跟進和發佈您的解決方案,這很有幫助。我想說的話,你可以通過添加第二個「路線」的路由的所有郵件與您的路由鍵的值避免你的過濾解決方案如下解釋:http://logging.apache.org/log4j/2.x/faq.html#separate_log_files

所以更新的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」,「東西」)設置ThreadContext並清除它,當你通過調用ThreadContext.clear()或ThreadContext.remove完成( 「關聯標識符」)

最後,我用來代替

<appender type="RollingFile"> 

<RollingFile> 

元件(如上面鏈接的示例)

您使用的元素。我相信當你從log4j遷移到log4j2時,這是首選。

2

我對使用https://issues.apache.org/jira/browse/LOG4J2-326http://logging.apache.org/log4j/2.x/faq.html#separate_log_files中描述的技巧定義回退路線的解決方案感到不滿,因爲這迫使我重複包含在路由中的appender配置。對於默認路由,我不需要不同的appender配置,但只需要一個適當的文件名稱作爲通用日誌。

鑑於默認的屬性映射是在上下文中未定義的屬性中查找的,請參見https://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution,我認爲最直接的方法就是定義默認屬性,例如,

<Properties> 
    <Property name="fruits">any_fruit</Property> 
</Properties> 

並且在線程上下文沒有$ {ctx:fruits}的情況下采用「any_fruit」。