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.
source to share
- 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.
source to share
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 interfaceMessageFactory
) - Create a new LoggerContext (extend from class
LoggerContext
or use interfaceLoggerContext
- Override
newInstance(LoggerContext, String, MessageFactory)
and return the previously defined MessageFactory if argumentMessageFactory
isnull
- Override
- Create a new ContextSelector (extend from
ClassLoaderContextSelector
or just use an interfaceContextSelector
).- 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 propertyLog4jContextSelector
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
- Alternative: don't create the file, just set the system property
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
source to share
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.
source to share