使用slf4j和log4j2动态添加附加器 [英] Dynamically add appender with slf4j and log4j2

查看:497
本文介绍了使用slf4j和log4j2动态添加附加器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想动态创建一个追加器并将其添加到记录器.但是,这对于slf4j似乎是不可能的.我可以将添加程序添加到log4j记录器中,但是随后我无法使用slf4j LoggerFactoy检索记录器.

I want to dynamically create an appender and add it to a logger. However, this seems not to be possible with slf4j. I can add my appender to a log4j logger but then I fail to retrieve the logger with the slf4j LoggerFactoy.

我想做什么:我创建一个测试类(不是jUnit测试),并在构造函数中传递记录器以供测试类使用.测试类的每个实例都需要使用自己的记录器和附加器来保存日志,以便以后可以在HTML报告中使用.

What I want to do: I create a test class (not a jUnit test) and pass a logger in the constructor for the test class to use. Every instance of the test class needs it's own logger and appender that saves the log so it can be later used in an HTML report.

我尝试过的内容(为简单起见,我创建了一个jUnit测试):

What I tried (for simplicity I created a jUnit test):

  import static org.junit.Assert.assertEquals;

  import java.util.LinkedList;
  import java.util.List;

  import org.apache.logging.log4j.core.LogEvent;
  import org.junit.Test;
  import org.slf4j.helpers.Log4jLoggerFactory;

  import ch.fides.fusion.logging.ListAppender;

  public class ListAppenderTest {

      @Test
      public void test() {

          String testName = "test1";

          // the log messages are to be inserted in this list
          List<LogEvent> testLog = new LinkedList<>();

          // create log4j logger
          org.apache.logging.log4j.core.Logger log4jlogger = (org.apache.logging.log4j.core.Logger) org.apache.logging.log4j.LogManager
                                          .getLogger("Test:" + testName);

          // create appender and add it to the logger
          ListAppender listAppender = new ListAppender("Test:" + testName + ":MemoryAppender", testLog);
          log4jlogger.addAppender(listAppender);

          // get the slf4j logger
          org.slf4j.helpers.Log4jLoggerFactory loggerFactory = new Log4jLoggerFactory();
          org.slf4j.Logger testLogger = loggerFactory.getLogger("Test:" + testName);

          // test it
          final String TEST_MESSAGE = "test message";
          testLogger.info(TEST_MESSAGE);

          assertEquals(1, testLog.size());
          LogEvent logEvent = testLog.get(0);
          assertEquals(TEST_MESSAGE, logEvent.getMessage().getFormattedMessage() );
      }

  }

这是我最基本的附加器:

and this is my very basic appender:

 package ch.fides.fusion.logging;

  import java.util.List;

  import org.apache.logging.log4j.core.LogEvent;
  import org.apache.logging.log4j.core.appender.AbstractAppender;

  public class ListAppender extends AbstractAppender {

      private final List<LogEvent> log;

      public ListAppender(String name, List<LogEvent> testLog) {
          super(name, null, null);
          this.log = testLog;
      }

      @Override
      public void append(LogEvent logEvent) {
          log.add(new TestLogEvent(logEvent));
      }

  }

我该怎么做才能使它正常工作?也许我是从错误的角度来解决这个问题,但我想避免创建自己的记录器类.任何帮助,我们将不胜感激.

What can I do to get this to work? Maybe I am approaching this from the wrong angle but I would like to avoid creating my own logger class. Any help is greatly appreciated.

推荐答案

通过代码/在运行时通过slf4j访问和操作log4j2:

Accessing and manipulating log4j2 over slf4j by code/at runtime:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Log4j2OverSlf4jConfigurator {

    final private static Logger LOGGER = LoggerFactory.getLogger(Log4j2OverSlf4jConfigurator.class);

    public static void main(final String[] args) {
        LOGGER.info("Starting");
        LoggerContext loggerContext = (LoggerContext) LogManager.getContext();
        Configuration configuration = loggerContext.getConfiguration();

        LOGGER.info("Filepath: {}", configuration.getConfigurationSource().getLocation());
        // Log4j root logger has no name attribute -> name == ""
        LoggerConfig rootLoggerConfig = configuration.getLoggerConfig("");

        rootLoggerConfig.getAppenders().forEach((name, appender) -> {
            LOGGER.info("Appender {}: {}", name, appender.getLayout().toString());
            // rootLoggerConfig.removeAppender(a.getName());
        });

        rootLoggerConfig.getAppenderRefs().forEach(ar -> {
            System.out.println("AppenderReference: " + ar.getRef());
        });

        // adding appenders
        configuration.addAppender(null);
    }
}

参考: https://logging.apache.org/log4j/2.x/manual/customconfig.html

这篇关于使用slf4j和log4j2动态添加附加器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆