Log4j2的RoutingAppender的通配符模式

ryoqjall  于 2022-11-06  发布在  其他
关注(0)|答案(5)|浏览(198)

我正在尝试使用Log4j 2的新RoutingAppender来根据MDC(Log4j 2中的ThreadContext)路由不同的日志。我想做的是:

  • 如果MDCMap具有$contextId -〉附加到$contextId附加器(特定日志)
  • 如果MDC没有$contextId -〉附加到主附加器(常规日志)

我希望在标记中使用通配符模式来实现这一点,然后使用for contextId(${ctx:contextId})中的key参数进行过滤,并对主附加器使用默认值(没有key参数),但我不知道哪个值是通配符。
任何帮助都是感激的,也许我是从错误的道路上接近这一点。我一直在阅读有关过滤器,但似乎没有工作,因为我想要的。
谢谢你!

niknxzdl

niknxzdl2#

感谢Remko的链接,我已经找到了一个临时的解决方案,直到该特性得到改进的家伙Log4j 2.该解决方案是使用RoutingAppender和过滤器.这是我的log4j 2配置看起来像(我有属性定义,但我没有显示在这里):

<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”),这取决于我想要记录的追加器。我希望wildward特性很快实现,但目前,这个解决方案对我来说已经足够了。
谢谢你!

6za6bjd0

6za6bjd03#

感谢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”,“something”)来设置ThreadContext,并在完成后通过调用ThreadContext.clear()或ThreadContext.remove(“contextId”)来清除它
最后,我使用了

<RollingFile>

元素(类似于上面链接的示例),而不是

<appender type="RollingFile">

我相信当您从log4j迁移到log4j2时,这是首选的。

mrphzbgm

mrphzbgm4#

我对使用https://issues.apache.org/jira/browse/LOG4J2-326和http://logging.apache.org/log4j/2.x/faq.html#separate_log_files中描述的技巧定义回退路由的解决方案不满意,因为这迫使我复制路由中包含的附加器配置。我不需要为默认路由提供不同的附加器配置,而只需要为常规日志提供适当的文件名。
如果在默认属性Map中查找在其上下文中未定义的属性,请参见https://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution,我认为最直接的方法就是定义默认值,例如

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

并且在线程上下文不具有${ctx:fruits}的情况下,采用“any_fruits”。

ibrsph3r

ibrsph3r5#

使用www.example.com中的RoutingAppender创建动态多个日志文件lo4j2.properties

status=debug
name=PropertiesConfig

filter.threshold.type=ThresholdFilter
filter.threshold.level=debug

appenders=routing
appender.routing.type=Routing
appender.routing.name=Routing
appender.routing.routes.type=Routes
appender.routing.routes.pattern=$${ctx:keyname}

appender.routing.routes.route.type=Route

appender.routing.routes.route.rolling.type=RollingFile
appender.routing.routes.route.rolling.name=RollingFile
appender.routing.routes.route.rolling.fileName=${ctx:keyname}.log
appender.routing.routes.route.rolling.filePattern=${ctx:keyname}-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.routing.routes.route.rolling.layout.type=PatternLayout
appender.routing.routes.route.rolling.layout.pattern=%m%n
appender.routing.routes.route.rolling.policies.type=Policies
appender.routing.routes.route.rolling.policies.time.type=TimeBasedTriggeringPolicy
appender.routing.routes.route.rolling.policies.time.interval=2
appender.routing.routes.route.rolling.policies.time.modulate=true
appender.routing.routes.route.rolling.policies.size.type=SizeBasedTriggeringPolicy
appender.routing.routes.route.rolling.policies.size.size=1KB
appender.routing.routes.route.rolling.strategy.type=DefaultRolloverStrategy
appender.routing.routes.route.rolling.strategy.max=5

appender.routing.routes.route2.type=Route

appender.routing.routes.route2.key=P:/TestLogging/specialspecial

# appender.routing.routes.route.ref=Routes

appender.routing.routes.route2.rolling.type=RollingFile
appender.routing.routes.route2.rolling.name=RollingFile
appender.routing.routes.route2.rolling.fileName=${ctx:keyname}.log
appender.routing.routes.route2.rolling.filePattern=${ctx:keyname}-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.routing.routes.route2.rolling.layout.type=PatternLayout
appender.routing.routes.route2.rolling.layout.pattern=%d %p %C{1.} [%t] %m%n
appender.routing.routes.route2.rolling.policies.type=Policies
appender.routing.routes.route2.rolling.policies.time.type=TimeBasedTriggeringPolicy
appender.routing.routes.route2.rolling.policies.time.interval=2
appender.routing.routes.route2.rolling.policies.time.modulate=true
appender.routing.routes.route2.rolling.policies.size.type=SizeBasedTriggeringPolicy
appender.routing.routes.route2.rolling.policies.size.size=1KB
appender.routing.routes.route2.rolling.strategy.type=DefaultRolloverStrategy
appender.routing.routes.route2.rolling.strategy.max = 5
loggers=routing
logger.routing.level=debug
logger.routing.name=com.infy.demo
logger.routing.additivity=false
logger.routing.appenderRef.routing.ref=Routing
rootLogger.level=debug

public class TestLog4j2Logging {

private static final Logger log = LogManager.getLogger(TestLog4j2Logging.class);

public static void testMsg()
{

    String[] arr = {"Msg1111111111111","Msg222222222222222","Msg3333333333333","Msg44444444444"};
    for (String string : arr) {
        log.info(string);
        log.error(string);
        ThreadContext.remove("keyname");
        ThreadContext.put("keyname", "P:/TestLogging/specialspecial");
        log.debug(string);
    }
}

public static void main(String[] args) throws FileNotFoundException, IOException
{
    TestLog4j2Logging testLog4j2Logging = new TestLog4j2Logging();

    ThreadContext.put("keyname","P:/TestLogging/rollingtest");
    Configurator.initialize(null, "./properties/log4j2.properties");

    TestLog4j2Logging.testMsg();
    System.out.println("Messages are getting Logged");
}

}

相关问题