Log4J的默认MessageFactory是什么

时间:2014-09-15 09:44:53

标签: java logging log4j log4j2

org.apache.logging.log4j.Logger的文档说

   /**
     * Logs a message with parameters at the given level.
     *
     * @param level the logging level
     * @param message the message to log; the format depends on the message factory.
     * @param params parameters to the message.
     * @see #getMessageFactory()
     */
    void log(Level level, String message, Object... params);

可是:

  1. 当我设置任何一个时使用了哪个MessageFactory?
  2. 哪种邮件格式使用默认工厂?
  3. 如果默认工厂无法满足我的需求,我如何设置自己的工厂?
  4. 更新

    请在答案中添加类名和XML元素名称。没有正确的搜索条件,很难在Google上找到关于Log4J 2.x的任何内容。

3 个答案:

答案 0 :(得分:12)

  1. 如果您未设置消息工厂,则默认使用ParameterizedMessageFactory
  2. 默认情况下,log4j使用消息工厂来处理参数化消息,因此您可以执行logger.warn("hello {}", user.getName());
  3. 当您获得记录器时,通过调用LogManager.getLogger(name, messageFactory)来设置自己的工厂。
  4. 如果需要String.format类型的params(System.out.printf格式),则可以使用LogManager.getLogger(MyClass.class, new StringFormatterMessageFactory())来获取记录器。

    如果您最常见的用法是参数化消息({}格式),但如果您偶尔需要对字符串格式化程序提供的输出格式进行更多控制,则可以正常声明您的记录器(因此它使用{}参数化消息),并使用Logger.printf方法。

    示例:

    class MyClass {
        private static Logger logger = LogManager.getLogger(MyClass.class);
    
        public void someMethod() {
            // use printf here to precisely control the number of digits displayed
            logger.printf(Level.INFO, "pi: %.5f", Math.PI);
        }
    }
    

    这都是代码。不涉及配置(XML或其他)。

答案 1 :(得分:1)

这个帖子已经有一年了,但也许我仍然可以帮助一些人,因为我遇到了同样的问题,并找到了如何设置自己的默认MessageFactory的方法。这有点棘手,也许别人知道一个更好的方法而不创造这么多的课程。但对我来说它有效:

  1. 创建自己的MessageFactory(从AbstractMessageFactory扩展或只使用MessageFactory界面)
  2. 创建一个新的LoggerContext(从LoggerContext类扩展或使用LoggerContext接口
    • 覆盖newInstance(LoggerContext, String, MessageFactory)并返回您之前定义的MessageFactory,如果参数messageFactorynull
  3. 创建一个新的ContextSelector(从ClassLoaderContextSelector扩展或仅使用ContextSelector接口)。
    • 覆盖方法createContext(String,URI)并返回先前定义的LoggerContext的新实例
  4. 在类路径中创建文件log4j.component.properties,并将属性Log4jContextSelector设置为您在步骤3中创建的contextSelector的完全限定名称
    • 替代方法:不要创建文件,只需将系统属性Log4jContextSelector设置为fqn
  5. 一些代码示例(没有任何注释):

    <强>的MessageFactory:

    public final class OwnMessageFactory extends AbstractMessageFactory
    {
      public static final OwnMessageFactory INSTANCE = new OwnMessageFactory();
    
      @Override
      public Message newMessage(final String message, final Object... params)
      {
        return new OwnDataMessage(message, params);
      }
    }
    

    <强> LoggerContext:

    public class OwnLoggerContext extends LoggerContext
    {
      // constructors
    
      protected Logger newInstance(final LoggerContext ctx, final String name, MessageFactory messageFactory)
      {
        if (null == messageFactory)
          messageFactory = OwnMessageFactory.INSTANCE;
    
        return super.newInstance(ctx, name, messageFactory);
      }
    
    }
    

    <强> ContextSelector

    public class OwnContextSelector extends ClassLoaderContextSelector
    {
    
      @Override
      protected LoggerContext createContext(String name, URI configLocation)
      {
        return new OwnLoggerContext(name, null, configLocation);
      }
    
    }
    

    <强> log4j2.component.properties

    Log4jContextSelector=com.example.OwnContextSelector
    

答案 2 :(得分:0)

1)当我设置了什么时使用了哪个MessageFactory?

使用@Remko Popma提示我输出默认消息工厂为org.apache.logging.log4j.message.ParameterizedMessageFactory

2)哪种消息格式使用默认工厂?

{}使用的java.util.logger语法。

3)如果默认工厂无法满足我的需求,我如何设置自己的工厂?

还不知道。