简体   繁体   English

如何在运行时访问配置的 Log4J 附加程序?

[英]How can I access the configured Log4J appenders at runtime?

I want to configure an appender at startup and then dynamically add and remove it from various loggers on demand.我想在启动时配置一个附加程序,然后根据需要从各种记录器中动态添加和删除它。 I'd prefer to have log4j configure this appender itself, and just grab a reference to it when needed.我更愿意让 log4j 自己配置这个附加程序,并在需要时获取对它的引用。 If that's not possible, I'll have to instantiate the appender myself and hold onto it.如果那不可能,我将不得不自己实例化 appender 并保留它。

Appenders are generally added to the root logger. 通常将追加器添加到根记录器中。 Here's some pseudocode 这是一些伪代码

// get the root logger and remove the appender we want
Logger logger = Logger.getRootLogger();
Appender appender = logger.getAppender("foo");
logger.removeAppender(appender)

// when we want to add it back...
logger.addAppender(appender);

I'm pretty sure you can do this on other loggers than the root logger as well, though I've never tried that. 我很确定你可以在其他记录器上执行此操作,而不是根记录器,尽管我从未尝试过。

The Logger class has methods to getAllAppenders() , getAppender() , addAppender() , and removeAppender() methods, inherited from the Category class. Logger类具有继承自Category类的getAllAppenders()getAppender()addAppender()removeAppender()方法。 However, the Category class is deprecated, and on top of that, I've never tried to do this before, but this might be a useful starting point. 但是,不推荐使用Category类,除此之外,我之前从未尝试过这样做,但这可能是一个有用的起点。

I want to do exactly the same thing. 我想做同样的事情。 I want to configure appenders in log4j.properties and then select some and add the to the rootLogger dynamically at runtime. 我想在log4j.properties中配置appender,然后选择一些并在运行时动态添加到rootLogger。

I could not figure out how to access the appenders other than via a logger to which they had been attached, so I ended up creating a dummy logger , and attaching the appenders to it so i could retrieve them dynamically. 我无法弄清楚除了通过它们附加的记录器之外如何访问appender,所以我最终创建了一个虚拟记录器 ,并将appender附加到它,以便我可以动态地检索它们。 This is not ideal though as any resources used by the appenders (eg files) are created upfront even if they are not used. 这并不理想,因为appender使用的任何资源(例如文件)都是预先创建的,即使它们没有被使用。

I would do it this way : 我会这样做:

  1. have you appender specified in log4j.properties, but not added to root logger. 你有没有在log4j.properties中指定的appender,但没有添加到root logger。
  2. at run time, when needed, grab log4j.properties, extract from it the properties you need, instantiate your appender and set its options by reading extracted properties. 在运行时,在需要时,抓取log4j.properties,从中提取您需要的属性,实例化您的appender并通过读取提取的属性来设置其选项。
  3. activate the appender 激活appender
  4. Logger.getRootLogger().addAppender(appender); 。Logger.getRootLogger()addAppender(附加器);
  5. Kick it off when finished using it - Logger.getRootLogger().removeAppender(..) 使用完毕后将其关闭 - Logger.getRootLogger()。removeAppender(..)

Now, if this is your own appender, doing (2) would be easy since you know the meaning of the properties and know what to expect. 现在,如果这是你自己的appender,那么做(2)会很容易,因为你知道属性的含义并知道会发生什么。 Otherwise you would probably want to use reflection to instantiate the class and call its property setters before doing (3). 否则,您可能希望在执行(3)之前使用反射来实例化类并调用其属性setter。

If it is enabling / disabling of Appenders at run time that you want to do then I found another solution (though not very elegant). 如果它是在你想要的运行时启用/禁用Appender,那么我找到了另一个解决方案(虽然不是很优雅)。 Using log4j configuration add all the Appenders you would need as you do normally. 使用log4j配置添加您正常需要的所有Appender。

At run time when you want to "disable" an appender add a (org.apache.log4j.spi) Filter to it that returns Filter.DENY for every log message. 在运行时,如果要“禁用”appender,请向其添加一个(org.apache.log4j.spi)过滤器,以便为每条日志消息返回Filter.DENY。 This way no messages make it through for this Appender. 这样,没有消息可以通过这个Appender。 When you want to "enable" the Appender back just clear the Filter that you added above. 当您想要“启用”Appender时,只需清除上面添加的过滤器即可。

I tested this and it works well for us (log4j 1.2). 我对此进行了测试,它对我们来说效果很好(log4j 1.2)。

Log4j1 Log4j1

I think the code you are looking for is:我认为您正在寻找的代码是:

import org.apache.log4j.Appender;

import org.apache.log4j.Logger;

//stuff

    Enumeration enm = Logger.getRootLogger().getAllAppenders();
    Appender appender = null;
    while(enm.hasMoreElements()){
        appender = (Appender)enm.nextElement();
        System.out.println("appender.getName():"+appender.getName());
    }

Log4j2 Log4j2

import org.apache.log4j.Appender;

import org.apache.log4j.Logger;

//stuff

    ((org.apache.logging.log4j.core.Logger) LogManager.getLogger()).getAppenders().values().forEach(a -> {
        System.out.println("appender.getName() " + a.getName());
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM