Skip to content

Commit

Permalink
Provide a uniform Log4j 1.x message factory
Browse files Browse the repository at this point in the history
This PR provides a factory method that decides the type of message
based on the runtime type of the logged object (cf. [LOG4J2-3080](
https://issues.apache.org/jira/browse/LOG4J2-3080)).

These are applied to both `maybeLog` and `forceLog`.
  • Loading branch information
ppkarwasz committed Feb 21, 2022
1 parent 77656c6 commit 2858c49
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 33 deletions.
49 changes: 21 additions & 28 deletions log4j-1.2-api/src/main/java/org/apache/log4j/Category.java
Expand Up @@ -307,17 +307,28 @@ private void fireRemoveAppenderEvent(final Appender appender) {
}
}

private static Message createMessage(Object message) {
if (message instanceof String) {
return new SimpleMessage((String) message);
}
if (message instanceof CharSequence) {
return new SimpleMessage((CharSequence) message);
}
if (message instanceof Map) {
return new MapMessage<>((Map<String, ?>) message);
}
if (message instanceof Message) {
return (Message) message;
}
return new ObjectMessage(message);
}

public void forcedLog(final String fqcn, final Priority level, final Object message, final Throwable t) {
final org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString());
final Message msg = createMessage(message);
if (logger instanceof ExtendedLogger) {
@SuppressWarnings("unchecked")
final Message msg = message instanceof Message ? (Message) message
: message instanceof Map ? new MapMessage((Map) message) : new ObjectMessage(message);
((ExtendedLogger) logger).logMessage(fqcn, lvl, null, msg, t);
} else {
final ObjectRenderer renderer = get(message.getClass());
final Message msg = message instanceof Message ? (Message) message
: renderer != null ? new RenderedMessage(renderer, message) : new ObjectMessage(message);
logger.log(lvl, msg, t);
}
}
Expand Down Expand Up @@ -537,43 +548,25 @@ public void l7dlog(final Priority priority, final String key, final Throwable t)

public void log(final Priority priority, final Object message) {
if (isEnabledFor(priority)) {
@SuppressWarnings("unchecked")
final Message msg = message instanceof Map ? new MapMessage((Map) message) : new ObjectMessage(message);
forcedLog(FQCN, priority, msg, null);
forcedLog(FQCN, priority, message, null);
}
}

public void log(final Priority priority, final Object message, final Throwable t) {
if (isEnabledFor(priority)) {
@SuppressWarnings("unchecked")
final Message msg = message instanceof Map ? new MapMessage((Map) message) : new ObjectMessage(message);
forcedLog(FQCN, priority, msg, t);
forcedLog(FQCN, priority, message, t);
}
}

public void log(final String fqcn, final Priority priority, final Object message, final Throwable t) {
if (isEnabledFor(priority)) {
final Message msg = new ObjectMessage(message);
forcedLog(fqcn, priority, msg, t);
forcedLog(fqcn, priority, message, t);
}
}

void maybeLog(final String fqcn, final org.apache.logging.log4j.Level level, final Object message, final Throwable throwable) {
if (logger.isEnabled(level)) {
final Message msg;
if (message instanceof String) {
msg = new SimpleMessage((String) message);
}
// SimpleMessage treats String and CharSequence differently, hence this else-if block.
else if (message instanceof CharSequence) {
msg = new SimpleMessage((CharSequence) message);
} else if (message instanceof Map) {
@SuppressWarnings("unchecked")
final Map<String, ?> map = (Map<String, ?>) message;
msg = new MapMessage<>(map);
} else {
msg = new ObjectMessage(message);
}
final Message msg = createMessage(message);
if (logger instanceof ExtendedLogger) {
((ExtendedLogger) logger).logMessage(fqcn, level, null, msg, throwable);
} else {
Expand Down
49 changes: 44 additions & 5 deletions log4j-1.2-api/src/test/java/org/apache/log4j/CategoryTest.java
Expand Up @@ -86,26 +86,65 @@ public void testForcedLog() {
final MockCategory category = new MockCategory("org.example.foo");
category.setAdditivity(false);
((org.apache.logging.log4j.core.Logger) category.getLogger()).addAppender(appender);
// Logging a String
category.info("Hello, World");
final List<LogEvent> list = appender.getEvents();
List<LogEvent> list = appender.getEvents();
int events = list.size();
assertTrue("Number of events should be 1, was " + events, events == 1);
LogEvent event = list.get(0);
Message msg = event.getMessage();
assertNotNull("No message", msg);
assertTrue("Incorrect Message type", msg instanceof ObjectMessage);
// LOG4J2-3080: use message type consistently
assertTrue("Incorrect Message type", msg instanceof SimpleMessage);
assertEquals("Hello, World", msg.getFormat());
appender.clear();
// Logging a String map
category.info(Collections.singletonMap("hello", "world"));
list = appender.getEvents();
events = list.size();
assertTrue("Number of events should be 1, was " + events, events == 1);
event = list.get(0);
msg = event.getMessage();
assertNotNull("No message", msg);
assertTrue("Incorrect Message type", msg instanceof MapMessage);
Object[] objects = msg.getParameters();
assertTrue("Incorrect Object type", objects[0] instanceof String);
assertEquals("world", objects[0]);
appender.clear();
category.log(Priority.INFO, "Hello, World");
// Logging a generic map
category.info(Collections.singletonMap(1234L, "world"));
list = appender.getEvents();
events = list.size();
assertTrue("Number of events should be 1, was " + events, events == 1);
event = list.get(0);
msg = event.getMessage();
assertNotNull("No message", msg);
assertTrue("Incorrect Message type", msg instanceof MapMessage);
objects = msg.getParameters();
assertEquals("world", objects[0]);
appender.clear();
// Logging an object
final Object obj = new Object();
category.info(obj);
list = appender.getEvents();
events = list.size();
assertTrue("Number of events should be 1, was " + events, events == 1);
event = list.get(0);
msg = event.getMessage();
assertNotNull("No message", msg);
assertTrue("Incorrect Message type", msg instanceof ObjectMessage);
objects = msg.getParameters();
assertTrue("Incorrect Object type", objects[0] instanceof String);
assertEquals(obj, objects[0]);
appender.clear();

category.log(Priority.INFO, "Hello, World");
list = appender.getEvents();
events = list.size();
assertTrue("Number of events should be 1, was " + events, events == 1);
event = list.get(0);
msg = event.getMessage();
assertNotNull("No message", msg);
assertTrue("Incorrect Message type", msg instanceof SimpleMessage);
assertEquals("Hello, World", msg.getFormat());
appender.clear();
}

Expand Down

0 comments on commit 2858c49

Please sign in to comment.