Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate Message#getFormat() #2773

Merged
merged 2 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1446,11 +1446,6 @@ public String getFormattedMessage() {
return null;
}

@Override
public String getFormat() {
return null;
}

@Override
public Object[] getParameters() {
return Constants.EMPTY_OBJECT_ARRAY;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,15 @@ public interface Message extends Serializable {
String getFormattedMessage();

/**
* Gets the format portion of the Message.
* This method has unclear semantics and inconsistent implementations – its usage is strongly discouraged.
*
* @return The message format. Some implementations, such as ParameterizedMessage, will use this as
* the message "pattern". Other Messages may simply return an empty String.
* TODO Do all messages have a format? What syntax? Using a Formatter object could be cleaner.
* (RG) In SimpleMessage the format is identical to the formatted message. In ParameterizedMessage and
* StructuredDataMessage it is not. It is up to the Message implementer to determine what this
* method will return. A Formatter is inappropriate as this is very specific to the Message
* implementation so it isn't clear to me how having a Formatter separate from the Message would be cleaner.
* @deprecated Deprecated since version {@code 2.24.0}.
* Use {@link MultiformatMessage} instead to implement messages that can format themselves in one or more encodings.
*/
String getFormat();
@Deprecated
default String getFormat() {
return null;
}

/**
* Gets parameter values, if any.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,6 @@ public String getFormattedMessage() {
throw new Error("Expected");
}

@Override
public String getFormat() {
return Strings.EMPTY;
}

@Override
public Object[] getParameters() {
return org.apache.logging.log4j.util.Constants.EMPTY_OBJECT_ARRAY;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,6 @@ public String getFormattedMessage() {
"getFormattedMessage invoked on " + Thread.currentThread().getName());
}

@Override
public String getFormat() {
return null;
}

@Override
public Object[] getParameters() {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,6 @@ public String getFormattedMessage() {
return "formatted";
}

@Override
public String getFormat() {
return null;
}

@Override
public Object[] getParameters() {
return org.apache.logging.log4j.util.Constants.EMPTY_OBJECT_ARRAY;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.util.Strings;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
Expand Down Expand Up @@ -151,11 +150,6 @@ public String getFormattedMessage() {
return message;
}

@Override
public String getFormat() {
return Strings.EMPTY;
}

@Override
public Object[] getParameters() {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.apache.logging.log4j.layout.template.json.JsonTemplateLayout;
import org.apache.logging.log4j.layout.template.json.util.JsonReader;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MultiformatMessage;
import org.apache.logging.log4j.message.ObjectMessage;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.message.StringMapMessage;
Expand Down Expand Up @@ -203,7 +204,7 @@ void test_MapMessage() {
}

@Test
void test_custom_Message() {
void test_MultiformatMessage() {

// Create the event template
final String eventTemplate = writeJson(asMap("$resolver", "message"));
Expand All @@ -216,7 +217,7 @@ void test_custom_Message() {

// Create the log event with a `TestMessage`
final LogEvent logEvent = Log4jLogEvent.newBuilder()
.setMessage(new TestMessage())
.setMessage(new TestMultiformatMessage())
.setTimeMillis(System.currentTimeMillis())
.build();

Expand All @@ -225,16 +226,24 @@ void test_custom_Message() {
.isEqualTo("bar"));
}

private static final class TestMessage implements Message {
private static final class TestMultiformatMessage implements MultiformatMessage {

@Override
public String getFormattedMessage() {
return "{\"foo\": \"bar\"}";
}

@Override
public String getFormat() {
return "JSON";
public String[] getFormats() {
return new String[] {"JSON"};
}

@Override
public String getFormattedMessage(final String[] formats) {
if (formats.length != 1 || !"JSON".equals(formats[0])) {
throw new UnsupportedOperationException();
}
return getFormattedMessage();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,22 +137,17 @@ private static void resolveString(final String fallbackKey, final Message messag
private static EventResolver createObjectResolver(final String fallbackKey) {
return (final LogEvent logEvent, final JsonWriter jsonWriter) -> {

// Skip custom serializers for `SimpleMessage`
// Skip custom serializers for SimpleMessage.
final Message message = logEvent.getMessage();
final boolean simple = message instanceof SimpleMessage;
if (!simple) {

// Try `Message` serializer
if (writeMessage(jsonWriter, message)) {
return;
}

// Try `MultiformatMessage` serializer
// Try MultiformatMessage serializer.
if (writeMultiformatMessage(jsonWriter, message)) {
return;
}

// Try `ObjectMessage` serializer
// Try ObjectMessage serializer.
if (writeObjectMessage(jsonWriter, message)) {
return;
}
Expand All @@ -163,20 +158,6 @@ private static EventResolver createObjectResolver(final String fallbackKey) {
};
}

private static boolean writeMessage(final JsonWriter jsonWriter, final Message message) {

// Check the format
final String format = message.getFormat();
if (!FORMATS[0].equalsIgnoreCase(format)) {
return false;
}

// Write the formatted message
final String messageJson = message.getFormattedMessage();
jsonWriter.writeRawString(messageJson);
return true;
}

private static boolean writeMultiformatMessage(final JsonWriter jsonWriter, final Message message) {

// Check type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,6 @@ public String getFormattedMessage() {
return getState().buffer.toString(); // not called by NoGcLayout
}

@Override
public String getFormat() {
return null;
}

@Override
public Object[] getParameters() {
return getState().getParamsCopy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://logging.apache.org/xml/ns"
xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
type="fixed">
<description format="asciidoc">Fix handling of `Message#getFormat()` in `MessageResolver` of `JsonTemplateLayout`</description>
type="deprecated">
<description format="asciidoc">Deprecate `Message#getFormat()` due to unclear semantics and inconsistent implementations</description>
</entry>
6 changes: 2 additions & 4 deletions src/site/antora/modules/ROOT/pages/manual/messages.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,9 @@ include::example$manual/messages/CustomMessageExample.java[tag=loginFailure]
[#format-type]
=== Format type

The link:../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html[`Message`] interface supports the notion of _format_ (e.g., JSON, XML) through its `getFormat()` method of return type `String`.
You can extend from <<MultiformatMessage>> (and optionally from <<MultiFormatStringBuilderFormattable>>) to implement messages that can format themselves in one or more encodings; JSON, XML, etc.
Layouts leverage this mechanism to encode a message in a particular format.
For instance, when xref:manual/json-template-layout.adoc[] figures out that `getFormat()` of a `Message` returns `JSON`, it injects the `Message#getFormattedMessage()` output as is without quoting it.
This way a message implementation can communicate its support for a particular encoding.
If you want to support multiple formats, extend from <<MultiformatMessage>>, and optionally from <<MultiFormatStringBuilderFormattable>>, instead.
For instance, when xref:manual/json-template-layout.adoc[] figures out that the array returned by `getFormats()` of a `MultiformatMessage` contains `JSON`, it injects the `MultiformatMessage#getFormattedMessage({"JSON"})` output as is without quoting it.

[#marker-interfaces]
=== Marker interfaces
Expand Down