代码之家  ›  专栏  ›  技术社区  ›  vl4d1m1r4

查找在logback中配置的所有logback Appender。xml,即使未连接到任何记录器

  •  4
  • vl4d1m1r4  · 技术社区  · 7 年前

    我正在构建一个管理UI,用于管理日志记录器级别和更改附加器。我知道我可以找到使用以下代码添加到某个记录器的所有appender:

    private Map<String, Appender<ILoggingEvent>> getAppendersMap() {
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
    
        Map<String, Appender<ILoggingEvent>> appendersMap = new HashMap<>();
        for (Logger logger : loggerContext.getLoggerList()) {
          Iterator<Appender<ILoggingEvent>> appenderIterator = logger.iteratorForAppenders();
          while (appenderIterator.hasNext()) {
            Appender<ILoggingEvent> appender = appenderIterator.next();
            if (!appendersMap.containsKey(appender.getName())) {
              appendersMap.put(appender.getName(), appender);
            }
          }
        }
    
        return appendersMap;
    }
    

    logback.xml 例如:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration debug="false" scan="true" scanPeriod="10 minutes">
    
      <appender name="writeToConsole" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
          <pattern>
            %date{yyyy-MM-dd;HH:mm:ss.SSS} %-11p: %40.40c: %X{tablist}%m %n
          </pattern>
        </encoder>
      </appender>
    
      <appender name="NOPAppender" class="ch.qos.logback.core.helpers.NOPAppender" />
    
      <root>
        <level value="INFO"/>
        <appender-ref ref="writeToConsole"/>
      </root>
    
    </configuration>
    

    NOPAppender 连接到任何记录器的a及其方法 getAppendersMap() 没有找到它

    2 回复  |  直到 7 年前
        1
  •  4
  •   glytching    7 年前

    当从外部文件(logback.xml、logback-test.xml、logback.groovy等)配置自身时,logback会像这样遍历配置(这是它所做操作的简化版本):

    • 查找任何附加器
    • APPENDER_BAG 在里面 InterpretationContext.objectMap
    • 对于每个 appender-ref (存在于记录器定义中)在此中查找引用的appender(按名称) APPENDER\u袋

    您可以使用appender关联定义显式记录器: <logger name="com.x.y" level="INFO"><appender-ref ref="STDOUT"/></logger> 或者使用 <root/> <root level="INFO"><appender-ref ref="STDOUT"/></root> .

    因此,不与任何记录器关联的附加器仅在配置时已知,一旦 LoggerContext APPENDER\u袋 getAppendersMap() 找不到您的 NOOPAppender

    希望在应用程序运行时的某个时候使用。为了做到这一点,您必须在 最初,但没有op实现。这是您在问题中已经在做的事情,但您只需要添加您的 NOPAppender 到根上下文。

    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="NOPAppender"/>
    </root>
    

    这对正在运行的系统没有影响,因为appender是no op,但在 LoggerContext 当然,如果您想启用它,您可以对其进行管理,那么必须通过编程将appender类的选择更改为非no-op类。

    LoggerContext 当你需要的时候。

        2
  •  2
  •   Dharman GPuri    3 年前

    import java.net.URL;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import ch.qos.logback.classic.LoggerContext;
    import ch.qos.logback.classic.joran.JoranConfigurator;
    import ch.qos.logback.classic.spi.ILoggingEvent;
    import ch.qos.logback.classic.util.ContextInitializer;
    import ch.qos.logback.core.Appender;
    import ch.qos.logback.core.joran.action.ActionConst;
    import ch.qos.logback.core.joran.spi.InterpretationContext;
    import ch.qos.logback.core.joran.spi.JoranException;
    
    /**
     * Utility class for finding all configured logback appenders.
     */
    public class LogbackAppenderFinder {
    
      private static final Logger LOGGER = LoggerFactory.getLogger(LogbackAppenderFinder.class);
    
      private LogbackAppenderFinder() {
    
      }
    
      /**
       * Tries to find all appenders from an xml config. The method works by trying to find the default logback config file 
       * names, can be further enhanced to include others, e.g. files supported by Spring Boot or custom files.
       *
       * @return Map of all the appenders configured with the XML file where the key is the appender name configured in
       * the xml file and the value is the appender itself.
       */
      public static Map<String, Appender<ILoggingEvent>> findAppendersFromXmlConfig() {
        try {
          LoggerContext dummyLoggerContext = new LoggerContext();
          ContextInitializer contextInitializer = new ContextInitializer(dummyLoggerContext);
          URL configurationFileUrl = contextInitializer.findURLOfDefaultConfigurationFile(true);
          if (configurationFileUrl != null && configurationFileUrl.toString().endsWith(".xml")) {
            JoranConfigurator configurator = new JoranConfigurator();
            configurator.setContext(dummyLoggerContext);
            configurator.doConfigure(configurationFileUrl);
            InterpretationContext interpretationContext = configurator.getInterpretationContext();
            Map<String, Object> objectMap = interpretationContext.getObjectMap();
            return (Map<String, Appender<ILoggingEvent>>) objectMap.get(ActionConst.APPENDER_BAG);
          } else {
            LOGGER.warn("Unable to find xml configuration file.");
          }
        } catch (JoranException e) {
          LOGGER.warn("Failed to parse logback configuration, check config file.");
        }
        return new HashMap<>();
      }
    
    }