What is the default MessageFactory for Log4J

The documentation for org.apache.logging.log4j.Logger

states

   /**
     * 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);

      

But:

  • What MessageFactory is used when I installed one?
  • What is the default message format for the factory?
  • How can I set my own factory in case the default factory cannot accomplish what I need?

Update:

Please add class names and XML element names to the response. It is very difficult to find anything about Log4J 2.x on Google without the right search terms.

+3


source to share


3 answers


  • If you haven't set a factory message, the default is used ParameterizedMessageFactory

    .
  • By default log4j uses a factory message for parameterized messages, so you can do logger.warn("hello {}", user.getName());

  • You set up your own factory by calling LogManager.getLogger(name, messageFactory)

    when you get the registrar.

If you want to use parameters of type String.format (System.out.printf format) you must use LogManager.getLogger(MyClass.class, new StringFormatterMessageFactory())

to get the logger.

If your most common use is parameterized messages ({} format), but if you sometimes want more control over the output format provided by string formatting, you can declare your logger ok (that's why it uses {} parameterized messages) and use methods Logger.printf

.



Example:

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);
    }
}

      

It's all in the code. No configuration (XML or otherwise) involved.

+8


source


This thread has been around for about one year now, but maybe I can still help some guys because I had the same problem and found out how to set my own MessageFactory by default. It's a bit tricky, maybe someone else knows a better way without creating so many classes. But it works for me:

  • Create your own MessageFactory (from AbstractMessageFactory

    or just use the interface MessageFactory

    )
  • Create a new LoggerContext (extend from class LoggerContext

    or use interfaceLoggerContext

    • Override newInstance(LoggerContext, String, MessageFactory)

      and return the previously defined MessageFactory if argument MessageFactory

      isnull

  • Create a new ContextSelector (extend from ClassLoaderContextSelector

    or just use an interface ContextSelector

    ).
    • Override the createContext (String, URI) method and return a new instance of your previously defined LoggerContext
  • Create a file log4j.component.properties

    in your classpath and set the property Log4jContextSelector

    to the fully qualified name of your step 3 created by contextSelector
    • Alternative: don't create the file, just set the system property Log4jContextSelector

      to fqn

Some code examples (no comments):

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

      

+1


source


1) What MessageFactory is used when I installed any?

Using @Remko Popma's hint I figured out that the default factory message is org.apache.logging.log4j.message.ParameterizedMessageFactory

.

2) What message format is the default factory used in?

Syntax {}

that also uses java.util.logger

.

3) How can I set my own factory in case the default factory cannot do what I need?

Do not know yet.

0


source







All Articles